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
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
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
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
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
36 'PrePluginOptionsEdit',
\r
38 'BookmarkletExtraHead',
\r
44 'PrePluginOptionsUpdate',
\r
45 'AddItemFormExtras',
\r
46 'EditItemFormExtras');
\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
61 public function uninstall () {
\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
71 include($this->getDirectory() . 'english.php');
\r
80 public function event_PrePluginOptionsEdit ($data)
\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
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
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
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
117 static private function t ($text,$array=array()){
\r
118 if (is_array($array)) {
\r
120 $replace = array();
\r
122 foreach ($array as $key => $value){
\r
123 if (is_array($value)) {
\r
126 $search[] = '<%'.preg_replace('/[^a-zA-Z0-9_]+/','',$key).'%>';
\r
127 $replace[] = $value;
\r
130 return htmlspecialchars (str_replace($search, $replace, $text), ENT_QUOTES, _CHARSET);
\r
134 * Change enctype attribute of form element as 'multipart/form-data'
\r
137 public function event_AdminPrePageHead ($data) {
\r
138 if (!in_array ($data['action'], array ('createitem', 'itemedit'))) {
\r
142 self::prepareEnctype ();
\r
146 public function event_BookmarkletExtraHead ($data) {
\r
147 self::prepareEnctype ();
\r
151 public function event_AddItemFormExtras ($data) {
\r
153 $blog = $data['blog'];
\r
154 self::$blogid = $blog->blogid;
\r
156 self::setEnctype ();
\r
157 $this->setData($DIR_MEDIA);
\r
158 $this->showInterface ();
\r
162 public function event_EditItemFormExtras ($data) {
\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
174 * Process upload and update plugin item option
\r
176 public function event_PreAddItem ($data) {
\r
177 self::$blogid = $data['blog']->blogid;
\r
180 public function event_PreUpdateItem ($data) {
\r
181 self::$blogid = $data['blog']->blogid;
\r
184 public function event_PostAddItem ($data) {
\r
185 self::$itemid = $data['itemid'];
\r
188 public function event_PostUpdateItem ($data) {
\r
189 self::$itemid = $data['itemid'];
\r
192 public function event_PrePluginOptionsUpdate ($data) {
\r
193 global $DIR_MEDIA, $member;
\r
195 if ($data['plugid'] != $this->getID () || $data['optionname'] != 'media') {
\r
199 $this->setData($DIR_MEDIA);
\r
200 self::batchRequest ($DIR_MEDIA, $member->getID());
\r
203 foreach (self::$data as $datum) {
\r
204 if (!$datum['path']) {
\r
207 $value .= "{$datum['path']}:{$datum['alt']}:{$datum['way']};";
\r
210 $data['value'] = $value;
\r
215 * Show media in item
\r
217 public function event_PreItem($data) {
\r
219 self::$blogid =& $data['blog']->blogid;
\r
220 self::$itemid =& $data["item"]->itemid;
\r
221 $this->setData($DIR_MEDIA);
\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
227 public function doTemplateVar($item, $mediumid) {
\r
228 global $DIR_MEDIA, $blogid;
\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
235 $this->getParsedTag(array('item', $mediumid));
\r
239 private function getParsedTag($match) {
\r
240 global $DIR_MEDIA, $manager;
\r
244 if (array_key_exists(3, $match)) {
\r
245 $maxheight = (integer) trim($match[3], ',');
\r
247 if (array_key_exists(2, $match)) {
\r
248 $maxwidth = (integer) trim($match[2], ',');
\r
251 $data = &self::$data;
\r
252 $mediumid = $match[1];
\r
255 if (!array_key_exists ($mediumid, $data) || !$data[$mediumid]['path']) {
\r
259 $NP_Thumbnail =& $manager->getPlugin('NP_Thumbnail');
\r
261 if ($maxwidth==0 && $maxheight==0) {
\r
262 $maxwidth = $NP_Thumbnail->getOption('maxwidth');
\r
263 $maxheight = $NP_Thumbnail->getOption('maxheight');
\r
266 if (FALSE === ($medium = new MEDIUM($DIR_MEDIA, $data[$mediumid]['path'], MediaUtils::$prefix))) {
\r
270 if (array_key_exists($medium->mime, MediaUtils::$image_mime)
\r
271 && !$medium->setResampledSize($maxwidth, $maxheight)) {
\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
281 $template = $NP_Thumbnail->getBlogOption(self::$blogid, 'thumb_template');
\r
283 return $NP_Thumbnail->generateTag($template, $medium, $data[$mediumid]['alt']);
\r
286 private function showInterface () {
\r
287 global $CONF, $DIR_LIBS, $DIR_MEDIA, $manager;
\r
289 if (!class_exists('BODYACTIONS', FALSE)) {
\r
290 include ($DIR_LIBS . 'BODYACTIONS.php');
\r
292 $action = new BODYACTIONS;
\r
294 if (!$manager->pluginInstalled('NP_Thumbnail')) {
\r
297 $NP_Thumbnail = &$manager->getPlugin('NP_Thumbnail');
\r
298 $maxwidth = $NP_Thumbnail->getOption('maxwidth');
\r
299 $maxheight = $NP_Thumbnail->getOption('maxheight');
\r
301 if (!self::$amount) {
\r
305 $data = self::$data;
\r
307 if (empty($data)) {
\r
311 echo "<table frame=\"box\" rules=\"all\" summary=\"Attached Media\">\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
321 for ($count = 0; $count < self::$amount; $count++) {
\r
326 echo "<label for=\"alt{$count}\"><%Attach({$id})%></label>\n";
\r
328 if ($data[$count]['path']) {
\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
337 if (!$data[$count]['path']) {
\r
338 echo "<input type=\"file\" id=\"medium{$count}\" name=\"medium[{$count}]\" size=\"1\" /><br />\n";
\r
340 if (FALSE === ($medium = new MEDIUM($DIR_MEDIA, $data[$count]['path'], MediaUtils::$prefix))) {
\r
344 if (array_key_exists($medium->mime, MediaUtils::$image_mime)
\r
345 && !$medium->setResampledSize($maxwidth, $maxheight)) {
\r
349 if (array_key_exists($medium->mime, MediaUtils::$image_mime)) {
\r
350 $template = $this->getOption('admin_popup_template');
\r
352 $template = $this->getOption('admin_media_template');
\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
358 echo "<input type=\"text\" id=\"alt{$count}\" name=\"alt[{$count}]\" value=\"{$data[$count]['alt']}\" size=\"12\" />\n";
\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
366 $thumbnail_checked = "";
\r
367 $original_checked = "";
\r
368 $anchor_checked = "";
\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
375 $thumbnail_checked = 'checked="checked"';
\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
394 private function setData($root) {
\r
395 if(self::$blogid === 0 || !self::$itemid === 0) {
\r
399 self::$amount = $this->getBlogOption(self::$blogid, 'amount');
\r
400 $media = explode(';', $this->getitemOption (self::$itemid, 'media'));
\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
410 if (FALSE === ($file = new Medium($root, $data[$count]['path'], MediaUtils::$prefix))) {
\r
411 $data[$count] = array ('path' => "", 'alt' => "", 'way' => "");
\r
414 $data[$count]['mime'] = $file->mime;
\r
415 $data[$count]['width'] = $file->width;
\r
416 $data[$count]['height'] = $file->height;
\r
418 $data[$count] = array ('path' => "", 'alt' => "", 'way' => "");
\r
422 self::$data = $data;
\r
426 static private function batchRequest($root, $collection) {
\r
427 global $CONF, $manager;
\r
432 $deletes = array ();
\r
434 if (array_key_exists ('medium', $_FILES)) {
\r
435 $media = $_FILES['medium'];
\r
438 if (array_key_exists ('path', $_POST)) {
\r
439 $paths = $_POST['path'];
\r
442 if (array_key_exists ('alt', $_POST)) {
\r
443 $alts = $_POST['alt'];
\r
446 if (array_key_exists ('way', $_POST)) {
\r
447 $ways = $_POST['way'];
\r
450 if (array_key_exists ('delete', $_POST)) {
\r
451 $deletes = $_POST['delete'];
\r
454 $data = &self::$data;
\r
456 if (!$manager->pluginInstalled('NP_Thumbnail')) {
\r
459 $NP_Thumbnail = &$manager->getPlugin('NP_Thumbnail');
\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
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
474 $result = MediaUtils::uploadMedium ($root, $collection, $medium, $medium['name'], $manager);
\r
477 $data[$key]['path'] = "";
\r
478 $data[$key]['alt'] = $result . ' (' . $medium['name'] . ')';
\r
479 $data[$key]['way'] = "";
\r
482 $data[$key]['path'] = $collection . '/' . $medium['name'];
\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
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
494 $data[$key] = array ('path' => "", 'alt' => "", 'way' => "");
\r
500 if (array_key_exists ($key, $alts) && $alts[$key] != $value['alt']) {
\r
501 $data[$key]['alt'] = htmlspecialchars ($alts[$key], ENT_QUOTES, _CHARSET);
\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
508 $data[$key]['way'] = $ways[$key];
\r
515 static private function prepareEnctype () {
\r
516 self::$buffer = ob_start ();
\r
520 static private function setEnctype () {
\r
521 if (!self::$buffer) {
\r
524 $strings = ob_get_contents ();
\r
526 $strings = preg_replace ('#action="(index.php|bookmarklet.php)"#', '$0 enctype="multipart/form-data"', $strings);
\r