diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..16cbe1f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +phpThumbOn 1.0.0 (02.08.2013) +===================================== +- Имя файла превьюхи максимально вычищенно от непонятных последовательностей символов +- Картинки семантично раскладываются по папкам в соответствии с оригинальными картинками +- Удалены постоянные проверки и отчистки всего кеша +- Отключена поддержка AWS Amazon +- Добавлен ряд параметров отвечающих за качество и тип превьюхи по умолчанию +- Код сниппета оптимизирован под множественные вызовы \ No newline at end of file diff --git a/_build/build.config.php b/_build/build.config.php new file mode 100644 index 0000000..4bd0aad --- /dev/null +++ b/_build/build.config.php @@ -0,0 +1,24 @@ + + * + * @category images + * @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html + * @author Agel_Nash + * @date 02.08.2013 + * @version 1.0.0 + * + */ +/** + * @package phpThumbOn + * @subpackage build + */ + +define('MODX_BASE_PATH', dirname(dirname(dirname(__FILE__))).'/'); +define('MODX_CORE_PATH', MODX_BASE_PATH . 'core/'); +define('MODX_MANAGER_PATH', MODX_BASE_PATH . 'manager/'); +define('MODX_CONNECTORS_PATH', MODX_BASE_PATH . 'connectors/'); +define('MODX_ASSETS_PATH', MODX_BASE_PATH . 'assets/'); \ No newline at end of file diff --git a/_build/build.transport.php b/_build/build.transport.php new file mode 100644 index 0000000..b5eec05 --- /dev/null +++ b/_build/build.transport.php @@ -0,0 +1,124 @@ + + * + * @category images + * @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html + * @author Agel_Nash + * @date 02.08.2013 + * @version 1.0. + * + */ +/** + * @package phpThumbOn + * @subpackage build + */ +$mtime = microtime(); +$mtime = explode(" ", $mtime); +$mtime = $mtime[1] + $mtime[0]; +$tstart = $mtime; +set_time_limit(0); + +/* set package defines */ +define('PKG_NAME','phpThumbOn'); +define('PKG_NAME_LOWER',strtolower(PKG_NAME)); +define('PKG_VERSION','1.0.0'); +define('PKG_RELEASE','pl'); + +/* override with your own defines here (see build.config.sample.php) */ +require_once dirname(__FILE__) . '/build.config.php'; +require_once MODX_CORE_PATH . 'model/modx/modx.class.php'; +require_once dirname(__FILE__). '/includes/functions.php'; + +$modx= new modX(); +$root = dirname(dirname(__FILE__)).'/'; +$assets = MODX_ASSETS_PATH.'components/'.PKG_NAME_LOWER.'/'; +$sources= array ( + 'root' => $root, + 'build' => $root .'_build/', + 'resolvers' => $root . '_build/resolvers/', + 'data' => $root . '_build/data/', + 'properties' => $root . '_build/properties/', + 'events' => $root . '_build/data/events/', + 'source_core' => $root.'core/components/'.PKG_NAME_LOWER, + 'source_assets' => $root.'assets/components/'.PKG_NAME_LOWER, + 'plugins' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/plugins/', + 'snippets' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/snippets/', + 'lexicon' => $root.'core/components/'.PKG_NAME_LOWER.'/lexicon/', + 'docs' => $root.'core/components/'.PKG_NAME_LOWER.'/docs/', +); +unset($root); + +$modx->initialize('mgr'); +echo '
';
+$modx->setLogLevel(modX::LOG_LEVEL_INFO);
+$modx->setLogTarget('ECHO');
+
+$modx->loadClass('transport.modPackageBuilder','',false, true);
+$builder = new modPackageBuilder($modx);
+$builder->createPackage(PKG_NAME,PKG_VERSION,PKG_RELEASE);
+$builder->registerNamespace(PKG_NAME_LOWER,false,true,'{core_path}components/'.PKG_NAME_LOWER.'/');
+
+/* package snippets */
+$snippets = include $sources['data'].'transport.snippets.php';
+if (!is_array($snippets)) { $modx->log(modX::LOG_LEVEL_FATAL,'Adding snippets failed.'); }
+$attr = array(
+    xPDOTransport::PRESERVE_KEYS => false,
+    xPDOTransport::UPDATE_OBJECT => true,
+    xPDOTransport::UNIQUE_KEY => 'name',
+);
+$i = 1;
+foreach ($snippets as $snippet) {
+    $vehicle = $builder->createVehicle($snippet,$attr);
+    if ($i == count($snippets)) {
+        $vehicle->resolve('file',array(
+            'source' => $sources['source_core'],
+            'target' => "return MODX_CORE_PATH . 'components/';",
+        ));
+        $vehicle->resolve('file',array(
+            'source' => $sources['source_assets'],
+            'target' => "return MODX_ASSETS_PATH . 'components/';",
+        ));
+    }
+    $builder->putVehicle($vehicle);
+    $i++;
+}
+$modx->log(modX::LOG_LEVEL_INFO,'Packaged in '.count($snippets).' Snippets.'); flush();
+
+/* load system settings */
+$settings = include_once $sources['data'].'transport.settings.php';
+if (!is_array($settings)) $modx->log(modX::LOG_LEVEL_FATAL,'No settings returned.');
+$attributes= array(
+    xPDOTransport::UNIQUE_KEY => 'key',
+    xPDOTransport::PRESERVE_KEYS => true,
+    xPDOTransport::UPDATE_OBJECT => false,
+);
+foreach ($settings as $setting) {
+    $vehicle = $builder->createVehicle($setting,$attributes);
+    $builder->putVehicle($vehicle);
+}
+$modx->log(modX::LOG_LEVEL_INFO,'Packaged in '.count($settings).' System Settings.'); flush();
+unset($settings,$setting,$attributes);
+
+/* now pack in the license file, readme and setup options */
+$builder->setPackageAttributes(array(
+    'license' => file_get_contents($sources['docs'] . 'license.txt'),
+    'readme' => file_get_contents($sources['docs'] . 'readme.txt'),
+    'changelog' => file_get_contents($sources['docs'] . 'changelog.txt'),
+));
+
+$builder->pack();
+
+$mtime= microtime();
+$mtime= explode(" ", $mtime);
+$mtime= $mtime[1] + $mtime[0];
+$tend= $mtime;
+$totalTime= ($tend - $tstart);
+$totalTime= sprintf("%2.4f s", $totalTime);
+
+$modx->log(modX::LOG_LEVEL_INFO,"\n
Package Built.
\nExecution time: {$totalTime}\n"); + +exit (); \ No newline at end of file diff --git a/_build/data/transport.settings.php b/_build/data/transport.settings.php new file mode 100644 index 0000000..ef40a51 --- /dev/null +++ b/_build/data/transport.settings.php @@ -0,0 +1,72 @@ + + * + * @category images + * @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html + * @author Agel_Nash + * @date 02.08.2013 + * @version 1.0.0 + * + */ +/** + * @package phpThumbOn + * @subpackage build + */ + +$settings = array(); + +//Имя папки с картинками +$settings['phpthumbon.images_dir']= $modx->newObject('modSystemSetting'); +$settings['phpthumbon.images_dir']->fromArray(array( + 'key' => 'phpthumbon.images_dir', + 'value' => 'images', + 'xtype' => 'textfield', + 'namespace' => 'phpthumbon', + 'area' => 'paths', +),'',true,true); + +//Качество картинки по умолчанию +$settings['phpthumbon.quality']= $modx->newObject('modSystemSetting'); +$settings['phpthumbon.quality']->fromArray(array( + 'key' => 'phpthumbon.quality', + 'value' => '96', + 'xtype' => 'textfield', + 'namespace' => 'phpthumbon', + 'area' => 'general', +),'',true,true); + +//Имя папки кеша +$settings['phpthumbon.cache_dir']= $modx->newObject('modSystemSetting'); +$settings['phpthumbon.cache_dir']->fromArray(array( + 'key' => 'phpthumbon.cache_dir', + 'value' => 'cache_image', + 'xtype' => 'textfield', + 'namespace' => 'phpthumbon', + 'area' => 'path', +),'',true,true); + +//Тип картинки по умолчанию +$settings['phpthumbon.ext']= $modx->newObject('modSystemSetting'); +$settings['phpthumbon.ext']->fromArray(array( + 'key' => 'phpthumbon.ext', + 'value' => 'jpeg', + 'xtype' => 'textfield', + 'namespace' => 'phpthumbon', + 'area' => 'general', +),'',true,true); + +//Путь к картинки с изображением "картинка не существует" +$settings['phpthumbon.noimage']= $modx->newObject('modSystemSetting'); +$settings['phpthumbon.noimage']->fromArray(array( + 'key' => 'phpthumbon.noimage', + 'value' => '{assets_path}components/phpthumbon/noimage.jpg', + 'xtype' => 'textfield', + 'namespace' => 'phpthumbon', + 'area' => 'path', +),'',true,true); + +return $settings; \ No newline at end of file diff --git a/_build/data/transport.snippets.php b/_build/data/transport.snippets.php new file mode 100644 index 0000000..54451ea --- /dev/null +++ b/_build/data/transport.snippets.php @@ -0,0 +1,43 @@ + +* +* @category images +* @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html +* @author Agel_Nash +* @date 02.08.2013 +* @version 1.0.0 +* +*/ +/** + * @package phpThumbOn + * @subpackage build + */ +$snippets = array(); + +$snippets[0]= $modx->newObject('modSnippet'); +$snippets[0]->fromArray(array( + 'id' => 0, + 'name' => PKG_NAME_LOWER, + 'description' => 'Создание превьюх картинок', + 'snippet' => getSnippetContent($sources['source_core'].'/elements/snippets/snippet.phpthumbon.php'), +)); +$snippets[0]->setProperties(array( + array( + 'name' => 'input', + 'value' => '', + 'type' => 'textfield', + 'desc' => 'phpthumbon.input', + 'lexicon' => 'phpthumbon:properties' + ),array( + 'name' => 'options', + 'value' => '', + 'type' => 'textfield', + 'desc' => 'phpthumbon.folder', + 'lexicon' => 'phpthumbon:properties' + )) +); +return $snippets; \ No newline at end of file diff --git a/_build/includes/functions.php b/_build/includes/functions.php new file mode 100644 index 0000000..b670df4 --- /dev/null +++ b/_build/includes/functions.php @@ -0,0 +1,11 @@ +','',$o); + $o = trim($o); + return $o; +} \ No newline at end of file diff --git a/assets/components/phpthumbon/Thumbs.db b/assets/components/phpthumbon/Thumbs.db new file mode 100644 index 0000000..bdc82eb Binary files /dev/null and b/assets/components/phpthumbon/Thumbs.db differ diff --git a/assets/components/phpthumbon/noimage.jpg b/assets/components/phpthumbon/noimage.jpg new file mode 100644 index 0000000..752eaee Binary files /dev/null and b/assets/components/phpthumbon/noimage.jpg differ diff --git a/core/components/phpthumbon/docs/changelog.txt b/core/components/phpthumbon/docs/changelog.txt new file mode 100644 index 0000000..16cbe1f --- /dev/null +++ b/core/components/phpthumbon/docs/changelog.txt @@ -0,0 +1,8 @@ +phpThumbOn 1.0.0 (02.08.2013) +===================================== +- Имя файла превьюхи максимально вычищенно от непонятных последовательностей символов +- Картинки семантично раскладываются по папкам в соответствии с оригинальными картинками +- Удалены постоянные проверки и отчистки всего кеша +- Отключена поддержка AWS Amazon +- Добавлен ряд параметров отвечающих за качество и тип превьюхи по умолчанию +- Код сниппета оптимизирован под множественные вызовы \ No newline at end of file diff --git a/core/components/phpthumbon/docs/license.txt b/core/components/phpthumbon/docs/license.txt new file mode 100644 index 0000000..1883303 --- /dev/null +++ b/core/components/phpthumbon/docs/license.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/core/components/phpthumbon/docs/readme.txt b/core/components/phpthumbon/docs/readme.txt new file mode 100644 index 0000000..a954fee --- /dev/null +++ b/core/components/phpthumbon/docs/readme.txt @@ -0,0 +1,6 @@ +phpThumbOn +========= +Оптимизированный сниппет phpThumbOf под MODX Revolution. Схожый синтаксис, но более быстрая работа. Более подробно смотрите в changelog + +Документация: http://blog.agel-nash.ru/addon/qrcode.html +Проект на GitHub: https://github.com/AgelxNash/summary/tree/master/MODX%20Revolution \ No newline at end of file diff --git a/core/components/phpthumbon/elements/snippets/snippet.phpthumbon.php b/core/components/phpthumbon/elements/snippets/snippet.phpthumbon.php new file mode 100644 index 0000000..0a1a8bd --- /dev/null +++ b/core/components/phpthumbon/elements/snippets/snippet.phpthumbon.php @@ -0,0 +1,26 @@ + + * + * @category images + * @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html + * @author Agel_Nash + * @date 02.08.2013 + * @version 1.0.0 + */ + +if(empty($modx) || !($modx instanceof modX)) return ''; + +$componentPath = (string)$modx->getOption('phpthumbon.core_path', null, $modx->getOption('core_path').'components/phpthumbon/'); + +if(!isset($modx->phpThumbOn)){ + $modx->phpThumbOn = $modx->getService("phpthumbon","phpThumbOn",$componentPath.'model/phpthumbon/', $scriptProperties); +} + +if(!($flag = ($modx->phpThumbOn instanceof phpThumbOn))){ + $modx->phpThumbOn = null; +} +return $flag ? $modx->phpThumbOn->run($scriptProperties) : ''; \ No newline at end of file diff --git a/core/components/phpthumbon/lexicon/ru/default.inc.php b/core/components/phpthumbon/lexicon/ru/default.inc.php new file mode 100644 index 0000000..2c0e1c7 --- /dev/null +++ b/core/components/phpthumbon/lexicon/ru/default.inc.php @@ -0,0 +1,39 @@ + + * + * @category images + * @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html + * @author Agel_Nash + * @date 02.08.2013 + * @version 1.0.0 + */ +/** + * Russian Lexicon for phpThumbOn + * + * @package phpThumbOn + * + * @subpackage lexicon + * @language ru + */ + +$_lang['setting_phpthumbon.cache_dir'] = 'Имя папки кеша'; +$_lang['setting_phpthumbon.cache_dir_desc'] = 'Имя папки с кешем относительно папки assets.'; + +$_lang['setting_phpthumbon.images_dir'] = 'Имя папки с картинками'; +$_lang['setting_phpthumbon.images_dir_desc'] = 'Имя папки относительно директории assets, имя которой будет удаляться из пути в кеш-директории'; + +$_lang['setting_phpthumbon.quality_names'] = 'Качество картинки по умолчанию'; +$_lang['setting_phpthumbon.quality_desc'] = 'Если не задано качество картинки в параметрах при вызове сниппета, то будет использоваться это значение'; + +$_lang['setting_phpthumbon.ext'] = 'Тип картинки по умолчанию'; +$_lang['setting_phpthumbon.ext_desc'] = 'Если на сжатие приходит картинка в неизвестном формате, то будет использоваться этот тип'; + +$_lang['setting_phpthumbon.noimage'] = 'Путь к картинки с изображением "картинка не существует"'; +$_lang['setting_phpthumbon.noimage_desc'] = 'Если картинка указанная в input окажется не доступной или вообще этот параметр пуст, то на обработку поступит картинка указанная в этом параметре'; + +$_lang['setting_phpthumbon.core_path'] = 'Путь к ядру компонента phpThumbOn'; +$_lang['setting_phpthumbon.core_path_desc'] = 'По умолчанию это /core/components/phpthumbon/'; \ No newline at end of file diff --git a/core/components/phpthumbon/lexicon/ru/properties.inc.php b/core/components/phpthumbon/lexicon/ru/properties.inc.php new file mode 100644 index 0000000..e865bf5 --- /dev/null +++ b/core/components/phpthumbon/lexicon/ru/properties.inc.php @@ -0,0 +1,24 @@ + + * + * @category images + * @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html + * @author Agel_Nash + * @date 02.08.2013 + * @version 1.0.0 + */ +/** + * Russian Lexicon for phpThumbOn + * + * @package phpThumbOn + * + * @subpackage lexicon + * @language ru + */ + +$_lang['phpthumbon.input'] = 'Путь к картинке'; +$_lang['phpthumbon.options'] = 'Параметры сжатия картинки для phpThumb'; diff --git a/core/components/phpthumbon/model/phpthumbon/phpthumbon.class.php b/core/components/phpthumbon/model/phpthumbon/phpthumbon.class.php new file mode 100644 index 0000000..92869fd --- /dev/null +++ b/core/components/phpthumbon/model/phpthumbon/phpthumbon.class.php @@ -0,0 +1,488 @@ + + * + * @category images + * @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html + * @author Agel_Nash + * @date 02.08.2013 + * @version 1.0.0 + * @package phpThumbOn + * + * I love chaining:-) + */ +class phpThumbOn { + /** @var modX объект класса modX */ + protected $modx; + + /** @var phpThumb объект класса phpThumb */ + protected $_phpThumb = null; + + /** @var null информация об обрабатываемом файле */ + protected $_fileInfo = null; + + /** @var bool наличие ошибки */ + protected $_flag = true; + + /** @var array все настройки класса */ + protected $_config = array(); + + /** @var array основные настройки класса */ + private $_cfg = array(); + + /** @var array кеш со */ + private $_cacheDir = array(); + + /** качество картинки по умолчанию */ + const DEFAULT_QUALITY = '96'; + + /** тип файла по умолчанию */ + const DEFAULT_EXT = 'jpeg'; + + /** @var array константа */ + private static $ALLOWED_EXT = array( + 'jpg'=>true, + 'jpeg'=>true, + 'png'=>true, + 'gif'=>true, + 'bmp'=>true + ); + + /** + * Проверка резрешено ли создавать такие файлы + * + * @param string расширение файла + * @return array константа ALLOWED_EXT + */ + public static function ALLOWED_EXT($ext=null){ + if(isset($ext)){ + if(is_scalar($ext) && isset(self::$ALLOWED_EXT[$ext])){ + $out = self::$ALLOWED_EXT[$ext]; + } else{ + $out = false; + } + } else{ + $out = self::$_ALLOWED_EXT; + } + + return $out; + } + + /** + * @param modX $modx + * @param array $config + * @access public + */ + public function __construct(modX $modx, array $config = array()) { + //$this->debugTime[__FUNCTION__][0] = microtime(true); + $this->modx = &$modx; + + $corePath = $this->modx->getOption('phpthumbon.core_path',array(),$this->modx->getOption('core_path').'components/phpthumbon/'); + $assetsPath = $this->modx->getOption('assets_path'); + $assetsUrl = $this->modx->getOption('assets_url'); + $this->_cfg = $this->_config = array_merge(array( + 'input' => null, + 'options' => null, + + //путь к папке с компонента + 'corePath' => $corePath, + + //путь к папке с моделью + 'modelPath' => $corePath.'model/', + + //Папка assets относительно корня сервера + 'assetsPath' => $assetsPath, + + //папка assets относительно web-root директории + 'assetsUrl' => $assetsUrl, + + // Папка в которой будут храниться кешированные картинки + 'cacheDir' => $assetsPath.trim($this->modx->getOption('phpthumbon.cache_dir', $this->_config, 'cache_image'),'/'), + + // подпапка из assets, в которой будут храниться картинки и загрузка картинок в которую будет сопровождаться плагином отчистки кеша + 'imagesFolder' => trim($this->modx->getOption('phpthumbon.images_dir', $this->_config, 'images'),'/'), + + //качество картинки по умолчанию + 'quality' => $this->modx->getOption('phpthumbon.quality', $this->_config, self::DEFAULT_QUALITY), + + //Тип картинки по умолчанию + 'ext' => $this->modx->getOption('phpthumbon.ext', $this->_config, self::DEFAULT_EXT), + + //Права на только что созданный файл + 'new_file_permissions' => (int)$this->modx->getOption('new_file_permissions',$this->_config,'0664'), + + // картинки нет + 'noimage' => $this->modx->getOption('phpthumbon.noimage', $this->_config, trim($assetsUrl,'/').'/components/phpthumbon/noimage.jpg') + ),$config); + + $this->_cfg['options'] = null; + $this->_cfg['input'] = null; + + $this->_validateConfig(); + + if (!$this->modx->loadClass('phpthumb',$this->modx->getOption('core_path').'model/phpthumb/',true,true)) { + $this->modx->log(modX::LOG_LEVEL_ERROR,'[phpthumbon] Could not load phpthumb class'); + $this->_flag = false; + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + } + + /** + * Проверка и исправление настроек по умолчанию + * + * @return bool были ли ошибки в конфигурации по умолчанию + */ + private function _validateConfig(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + $flag = true; + + if(!isset($this->_config['ext']) || !self::ALLOWED_EXT($this->_config['ext'])){ + $this->_config['ext'] = self::DEFAULT_EXT; + $flag = false; + } + + if(!isset($this->_config['quality']) || (int)$this->_config['quality']<=0){ + $this->_config['quality'] = self::DEFAULT_QUALITY; + $flag = false; + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $flag; + } + /** + * Обновление настроек класса + * + * @param array $options настройки для перезагрузки + * @access private + * @return bool статус обновления конфигов + */ + private function _setConfig($options = array()){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if($flag = (is_array($options) && array()!=$options)){ + $this->_config = array_merge($this->_cfg,$options); + $this->_validateConfig(); + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $flag; + } + + /** + * Запуск процесса создания превьюхи + * + * @param array обновление конфигов без перезагрузки класса + * @access public + * @return string имя файла с превьюхой или пустая строка + */ + public function run($options = array()){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + $this->_setConfig($options); + if($this->_flag){ + $this->_phpThumb = new phpthumb(); + + $out = $this->relativeSrcPath() + ->makeCacheDir() + ->makeOptions() + ->checkOptions() + ->saveOptions() + ->getCacheFileName() + ->getThumb(); + }else{ + $out = ''; + } + $this->flush(); + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $out; + } + + /** + * Цепочка для проверки необходимых параметров + * + * @access public + * @return $this + */ + public function checkOptions(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + $this->checkExt() + ->checkQuality() + ->setImage(); + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Создаем папку в которой будут храниться превьюхи текущей картинки + * + * @access public + * @return $this + */ + public function makeCacheDir(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + $exists = false; + $this->_config['_cachePath'] = $this->_config['cacheDir'].'/'.$this->_config['relativePath']; + + if($this->_flag){ + if($exists = isset($this->_cacheDir[$this->_config['_cachePath']])){ + $this->_flag = $this->_cacheDir[$this->_config['_cachePath']]; + } + } + if($this->_flag && !$exists){ + $this->modx->getService('fileHandler','modFileHandler'); + $dir = $this->modx->fileHandler->make($this->_config['_cachePath'], array(),'modDirectory'); + if(!is_object($dir) || !($dir instanceof modDirectory)) { + $this->modx->log(modX::LOG_LEVEL_ERROR,'[phpthumbon] Could not get class modDirectory'); + $this->_cacheDir[$this->_config['_cachePath']] = $this->_flag = false; + } + if($this->_flag){ + if(is_dir($this->_config['_cachePath']) || $dir->create()){ + $this->_cacheDir[$this->_config['_cachePath']] = true; + }else{ + $this->_cacheDir[$this->_config['_cachePath']] = $this->_flag = false; + $this->modx->log(modX::LOG_LEVEL_ERROR, "[phpthmbon] Could not create cache directory ".$this->_config['_cachePath']); + } + } + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Проверяем имя и его существование. + * Затем определяем папку в которую будут складываться превьюхи этого файла + * + * @access public + * @return $this + */ + public function relativeSrcPath(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if(!(empty($this->_config['input']) || !is_scalar($this->_config['input'])) + && !preg_match("/^http(s)?:\/\/\w+/",$this->_config['input']) + && file_exists($this->_config['input'])){ + $full_assets = $this->_config['assetsPath']; + $assets = ltrim($this->_config['assetsUrl'],'/'); + $imgDir = $this->_config['imagesFolder']; + $this->_config['relativePath'] = preg_replace("#^({$full_assets}|(/)?{$assets})(/)?{$imgDir}(/)?#", '', $this->_pathinfo('dirname')); + }else{ + if($this->_flag = file_exists($this->_config['noimage'])){ + $this->_config['input'] = $this->_config['noimage']; + $this->_config['relativePath'] = ''; + }else{ + $this->modx->log(modX::LOG_LEVEL_ERROR,'[phpthumbon] Input image path is empty'); + } + } + + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Чтобы не дергать постоянно файл который обрабатываем + * + * @access private + * @return string информация из pathinfo о обрабатываемом файле input + */ + private function _pathinfo($name){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if(empty($this->_fileInfo)){ + $this->_fileInfo = pathinfo($this->_config['input']); + } + $out = is_scalar($name) && isset($this->_fileInfo[$name]) ? $this->_fileInfo[$name] : ''; + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $out; + } + + /** + * Формируем массив параметров для phpThumb из параметра options у сниппета + * + * @access public + * @return $this + */ + public function makeOptions(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if($this->_flag){ + $eoptions = is_array($this->_config['options']) ? $this->_config['options'] : explode('&',$this->_config['options']); + $this->_config['_options'] = array(); + foreach ($eoptions as $opt) { + $opt = explode('=',$opt); + $key = str_replace('[]','',$opt[0]); + if (!empty($key)) { + /* allow arrays of options */ + if (isset($this->_config['_options'][$key])) { + if (is_string($this->_config['_options'][$key])) { + $this->_config['_options'][$key] = array($this->_config['_options'][$key]); + } + $this->_config['_options'][$key][] = $opt[1]; + } else { /* otherwise pass in as string */ + $this->_config['_options'][$key] = $opt[1]; + } + } + } + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Если параметр с расширением файла не установлен + * + * @access public + * @return $this + */ + public function checkExt(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if ($this->_flag && empty($this->_config['_options']['f'])){ + $ext = $this->_pathinfo('extension'); + $ext = strtolower($ext); + $this->_config['_options']['f'] = self::ALLOWED_EXT($ext) ? $ext : $this->_config['ext']; + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Если качество картинки не установлено + * + * @access public + * @return $this + */ + public function checkQuality(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if($this->_flag && empty($this->_config['_options']['q'])){ + $this->_config['_options']['q'] = $this->_config['quality']; + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Если вдруг передан параметр src - то игнорируем его, т.к. у нас единственный и основной должен быть input + * + * @access public + * @return $this + */ + public function setImage(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if($this->_flag){ + if(!empty($this->_config['_options']['src'])){ + unset($this->_config['_options']['src']); + } + $this->_phpThumb->setSourceFilename($this->_config['input']); //картинка какую будем сжимать + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Все необходимые параметры для создания превьюхи определены. Поэтому передаем их в phpthumb + * + * @access public + * @return $this + */ + public function saveOptions(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if($this->_flag){ + foreach($this->_config['_options'] as $item=>$value){ + $this->_phpThumb->setParameter($item,$value); + } + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Определяем имя файла и проверяем его наличие в кеш-папке + * + * @access public + * @return $this + */ + public function getCacheFileName(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + if($this->_flag){ + $w = isset($this->_config['_options']['w']) ? $this->_config['_options']['w'] : 0; + $h = isset($this->_config['_options']['h']) ? $this->_config['_options']['h'] : 0; + + //Уникальный суффикс в имени файла превьюхи + //$suffix = '_'.$w.'x'.$h.'_'.substr(md5($this->modx->toJSON($this->_config['_options'])),0,3); + $suffix = '_'.$w.'x'.$h.'_'.substr(md5(serialize($this->_config['_options'])),0,3); + + //папка в которой лежат превьюхи текущей картинки + $this->_cache['_cacheFileDir'] = rtrim($this->_config['_cachePath'],'/').'/'.$this->_pathinfo('filename'); + + //Для поиска других превьюх с этого же файла + //glob("fullfolder_to_cache_image/filename_[0-9]*x[0-9]*_???.{jpeg,gif,bmp,jpg,png}",GLOB_BRACE) + $this->_config['_globThumb'] = $this->_cache['_cacheFileDir']."_[0-9]*x[0-9]*_???.{jpeg,gif,bmp,jpg,png}"; + + //Кеш файл превьюхи + $this->_config['_cacheFileName'] = $this->_cache['_cacheFileDir'].$suffix.".".$this->_config['_options']['f']; + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $this; + } + + /** + * Пытаемся создать превьюху + * + * @access public + * @return string путь к превьюхе или пустая строка + */ + public function getThumb(){ + //$this->debugTime[__FUNCTION__][0] = microtime(true); + $new = false; + if($this->_flag){ + $out = $this->_config['_cacheFileName']; + //Если оригинальный файл был изменен + if(file_exists($out) && filemtime($out) < filemtime($this->_config['input'])){ + unlink($out); + //Удаляем другие превьюхи этого же файла + $thumbFile = glob($this->_config['_globThumb'],GLOB_BRACE); + foreach($thumbFile as $tf){ + unlink($tf); + } + } + if (!file_exists($out)){ + // Пробуем создать превьюху + if ($this->_phpThumb->GenerateThumbnail()){ + // Сохраняем превьюху в кеш-файл + $new = true; + $out = $this->_phpThumb->RenderToFile($out); + }else{ + $out = false; + $this->modx->log(modX::LOG_LEVEL_ERROR,'[phpthumbon] Could not generate thumbnail'); + } + } + + // Отдаем имя превьюхи предварительно заменив абсолютный путь на относительный + if($out){ + if($new){ + chmod($this->_config['_cacheFileName'], octdec($this->_config['new_file_permissions'])); + } + $out = str_replace($this->_config['assetsPath'], $this->_config['assetsUrl'], $this->_config['_cacheFileName']); + } + }else{ + $out = false; + } + + if($out===false){ + $out = ''; + } + //$this->debugTime[__FUNCTION__][1] = microtime(true); + return $out; + } + + /** + * Сброс текущих настроек + * + * @access public + * @return bool всегда true + */ + public function flush(){ + $this->_flag = class_exists('phpthumb'); + $this->_config = array_merge( + $this->_cfg, + array('options'=>null,'input'=>null) + ); + $this->_fileInfo = $this->_phpThumb = null; + return true; + } +} \ No newline at end of file