OSDN Git Service

ADD: Mocchiが手がけたファイル管理プラグイン一式をコミット
[nucleus-jp/nucleus-plugins.git] / NP_Attach / NP_Attach.php
1 <?php\r
2 /**\r
3  * Attach plugin for Nucleus CMS\r
4  * Version 0.9.6 (1.0 RC2) for PHP5\r
5  * Written By Mocchi, Apr. 04, 2011\r
6  * Original code was written by NKJG and yamamoto, May 02, 2009\r
7  * This plugin depends on NP_Thumbnail and NP_MediaUtils\r
8  * \r
9  * This program is free software; you can redistribute it and/or\r
10  * modify it under the terms of the GNU General Public License\r
11  * as published by the Free Software Foundation; either version 3\r
12  * of the License, or (at your option) any later version.\r
13  */\r
14 \r
15 // TODO (hard) If itemOption is set as "hidden", PrePluginOptionsUpdate event is not generated, related Nucleus CMS library problem.\r
16 // TODO (hard) There are no ways to show the error message even if upload processing is failed.\r
17 // TODO (medium) all of the plugin options are purged when uninstalling plugins.\r
18 \r
19 class NP_Attach extends NucleusPlugin {\r
20         static private  $buffer = false;\r
21         static private  $blogid = 0;\r
22         static private  $itemid = 0;\r
23         static private  $amount = 0;\r
24         static private  $data   = array();\r
25         \r
26         public function getName()                       { return 'Attach'; }\r
27         public function getAuthor()             { return 'Mocchi, yamamoto, NKJG'; }\r
28         public function getURL()                        { return 'http://japan.nucleuscms.org/wiki/plugins:attach'; }\r
29         public function getVersion()            { return '0.9.6 (1.0 RC2)'; }\r
30         public function getDescription()        { return _NP_ATTACH_01; }\r
31         public function getPluginDep()  { return array('NP_MediaUtils', 'NP_Thumbnail');}\r
32         public function getMinNucleusVersion()          {return 340;}\r
33         public function supportsFeature($feature)       { return in_array ($feature, array ('SqlTablePrefix', 'SqlApi'));}\r
34         public function getEventList() {\r
35                 return array (\r
36                         'PrePluginOptionsEdit', \r
37                         'AdminPrePageHead',\r
38                         'BookmarkletExtraHead',\r
39                         'PreItem',\r
40                         'PreAddItem',\r
41                         'PreUpdateItem',\r
42                         'PostAddItem',\r
43                         'PostUpdateItem',\r
44                         'PrePluginOptionsUpdate',\r
45                         'AddItemFormExtras',\r
46                         'EditItemFormExtras');\r
47         }\r
48         \r
49         public function install () {\r
50                 $this->createOption('maxwidth', '_NP_ATTACH_02', 'text', '90',  'datatype=numerical');\r
51                 $this->createOption('maxheight', '_NP_ATTACH_03', 'text', '90',  'datatype=numerical');\r
52                 $this->createOption('admin_popup_template', '_NP_ATTACH_04', 'textarea', '<a href="<%rawpopuplink%>" title="<%popuptext%>" onclick="<%popupcode%>"><img src="<%thumb_url%>" width="<%thumb_width%>" height="<%thumb_height%>" alt="<%popuptext%>" /></a>');\r
53                 $this->createOption('admin_media_template', '_NP_ATTACH_05', 'textarea', '<a href="<%link%>" title="<%text%>"><%text%></a>');\r
54                 $this->createBlogOption('amount', '_NP_ATTACH_06', 'text', '3');\r
55                 $this->createBlogOption('blog_image_template', '_NP_ATTACH_07', 'textarea', '<img src="<%link%>" width="<%width%>" height="<%height%>" alt="<%text%>" />');\r
56                 $this->createBlogOption('blog_media_template', '_NP_ATTACH_08', 'textarea', '<a href="<%link%>" title="<%text%>"><%text%></a>');\r
57                 $this->createItemOption('media', '_NP_ATTACH_09', 'text', '');\r
58                 return;\r
59         }\r
60         \r
61         public function uninstall () {\r
62                 return;\r
63         }\r
64         \r
65         public function init() {\r
66                 if(!defined('_NP_ATTACH_01')) {\r
67                         $language = preg_replace('#[/|\\\\]#', '', getLanguageName());\r
68                         if (file_exists($this->getDirectory() . $language.'.php')) {\r
69                                 include($this->getDirectory() . $language.'.php');\r
70                         } else {\r
71                                 include($this->getDirectory() . 'english.php');\r
72                         }\r
73                 }\r
74                 return;\r
75         }\r
76         \r
77 /*\r
78  * for translation\r
79  */\r
80         public function event_PrePluginOptionsEdit ($data)\r
81         {\r
82                 if ($data['context'] != 'global') {\r
83                         foreach($data['options'] as $key => $option) {\r
84                                 if ($option['pid'] == $this->getID()) {\r
85                                         if (defined($option['description'])) {\r
86                                                 $data['options'][$key]['description'] = constant($option['description']);\r
87                                         }\r
88                                         if ($option['type'] == 'select') {\r
89                                                 foreach (explode('|', $option['typeinfo']) as $option) {\r
90                                                         if (defined($option)) {\r
91                                                                 $data['options'][$key]['typeinfo'] = str_replace($option, constant($option), $data['options'][$key]['typeinfo']);\r
92                                                         }\r
93                                                 }\r
94                                         }\r
95                                 }\r
96                         }\r
97                 } else if ($data['plugid'] == $this->getID()) {\r
98                         foreach($data['options'] as $key => $option){\r
99                                 if (defined($option['description'])) {\r
100                                         $data['options'][$key]['description'] = constant($option['description']);\r
101                                 }\r
102                                 if ($option['type'] == 'select') {\r
103                                                 foreach (explode('|', $option['typeinfo']) as $option) {\r
104                                                         if (defined($option)) {\r
105                                                                 $data['options'][$key]['typeinfo'] = str_replace($option, constant($option), $data['options'][$key]['typeinfo']);\r
106                                                         }\r
107                                                 }\r
108                                 }\r
109                         }\r
110                 }\r
111                 return;\r
112         }\r
113         \r
114 /*\r
115  * for translation\r
116  */\r
117         static private function t ($text,$array=array()){\r
118                 if (is_array($array)) {\r
119                         $search = array();\r
120                         $replace = array();\r
121                         \r
122                         foreach ($array as $key => $value){\r
123                                 if (is_array($value)) {\r
124                                         continue;\r
125                                 }\r
126                                 $search[] = '<%'.preg_replace('/[^a-zA-Z0-9_]+/','',$key).'%>';\r
127                                 $replace[] = $value;\r
128                         }\r
129                 }\r
130                 return htmlspecialchars (str_replace($search, $replace, $text), ENT_QUOTES, _CHARSET);\r
131         }\r
132         \r
133 /*\r
134  * Change enctype attribute of form element as 'multipart/form-data'\r
135  * Insert interface\r
136  */\r
137         public function event_AdminPrePageHead ($data) {\r
138                 if (!in_array ($data['action'], array ('createitem', 'itemedit'))) {\r
139                  return;\r
140                 }\r
141                 \r
142                 self::prepareEnctype ();\r
143                 return;\r
144         }\r
145         \r
146         public function event_BookmarkletExtraHead ($data) {\r
147                 self::prepareEnctype ();\r
148                 return;\r
149         }\r
150         \r
151         public function event_AddItemFormExtras ($data) {\r
152                 global $DIR_MEDIA;\r
153                 $blog = $data['blog'];\r
154                 self::$blogid = $blog->blogid;\r
155                 self::$itemid = 0;\r
156                 self::setEnctype ();\r
157                 $this->setData($DIR_MEDIA);\r
158                 $this->showInterface ();\r
159                 return;\r
160         }\r
161         \r
162         public function event_EditItemFormExtras ($data) {\r
163                 global $DIR_MEDIA;\r
164                 $blog = $data['blog'];\r
165                 self::$blogid = $blog->blogid;\r
166                 self::$itemid = $data['itemid'];\r
167                 self::setEnctype ();\r
168                 $this->setData($DIR_MEDIA);\r
169                 $this->showInterface ();\r
170                 return;\r
171         }\r
172         \r
173 /*\r
174  * Process upload and update plugin item option\r
175  */\r
176         public function event_PreAddItem ($data) {\r
177                 self::$blogid = $data['blog']->blogid;\r
178                 return;\r
179         }\r
180         public function event_PreUpdateItem ($data) {\r
181                 self::$blogid = $data['blog']->blogid;\r
182                 return;\r
183         }\r
184         public function event_PostAddItem ($data) {\r
185                 self::$itemid = $data['itemid'];\r
186                 return;\r
187         }\r
188         public function event_PostUpdateItem ($data) {\r
189                 self::$itemid = $data['itemid'];\r
190                 return;\r
191         }\r
192         public function event_PrePluginOptionsUpdate ($data) {\r
193                 global $DIR_MEDIA, $member;\r
194                 \r
195                 if ($data['plugid'] != $this->getID () || $data['optionname'] != 'media') {\r
196                         return;\r
197                 }\r
198                 \r
199                 $this->setData($DIR_MEDIA);\r
200                 self::batchRequest ($DIR_MEDIA, $member->getID());\r
201                 \r
202                 $value = '';\r
203                 foreach (self::$data as $datum) {\r
204                         if (!$datum['path']) {\r
205                                 continue;\r
206                         }\r
207                         $value .= "{$datum['path']}:{$datum['alt']}:{$datum['way']};";\r
208                 }\r
209                 \r
210                 $data['value'] = $value;\r
211                 return;\r
212         }\r
213         \r
214 /*\r
215  * Show media in item\r
216  */\r
217         public function event_PreItem($data) {\r
218                 global $DIR_MEDIA;\r
219                 self::$blogid =& $data['blog']->blogid;\r
220                 self::$itemid =& $data["item"]->itemid;\r
221                 $this->setData($DIR_MEDIA);\r
222                 \r
223                 $data["item"]->body = preg_replace_callback("#<\%Attach\((.+?)(,.+?)?(,.+?)?\)%\>#", array(&$this, 'getParsedTag'), $data["item"]->body);\r
224                 $data["item"]->more = preg_replace_callback("#<\%Attach\((.+?)(,.+?)?(,.+?)?\)%\>#", array(&$this, 'getParsedTag'), $data["item"]->more);\r
225                 return;\r
226         }\r
227         public function doTemplateVar($item, $mediumid) {\r
228                 global $DIR_MEDIA, $blogid;\r
229                 \r
230                 if (!self::$itemid || !self::$blogid) {\r
231                         self::$blogid = $blogid;\r
232                         self::$itemid = $item->itemid;\r
233                         $this->setData($DIR_MEDIA);\r
234                 }\r
235                 $this->getParsedTag(array('item', $mediumid));\r
236                 return;\r
237         }\r
238         \r
239         private function getParsedTag($match) {\r
240                 global $DIR_MEDIA, $manager;\r
241                 \r
242                 $maxwidth = 0;\r
243                 $maxheight = 0;\r
244                 if (array_key_exists(3, $match)) {\r
245                         $maxheight = (integer) trim($match[3], ',');\r
246                 }\r
247                 if (array_key_exists(2, $match)) {\r
248                         $maxwidth = (integer) trim($match[2], ',');\r
249                 }\r
250                 \r
251                 $data = &self::$data;\r
252                 $mediumid = $match[1];\r
253                 $mediumid--;\r
254                 \r
255                 if (!array_key_exists ($mediumid, $data) || !$data[$mediumid]['path']) {\r
256                         return;\r
257                 }\r
258                 \r
259                 $NP_Thumbnail =& $manager->getPlugin('NP_Thumbnail');\r
260                 \r
261                 if ($maxwidth==0 && $maxheight==0) {\r
262                         $maxwidth = $NP_Thumbnail->getOption('maxwidth');\r
263                         $maxheight = $NP_Thumbnail->getOption('maxheight');\r
264                 }\r
265                 \r
266                 if (FALSE === ($medium = new MEDIUM($DIR_MEDIA, $data[$mediumid]['path'], MediaUtils::$prefix))) {\r
267                         return;\r
268                 }\r
269                 \r
270                 if (array_key_exists($medium->mime, MediaUtils::$image_mime)\r
271                  && !$medium->setResampledSize($maxwidth, $maxheight)) {\r
272                         return;\r
273                 }\r
274                 \r
275                 if (!array_key_exists($medium->mime, MediaUtils::$image_mime)\r
276                  || $data[$mediumid]['way'] == 'anchor') {\r
277                         $template = $this->getBlogOption(self::$blogid, 'blog_media_template');\r
278                 } else if ($data[$mediumid]['way'] == 'original') {\r
279                         $template = $this->getBlogOption(self::$blogid, 'blog_image_template');\r
280                 } else {\r
281                         $template = $NP_Thumbnail->getBlogOption(self::$blogid, 'thumb_template');\r
282                 }\r
283                 return $NP_Thumbnail->generateTag($template, $medium, $data[$mediumid]['alt']);\r
284         }\r
285         \r
286         private function showInterface () {\r
287                 global $CONF, $DIR_LIBS, $DIR_MEDIA, $manager;\r
288                 \r
289                 if (!class_exists('BODYACTIONS', FALSE)) {\r
290                         include ($DIR_LIBS . 'BODYACTIONS.php');\r
291                 }\r
292                 $action = new BODYACTIONS;\r
293                 \r
294                 if (!$manager->pluginInstalled('NP_Thumbnail')) {\r
295                         return;\r
296                 }\r
297                 $NP_Thumbnail = &$manager->getPlugin('NP_Thumbnail');\r
298                 $maxwidth = $NP_Thumbnail->getOption('maxwidth');\r
299                 $maxheight = $NP_Thumbnail->getOption('maxheight');\r
300                         \r
301                 if (!self::$amount) {\r
302                         return;\r
303                 }\r
304                 \r
305                 $data = self::$data;\r
306                 \r
307                 if (empty($data)) {\r
308                         return;\r
309                 }\r
310                 \r
311                 echo "<table frame=\"box\" rules=\"all\" summary=\"Attached Media\">\n";\r
312                 echo "<thead>\n";\r
313                 echo "<tr>\n";\r
314                 echo "<th>" . _NP_ATTACH_10 . "</th>\n";\r
315                 echo "<th>" . _NP_ATTACH_11 . "</th>\n";\r
316                 echo "<th>" . _NP_ATTACH_12 . "</th>\n";\r
317                 echo "</tr>\n";\r
318                 echo "</thead>\n";\r
319                 echo "<tbody>\n";\r
320                 \r
321                 for ($count = 0; $count < self::$amount; $count++) {\r
322                         $id = $count + 1;\r
323                         \r
324                         echo "<tr>\n";\r
325                         echo "<td>\n";\r
326                         echo "<label for=\"alt{$count}\"><%Attach({$id})%></label>\n";\r
327                         \r
328                         if ($data[$count]['path']) {\r
329                                 echo "<br />\n";\r
330                                 echo "<input type=\"checkbox\" id=\"delete{$count}\" name=\"delete[{$count}]\" value=\"1\" />\n";\r
331                                 echo "<label for=\"delete{$count}\">" . _NP_ATTACH_13 . "</label>\n";\r
332                         }\r
333                         \r
334                         echo "</td>\n";\r
335                         echo "<td>\n";\r
336                         \r
337                         if (!$data[$count]['path']) {\r
338                                 echo "<input type=\"file\" id=\"medium{$count}\" name=\"medium[{$count}]\" size=\"1\" /><br />\n";\r
339                         } else {\r
340                                 if (FALSE === ($medium = new MEDIUM($DIR_MEDIA, $data[$count]['path'], MediaUtils::$prefix))) {\r
341                                         return;\r
342                                 }\r
343                                 \r
344                                 if (array_key_exists($medium->mime, MediaUtils::$image_mime)\r
345                                  && !$medium->setResampledSize($maxwidth, $maxheight)) {\r
346                                         return;\r
347                                 }\r
348                                 \r
349                                 if (array_key_exists($medium->mime, MediaUtils::$image_mime)) {\r
350                                         $template = $this->getOption('admin_popup_template');\r
351                                 } else {\r
352                                         $template = $this->getOption('admin_media_template');\r
353                                 }\r
354                                 \r
355                                 echo $NP_Thumbnail->generateTag($template, $medium, $data[$count]['alt']) . "<br />\n";\r
356                                 echo "<input type=\"hidden\" id=\"path{$count}\" name=\"path[{$count}]\" value=\"{$data[$count]['path']}\" /><br />\n";\r
357                         }\r
358                         echo "<input type=\"text\" id=\"alt{$count}\" name=\"alt[{$count}]\" value=\"{$data[$count]['alt']}\" size=\"12\" />\n";\r
359                         echo "</td>\n";\r
360                         echo "<td>\n";\r
361                         \r
362                         if ($data[$count]['path'] && !array_key_exists($data[$count]['mime'], MediaUtils::$image_mime)) {\r
363                                 echo "<input type=\"hidden\" name=\"way[{$count}]\" value=\"anchor\" />\n";\r
364                                 echo _NP_ATTACH_14 . "\n";\r
365                         } else {\r
366                                 $thumbnail_checked = "";\r
367                                 $original_checked = "";\r
368                                 $anchor_checked = "";\r
369                                 \r
370                                 if ($data[$count]['way'] == 'original') {\r
371                                         $original_checked = 'checked="checked"';\r
372                                 } else if ($data[$count]['way'] == 'anchor') {\r
373                                         $anchor_checked = 'checked="checked"';\r
374                                 } else {\r
375                                         $thumbnail_checked = 'checked="checked"';\r
376                                 }\r
377                                 \r
378                                 echo "<input type=\"radio\" id=\"way{$count}-anchor\" name=\"way[{$count}]\" value=\"anchor\" {$anchor_checked} />\n";\r
379                                 echo "<label for=\"way{$count}-anchor\">" . _NP_ATTACH_15 . "<label><br />\n";\r
380                                 echo "<input type=\"radio\" id=\"way{$count}-small\" name=\"way[{$count}]\" value=\"thumbnail\" {$thumbnail_checked} />\n";\r
381                                 echo "<label for=\"way{$count}-small\">" . _NP_ATTACH_16 . "<label><br />\n";\r
382                                 echo "<input type=\"radio\" id=\"way{$count}-original\" name=\"way[{$count}]\" value=\"original\" {$original_checked} />\n";\r
383                                 echo "<label for=\"way{$count}-original\">" . _NP_ATTACH_17 . "<label>\n";\r
384                         }\r
385                         echo "</td>\n";\r
386                         echo "</tr>\n";\r
387                 }\r
388                 \r
389                 echo "</tbody>\n";\r
390                 echo "</table>\n";\r
391                 return;\r
392         }\r
393         \r
394         private function setData($root) {\r
395                 if(self::$blogid === 0 || !self::$itemid === 0) {\r
396                  return;\r
397                 }\r
398                 \r
399                 self::$amount = $this->getBlogOption(self::$blogid, 'amount');\r
400                 $media = explode(';', $this->getitemOption (self::$itemid, 'media'));\r
401                 $data = array();\r
402                 \r
403                 for ($count = 0; $count < self::$amount; $count++) {\r
404                         if((self::$itemid != 0) && array_key_exists ($count, $media) && !empty ($media[$count])) {\r
405                                 $medium = explode (':', $media[$count]);\r
406                                 $data[$count]['path'] = $medium[0];\r
407                                 $data[$count]['alt'] = $medium[1];\r
408                                 $data[$count]['way'] = $medium[2];\r
409                                 \r
410                                 if (FALSE === ($file = new Medium($root, $data[$count]['path'], MediaUtils::$prefix))) {\r
411                                         $data[$count] = array ('path' => "", 'alt' => "", 'way' => "");\r
412                                 }\r
413                                 \r
414                                 $data[$count]['mime'] = $file->mime;\r
415                                 $data[$count]['width'] = $file->width;\r
416                                 $data[$count]['height'] = $file->height;\r
417                         } else {\r
418                                 $data[$count] = array ('path' => "", 'alt' => "", 'way' => "");\r
419                         }\r
420                 }\r
421                 \r
422                 self::$data = $data;\r
423                 return;\r
424         }\r
425         \r
426         static private function batchRequest($root, $collection) {\r
427                 global $CONF, $manager;\r
428                 $media = array ();\r
429                 $paths = array ();\r
430                 $alts = array ();\r
431                 $ways = array ();\r
432                 $deletes = array ();\r
433                 \r
434                 if (array_key_exists ('medium', $_FILES)) {\r
435                         $media = $_FILES['medium'];\r
436                 }\r
437                 \r
438                 if (array_key_exists ('path', $_POST)) {\r
439                         $paths = $_POST['path'];\r
440                 }\r
441                 \r
442                 if (array_key_exists ('alt', $_POST)) {\r
443                         $alts = $_POST['alt'];\r
444                 }\r
445                 \r
446                 if (array_key_exists ('way', $_POST)) {\r
447                         $ways = $_POST['way'];\r
448                 }\r
449                 \r
450                 if (array_key_exists ('delete', $_POST)) {\r
451                         $deletes = $_POST['delete'];\r
452                 }\r
453                 \r
454                 $data = &self::$data;\r
455                 \r
456                 if (!$manager->pluginInstalled('NP_Thumbnail')) {\r
457                         return;\r
458                 }\r
459                 $NP_Thumbnail = &$manager->getPlugin('NP_Thumbnail');\r
460                 \r
461                 foreach ($data as $key => $value) {\r
462                         if ($media && array_key_exists ($key, $media['name']) && !empty ($media['name'][$key])) {\r
463                                 $medium = array ();\r
464                                 if (preg_match ("#(\\\\|/|\\n)#", $media['name'][$key])) {\r
465                                         $data[$key] = array ('path' => "", 'alt' => "", 'way' => "");\r
466                                         continue;\r
467                                 }\r
468                                 \r
469                                 $medium['name'] = &$media['name'][$key];\r
470                                 $medium['size'] = $media['size'][$key];\r
471                                 $medium['tmp_name'] = $media['tmp_name'][$key];\r
472                                 $medium['error'] = $media['error'][$key];\r
473                                 \r
474                                 $result = MediaUtils::uploadMedium ($root, $collection, $medium, $medium['name'], $manager);\r
475                                 \r
476                                 if ($result) {\r
477                                         $data[$key]['path'] = "";\r
478                                         $data[$key]['alt']  = $result . ' (' . $medium['name'] . ')';\r
479                                         $data[$key]['way']  = "";\r
480                                         continue;\r
481                                 } else {\r
482                                         $data[$key]['path'] = $collection . '/' . $medium['name'];\r
483                                 }\r
484                         } else if (array_key_exists($key, $paths) && !empty ($paths[$key])) {\r
485                                 if (FALSE === ($medium = new MEDIUM($root, $paths[$key], MediaUtils::$prefix))) {\r
486                                         $data[$key] = array ('path' => "", 'alt' => "", 'way' => "");\r
487                                         continue;\r
488                                 }\r
489                                 if ($deletes && array_key_exists ($key, $deletes) && $deletes[$key] == 1) {\r
490                                         if (@ unlink ($root . $paths[$key])) {\r
491                                                 if (array_key_exists($medium->mime, MediaUtils::$image_mime)) {\r
492                                                         @ unlink ($root . $NP_Thumbnail->getThumbPath($medium));\r
493                                                 }\r
494                                                 $data[$key] = array ('path' => "", 'alt' => "", 'way' => "");\r
495                                                 continue;\r
496                                         }\r
497                                 }\r
498                         }\r
499                         \r
500                         if (array_key_exists ($key, $alts) && $alts[$key] != $value['alt']) {\r
501                                 $data[$key]['alt'] = htmlspecialchars ($alts[$key], ENT_QUOTES, _CHARSET);\r
502                         }\r
503                         \r
504                         if (array_key_exists ($key, $ways) && $ways[$key] != $value['way']) {\r
505                                 if (!in_array ($ways[$key], array ('thumbnail', 'original', 'anchor'))) {\r
506                                         $data[$key]['way'] = 'thumbnail';\r
507                                 } else {\r
508                                         $data[$key]['way'] = $ways[$key];\r
509                                 }\r
510                         }\r
511                 }\r
512                 return;\r
513         }\r
514         \r
515         static private function prepareEnctype () {\r
516                 self::$buffer = ob_start ();\r
517                 return;\r
518         }\r
519         \r
520         static private function setEnctype () {\r
521                 if (!self::$buffer) {\r
522                         return;\r
523                 }\r
524                 $strings = ob_get_contents ();\r
525                 ob_end_clean ();\r
526                 $strings = preg_replace ('#action="(index.php|bookmarklet.php)"#', '$0 enctype="multipart/form-data"', $strings);\r
527                 echo $strings;\r
528                 return;\r
529         }\r
530 }\r