diff options
author | rvelices <rv-github@modusoptimus.com> | 2012-01-01 21:10:43 +0000 |
---|---|---|
committer | rvelices <rv-github@modusoptimus.com> | 2012-01-01 21:10:43 +0000 |
commit | 95a78ca0d3412ffa1d54e13c9caab7bc8b6b0e13 (patch) | |
tree | e6fe20dc51fbd1efefbd0d11aa9d0893b470891e | |
parent | ec82ebbdccf9340d9168d8c061e94e52100aa8f1 (diff) |
feature 2541 multisize
- admin GUI for choosing derivative parameters + persistence
git-svn-id: http://piwigo.org/svn/trunk@12820 68402e56-0260-453c-a942-63ccdbb3a9ee
-rw-r--r-- | admin.php | 1 | ||||
-rw-r--r-- | admin/derivatives.php | 235 | ||||
-rw-r--r-- | admin/include/functions.php | 24 | ||||
-rw-r--r-- | admin/themes/default/template/admin.tpl | 1 | ||||
-rw-r--r-- | admin/themes/default/template/derivatives.tpl | 79 | ||||
-rw-r--r-- | i.php | 58 | ||||
-rw-r--r-- | include/derivative_params.inc.php | 9 | ||||
-rw-r--r-- | include/derivative_std_params.inc.php | 62 | ||||
-rw-r--r-- | language/en_UK/common.lang.php | 9 |
9 files changed, 432 insertions, 46 deletions
@@ -165,6 +165,7 @@ $template->assign( 'U_MAINTENANCE'=> $link_start.'maintenance', 'U_NOTIFICATION_BY_MAIL'=> $link_start.'notification_by_mail', 'U_CONFIG_GENERAL'=> $link_start.'configuration', + 'U_CONFIG_DERIVATIVES'=> $link_start.'derivatives', 'U_CONFIG_DISPLAY'=> $conf_link.'default', 'U_CONFIG_EXTENTS'=> $link_start.'extend_for_templates', 'U_CONFIG_MENUBAR'=> $link_start.'menubar', diff --git a/admin/derivatives.php b/admin/derivatives.php new file mode 100644 index 000000000..fbf1ccffb --- /dev/null +++ b/admin/derivatives.php @@ -0,0 +1,235 @@ +<?php +// +-----------------------------------------------------------------------+ +// | Piwigo - a PHP based photo gallery | +// +-----------------------------------------------------------------------+ +// | Copyright(C) 2008-2011 Piwigo Team http://piwigo.org | +// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net | +// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick | +// +-----------------------------------------------------------------------+ +// | This program is free software; you can redistribute it and/or modify | +// | it under the terms of the GNU General Public License as published by | +// | the Free Software Foundation | +// | | +// | This program is distributed in the hope that it will be useful, but | +// | WITHOUT ANY WARRANTY; without even the implied warranty of | +// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | +// | General Public License for more details. | +// | | +// | You should have received a copy of the GNU General Public License | +// | along with this program; if not, write to the Free Software | +// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | +// | USA. | +// +-----------------------------------------------------------------------+ + +defined('PHPWG_ROOT_PATH') or trigger_error('Hacking attempt!', E_USER_ERROR); + +$errors = array(); + +if ( isset($_POST['d']) ) +{ + $pderivatives = $_POST['d']; + + // step 1 - sanitize HTML input + foreach($pderivatives as $type => &$pderivative) + { + if ($pderivative['must_square'] = ($type==IMG_SQUARE ? true : false)) + { + $pderivative['h'] = $pderivative['w']; + $pderivative['minh'] = $pderivative['minw'] = $pderivative['w']; + $pderivative['crop'] = 100; + } + $pderivative['must_enable'] = ($type==IMG_SQUARE || $type==IMG_THUMB)? true : false; + $pderivative['enabled'] = isset($pderivative['enabled']) || $pderivative['must_enable'] ? true : false; + } + unset($pderivative); + + // step 2 - check validity + $prev_w = $prev_h = 0; + foreach(ImageStdParams::get_all_types() as $type) + { + $pderivative = $pderivatives[$type]; + if (!$pderivative['enabled']) + continue; + + $v = intval($pderivative['w']); + if ($v<=0 || $v<=$prev_w) + { + $errors[$type]['w'] = '>'.$prev_w; + } + $v = intval($pderivative['h']); + if ($v<=0 || $v<=$prev_h) + { + $errors[$type]['h'] = '>'.$prev_h; + } + $v = intval($pderivative['crop']); + if ($v<0 || $v>100) + { + $errors[$type]['crop'] = '[0..100]'; + } + + if ($v!=0) + { + $v = intval($pderivative['minw']); + if ($v<0 || $v>intval($pderivative['w'])) + { + $errors[$type]['minw'] = '[0..'.intval($pderivative['w']).']'; + } + $v = intval($pderivative['minh']); + if ($v<0 || $v>intval($pderivative['h'])) + { + $errors[$type]['minh'] = '[0..'.intval($pderivative['h']).']'; + } + } + + if (count($errors)==0) + { + $prev_w = intval($pderivative['w']); + $prev_h = intval($pderivative['h']); + } + } + // step 3 - save data + if (count($errors)==0) + { + $enabled = ImageStdParams::get_defined_type_map(); + $disabled = @unserialize( @$conf['disabled_derivatives'] ); + if ($disabled===false) + { + $disabled = array(); + } + $changed_types = array(); + + foreach(ImageStdParams::get_all_types() as $type) + { + $pderivative = $pderivatives[$type]; + + if ($pderivative['enabled']) + { + $new_params = new DerivativeParams( + new SizingParams( + array($pderivative['w'],$pderivative['h']), + round($pderivative['crop'] / 100, 2), + array($pderivative['minw'],$pderivative['minh']) + ) + ); + if (isset($enabled[$type])) + { + $old_params = $enabled[$type]; + $same = true; + if ( !size_equals($old_params->sizing->ideal_size, $new_params->sizing->ideal_size) + or $old_params->sizing->max_crop != $new_params->sizing->max_crop) + { + $same = false; + } + + if ( $same && $new_params->sizing->max_crop != 0 + && !size_equals($old_params->sizing->min_size, $new_params->sizing->min_size) ) + { + $same = false; + } + + if (!$same) + { + $new_params->last_mod_time = time(); + $changed_types[] = $type; + } + else + { + $new_params->last_mod_time = $old_params->last_mod_time; + } + $enabled[$type] = $new_params; + } + else + {// now enabled, before was disabled + $enabled[$type] = $new_params; + unset($disabled[$type]); + } + } + else + {// disabled + if (isset($enabled[$type])) + {// now disabled, before was enabled + $disabled[$type] = $enabled[$type]; + unset($enabled[$type]); + } + } + } + + $enabled_by = array(); // keys ordered by all types + foreach(ImageStdParams::get_all_types() as $type) + { + if (isset($enabled[$type])) + { + $enabled_by[$type] = $enabled[$type]; + } + } + ImageStdParams::set_and_save($enabled_by); + if (count($disabled)==0) + { + $query='DELETE FROM '.CONFIG_TABLE.' WHERE param = \'disabled_derivatives\''; + pwg_query($query); + } + else + { + conf_update_param('disabled_derivatives', addslashes(serialize($disabled)) ); + } + $conf['disabled_derivatives']=serialize($disabled); + + if (count($changed_types)) + { + clear_derivative_cache($changed_types); + } + } + else + { + $template->assign('derivatives', $pderivatives); + $template->assign('ferrors', $errors); + } +} + +if (count($errors)==0) +{ + $enabled = ImageStdParams::get_defined_type_map(); + $disabled = @unserialize( @$conf['disabled_derivatives'] ); + if ($disabled===false) + { + $disabled = array(); + } + + $tpl_vars = array(); + foreach(ImageStdParams::get_all_types() as $type) + { + $tpl_var = array(); + + $tpl_var['must_square'] = ($type==IMG_SQUARE ? true : false); + $tpl_var['must_enable'] = ($type==IMG_SQUARE || $type==IMG_THUMB)? true : false; + + if ($params=@$enabled[$type]) + { + $tpl_var['enabled']=true; + } + else + { + $tpl_var['enabled']=false; + $params=@$disabled[$type]; + } + + if ($params) + { + list($tpl_var['w'],$tpl_var['h']) = $params->sizing->ideal_size; + if ( ($tpl_var['crop'] = round(100*$params->sizing->max_crop)) > 0) + { + list($tpl_var['minw'],$tpl_var['minh']) = $params->sizing->min_size; + } + else + { + $tpl_var['minw'] = $tpl_var['minh'] = ""; + } + } + $tpl_vars[$type]=$tpl_var; + } + $template->assign('derivatives', $tpl_vars); +} + +$template->set_filename('derivatives', 'derivatives.tpl'); +$template->assign_var_from_handle('ADMIN_CONTENT', 'derivatives'); +?>
\ No newline at end of file diff --git a/admin/include/functions.php b/admin/include/functions.php index 85ee0f4f2..0669c8d6d 100644 --- a/admin/include/functions.php +++ b/admin/include/functions.php @@ -2054,6 +2054,7 @@ function get_active_menu($menu_page) return 4; case 'configuration': + case 'derivatives': case 'extend_for_templates': case 'menubar': case 'themes': @@ -2247,23 +2248,34 @@ SELECT return array_from_query($query, 'user_id'); } -function clear_derivative_cache($type='all') +/** delete all derivative files for one or several types */ +function clear_derivative_cache($types='all') { $pattern='#.*-'; - if ($type == 'all') + if ($types == 'all') + { + $types = ImageStdParams::get_all_types(); + $types[] = IMG_CUSTOM; + } + elseif (!is_array($types)) + { + $types = array($types); + } + + if (count($types)>1) { $type_urls = array(); - foreach(ImageStdParams::get_all_types() as $dtype) + foreach($types as $dtype) { $type_urls[] = derivative_to_url($dtype); } - $type_urls[] = derivative_to_url(IMG_CUSTOM); $pattern .= '(' . implode('|',$type_urls) . ')'; } else { - $pattern .= derivative_to_url($type); + $pattern .= derivative_to_url($types[0]); } + $pattern.='(_[a-zA-Z0-9]+)*\.[a-zA-Z0-9]{3,4}$#'; if ($contents = opendir(PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR)) { @@ -2320,7 +2332,7 @@ function clear_derivative_cache_rec($path, $pattern) unlink($path.'/index.htm'); } clearstatcache(); - rmdir($path); + @rmdir($path); } return $rmdir; } diff --git a/admin/themes/default/template/admin.tpl b/admin/themes/default/template/admin.tpl index 320e11c7c..c04812090 100644 --- a/admin/themes/default/template/admin.tpl +++ b/admin/themes/default/template/admin.tpl @@ -84,6 +84,7 @@ jQuery(document).ready(function(){ldelim} <dd> <ul> <li><a href="{$U_CONFIG_GENERAL}">{'Options'|@translate}</a></li> + <li><a href="{$U_CONFIG_DERIVATIVES}">{'Derivatives'|@translate}</a></li> <li><a href="{$U_CONFIG_MENUBAR}">{'Menu Management'|@translate}</a></li> <li><a href="{$U_CONFIG_EXTENTS}">{'Templates'|@translate}</a></li> <li><a href="{$U_CONFIG_LANGUAGES}">{'Languages'|@translate}</a></li> diff --git a/admin/themes/default/template/derivatives.tpl b/admin/themes/default/template/derivatives.tpl new file mode 100644 index 000000000..212d72db7 --- /dev/null +++ b/admin/themes/default/template/derivatives.tpl @@ -0,0 +1,79 @@ +<h2>{'Derivatives'|@translate}</h2> + +{html_head}{literal} +<style type="text/css"> +#derviativesForm .dError { + background-color: red; + color: yellow; +} + +#derviativesForm .dErrorDesc { +} + +#derviativesForm TABLE THEAD { + height: 3em; +} + +#derviativesForm TABLE INPUT[type="text"] { + border: 0; + width: 5em; +} + +</style> +{/literal}{/html_head} + +<form method="post" id="derviativesForm"> +<table class="table2"> + <thead> + <tr> + <td></td> + <td>Enabled</td> + <td>{'Width'|@translate}</td> + <td>{'Height'|@translate}</td> + <td>{'Crop'|@translate} (%)</td> + <td>{'Min Width'|@translate}</td> + <td>{'Min Height'|@translate}</td> + </tr> + </thead> + {foreach from=$derivatives item=d key=type} + <tr> + <td>{$type|@translate}</td> + <td> + {if $d.must_enable} + x + {else} + <input type="checkbox" name="d[{$type}][enabled]" {if $d.enabled}checked="checked"{/if}> + {/if} + </td> + <td> + <input type="text" name="d[{$type}][w]" value="{$d.w}"{if isset($ferrors.$type.w)}class="dError"{/if}> + {if isset($ferrors.$type.w)}<span class="dErrorDesc" title="{$ferrors.$type.w}">!</span>{/if} + </td> + <td>{if !$d.must_square} + <input type="text" name="d[{$type}][h]" value="{$d.h}"{if isset($ferrors.$type.h)}class="dError"{/if}> + {if isset($ferrors.$type.h)}<span class="dErrorDesc" title="{$ferrors.$type.h}">!</span>{/if} + {/if}</td> + <td>{if !$d.must_square} + <input type="text" name="d[{$type}][crop]" value="{$d.crop}"{if isset($ferrors.$type.crop)}class="dError"{/if}> + {if isset($ferrors.$type.crop)}<span class="dErrorDesc" title="{$ferrors.$type.crop}">!</span>{/if} + {/if}</td> + <td>{if !$d.must_square} + <input type="text" name="d[{$type}][minw]" value="{$d.minw}"{if isset($ferrors.$type.minw)}class="dError"{/if}> + {if isset($ferrors.$type.minw)}<span class="dErrorDesc" title="{$ferrors.$type.minw}">!</span>{/if} + {/if}</td> + <td>{if !$d.must_square} + <input type="text" name="d[{$type}][minh]" value="{$d.minh}"{if isset($ferrors.$type.minh)}class="dError"{/if}> + {if isset($ferrors.$type.minh)}<span class="dErrorDesc" title="{$ferrors.$type.minh}">!</span>{/if} + {/if}</td> + + </tr> + {/foreach} +</table> +<p><input type="submit" value="{'Submit'|@translate}"></p> +</form> + +{footer_script}{literal} +jQuery(".dError").bind("focus", function () { + jQuery(this).removeClass("dError"); +} ); +{/literal}{/footer_script}
\ No newline at end of file @@ -167,7 +167,7 @@ function parse_request() { try { - $page['derivative_params'] = ImageParams::from_url_tokens($deriv); + $page['derivative_params'] = DerivativeParams::from_url_tokens($deriv); } catch (Exception $e) { @@ -184,6 +184,33 @@ function parse_request() } +function send_derivative($expires) +{ + global $page; + $fp = fopen($page['derivative_path'], 'rb'); + + $fstat = fstat($fp); + header('Last-Modified: '.gmdate('D, d M Y H:i:s', $fstat['mtime']).' GMT'); + if ($expires!==false) + { + header('Expires: '.gmdate('D, d M Y H:i:s', $expires).' GMT'); + } + header('Content-length: '.$fstat['size']); + header('Connection: close'); + + $ctype="application/octet-stream"; + switch (strtolower($page['derivative_ext'])) + { + case ".jpe": case ".jpeg": case ".jpg": $ctype="image/jpeg"; break; + case ".png": $ctype="image/png"; break; + case ".gif": $ctype="image/gif"; break; + } + header("Content-Type: $ctype"); + + fpassthru($fp); + fclose($fp); +} + $page=array(); @@ -221,6 +248,13 @@ if ($derivative_mtime === false or $need_generate = true; } +$expires=false; +$now = time(); +if ( $now > (max($src_mtime, $params->last_mod_time) + 24*3600) ) +{// somehow arbitrary - if derivative params or src didn't change for the last 24 hours, we send an expire header for several days + $expires = $now + 10*24*3600; +} + if (!$need_generate) { if ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) @@ -230,7 +264,7 @@ if (!$need_generate) header('Expires: '.gmdate('D, d M Y H:i:s', time()+10*24*3600).' GMT', true, 304); exit; } - // todo send pass-through + send_derivative($expires); } @@ -270,23 +304,5 @@ if (!$changes) $image->write( $page['derivative_path'] ); $image->destroy(); -$fp = fopen($page['derivative_path'], 'rb'); - -$fstat = fstat($fp); -header('Last-Modified: '.gmdate('D, d M Y H:i:s', $fstat['mtime']).' GMT'); -header('Expires: '.gmdate('D, d M Y H:i:s', time()+10*24*3600).' GMT'); -header('Content-length: '.$fstat['size']); -header('Connection: close'); - -$ctype="application/octet-stream"; -switch (strtolower($page['derivative_ext'])) -{ - case ".jpe": case ".jpeg": case ".jpg": $ctype="image/jpeg"; break; - case ".png": $ctype="image/png"; break; - case ".gif": $ctype="image/gif"; break; -} -header("Content-Type: $ctype"); - -fpassthru($fp); -fclose($fp); +send_derivative($expires); ?>
\ No newline at end of file diff --git a/include/derivative_params.inc.php b/include/derivative_params.inc.php index a84c0f854..42bdfb7d5 100644 --- a/include/derivative_params.inc.php +++ b/include/derivative_params.inc.php @@ -278,7 +278,7 @@ final class SizingParams /*how we generate a derivative image*/ -final class ImageParams +final class DerivativeParams { public $type = IMG_CUSTOM; public $last_mod_time = 0; // used for non-custom images to regenerate the cached files @@ -289,6 +289,11 @@ final class ImageParams $this->sizing = $sizing; } + public function __sleep() + { + return array('last_mod_time', 'sizing'); + } + function add_url_tokens(&$tokens) { $this->sizing->add_url_tokens($tokens); @@ -297,7 +302,7 @@ final class ImageParams static function from_url_tokens($tokens) { $sizing = SizingParams::from_url_tokens($tokens); - $ret = new ImageParams($sizing); + $ret = new DerivativeParams($sizing); return $ret; } diff --git a/include/derivative_std_params.inc.php b/include/derivative_std_params.inc.php index 3a6394886..41056cadf 100644 --- a/include/derivative_std_params.inc.php +++ b/include/derivative_std_params.inc.php @@ -34,12 +34,12 @@ final class ImageStdParams private static $all_type_map = array(); private static $type_map = array(); private static $undefined_type_map = array(); - + static function get_all_types() { return self::$all_types; } - + static function get_all_type_map() { return self::$all_type_map; @@ -54,36 +54,66 @@ final class ImageStdParams { return self::$undefined_type_map; } - + static function get_by_type($type) { return self::$all_type_map[$type]; } - + static function load_from_db() { - self::make_default(); + global $conf; + $arr = @unserialize($conf['derivatives']); + if (false!==$arr) + { + self::$type_map = $arr['d']; + } + else + { + self::make_default(); + } self::build_maps(); } static function load_from_file() { - self::make_default(); + global $conf; + $arr = @unserialize(@file_get_contents(PHPWG_ROOT_PATH.$conf['data_location'].'derivatives.dat')); + if (false!==$arr) + { + self::$type_map = $arr['d']; + } + else + { + self::make_default(); + } + self::build_maps(); + } + + static function set_and_save($map) + { + global $conf; + self::$type_map = $map; + + $ser = serialize( array( + 'd' => self::$type_map + ) ); + conf_update_param('derivatives', addslashes($ser) ); + file_put_contents(PHPWG_ROOT_PATH.$conf['data_location'].'derivatives.dat', $ser); self::build_maps(); } static function make_default() { - //todo - self::$type_map[IMG_SQUARE] = new ImageParams( SizingParams::square(100,100) ); - self::$type_map[IMG_THUMB] = new ImageParams( SizingParams::classic(144,144) ); - self::$type_map[IMG_SMALL] = new ImageParams( SizingParams::classic(240,240) ); - self::$type_map[IMG_MEDIUM] = new ImageParams( SizingParams::classic(432,432) ); - self::$type_map[IMG_LARGE] = new ImageParams( SizingParams::classic(648,576) ); - self::$type_map[IMG_XLARGE] = new ImageParams( SizingParams::classic(864,648) ); - self::$type_map[IMG_XXLARGE] = new ImageParams( SizingParams::classic(1200,900) ); + self::$type_map[IMG_SQUARE] = new DerivativeParams( SizingParams::square(100,100) ); + self::$type_map[IMG_THUMB] = new DerivativeParams( SizingParams::classic(144,144) ); + self::$type_map[IMG_SMALL] = new DerivativeParams( SizingParams::classic(240,240) ); + self::$type_map[IMG_MEDIUM] = new DerivativeParams( SizingParams::classic(432,432) ); + self::$type_map[IMG_LARGE] = new DerivativeParams( SizingParams::classic(648,576) ); + self::$type_map[IMG_XLARGE] = new DerivativeParams( SizingParams::classic(864,648) ); + self::$type_map[IMG_XXLARGE] = new DerivativeParams( SizingParams::classic(1200,900) ); } - + private static function build_maps() { foreach (self::$type_map as $type=>$params) @@ -110,7 +140,7 @@ final class ImageStdParams } } } - + } ?>
\ No newline at end of file diff --git a/language/en_UK/common.lang.php b/language/en_UK/common.lang.php index 2b1534c92..ac36d5c51 100644 --- a/language/en_UK/common.lang.php +++ b/language/en_UK/common.lang.php @@ -362,5 +362,12 @@ $lang['Your comment has NOT been registered because it did not pass the validati $lang['Your favorites'] = "Your favorites"; $lang['Your Gallery Customization'] = "Your gallery customization"; $lang['Your password has been reset'] = 'Your password has been reset'; - +$lang['square'] = "Square"; +$lang['thumb'] = "Thumb"; +$lang['small'] = "Small"; +$lang['medium'] = "Medium"; +$lang['large'] = "Large"; +$lang['xlarge'] = "XLarge"; +$lang['xxlarge'] = "XXLarge"; +$lang['original'] = "Original"; ?>
\ No newline at end of file |