--- /dev/null
+<?php\r
+// vim: tabstop=2:shiftwidth=2\r
+\r
+/**\r
+ * NP_Paint ($Revision: 1.273 $)\r
+ * by hsur ( http://blog.cles.jp/np_cles )\r
+ * \r
+ * $Id: NP_Paint.php,v 1.273 2010/06/06 11:44:19 hsur Exp $\r
+*/\r
+\r
+/*\r
+ * Copyright (C) 2005-2010 CLES. All rights reserved.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
+ * \r
+ * In addition, as a special exception, cles( http://blog.cles.jp/np_cles ) gives\r
+ * permission to link the code of this program with those files in the PEAR\r
+ * library that are licensed under the PHP License (or with modified versions\r
+ * of those files that use the same license as those files), and distribute\r
+ * linked combinations including the two. You must obey the GNU General Public\r
+ * License in all respects for all of the code used other than those files in\r
+ * the PEAR library that are licensed under the PHP License. If you modify\r
+ * this file, you may extend this exception to your version of the file,\r
+ * but you are not obligated to do so. If you do not wish to do so, delete\r
+ * this exception statement from your version.\r
+*/\r
+\r
+if (!class_exists('NucleusPlugin')) exit;\r
+define("NP_PAINT_IMAGE_NAME", "pbbsimage");\r
+define("NP_PAINT_TICKET_TABLE", "plugin_paint_tickets");\r
+define("NP_PAINT_TICKET_LIFETIME", 86400);\r
+\r
+global $DIR_LIBS;\r
+require_once($DIR_LIBS . 'MEDIA.php');\r
+\r
+// load class\r
+require_once(dirname(__FILE__).'/sharedlibs/sharedlibs.php');\r
+require_once('cles/Template.php');\r
+require_once(dirname(__FILE__).'/paint/PaintPlugin.php');\r
+\r
+class NP_Paint extends NucleusPlugin {\r
+\r
+ // name of plugin\r
+ function getName() {\r
+ return 'Paint';\r
+ }\r
+\r
+ // author of plugin\r
+ function getAuthor() {\r
+ return 'hsur';\r
+ }\r
+\r
+ // an URL to the plugin website\r
+ // can also be of the form mailto:foo@bar.com\r
+ function getURL() {\r
+ return 'http://blog.cles.jp/np_cles/category/31/subcatid/5';\r
+ }\r
+\r
+ // version of the plugin\r
+ function getVersion() {\r
+ return '1.18.0';\r
+ }\r
+ \r
+ function hasAdminArea() {\r
+ return 1;\r
+ }\r
+\r
+ function install() {\r
+ // FORM default\r
+ $this->createOption('defaultWidth', _PAINT_defaultWidth, 'text', '300', 'numerical=true'); \r
+ $this->createOption('defaultHeight', _PAINT_defaultHeight, 'text', '300', 'numerical=true'); \r
+ $this->createOption('defaultAnimation', _PAINT_defaultAnimation, 'yesno', 'yes'); \r
+ $this->createOption('defaultApplet', _PAINT_defaultApplet, 'select', '', '');\r
+ $this->createOption('defaultPalette', _PAINT_defaultPalette, 'select', '', '');\r
+\r
+ $this->createOption('defaultImgType', _PAINT_defaultImgType, 'select', 'AUTO', 'AUTO|AUTO|JPG|JPG|PNG|PNG');\r
+ $this->createOption('defaultImgCompress', _PAINT_defaultImgCompress, 'text', '15', 'numerical=true'); \r
+ $this->createOption('defaultImgDecrease', _PAINT_defaultImgDecrease, 'text', '60', 'numerical=true'); \r
+ $this->createOption('defaultImgQuality', _PAINT_defaultImgQuality, 'text', '75', 'numerical=true'); \r
+\r
+ $this->createOption('defaultAppletQuality', _PAINT_defaultAppletQuality, 'select', '1', '1|1|2|2|3|3|4|4|5|5');\r
+\r
+ $this->createOption('bodyTpl', _PAINT_bodyTpl, 'textarea', '<%paint(<%url%>|<%w%>|<%h%>|'.NP_PAINT_IMAGE_NAME.')%>');\r
+ $this->createOption('tagTpl', _PAINT_tagTpl, 'textarea', '<%img%><a href="<%viewer%>" onclick="window.open(this.href, \'popupwindow\', \'width=400, height=400, scrollbars, resizable\'); return false; " >'._PAINT_STAR.'Anime</a>');\r
+ $this->createOption('imageTpl', _PAINT_imageTpl, 'textarea', '<%image(<%url%>|<%w%>|<%h%>|<%alt%>)%><%continue%>');\r
+ $this->createOption('continueTpl', _PAINT_continueTpl, 'textarea', '<br /><a onclick="window.open(this.href, \'popupwindow\', \'width=400, height=400, scrollbars, resizable\'); return false;" href="<%actionurl%>">'._PAINT_STAR.'Continue</a>');\r
+ // debug\r
+ $this->createOption('debug', _PAINT_debug, 'yesno', 'no');\r
+ \r
+ // for authentication\r
+ sql_query("\r
+ CREATE TABLE IF NOT EXISTS \r
+ ".sql_table(NP_PAINT_TICKET_TABLE).'\r
+ (\r
+ `ticket` CHAR(40) NOT NULL,\r
+ `member` INT(11) NOT NULL,\r
+ `generated` TIMESTAMP,\r
+ PRIMARY KEY (`ticket`, `member`),\r
+ INDEX genarated_idx (`generated` DESC)\r
+ )\r
+ ');\r
+ }\r
+ \r
+ function unInstall() {\r
+ sql_query("DROP TABLE ".sql_table(NP_PAINT_TICKET_TABLE));\r
+ }\r
+ \r
+ function getMinNucleusVersion() { return 330; }\r
+ function getMinNucleusPatchLevel() { return 0; }\r
+\r
+ // a description to be shown on the installed plugins listing\r
+ function getDescription() {\r
+ return '[$Revision: 1.273 $]<br />' . _PAINT_DESCRIPTION;\r
+ }\r
+\r
+ function supportsFeature($what) {\r
+ switch ($what) {\r
+ case 'SqlTablePrefix' :\r
+// case 'HelpPage':\r
+ return 1;\r
+ default :\r
+ return 0;\r
+ }\r
+ }\r
+ \r
+ function getEventList() {\r
+ return array('PrePluginOptionsEdit', 'PreItem');\r
+ }\r
+ \r
+ function event_PrePluginOptionsEdit(&$data) {\r
+ $this->_loadPlugin();\r
+ $trimChar = array(\r
+ '=' => '',\r
+ '|' => '',\r
+ ';' => '',\r
+ );\r
+\r
+ switch($data['context']){\r
+ case 'global':\r
+ if( $data['plugid'] != $this->getID() ) return ;\r
+ \r
+ $appletTypeinfo = '';\r
+ foreach($this->applets as $key => $applet){\r
+ if($appletTypeinfo) $appletTypeinfo .= '|';\r
+ $applet->name = strtr($applet->name, $trimChar);\r
+ $key = strtr($key, $trimChar);\r
+ $appletTypeinfo .= "{$applet->name}|{$key}";\r
+ }\r
+ $paletteTypeinfo = '';\r
+ foreach($this->palettes as $key => $palette){\r
+ if($paletteTypeinfo) $paletteTypeinfo .= '|';\r
+ $palette->name = strtr($palette->name, $trimChar);\r
+ $key = strtr($key, $trimChar);\r
+ $paletteTypeinfo .= "{$palette->name}|{$key}";\r
+ }\r
+ foreach($data['options'] as $oid => $option ){\r
+ switch($data['options'][$oid]['name']){\r
+ case 'defaultApplet':\r
+ $data['options'][$oid]['typeinfo'] = $appletTypeinfo;\r
+ break;\r
+ case 'defaultPalette':\r
+ $data['options'][$oid]['typeinfo'] = $paletteTypeinfo;\r
+ break;\r
+ }\r
+ }\r
+ \r
+ break;\r
+ default:\r
+ // nothing \r
+ }\r
+ }\r
+\r
+/*\r
+ function doItemVar($item, $arg){\r
+ $arr[1] = $arg;\r
+ echo $this->_convertPaint($arr);\r
+ }\r
+*/\r
+\r
+ function event_PreItem($data) {\r
+ $this->_loadPlugin();\r
+ $preg_expr = "#<\%paint\((.*?)\)%\>#i";\r
+ $this->currentItem = &$data["item"];\r
+ \r
+ $this->currentItem->body = preg_replace_callback($preg_expr, array(&$this, '_convertPaint'), $this->currentItem->body);\r
+ $this->currentItem->more = preg_replace_callback($preg_expr, array(&$this, '_convertPaint'), $this->currentItem->more);\r
+ }\r
+ \r
+ function _convertPaint($matches) {\r
+ global $CONF, $DIR_MEDIA, $member;\r
+ list($url, $w, $h, $alt) = explode("|", $matches[1], 4);\r
+ \r
+ if (strstr($url,'/'))\r
+ $collection = intval(dirname($url));\r
+ else\r
+ $collection = intval($this->currentItem->authorid);\r
+ \r
+ $vars = array (\r
+ 'w' => intval($w),\r
+ 'h' => intval($h),\r
+ 'url' => $url,\r
+ 'alt' => $alt,\r
+ );\r
+ \r
+ $basename = basename($url, '.jpg');\r
+ $basename = basename($basename, '.png');\r
+ foreach( $this->viewers as $key => $viewer ){\r
+ foreach( $viewer->animeExt as $ext ){\r
+ $file = $DIR_MEDIA . $collection . '/' . $basename . '.' . $ext;\r
+ if( file_exists( $file ) ){\r
+ $vars['viewer'] = htmlspecialchars($CONF['ActionURL'] . "?action=plugin&name=Paint&type=viewer&w=".$vars['w']."&h=".$vars['h']."&file={$collection}/{$basename}.{$ext}&viewer=$key", ENT_QUOTES);\r
+ break 2;\r
+ }\r
+ }\r
+ }\r
+ \r
+ if ( $member->isLoggedIn() && $member->getID() == $collection && $this->viewers['continue'] ){\r
+ $vars['actionurl'] = htmlspecialchars($CONF['ActionURL'] . "?action=plugin&name=Paint&type=viewer&w=".$vars['w']."&h=".$vars['h']."&file=".$url."&viewer=continue", ENT_QUOTES);\r
+ $vars['continue'] = TEMPLATE :: fill($this->getOption('continueTpl'), $vars);\r
+ }\r
+ \r
+ $vars['img'] = TEMPLATE :: fill($this->getOption('imageTpl'), $vars);\r
+ \r
+ if( $vars['viewer'] )\r
+ return TEMPLATE :: fill($this->getOption('tagTpl'), $vars); \r
+ return $vars['img'];\r
+ }\r
+ \r
+ function init(){\r
+ $this->template =& new cles_Template(dirname(__FILE__).'/paint/template');\r
+ \r
+ $this->parsers = Array();\r
+ $this->applets = Array();\r
+ $this->palettes = Array();\r
+ $this->viewers = Array();\r
+ $this->files = Array();\r
+ $this->disabledPlugin = Array();\r
+ $this->isPluginLoaded = false;\r
+ \r
+ // include language file for this plugin \r
+ $language = ereg_replace( '[\\|/]', '', getLanguageName()); \r
+ if (file_exists($this->getDirectory().'language/'.$language.'.php')) \r
+ @ include_once($this->getDirectory().'language/'.$language.'.php');\r
+ }\r
+ \r
+ function doAction($type) {\r
+ @ini_set('display_errors', 0);\r
+ //@ini_set('error_reporting', 0);\r
+ \r
+ global $member;\r
+ $this->_loadPlugin();\r
+ header('Pragma: no-cache');\r
+ header('Expires: 0');\r
+ \r
+ switch ($type) {\r
+ case 'postimg':\r
+ $err = $this->_postimg(requestVar('parser'));\r
+ \r
+ if($err){\r
+ $this->_warn('postimg Err: ' . $err);\r
+ $file = $line = '';\r
+ if( ! headers_sent($file, $line) ){\r
+ header("HTTP/1.0 500 Internal Server Error");\r
+ header("Status: 500 Internal Server Error");\r
+ echo 'postimg Err: ' . mb_convert_encoding($err, 'UTF-8', _CHARSET);\r
+ } else {\r
+ $this->_warn(_PAINT_HeadersAlreadySent . "file:$file, line:$line" );\r
+ echo "error\n" . mb_convert_encoding($err, "UTF-8", _CHARSET);\r
+ }\r
+ }\r
+ // always no err\r
+ return '';\r
+ break;\r
+\r
+ case 'applet':\r
+ if ( ! $member->isLoggedIn() )\r
+ return _PAINT_NeedLogin;\r
+ return $this->_showApplet();\r
+ break;\r
+ \r
+ case 'postsuccess':\r
+ if ( ! $member->isLoggedIn() )\r
+ return _PAINT_NeedLogin;\r
+ \r
+ if( intRequestVar('ow') ){\r
+ $this->_showOk();\r
+ return '';\r
+ }\r
+ \r
+ return $this->_showItemAddForm();\r
+ break;\r
+ \r
+ case 'viewer':\r
+ return $this->_showViewer();\r
+ break;\r
+\r
+ case 'plugin':\r
+ echo 'NP_Paint: ' . $this->getVersion() . ' ($Id: NP_Paint.php,v 1.273 2010/06/06 11:44:19 hsur Exp $)<br />';\r
+ foreach( $this->parsers as $key => $name){\r
+ echo 'Parser: ' . $key . ' (' . $name->id . ')<br />';\r
+ }\r
+ foreach( $this->applets as $key => $name){\r
+ echo 'Applet: ' . $key . ' (' . $name->id . ')<br />';\r
+ }\r
+ foreach( $this->palettes as $key => $name){\r
+ echo 'Palette: ' . $key . ' (' . $name->id . ')<br />';\r
+ }\r
+ foreach( $this->viewers as $key => $name){\r
+ echo 'Viewer: ' . $key . ' (' . $name->id . ')<br />';\r
+ }\r
+ return '';\r
+ break;\r
+ \r
+ case 'getLoginkey':\r
+ if ( $member->isLoggedIn() ){\r
+ header('Content-Type: application/xml');\r
+ echo $this->_getLoginkey();\r
+ } else {\r
+ header("HTTP/1.0 500 Internal Server Error");\r
+ header("Status: 500 Internal Server Error");\r
+ echo _PAINT_NeedLogin;\r
+ }\r
+ return '';\r
+ break;\r
+ \r
+ // other actions result in an error\r
+ case '':\r
+ default:\r
+ return 'Unexisting action: ' . $type;\r
+ }\r
+ }\r
+ \r
+ function doSkinVar($skinType, $type = '') {\r
+ global $member, $CONF;\r
+ \r
+ if($mes = $this->_phpVersionWarning() ){\r
+ echo $mes;\r
+ $this->_warn($mes);\r
+ }\r
+ \r
+ switch ($type) {\r
+ case '' :\r
+ case 'form' :\r
+ if ( $member->isLoggedIn() ){\r
+ $this->_loadPlugin();\r
+ $vars = array (\r
+ 'ActionURL' => $CONF['ActionURL'],\r
+ 'appletSelect' => $this->_getAppletSelect(),\r
+ 'paletteSelect' => $this->_getPaletteSelect(),\r
+ 'paletteSelectExtra' => $this->_getPaletteSelectExtra(),\r
+ 'qualitySelect' => $this->_getQualitySelect(),\r
+ 'animation' => ($this->getOption('defaultAnimation') == 'yes') ? 'checked="checked"' : '',\r
+ 'defaultWidth' => $this->getOption('defaultWidth'),\r
+ 'defaultHeight' => $this->getOption('defaultHeight'),\r
+ );\r
+ $tpl = $this->template->fetch('form', strtolower(__CLASS__));\r
+ echo $this->template->fill($tpl, $vars, false);\r
+ } else { \r
+ echo '<span class="paint">Powered by <a href="http://blog.cles.jp/">NP_Paint</a></span>';\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ function _phpVersionWarning(){\r
+ $required = '4.3.2';\r
+ if( ! version_compare(phpversion() , $required , '>=') ){\r
+ return 'Warning' . _PAINT_phpVersion_before . $required . _PAINT_phpVersion_after ;\r
+ }\r
+ return '';\r
+ }\r
+ \r
+ function _showApplet(){\r
+ global $DIR_MEDIA, $CONF, $member;\r
+\r
+ $w = intRequestVar('w') ? intRequestVar('w') : $this->getOption('defaultWidth');\r
+ $h = intRequestVar('h') ? intRequestVar('h') : $this->getOption('defaultHeight');\r
+ $animation = intRequestVar('animation') ? true : false;\r
+ $ow = intRequestVar('ow');\r
+ $usePch = intRequestVar('usepch') ? true : false;\r
+ $file = requestVar('file');\r
+ $quality = intRequestVar('quality') ? intRequestVar('quality') : 1 ;\r
+ \r
+ if( $file ){\r
+ $collection = intval(dirname($file));\r
+ if( $collection != intval($member->getID()) ){\r
+ $file = null;\r
+ $this->_warn( _PAINT_illegalCollection );\r
+ }\r
+ }\r
+ \r
+ $applet =& $this->applets[requestVar('applet')];\r
+ if(! $applet ){\r
+ $this->_warn(_PAINT_canNotFindApplet);\r
+ return _PAINT_canNotFindApplet;\r
+ }\r
+ $palette =& $this->palettes[requestVar('palette')];\r
+ \r
+ $header = $beforeapplet = $param = $afterapplet = $copyright = '';\r
+ \r
+ if($applet){\r
+ $header .= $applet->getHeaderPart(); \r
+ $beforeapplet .= $applet->getBeforeAppletPart();\r
+ $param .= $applet->getParamPart();\r
+ $afterapplet .= $applet->getAfterAppletPart();\r
+ $copyright .= $applet->getCopyrightsPart();\r
+ }\r
+\r
+ if($palette){\r
+ $header .= $palette->getHeaderPart(); \r
+ $beforeapplet .= $palette->getBeforeAppletPart();\r
+ $param .= $palette->getParamPart();\r
+ $afterapplet .= $palette->getAfterAppletPart();\r
+ $copyright .= $palette->getCopyrightsPart();\r
+ }\r
+ \r
+ if( $animation ){\r
+ $param .= '<param name="thumbnail_type" value="animation" />';\r
+ }\r
+ \r
+ $copyright .= 'NP_Paint by <a href="http://blog.cles.jp">cles</a><br />';\r
+ \r
+ if( $file && file_exists( $DIR_MEDIA . $file ) ){\r
+ $appletName = requestVar('applet');\r
+ list($animePath, $appletName) = $this->findAppletByImg($file);\r
+ \r
+ if( $animePath && $usePch ){\r
+ $param .= '<param name="thumbnail_type" value="animation" />';\r
+ $param .= "<param name=\"pch_file\" value=\"{$CONF['MediaURL']}{$animePath}\" />";\r
+ } else {\r
+ $param .= "<param name=\"image_canvas\" value=\"{$CONF['MediaURL']}{$file}\" />";\r
+ }\r
+ \r
+ if( $ow ){\r
+ list($prefix, ) = explode('-', basename($file), 2);\r
+ } else {\r
+ $prefix = $this->_getFilePrefix();\r
+ }\r
+ } else {\r
+ $prefix = $this->_getFilePrefix();\r
+ $ow = 0;\r
+ }\r
+ \r
+ $vars = array (\r
+ 'w' => $w,\r
+ 'h' => $h,\r
+ 'user' => $member->getDisplayName(),\r
+ 'loginkey' => $this->_generateLoginkey(),\r
+ 'prefix' => $prefix,\r
+ 'charset' => _CHARSET,\r
+ 'header' => $header,\r
+ 'beforeapplet' => $beforeapplet,\r
+ 'param' => $param,\r
+ 'afterapplet' => $afterapplet,\r
+ 'copyright' => $copyright,\r
+ 'ow' => $ow,\r
+ 'file' => $file,\r
+ 'imgJpeg' => ( $this->getOption('defaultImgType') == 'AUTO' ) ? 'true' : 'false',\r
+ 'imgDecrease' => ( $this->getOption('defaultImgType') == 'AUTO' ) ? $this->getOption('defaultImgDecrease') : '0',\r
+ 'imgCompress' => ( $this->getOption('defaultImgType') == 'AUTO' ) ? $this->getOption('defaultImgCompress') : '0',\r
+ 'quality' => $quality,\r
+ );\r
+ \r
+ echo $applet->getPageTemplate($vars);\r
+ return '';\r
+ }\r
+ \r
+ // return list($animeFile, $appletName)\r
+ function findAppletByImg($file){\r
+ global $DIR_MEDIA;\r
+ $collection = intval(dirname($file));\r
+ $basename = basename($file, '.jpg');\r
+ $basename = basename($basename, '.png');\r
+ \r
+ foreach( $this->applets as $key => $applet ){\r
+ foreach( $applet->animeExt as $ext ){\r
+ $anime = $DIR_MEDIA . $collection . '/' . $basename . $ext;\r
+ if( file_exists( $anime ) ){\r
+ $appletName = $key;\r
+ $animeFile = $collection . '/' . $basename . $ext;\r
+ $ret = Array($animeFile, $appletName);\r
+ return $ret;\r
+ }\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ function getFileInfo($animeFile){\r
+ global $DIR_MEDIA;\r
+ \r
+ list(,$ext) = explode('.', basename($animeFile), 2);\r
+ $animeFile = $DIR_MEDIA . $animeFile;\r
+ \r
+ $fileInfo = Array();\r
+ if( is_readable($animeFile) && ($ext == 'spch' || $ext == 'rpch') ){\r
+ $fp = fopen($animeFile, 'r');\r
+ while (!feof ($fp)) {\r
+ $line = fgets($fp, 100);\r
+ if (preg_match('/([a-zA-Z0-9_.-]+)=([a-zA-Z0-9_.-]+)/i', $line, $matches)) {\r
+ list(, $key, $value, ) = $matches;\r
+ $fileInfo[$key] = $value;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ fclose($fp);\r
+ }\r
+ return $fileInfo;\r
+ }\r
+ \r
+ function _showViewer(){\r
+ global $member;\r
+ \r
+ if( ! $file = requestVar('file') ){\r
+ return _PAINT_fileIsNotSet;\r
+ }\r
+ if( ! $type = requestVar('viewer') ){\r
+ return _PAINT_viewerIsNotSet;\r
+ }\r
+\r
+ $w = intRequestVar('w') ? intRequestVar('w') : $this->getOption('defaultWidth');\r
+ $h = intRequestVar('h') ? intRequestVar('h') : $this->getOption('defaultHeight');\r
+\r
+ if( ! $viewer = $this->viewers[$type] ){\r
+ return _PAINT_canNotFindViewer .' viewer:' . $type;\r
+ }\r
+ if( $type == 'continue' ){\r
+ if ( ! $member->isLoggedIn() )\r
+ return _PAINT_NeedLogin;\r
+ $collection = intval(dirname($file));\r
+ if ( $collection != $member->getId() ){\r
+ return _PAINT_illegalCollection;\r
+ }\r
+ }\r
+ \r
+ $vars = array (\r
+ 'w' => intval($w),\r
+ 'h' => intval($h),\r
+ 'file' => $file,\r
+ 'charset' => _CHARSET,\r
+ );\r
+ \r
+ echo $viewer->getPageTemplate($vars);\r
+ return '';\r
+ }\r
+ \r
+ function _loadPlugin( $typelist = false, $reload = false ){\r
+ if( $this->isPluginLoaded && ( ! $reload ) )\r
+ return ;\r
+ if( $this->isPluginLoaded ){\r
+ $this->init();\r
+ }\r
+ \r
+ $this->isPluginLoaded = true;\r
+ \r
+ if( ! $typelist ){\r
+ $typelist = 'Applet|Palette|Parser|Viewer';\r
+ }\r
+ \r
+ $pluginDir = $this->getDirectory();\r
+ $dirhandle = opendir( $pluginDir );\r
+ while ($filename = readdir($dirhandle)) {\r
+ if (preg_match('/^('.$typelist.')_(.*)\.php$/i',$filename,$matches)) {\r
+ list(, $type, $name, ) = $matches;\r
+ \r
+ $pluginPath = $pluginDir . $filename;\r
+ if( ! is_readable( $pluginPath ) ){\r
+ $this->_warn(_PAINT_canNotReadFile . " file:$pluginPath, type:$type, name:$name");\r
+ continue;\r
+ }\r
+ \r
+ require_once($pluginPath);\r
+ if( class_exists($type . '_' . $name) ){\r
+ eval('$plugin =& new ' . $type . '_' . $name . '();');\r
+ $plugin->appletBaseUrl = $this->getAdminURL() . 'applet/';\r
+ $plugin->template =& $this->template;\r
+ \r
+ if( $plugin->enable ){\r
+ //$this->_info('Plugin installed: ' . $name);\r
+ switch( strtolower($type) ){\r
+ case 'parser':\r
+ $this->parsers[strtolower($name)] =& $plugin;\r
+ break;\r
+ case 'applet':\r
+ $this->applets[strtolower($name)] =& $plugin;\r
+ break;\r
+ case 'palette':\r
+ $this->palettes[strtolower($name)] =& $plugin;\r
+ break;\r
+ case 'viewer':\r
+ $this->viewers[strtolower($name)] =& $plugin;\r
+ break;\r
+ default:\r
+ // nothing\r
+ $this->_warn('Unknown plugin: ' . $name);\r
+ }\r
+ } else {\r
+ $this->disabledPlugin[strtolower($type.'_'.$name)] =& $plugin;\r
+ }\r
+ } else {\r
+ $this->_warn(_PAINT_canNotLoadClass . " file:$pluginPath, type:$type, name:$name");\r
+ continue;\r
+ }\r
+ }\r
+ }\r
+ closedir($dirhandle);\r
+ }\r
+ \r
+ function _postimg($parser){\r
+ global $member, $DIR_MEDIA;\r
+ \r
+ $parser =& $this->parsers[$parser];\r
+ if(! $parser ){\r
+ $this->_warn('Parser not found');\r
+ return 'Parser not found';\r
+ }\r
+ \r
+ $data =& $parser->parse();\r
+ // exist parse error\r
+ if( ! is_array($data) ){\r
+ $this->_warn($data);\r
+ return $data;\r
+ }\r
+ \r
+ // Login check\r
+ $user = '';\r
+ $loginkey = '';\r
+ if( $data['header'] ){\r
+ if (preg_match('/user=([^&=]+)&loginkey=([^&=]+)&prefix=([^&=]+)&ow=([^&=]+)&applet=([^&=]+)/i', urldecode($data['header']), $word)) {\r
+ list(, $user, $loginkey, $prefix, $ow, $applet, ) = $word;\r
+ }\r
+ }\r
+ \r
+ if( ! MEMBER::exists($user) ){\r
+ $this->_warn("User Not Found ( user:$user, loginkey:$loginkey, prefix:$prefix )");\r
+ return _PAINT_UserNotFound;\r
+ }\r
+ \r
+ $member =& MEMBER::createFromName($user);\r
+ if ( ! $this->_checkLoginkey($loginkey, intval($member->getID())) ){\r
+ $this->_warn("Invalid Ticket ( user:$user, loginkey:$loginkey, prefix:$prefix )");\r
+ return _PAINT_InvalidTicket;\r
+ }\r
+ $member->loggedin = 1;\r
+ $this->_info("Login OK ( user:$user, loginkey:$loginkey, prefix:$prefix)");\r
+ $this->_info(count($data['images']) . ' images found.');\r
+ foreach( $data['size'] as $idx => $size ){\r
+ $this->_info('DataSize['.$idx.']: '.$size);\r
+ }\r
+ \r
+ if( $prefix ){\r
+ $this->_getFilePrefix($prefix);\r
+ } else {\r
+ $this->_warn(_PAINT_canNotFindPrefix);\r
+ $this->_getFilePrefix(); \r
+ }\r
+ \r
+ $collection = intval($member->getID());\r
+ // ow delete\r
+ if( $ow ){\r
+ foreach( Array('.jpg', '.png', '.pch', '.spch', '.rpch') as $ext ){\r
+ if( file_exists( $file = $DIR_MEDIA . $collection . '/' . $this->_getFilePrefix() . '-' . NP_PAINT_IMAGE_NAME . $ext ) ){\r
+ if( unlink($file) ){\r
+ $this->_info(_PAINT_deleteFile . ' file:'. $file);\r
+ } else {\r
+ $this->_warn(_PAINT_deleteFile_failure . ' file:'. $file);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ foreach( $data['images'] as $idx => $imgdata ){\r
+ $imgDir = $DIR_MEDIA . $collection;\r
+ $tmpFileName = $this->_getFilePrefix() . '_'. $idx . '.tmp';\r
+ \r
+ $this->_info('tmpfile: '.$tmpFileName);\r
+ $err = MEDIA::addMediaObjectRaw($collection, $tmpFileName, $imgdata);\r
+ if($err){\r
+ $this->_warn('addMediaObjectRaw Error: '. $err);\r
+ return $err;\r
+ }\r
+ \r
+ $imageSize = @GetImageSize($imgDir . '/' . $tmpFileName);\r
+ // detect file type\r
+ if($imageSize === false){\r
+ switch( $applet ){\r
+ case 'paintbbs':\r
+ $suffix = '.pch';\r
+ break;\r
+ case 'shipainter':\r
+ $suffix = '.spch';\r
+ break;\r
+ case 'shipainterpro':\r
+ $suffix = '.rpch';\r
+ break;\r
+ }\r
+ } else {\r
+ switch($imageSize[2]){\r
+ case IMAGETYPE_JPEG:\r
+ $suffix = '.jpg'; \r
+ break;\r
+ case IMAGETYPE_PNG:\r
+ $suffix = '.png';\r
+ break;\r
+ default:\r
+ $suffix = '.dat';\r
+ }\r
+ }\r
+ \r
+ $filename = $this->_getFilePrefix() . '-' . NP_PAINT_IMAGE_NAME .$suffix;\r
+ if( rename($imgDir . '/' . $tmpFileName, $imgDir . '/' . $filename ) === FALSE ){\r
+ $this->_warn(_PAINT_rename_failure . ": {$tmpFileName} => {$filename}" );\r
+ } else {\r
+ $this->_info(_PAINT_rename_ok . ": {$tmpFileName} => {$filename}" );\r
+ }\r
+ \r
+ \r
+ if( !( function_exists('ImageTypes') && defined('IMG_JPG') && defined('IMG_PNG') )){\r
+ $this->_info(_PAINT_GDNotSupported);\r
+ continue;\r
+ }\r
+ \r
+ if( $this->getOption('defaultImgType') == 'JPG' && $suffix == '.png' && (@ImageTypes() & IMG_JPG) ){\r
+ $this->_info(_PAINT_convertToJpg);\r
+ $imgres = @ImageCreateFromPNG($imgDir . '/' . $filename);\r
+ if( $imgres ){\r
+ $suffix = '.jpg';\r
+ $filename = $this->_getFilePrefix() . '-'. NP_PAINT_IMAGE_NAME . $suffix;\r
+ $this->_info('convertedFilename: ' . $filename); \r
+ if( @ImageJPEG($imgres, $imgDir . '/' . $filename, $this->getOption('defaultImgQuality'))){\r
+ $this->_info(_PAINT_convertToJpg_succeeded);\r
+ if( @unlink($imgDir . '/' . $filename) ){\r
+ $this->_info(_PAINT_deleteFile . ':'. $filename);\r
+ } else {\r
+ $this->_warn(_PAINT_deleteFile_failure .':'. $filename);\r
+ }\r
+ } else {\r
+ $this->_warn(_PAINT_convertToJpg_failure);\r
+ }\r
+ @ImageDestroy($imgres);\r
+ } else {\r
+ $this->_warn(_PAINT_pngRead_failure);\r
+ }\r
+ }\r
+ } \r
+ return '';\r
+ }\r
+ \r
+ function _getFilePrefix($prefix = ''){\r
+ if( $prefix )\r
+ $this->filePrefix = $prefix;\r
+ if( ! $this->filePrefix )\r
+ $this->filePrefix = date('YmdHis');\r
+// $this->filePrefix = uniqid('');\r
+ return $this->filePrefix;\r
+ }\r
+\r
+ function _showItemAddForm() {\r
+ global $member, $manager, $CONF;\r
+ $manager->loadClass('ADMIN');\r
+ \r
+ $query = 'SELECT tblog as blogid from '.sql_table('team').' where tmember=' . intval($member->getID()) . ' limit 1';\r
+ $res = sql_query($query);\r
+ if (mysql_num_rows($res) > 0) {\r
+ $obj = mysql_fetch_object($res);\r
+ $blogid = $obj->blogid;\r
+ } else {\r
+ return _ERROR_NOTONTEAM; \r
+ }\r
+ \r
+ $body = '';\r
+ if( intRequestVar('w') && intRequestVar('h') && requestVar('prefix') ){\r
+ $prefix = requestVar('prefix');\r
+ \r
+ $collection = intval($member->getID());\r
+ $mediaobjects = MEDIA::getMediaListByCollection($collection, $prefix . '-'.NP_PAINT_IMAGE_NAME);\r
+ \r
+ $this->_info( Count($mediaobjects) . ' mediaobject(s) found.');\r
+ \r
+ if( Count($mediaobjects) > 0){\r
+ foreach($mediaobjects as $mo){\r
+ if (preg_match('/\.(jpg|png)$/i', $mo->filename)){\r
+ $filename = $mo->filename;\r
+ break;\r
+ }\r
+ }\r
+ \r
+ $vars = array (\r
+ 'url' => $collection . '/' . $filename,\r
+ 'w' => intRequestVar('w'),\r
+ 'h' => intRequestVar('h'),\r
+ );\r
+ $body = TEMPLATE :: fill($this->getOption('bodyTpl'), $vars);\r
+ }\r
+ }\r
+\r
+ $item['body'] = $body;\r
+ $item['title'] = '';\r
+ //default category\r
+ //$item['catid'] = '';\r
+\r
+ ob_start();\r
+ $factory =& new PAGEFACTORY($blogid);\r
+ $factory->createAddForm('bookmarklet',$item);\r
+ $content = ob_get_contents();\r
+ ob_end_clean();\r
+\r
+ $replace = '<head>\r
+<meta http-equiv="Content-Type" content="text/html; charset=' . _CHARSET . '" />\r
+<base href="' . $CONF['AdminURL'] . '" />'; \r
+ $content = preg_replace ("/<head>/", $replace, $content);\r
+ \r
+ $replace = '<form method="post" action="index.php" >';\r
+ $content = preg_replace ("/<form[^>]*>/", $replace, $content);\r
+ \r
+ echo $content;\r
+ return '';\r
+ }\r
+ \r
+ function _showOk(){\r
+ $vars = array(\r
+ 'charset' => _CHARSET,\r
+ );\r
+ $tpl = $this->template->fetch('ok', strtolower(__CLASS__)); \r
+ return $this->template->fill($tpl, $vars, false);\r
+ }\r
+ \r
+ function _info($msg) {\r
+ if ($this->getOption('debug') == 'yes') {\r
+ ACTIONLOG :: add(INFO, 'Paint: '.$msg);\r
+ }\r
+ }\r
+\r
+ function _warn($msg) {\r
+ ACTIONLOG :: add(WARNING, 'Paint: '.$msg);\r
+ }\r
+\r
+ function _getAppletSelect($default = null){\r
+ if( $default ){\r
+ $recomended = _PAINT_STAR;\r
+ } else {\r
+ $recomended = '';\r
+ $default = $this->getOption('defaultApplet');\r
+ }\r
+ \r
+ $ret = '<select name="applet">';\r
+ foreach( $this->applets as $key => $applet ){\r
+ $selected = ( $default == $key ) ? 'selected="selected"' : '';\r
+ $ret .= '<option value="' . $key . '" ' . $selected . ' >' . ($selected ? $recomended : '') .$applet->name . '</option>' . "\n";\r
+ }\r
+ $ret .= '</select>';\r
+ return $ret;\r
+ } \r
+ \r
+ function _getPaletteSelect(){\r
+ $ret = '<select name="palette">';\r
+ foreach( $this->palettes as $key => $palette ){\r
+ $selected = ( $this->getOption('defaultPalette') == $key ) ? 'selected="selected"' : '';\r
+ $ret .= '<option value="' . $key . '" ' . $selected . '>' . $palette->name . '</option>' . "\n";\r
+ }\r
+ $ret .= '</select>';\r
+ return $ret;\r
+ }\r
+\r function _getPaletteSelectExtra(){\r
+ foreach( $this->palettes as $key => $palette ){\r
+ $ret .= $palette->getExtraOption();\r
+ }\r
+ return $ret;\r
+ }\r
+ \r
+ function _getQualitySelect($selected = null){\r
+ if(! $selected )\r
+ $selected = $this->getOption('defaultAppletQuality');\r
+ $qualities = Range(1,5);\r
+ \r
+ $tpl = '<select name="quality">';\r
+ foreach( $qualities as $quality ){\r
+ $tpl .= '<option value="' . $quality . '" ' . ( $quality == $selected ? 'selected="selected" ' : '' ) . '>' . $quality . '</option>';\r
+ }\r
+ $tpl .= '</select>';\r
+ \r
+ return $tpl;\r
+ }\r
+ \r
+ function _generateLoginkey(){\r
+ global $member;\r
+ $memberid = $member->getID();\r
+ \r
+ $done = false;\r
+ $ticket = null;\r
+ while(!$done){\r
+ $ticket = sha1(uniqid('').mt_rand(1,999999999));\r
+ $query = sprintf('INSERT INTO ' . sql_table(NP_PAINT_TICKET_TABLE) \r
+ . "(ticket, member) VALUES('%s', %s)"\r
+ , mysql_real_escape_string( $ticket )\r
+ , mysql_real_escape_string( intval($memberid) )\r
+ );\r
+ if( sql_query($query) ) $done = true;\r
+ }\r
+ return $ticket;\r
+ }\r
+ \r
+ function _checkLoginkey($ticket, $memberid ){\r
+ $query = sprintf('SELECT count(*) as result FROM ' . sql_table(NP_PAINT_TICKET_TABLE) \r
+ . " WHERE ticket = '%s' AND member = %s AND generated > DATE_SUB(NOW(),INTERVAL %s SECOND)"\r
+ , mysql_real_escape_string( $ticket )\r
+ , mysql_real_escape_string( intval($memberid) )\r
+ , mysql_real_escape_string( NP_PAINT_TICKET_LIFETIME )\r
+ );\r
+ $result = quickQuery($query) ? true : false ;\r
+\r
+ $query = sprintf('DELETE FROM ' . sql_table(NP_PAINT_TICKET_TABLE)\r
+ . " WHERE ticket = '%s' OR generated < DATE_SUB(NOW(),INTERVAL %s SECOND)"\r
+ , mysql_real_escape_string( $ticket )\r
+ , mysql_real_escape_string( NP_PAINT_TICKET_LIFETIME )\r
+ );\r
+ sql_query($query);\r
+ \r
+ return $result;\r
+ }\r
+ \r
+ function _getLoginkey(){\r
+ $ret = '<?xml version="1.0" encoding="utf-8" ?>'."\n";\r
+ $ret .= '<loginkey>'.$this->_generateLoginkey().'</loginkey>'."\n";\r
+ return $ret;\r
+ }\r
+}\r