OSDN Git Service

b80996a8017a3b03c249a83dbf7a9e8a3d16c9da
[nucleus-jp/nucleus-next.git] / nucleus / plugins / NP_Medium.php
1 <?php
2 class NP_Medium extends NucleusPlugin
3 {
4         private $skin = '';
5         
6         public $type = '';
7         
8         public $collection = '';
9         public $description = '';
10         public $filter = '';
11         public $message = '';
12         
13         public $amount = 0;
14         public $media = array();
15         public $offset = 0;
16         public $prev = 0;
17         public $next = 0;
18         
19         public function getName()
20         {
21                 return 'Medium';
22         }
23         
24         public function getAuthor()
25         {
26                 return 'Sakamoto Takashi';
27         }
28         
29         public function getURL()
30         {
31                 return '';
32         }
33         
34         public function getVersion()
35         {
36                 return '0.9(beta)';
37         }
38         
39         public function getMinNucleusVersion()
40         {
41                 return '400';
42         }
43         
44         public function getDescription()
45         {
46                 return NP_MEDIUM_DESC;
47         }
48         
49         public function supportsFeature($what)
50         {
51                 return ( $what == 'SqlTablePrefix' );
52         }
53         
54         public function getEventList()
55         {
56                 return array('AdminPrePageHead', 'AdminTemplateExtraFields');
57         }
58         
59         public function init()
60         {
61                 // include translation file for this plugin
62                 if ( file_exists($this->getDirectory() . 'locales/' . i18n::get_current_locale() . '.' . i18n::get_current_charset() . '.php') )
63                 {
64                         include_once($this->getDirectory() . 'locales/' . i18n::get_current_locale() . '.' . i18n::get_current_charset() . '.php');
65                 }
66                 else
67                 {
68                         include_once($this->getDirectory() . 'locales/en_Latn_US.UTF-8.php');
69                 }
70                 return;
71         }
72         
73         public function install()
74         {
75                 $this->createOption('collectionlist_head', 'NP_MEDIUM_COLLECTIONLIST_HEAD', 'textarea',
76                           "<label for=\"media_collection\">"
77                         . "<%text(_MEDIA_COLLECTION_LABEL)%>"
78                         . "</label>"
79                         . "<select name=\"collection\" id=\"media_collection\">\n");
80                 
81                 $this->createOption('collectionlist_body', 'NP_MEDIUM_COLLECTIONLIST_BODY', 'textarea',
82                           "<option value=\"<%name%>\" <%selected%>>"
83                         . "<%desc%>"
84                         . "</option>\n");
85                         
86                 $this->createOption('collectionlist_foot', 'NP_MEDIUM_COLLECTIONLIST_FOOT', 'textarea',
87                         "</select>\n");
88                 
89                 $this->createOption('medialist_head', 'NP_MEDIUM_MEDIALIST_HEAD', 'textarea',
90                           "<table frame=\"box\" rules=\"frame\" sumary=\"<%text(Media List)%>\">\n"
91                         . "<caption><%text(_MEDIA_COLLECTION_LABEL)%> <%description%></caption>\n"
92                         . "<thead>\n"
93                         . "<tr>\n"
94                         . "<th><%text(_MEDIA_MODIFIED)%></th>\n"
95                         . "<th><%text(_MEDIA_FILENAME)%></th>\n"
96                         . "<th><%text(_MEDIA_DIMENSIONS)%></th>\n"
97                         . "</tr>\n"
98                         . "</thead>\n"
99                         . "<tbody>\n");
100                 
101                 $this->createOption('medialist_body_image', 'NP_MEDIUM_MEDIALIST_BODY_IMAGE', 'textarea',
102                           "<tr>\n"
103                         . "<td><%timestamp%></td>\n"
104                         . "<td>\n"
105                         . "<a href=\"<%mediumurl%>\" onclick=\"medium.chooseImage('<%collection%>', '<%filename%>', <%width%>, <%height%>);\" title=\"<%filename%>\">\n"
106                         . "<%shortfilename%>\n"
107                         . "</a>\n"
108                         . "(\n"
109                         . "<a href=\"<%mediumurl%>\" onclick=\"window.open(this.href); return false;\" title=\"<%text(_MEDIA_VIEW_TT%>\">\n"
110                         . "<%text(_MEDIA_VIEW)%>\n"
111                         . "</a>\n"
112                         . ")\n"
113                         . "</td>\n"
114                         . "<td><%width%> x <%height%></td>\n"
115                         . "</tr>\n");
116                 
117                 $this->createOption('medialist_body_other', 'NP_MEDIUM_MEDIALIST_BODY_OTHER', 'textarea',
118                           "<tr>\n"
119                         . "<td><%timestamp%></td>\n"
120                         . "<td>\n"
121                         . "<a href=\"<%mediumurl%>\" onclick=\"medium.chooseOther('<%collection%>', '<%filename%>');\" title=\"<%filename%>\">\n"
122                         . "<%shortfilename%>\n"
123                         . "</a>\n"
124                         . "</td>\n"
125                         . "<td><%size%> KB</td>\n"
126                         . "</tr>\n");
127                 
128                 $this->createOption('medialist_foot', 'NP_MEDIUM_MEDIALIST_FOOT', 'textarea',
129                           "</tbody>\n"
130                         . "</table>\n");
131                 
132                 $this->createOption('medialist_blank', 'NP_MEDIUM_MEDIALIST_BLANK', 'textarea',
133                           "<p>Nothing</p>\n");
134                 
135                 return;
136         }
137         
138         public function event_AdminPrePageHead($data)
139         {
140                 global $CONF;
141                 
142                 if ( !in_array($data['action'], array('createitem', 'itemedit')) )
143                 {
144                         return;
145                 }
146                 
147                 $data['extrahead'] .= "<script type=\"text/javascript\" src=\"{$CONF['PluginURL']}/medium/scripts/medium.js\"></script>\n"
148                                     . "<script type=\"text/javascript\">\n"
149                                     . " medium.url = '{$CONF['ActionURL']}?action=plugin&name=medium';\n"
150                                     . '</script>'."\n";
151                 
152                 return;
153         }
154         
155         public function doAction($type)
156         {
157                 global $CONF, $DIR_MEDIA, $manager, $member;
158                 
159                 /*
160                  * defines how much media items will be shown per page. You can override this
161                  * in config.php if you like. (changing it in config.php instead of here will
162                  * allow your settings to be kept even after a Nucleus upgrade)
163                  */
164                 $CONF['MediaPerPage'] = 10;
165                 
166                 /* include all classes */
167                 if ( !class_exists('Media', FALSE) )
168                 {
169                         include_libs('MEDIA.php', FALSE, FALSE);
170                 }
171                 
172                 /* include all classes */
173                 if ( !class_exists('BaseActions', FALSE) )
174                 {
175                         include_libs('BaseActions.php', FALSE, FALSE);
176                 }
177                 
178                 if ( !class_exists('MediumActions', FALSE) )
179                 {
180                         include($this->getDirectory() . 'MediumActions.php');
181                 }
182                 
183                 /* get skin object */
184                 $skinid = $CONF['AdminSkin'];
185                 if ( !Skin::existsID($skinid) )
186                 {
187                         echo _ERROR_SKIN;
188                         exit;
189                 }
190                 $this->skin = new Skin($skinid, 'MediumActions', 'MediumSkin');
191                 
192                 /* user needs to be logged in to use this */
193                 if ( !$member->isLoggedIn() )
194                 {
195                         $this->login();
196                         exit;
197                 }
198                 
199                 /* check if member is on at least one teamlist */
200                 $query = 'SELECT * FROM %s WHERE tmember=%d;';
201                 $query = sprintf($query, sql_table('team'), $member->getID());
202                 $teams = DB::getResult($query);
203                 if ( $teams->rowCount() == 0 && !$member->isAdmin() )
204                 {
205                         $this->error(_ERROR_DISALLOWEDUPLOAD);
206                         return;
207                 }
208                 
209                 /* avoid directory travarsal and accessing invalid directory */
210                 $this->collection = requestVar('collection');
211                 $this->description = $this->collection;
212                 if ( !$this->collection || $this->collection == $member->getID()
213                    || !@is_dir("{$DIR_MEDIA}{$this->collection}") )
214                 {
215                         $this->collection = $member->getID();
216                         $this->description = PRIVATE_COLLECTION;
217                 }
218                 else if ( !Media::isValidCollection($this->collection) )
219                 {
220                         $this->error(_ERROR_DISALLOWED);
221                         return;
222                 }
223                 
224                 /* check type */
225                 if ( !in_array($type, array('select', 'choose', 'upload')) )
226                 {
227                         $type = 'select';
228                 }
229                 
230                 /* check ticket */
231                 $needless_to_check = array('select', 'choose');
232                 if ( !in_array($type, $needless_to_check) )
233                 {
234                         if ( !$manager->checkTicket() )
235                         {
236                                 $this->error(_ERROR_BADTICKET);
237                         return;
238                         }
239                 }
240                 
241                 /* processing */
242                 switch ( $type )
243                 {
244                 case 'choose':
245                         if ( !$member->isAdmin() && !$CONF['AllowUpload'] )
246                         {
247                                 $this->error(_ERROR_DISALLOWED);
248                                 return;
249                         }
250                         $this->choose();
251                         break;
252                 case 'upload':
253                         if ( !$member->isAdmin() && !$CONF['AllowUpload'] )
254                         {
255                                 $this->error(_ERROR_DISALLOWED);
256                                 return;
257                         }
258                         $this->upload();
259                         break;
260                 case 'select':
261                 default:
262                         $this->select();
263                         break;
264                 }
265                 exit;
266         }
267         
268         private function select()
269         {
270                 global $CONF;
271                 
272                 $this->type = 'select';
273                 $this->filter = requestVar('filter');
274                 
275                 $media = Media::getMediaListByCollection($this->collection, $this->filter);
276                 
277                 $this->amount = count($media);
278                 $this->offset = intRequestVar('offset');
279                 
280                 if ( $this->amount > 0 )
281                 {
282                         if ( ($this->offset + $CONF['MediaPerPage']) >= $this->amount )
283                         {
284                                 $this->offset = $this->amount - $CONF['MediaPerPage'];
285                         }
286                         
287                         if ( $this->offset < 0 )
288                         {
289                                 $this->offset = 0;
290                         }
291                         
292                         $start = $this->offset;
293                         $end = $this->offset + $CONF['MediaPerPage'];
294                         $next = $end;
295                         $prev = $start - $CONF['MediaPerPage'];
296                         
297                         if ( $prev < 0 )
298                         {
299                                 $prev = 0;
300                         }
301                         
302                         if ( $end > $this->amount )
303                         {
304                                 $end = $this->amount;
305                         }
306                         
307                         if ( $start > 0 )
308                         {
309                                 $this->prev = $prev;
310                         }
311                         
312                         if ( $end < $this->amount )
313                         {
314                                 $this->next = $next;
315                         }
316                         
317                         for( $index = $start; $index < $end; $index++ )
318                         {
319                                 $this->media[] = $media[$index];
320                         }
321                         
322                         unset($media);
323                 }
324                 
325                 $this->skin->parse('fileparse', $this->getDirectory() . 'skins/select.skn');
326                 return;
327         }
328         
329         private function choose()
330         {
331                 $this->type = 'choose';
332                 $this->skin->parse('fileparse', $this->getDirectory() . 'skins/choose.skn');
333         }
334         
335         private function upload()
336         {
337                 global $CONF;
338                 
339                 $this->type = 'upload';
340                 
341                 $uploadInfo = postFileInfo('uploadfile');
342                 
343                 $filename = $uploadInfo['name'];
344                 $filetype = $uploadInfo['type'];
345                 $filesize = $uploadInfo['size'];
346                 $filetempname = $uploadInfo['tmp_name'];
347                 $fileerror = (integer) $uploadInfo['error'];
348                 
349                 switch ( $fileerror )
350                 {
351                         // include error code for debugging
352                         // (see http://www.php.net/manual/en/features.file-upload.errors.php)
353                         case 0:         // = UPLOAD_ERR_OK
354                                 break;
355                         case 1:         // = UPLOAD_ERR_INI_SIZE
356                         case 2:         // = UPLOAD_ERR_FORM_SIZE
357                                 $this->error(_ERROR_FILE_TOO_BIG);
358                                 return;
359                         case 3:         // = UPLOAD_ERR_PARTIAL
360                         case 4:         // = UPLOAD_ERR_NO_FILE
361                         case 6:         // = UPLOAD_ERR_NO_TMP_DIR
362                         case 7:         // = UPLOAD_ERR_CANT_WRITE
363                         default:
364                                 $this->error(_ERROR_BADREQUEST . ' (' . $fileerror . ')');
365                                 return;
366                 }
367                 
368                 if ( $filesize > $CONF['MaxUploadSize'] )
369                 {
370                         $this->error(_ERROR_FILE_TOO_BIG);
371                         return;
372                 }
373                 
374                 // check file type against allowed types
375                 $ok = 0;
376                 $allowedtypes = preg_split('#,#', $CONF['AllowedTypes']);
377                 foreach ( $allowedtypes as $type )
378                 {
379                         if ( preg_match("#.{$type}$#i", $filename) )
380                         {
381                                 $ok = 1;
382                         }
383                 }
384                 if ( !$ok )
385                 {
386                         $this->error(_ERROR_BADFILETYPE);
387                         return;
388                 }
389                 
390                 if ( !is_uploaded_file($filetempname) )
391                 {
392                         $this->error(_ERROR_BADREQUEST);
393                         return;
394                 }
395                 // prefix filename with current date (YYYY-MM-DD-)
396                 // this to avoid nameclashes
397                 if ( $CONF['MediaPrefix'] )
398                 {
399                         $filename = i18n::formatted_datetime("%Y%m%d-", time()) . $filename;
400                 }
401                 
402                 $res = Media::addMediaObject($this->collection, $filetempname, $filename);
403                 
404                 if ( $res != '' )
405                 {
406                         $this->error($res);
407                         return;
408                 }
409                 
410                 $this->select();
411                 return;
412         }
413         
414         private function login()
415         {
416                 $this->type = 'login';
417                 $this->skin->parse('fileparse', $this->getDirectory() . 'skins/login.skn');
418                 return;
419         }
420         
421         private function error($msg)
422         {
423                 $this->type = 'error';
424                 $this->message = $msg;
425                 $this->skin->parse('fileparse', $this->getDirectory() . 'skins/error.skn');
426                 return;
427         }
428 }