loadClass('phpthumb', MODX_CORE_PATH . 'model/phpthumb/', true, true)) {
$modx->log(modX::LOG_LEVEL_ERROR, '[phpThumbOf] Could not load modPhpThumb class.');
return '';
}
}
$debug = $modx->getOption('debug', $scriptProperties, false);
$src = $modx->getOption('src', $scriptProperties, '');
$src = str_replace('+', '%27', urldecode($src));
/* explode tag options */
$ptOptions = array();
// Only public parameters of phpThumb should be allowed to pass from user input.
// List properties between START PARAMETERS and START PARAMETERS in src/core/model/phpthumb/phpthumb.class.php
$allowed = array(
'src', 'new', 'w', 'h', 'wp', 'hp', 'wl', 'hl', 'ws', 'hs',
'f', 'q', 'sx', 'sy', 'sw', 'sh', 'zc', 'bc', 'bg', 'fltr',
'goto', 'err', 'xto', 'ra', 'ar', 'aoe', 'far', 'iar', 'maxb', 'down',
'md5s', 'sfn', 'dpi', 'sia', 'phpThumbDebug'
);
/* iterate through properties */
foreach ($scriptProperties as $property => $value) {
if (!in_array($property, $allowed, true)) {
$this->modx->log(modX::LOG_LEVEL_WARN, "Detected attempt of using private parameter `$property` (for internal usage) of phpThumb that not allowed and insecure");
continue;
}
$ptOptions[$property] = $value;
}
if (empty($ptOptions['f'])) {
$ext = pathinfo($src, PATHINFO_EXTENSION);
$ext = strtolower($ext);
switch ($ext) {
case 'jpg':
case 'jpeg':
case 'png':
case 'gif':
case 'bmp':
$ptOptions['f'] = $ext;
break;
default:
$ptOptions['f'] = 'jpeg';
break;
}
}
/* load phpthumb */
$assetsPath = $modx->getOption('gallery.assets_path', $scriptProperties, $modx->getOption('assets_path') . 'components/gallery/');
$cacheDir = $assetsPath . 'cache/';
/* check to make sure cache dir is writable */
if (!is_writable($cacheDir)) {
if (!$modx->cacheManager->writeTree($cacheDir)) {
$modx->log(modX::LOG_LEVEL_ERROR, '[phpThumbOf] Cache dir not writable: ' . $assetsPath . 'cache/');
return '';
}
}
/* get absolute url of image */
if (strpos($src, '/') != 0 && strpos($src, 'http') != 0) {
$src = $modx->getOption('base_url') . $src;
} else {
$src = urldecode($src);
}
/* auto-prepend base path if not a URL */
if (strpos($src, 'http') === false) {
$basePath = $modx->getOption('base_path', null, MODX_BASE_PATH);
if ($basePath != '/') {
$src = str_replace(basename($basePath), '', $src);
$src = ltrim($src, '/');
$src = $basePath . $src;
}
}
if (!isset($config['modphpthumb'])) { // make sure we get a few relevant system settings
$config['modphpthumb'] = array();
$config['modphpthumb']['config_allow_src_above_docroot'] = (boolean)$modx->getOption('phpthumb_allow_src_above_docroot', null, false);
$config['modphpthumb']['zc'] = $modx->getOption('phpthumb_zoomcrop', null, 0);
$config['modphpthumb']['far'] = $modx->getOption('phpthumb_far', null, 'C');
$config['modphpthumb']['config_ttf_directory'] = MODX_CORE_PATH . 'model/phpthumb/fonts/';
$config['modphpthumb']['config_document_root'] = $modx->getOption('phpthumb_document_root', null, '');
}
$phpThumb = new phpthumb(); // unfortunately we have to create a new object for each image!
foreach ($config['modphpthumb'] as $param => $value) { // add MODX system settings
$phpThumb->$param = $value;
}
foreach ($ptOptions as $param => $value) { // add options passed to the snippet
$phpThumb->setParameter($param, $value);
}
// try to avert problems when $_SERVER['DOCUMENT_ROOT'] is different than MODX_BASE_PATH
if (!$phpThumb->config_document_root) {
$phpThumb->config_document_root = MODX_BASE_PATH; // default if nothing set from system settings
}
$phpThumb->config_cache_directory = $assetsPath . 'cache/'; // doesn't matter, but saves phpThumb some frustration
$phpThumb->setSourceFilename($src);
/* setup cache filename that is unique to this tag */
$inputSanitized = str_replace(array(':', '/'), '_', $src);
$cacheFilename = $inputSanitized;
$cacheFilename .= '.' . md5(serialize($scriptProperties));
$cacheFilename .= '.' . (!empty($ptOptions['f']) ? $ptOptions['f'] : 'png');
$cacheKey = $assetsPath . 'cache/' . $cacheFilename;
/* get cache Url */
$assetsUrl = $modx->getOption('gallery.assets_url', $scriptProperties, $modx->getOption('assets_url') . 'components/gallery/');
$cacheUrl = $assetsUrl . 'cache/' . str_replace($cacheDir, '', $cacheKey);
$cacheUrl = str_replace('//', '/', $cacheUrl);
/* ensure we have an accurate and clean cache directory */
$phpThumb->CleanUpCacheDirectory();
/* debugging code */
if ($debug) {
$mtime = microtime();
$mtime = explode(" ", $mtime);
$mtime = $mtime[1] + $mtime[0];
$tstart = $mtime;
set_time_limit(0);
$oldLogTarget = $modx->getLogTarget();
$oldLogLevel = $modx->getLogLevel();
$modx->setLogLevel(modX::LOG_LEVEL_DEBUG);
$logTarget = $modx->getOption('debugTarget', $scriptProperties, '');
if (!empty($logTarget)) {
$modx->setLogTarget();
}
}
/* ensure file has proper permissions */
if (!empty($cacheKey)) {
$filePerm = (int)$modx->getOption('new_file_permissions', $scriptProperties, '0664');
@chmod($cacheKey, octdec($filePerm));
}
if ($debug) {
$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_DEBUG, "\n
Execution time: {$totalTime}\n
");
$modx->setLogLevel($oldLogLevel);
$modx->setLogTarget($oldLogTarget);
}
$output = $assetsUrl;
/* check to see if there's a cached file of this already */
if (file_exists($cacheKey)) {
$modx->log(modX::LOG_LEVEL_DEBUG, '[phpThumbOf] Using cached file found for thumb: ' . $cacheKey);
$output = str_replace(' ', '%20', $cacheUrl);
} else {
/* actually make the thumbnail */
//return $cacheKey;
if ($phpThumb->GenerateThumbnail()) { // this line is VERY important, do not remove it!
if ($phpThumb->RenderToFile($cacheKey)) {
$output = str_replace(' ', '%20', $cacheUrl);
} else {
$modx->log(modX::LOG_LEVEL_ERROR, '[phpThumbOf] Could not cache thumb "' . $src . '" to file at: ' . $cacheKey . ' - Debug: ' . print_r($phpThumb->debugmessages, true));
}
} else {
$modx->log(modX::LOG_LEVEL_ERROR, '[phpThumbOf] Could not generate thumbnail: ' . $src . ' - Debug: ' . print_r($phpThumb->debugmessages, true));
}
}
if (!headers_sent()) {
$headers = $modx->request->getHeaders();
$mtime = filemtime($cacheKey);
if (isset($headers['If-Modified-Since']) && strtotime($headers['If-Modified-Since']) == $mtime) {
// cache is good, send 304
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT', true, 304);
exit();
}
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT', true, 200);
$phpThumb->setOutputFormat();
header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($phpThumb->thumbnailFormat));
header('Content-Disposition: inline; filename="'.basename($src).'"');
}
return file_get_contents($cacheKey);