Last active
December 30, 2015 08:59
-
-
Save AgelxNash/7806132 to your computer and use it in GitHub Desktop.
PHPThumb под MODX Evolution с поддержкой очереди сжатия картинок
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* QueuePHPThumb | |
* | |
* @category snippet | |
* @version 1.0 | |
* @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html | |
* @author Agel_Nash <Agel_Nash@xaker.ru> | |
* @internal @properties &queue=Использовать очередь;list;true,false;true | |
* | |
* [[phpthumb? &input=`[+tvimagename+]` &options=`w_255,h=200` &queue=`false`]] | |
*/ | |
if(!defined('MODX_BASE_PATH')){die('What are you doing? Get out of here!');} | |
require_once MODX_BASE_PATH."/assets/snippets/phpthumb/QueuePHPThumb.class.php"; | |
$qthumb = new QueuePHPThumb($modx); | |
$qthumb->init($modx->Event->params); | |
return $qthumb->makeFile(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class QueuePHPThumb{ | |
/** @var \DocumentParser|null */ | |
protected $_modx = null; | |
/** @var PhpThumb */ | |
protected $phpThumb = null; | |
protected $options = array(); | |
protected $image = null; | |
protected $noFile = null; | |
protected $queue = false; | |
protected $allowOptions = array(); | |
protected $_allowExt = array('png', 'gif', 'jpg'); | |
const DEFAULT_EXT = 'jpg'; | |
const DEFAULT_QUALITY = '96'; | |
const NO_IMAGE = 'assets/images/noimage.jpg'; | |
const CACHE_NOIMAGE_FOLDER = 'assets/images/noimage/'; | |
const CACHE_IMAGE_FOLDER = 'assets/thumbs/'; | |
const TABLE = 'images'; | |
/** | |
* @param $modx DocumentParser | |
*/ | |
public function __construct(DocumentParser $modx){ | |
$this->_modx = $modx; | |
} | |
/** | |
* Создать кэш файл с картинкой noImage | |
* | |
* @param string $fileName куда сохранить картинку | |
* @return array|string | |
*/ | |
public function getNoFile($fileName = ''){ | |
$to = MODX_BASE_PATH . QueuePHPThumb::CACHE_NOIMAGE_FOLDER . md5(serialize($this->options).$this->noFile) . "." . $this->getParam('f'); | |
if(!file_exists($to)){ | |
$to = $this->createFile(MODX_BASE_PATH.$this->noFile, $to); | |
} | |
if(file_exists($to)){ | |
copy($to, $fileName); | |
} | |
return $this->clearPath($fileName, false); | |
} | |
/** | |
* Запуск сниппета | |
* | |
* @param array $params | |
*/ | |
public function init(array $params = array()){ | |
$this->noFile = (isset($params['noimage']) && $this->checkFile($params['noimage'])) ? $params['noimage'] : QueuePHPThumb::NO_IMAGE; | |
$this->image = (isset($params['input']) && $this->checkFile($params['input'])) ? $params['input'] : $this->noFile; | |
$this->queue = (empty($params['queue']) || $params['queue']=='false') ? false : true; | |
$this->options = isset($params['options']) && is_scalar($params['options']) ? $params['options'] : ''; | |
$this->options = explode("&", strtr($this->options, array("," => "&", "_" => "="))); | |
$this->options = $this->getOptions(); | |
} | |
/** | |
* Получение настроек сжатия | |
* @return array | |
*/ | |
protected function getOptions(){ | |
$allow = $this->getAllow(); | |
$need=array_keys($allow); | |
$op = array(); | |
foreach ($this->options as $value) { | |
$thumb = explode("=", $value); | |
$key = str_replace('[]','',$thumb[0]); | |
if (!empty($key)) { | |
if (isset($need[$key])) { | |
if (is_string($need[$key])) { | |
$need[$key] = array($need[$key]); | |
} | |
$need[$key][] = $thumb[1]; | |
} else { | |
$need[$key] = $thumb[1]; | |
} | |
unset($allow[$key]); | |
} | |
$op[$key]=$need[$key]; | |
} | |
foreach($allow as $key=>$value){ | |
$op[$key]=$value; | |
} | |
$this->options = $op; | |
return $this->options; | |
} | |
/** | |
* Сохранение задания в очередь | |
* | |
* @param $oldImage Оригинальная картинка | |
* @param $newImage Путь к кэш файлу | |
* @param array $options Параметры сжатия | |
* @return $this | |
*/ | |
public function saveQueue($oldImage, $newImage, array $options = array()){ | |
$oldImage = $this->_modx->db->escape($oldImage); | |
$newImage = $this->_modx->db->escape($newImage); | |
$options = $this->_modx->db->escape(serialize($options)); | |
$table = $this->_modx->getFullTableName(QueuePHPThumb::TABLE); | |
$q = $this->_modx->db->getValue("SELECT count(`id`) FROM ".$table." WHERE `image` = '".$oldImage."' AND `cache_image` = '".$newImage."' AND `config` = '".$options."'"); | |
if($q==0){ | |
$this->_modx->db->insert(array( | |
'image' => $oldImage, | |
'cache_image' => $newImage, | |
'config' => $options, | |
'isend' => 0 | |
), $table); | |
} | |
return $this; | |
} | |
/** | |
* Проверка обязательных параметров для сжатия | |
* | |
* @return array | |
*/ | |
protected function getAllow(){ | |
$this->allowOptions = array(); | |
$this->allowOptions['q'] = QueuePHPThumb::DEFAULT_QUALITY; | |
$path_parts=pathinfo($this->getImage()); | |
if(in_array(strtolower($path_parts['extension']), $this->_allowExt)){ | |
$this->allowOptions['f'] = strtolower($path_parts['extension']); | |
}else{ | |
$this->allowOptions['f'] = QueuePHPThumb::DEFAULT_EXT; | |
} | |
return $this->allowOptions; | |
} | |
/** | |
* Путь к файлу от корня сайта | |
* | |
* @param $file | |
* @param bool $full | |
* @return mixed|string | |
*/ | |
public function clearPath($file, $full = true){ | |
$out = ''; | |
if(is_scalar($file)){ | |
$out = preg_replace("#^".MODX_BASE_PATH."#", '', $file); | |
if($full && !empty($out)){ | |
$out = MODX_BASE_PATH.$out; | |
} | |
} | |
return $out; | |
} | |
/** | |
* Определение файла которй нужно будет сжать | |
* @return mixed|string | |
*/ | |
protected function getImage(){ | |
$file = !empty($this->image) ? $this->image : $this->noFile; | |
return $this->clearPath($file); | |
} | |
/** | |
* Загрузка phpThumb и установка параметров | |
* @param $image | |
* @return $this | |
*/ | |
protected function loadPhpThumb($image){ | |
require_once MODX_BASE_PATH."/assets/snippets/phpthumb/phpthumb.class.php"; | |
$this->phpThumb = new phpthumb(); | |
$this->phpThumb->config_ttf_directory = dirname(__FILE__).'/fonts'; | |
$this->phpThumb->setSourceFilename($image); | |
foreach($this->options as $key=>$value){ | |
if(!empty($key)){ | |
$this->phpThumb->setParameter($key, $value); | |
} | |
} | |
return $this; | |
} | |
/** | |
* Сфрмировать путь и имя кэш файла | |
* | |
* @return string | |
*/ | |
public function getCacheName(){ | |
$image = $this->getImage(); | |
$path_parts=pathinfo($image); | |
$tmp = preg_replace("#^".MODX_BASE_PATH."#", "", $path_parts['dirname']); | |
$tmp = ($tmp=='assets/images' ? '' : preg_replace("#^assets/images/#", "/", ltrim($tmp,'/'))); | |
$ftime=filemtime($image); | |
$tmp=QueuePHPThumb::CACHE_IMAGE_FOLDER.ltrim($tmp, '/'); | |
$tmp=explode("/",$tmp); | |
$tmp[] = substr(md5(serialize($this->options)),0,3); | |
$tmp[]=date("Y-m",$ftime); | |
$folder = ''; | |
for($i=0;$i<count($tmp);$i++){ | |
$folder.="/".$tmp[$i]; | |
if(!is_dir(MODX_BASE_PATH . $folder) || !file_exists(MODX_BASE_PATH . $folder)){ | |
mkdir(MODX_BASE_PATH . $folder); | |
} | |
} | |
$outputFilename =MODX_BASE_PATH.$folder."/".date("d_h_i_s",$ftime)."_".$path_parts['extension']."_".$path_parts['filename'].".".$this->getParam('f'); | |
return $outputFilename; | |
} | |
/** | |
* Получение значения из конифга | |
* | |
* @param $key ключ в конфиге | |
* @return null | |
*/ | |
public function getParam($key){ | |
return (!empty($key) && is_scalar($key) && isset($this->options[$key])) ? $this->options[$key] : null; | |
} | |
/** | |
* Создания кэш файла | |
* | |
* @param $from оригинальнфй файл | |
* @param $to куда сохранять | |
* @return array|string | |
*/ | |
public function createFile($from, $to){ | |
if (!file_exists($to) || filemtime($from) > filemtime($to)){ | |
$this->loadPhpThumb($from); | |
if($this->phpThumb->GenerateThumbnail()){ | |
$this->phpThumb->RenderToFile($to) ; | |
} | |
} | |
$res = explode("/assets", $to, 2); | |
$res = "/assets".$res[1]; | |
return $res; | |
} | |
/** | |
* Проверка файла на существование | |
* | |
* @param $file Путь к файлу | |
* @return bool флаг доступности файла | |
*/ | |
protected function checkFile($file){ | |
$out = false; | |
if(is_scalar($file) && !preg_match("/^http(s)?:\/\/\w+/",$file)){ | |
$file = MODX_BASE_PATH . preg_replace("#^".MODX_BASE_PATH."#", '', $file); | |
$out = (file_exists($file) && is_file($file) && is_readable($file)); | |
} | |
return $out; | |
} | |
/** | |
* Постановка задания очередь | |
* | |
* @return mixed|string | |
*/ | |
public function makeFile(){ | |
$tmpName = $this->getCacheName(); | |
$image = $this->getImage(); | |
if(!file_exists($tmpName) || filemtime($image) > filemtime($tmpName)){ | |
if($this->queue){ | |
$res = $this->saveQueue($this->clearPath($image, false), $this->clearPath($tmpName, false), $this->options)->getNoFile($tmpName); | |
}else{ | |
$res = $this->createFile($image, $tmpName); | |
} | |
}else{ | |
$res = $this->clearPath($tmpName, false); | |
} | |
return $res; | |
} | |
/** | |
* Выполнения задания из очереди | |
* | |
* @return bool|null Результат выполнения задания в очереди | |
*/ | |
public function runQueue(){ | |
$flag = null; | |
$table = $this->_modx->getFullTableName(QueuePHPThumb::TABLE); | |
$q = $this->_modx->db->query("SELECT * FROM ".$table." WHERE `isend` = 0 ORDER BY RAND() LIMIT 1"); | |
if($this->_modx->db->getRecordCount($q)==1){ | |
$q = $this->_modx->db->getRow($q); | |
$this->options = unserialize($q['config']); | |
if(file_exists(MODX_BASE_PATH.$q['cache_image'])){ | |
unlink(MODX_BASE_PATH.$q['cache_image']); | |
} | |
if(file_exists(MODX_BASE_PATH.$q['image'])){ | |
$this->createFile(MODX_BASE_PATH.$q['image'], MODX_BASE_PATH.$q['cache_image']); | |
$this->_modx->db->update(array('isend'=>1), $table, "id = ".$q['id']); | |
$flag = true; | |
}else{ | |
$this->_modx->db->delete($table, "id = ".$q['id']); | |
$flag = false; | |
} | |
} | |
return $flag; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DROP TABLE IF EXISTS `modx_images`; | |
CREATE TABLE `modx_images` ( | |
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, | |
`image` varchar(255) DEFAULT NULL, | |
`cache_image` varchar(255) DEFAULT NULL, | |
`isend` tinyint(1) unsigned NOT NULL DEFAULT '0', | |
`config` varchar(255) DEFAULT NULL, | |
PRIMARY KEY (`id`), | |
KEY `image` (`image`), | |
KEY `isend` (`isend`), | |
KEY `config` (`config`) | |
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
define('MODX_API_MODE', true); | |
include_once(dirname(__FILE__)."/index.php"); | |
require_once MODX_BASE_PATH."/assets/snippets/phpthumb/phpthumb.class.php"; | |
$modx->db->connect(); | |
if (empty ($modx->config)) { | |
$modx->getSettings(); | |
} | |
require_once MODX_BASE_PATH."/assets/snippets/phpthumb/QueuePHPThumb.class.php"; | |
$qthumb = new QueuePHPThumb($modx); | |
$flag = $qthumb->runQueue(); | |
if($flag === null){ | |
echo 'Empty'; | |
}else if($flag === true){ | |
echo 'Good'; | |
}else{ | |
echo 'Fatal'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment