aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrvelices <rv-github@modusoptimus.com>2013-11-12 06:33:30 +0000
committerrvelices <rv-github@modusoptimus.com>2013-11-12 06:33:30 +0000
commit35337b01aeabfddd8eede74ca1c7e2b48672b595 (patch)
tree20f1b8d24fecc94896137d1caaf7223af903b615
parent0cb2c621deebc31aa1af0e2e656807aaf85590a3 (diff)
bug 2963: Ability to create css/js smarty templates with caching
so far can add template=true to combine_css function git-svn-id: http://piwigo.org/svn/trunk@25462 68402e56-0260-453c-a942-63ccdbb3a9ee
-rw-r--r--include/template.class.php270
1 files changed, 150 insertions, 120 deletions
diff --git a/include/template.class.php b/include/template.class.php
index 6628dbec9..6f37aa897 100644
--- a/include/template.class.php
+++ b/include/template.class.php
@@ -415,32 +415,22 @@ class Template {
ksort($this->css_by_priority);
global $conf;
- $css = array();
- if ($conf['template_combine_files'])
+ $combiner = new FileCombiner('css');
+ foreach ($this->css_by_priority as $files)
{
- $combiner = new FileCombiner('css');
- foreach ($this->css_by_priority as $files)
- {
- foreach ($files as $file_ver)
- $combiner->add( $file_ver[0], $file_ver[1] );
- }
- if ( $combiner->combine( $out_file, $out_version) )
- $css[] = array($out_file, $out_version);
- }
- else
- {
- foreach ($this->css_by_priority as $files)
- $css = array_merge($css, $files);
+ foreach ($files as $combi)
+ $combiner->add( $combi );
}
+ $css = $combiner->combine();
$content = array();
- foreach( $css as $file_ver )
+ foreach( $css as $combi )
{
- $href = embellish_url(get_root_url().$file_ver[0]);
- if ($file_ver[1] !== false)
- $href .= '?v' . ($file_ver[1] ? $file_ver[1] : PHPWG_VERSION);
+ $href = embellish_url(get_root_url().$combi->path);
+ if ($combi->version !== false)
+ $href .= '?v' . ($combi->version ? $combi->version : PHPWG_VERSION);
// trigger the event for eventual use of a cdn
- $href = trigger_event('combined_css', $href, $file_ver[0], $file_ver[1]);
+ $href = trigger_event('combined_css', $href, $combi);
$content[] = '<link rel="stylesheet" type="text/css" href="'.$href.'">';
}
$this->output = str_replace(self::COMBINED_CSS_TAG,
@@ -518,7 +508,7 @@ class Template {
return var_export($lang[$key], true);
}
return 'l10n('.$params[0].')';
-
+
default:
if ($conf['compiled_template_cache_language'])
{
@@ -764,7 +754,9 @@ var s,after = document.getElementsByTagName(\'script\')[document.getElementsByTa
!empty($params['path']) || fatal_error('combine_css missing path');
$order = (int)@$params['order'];
$version = isset($params['version']) ? $params['version'] : 0;
- $this->css_by_priority[$order][] = array( $params['path'], $version);
+ $css = new Css('', $params['path'], $version, $order);
+ $css->is_template = isset($params['template']) && !empty($params['template']);
+ $this->css_by_priority[$order][] = $css;
}
function func_get_combined_css($params)
@@ -986,23 +978,18 @@ class PwgTemplateAdapter
}
-final class Script
+class Combinable
{
public $id;
- public $load_mode;
- public $precedents = array();
public $path;
public $version;
- public $extra = array();
+ public $is_template;
- function Script($load_mode, $id, $path, $version, $precedents)
+ function __construct($id, $path, $version)
{
$this->id = $id;
- $this->load_mode = $load_mode;
- $this->id = $id;
$this->set_path($path);
$this->version = $version;
- $this->precedents = $precedents;
}
function set_path($path)
@@ -1017,6 +1004,31 @@ final class Script
}
}
+final class Script extends Combinable
+{
+ public $load_mode;
+ public $precedents = array();
+ public $extra = array();
+
+ function __construct($load_mode, $id, $path, $version, $precedents)
+ {
+ parent::__construct($id, $path, $version);
+ $this->load_mode = $load_mode;
+ $this->precedents = $precedents;
+ }
+}
+
+final class Css extends Combinable
+{
+ public $order;
+
+ function __construct($id, $path, $version, $order)
+ {
+ parent::__construct($id, $path, $version);
+ $this->order = $order;
+ }
+}
+
/** Manage a list of required scripts for a page, by optimizing their loading location (head, bottom, async)
and later on by combining them in a unique file respecting at the same time dependencies.*/
@@ -1184,29 +1196,12 @@ class ScriptLoader
private static function do_combine($scripts, $load_mode)
{
- global $conf;
- if (count($scripts)<2 or !$conf['template_combine_files'])
- return $scripts;
$combiner = new FileCombiner('js');
- $result = array();
foreach ($scripts as $script)
{
- if ($script->is_remote())
- {
- if ( $combiner->combine( $out_file, $out_version) )
- {
- $results[] = new Script($load_mode, 'combi', $out_file, $out_version, array() );
- }
- $results[] = $script;
- }
- else
- $combiner->add( $script->path, $script->version );
- }
- if ( $combiner->combine( $out_file, $out_version) )
- {
- $results[] = new Script($load_mode, 'combi', $out_file, $out_version, array() );
+ $combiner->add( $script);
}
- return $results;
+ return $combiner->combine();
}
// checks that if B depends on A, then B->load_mode >= A->load_mode in order to respect execution order
@@ -1325,12 +1320,13 @@ class ScriptLoader
final class FileCombiner
{
private $type; // js or css
- private $files = array();
- private $versions = array();
+ private $is_css;
+ private $combinables = array();
function FileCombiner($type)
{
$this->type = $type;
+ $this->is_css = $type=='css';
}
static function clear_combined_files()
@@ -1344,92 +1340,124 @@ final class FileCombiner
closedir($dir);
}
- function add($file, $version)
+ function add($combinable)
{
- $this->files[] = $file;
- $this->versions[] = $version;
+ $this->combinables[] = $combinable;
}
- function clear()
+ function combine()
{
- $this->files = array();
- $this->versions = array();
+ global $conf;
+ $force = false;
+ if (is_admin() && ($this->is_css || !$conf['template_compile_check']) )
+ {
+ $force = (isset($_SERVER['HTTP_CACHE_CONTROL']) && strpos($_SERVER['HTTP_CACHE_CONTROL'], 'max-age=0') !== false)
+ || (isset($_SERVER['HTTP_PRAGMA']) && strpos($_SERVER['HTTP_PRAGMA'], 'no-cache'));
+ }
+
+ $result = array();
+ $pending = array();
+ $key = $this->is_css ? array(get_absolute_root_url(false)): array(); //because for css we modify bg url
+
+ foreach ($this->combinables as $combinable)
+ {
+ if ($conf['template_combine_files'] && !$combinable->is_remote())
+ {
+ $key[] = $combinable->path;
+ $key[] = $combinable->version;
+ if ($conf['template_compile_check'])
+ $key[] = filemtime( PHPWG_ROOT_PATH . $combinable->path );
+ $pending[] = $combinable;
+ }
+ else
+ {
+ $this->flush_pending($result, $pending, $key, $force);
+ $pending = array();
+ $key = $this->is_css ? array(get_absolute_root_url(false)): array(); //because for css we modify bg url
+ $result[] = $combinable;
+ }
+ }
+ $this->flush_pending($result, $pending, $key, $force);
+ return $result;
}
- function combine(&$out_file, &$out_version)
+ private function flush_pending(&$result, $pending, $key, $force)
{
- if (count($this->files) == 0)
+ if (count($pending)>1)
{
- return false;
+ $key = join('>', $key);
+ $file = PWG_COMBINED_DIR . base_convert(crc32($key),10,36) . '.' . $this->type;
+ if ($force || !file_exists(PHPWG_ROOT_PATH.$file) )
+ {
+ $output = '';
+ foreach ($pending as $combinable)
+ {
+ $output .= "/*BEGIN $combinable->path */\n";
+ $output .= $this->process_combinable($combinable, true, $force);
+ $output .= "\n";
+ }
+ mkgetdir( dirname(PHPWG_ROOT_PATH.$file) );
+ file_put_contents( PHPWG_ROOT_PATH.$file, $output );
+ @chmod(PHPWG_ROOT_PATH.$file, 0644);
+ }
+ $result[] = new Combinable("combi", $file, false);
}
- if (count($this->files) == 1)
+ elseif ( count($pending)==1)
{
- $out_file = $this->files[0];
- $out_version = $this->versions[0];
- $this->clear();
- return 1;
+ $this->process_combinable($pending[0], false, $force);
+ $result[] = $pending[0];
}
-
- $is_css = $this->type == "css";
- global $conf;
$key = array();
- if ($is_css)
- $key[] = get_absolute_root_url(false);//because we modify bg url
- for ($i=0; $i<count($this->files); $i++)
- {
- $key[] = $this->files[$i];
- $key[] = $this->versions[$i];
- if ($conf['template_compile_check']) $key[] = filemtime( PHPWG_ROOT_PATH . $this->files[$i] );
- }
- $key = join('>', $key);
-
- $file = base_convert(crc32($key),10,36);
- $file = PWG_COMBINED_DIR . $file . '.' . $this->type;
+ $pending = array();
+ }
- $exists = file_exists( PHPWG_ROOT_PATH . $file );
- if ($exists)
+ private function process_combinable($combinable, $return_content, $force)
+ {
+ if ($combinable->is_template)
{
- $is_reload =
- (isset($_SERVER['HTTP_CACHE_CONTROL']) && strpos($_SERVER['HTTP_CACHE_CONTROL'], 'max-age=0') !== false)
- || (isset($_SERVER['HTTP_PRAGMA']) && strpos($_SERVER['HTTP_PRAGMA'], 'no-cache'));
- if (is_admin() && $is_reload)
- {// the user pressed F5 in the browser
- if ($is_css || $conf['template_compile_check']==false)
- $exists = false; // we foce regeneration of css because @import sub-files are never checked for modification
+ if (!$return_content)
+ {
+ $key = array($combinable->path, $combinable->version);
+ if ($conf['template_compile_check'])
+ $key[] = filemtime( PHPWG_ROOT_PATH . $combinable->path );
+ $file = PWG_COMBINED_DIR . 't' . base_convert(crc32($key),10,36) . '.' . $this->type;
+ if (!$force && file_exists(PHPWG_ROOT_PATH.$file) )
+ {
+ $combinable->path = $file;
+ $combinable->version = false;
+ return;
+ }
}
- }
- if ($exists)
- {
- $out_file = $file;
- $out_version = false;
- $this->clear();
- return 2;
- }
+ global $template;
+ $handle = $this->type. '.' .$combinable->id;
+ $template->set_filename($handle, realpath(PHPWG_ROOT_PATH.$combinable->path));
+ trigger_action( 'combinable_preparse', $template, $combinable, $this); //allow themes and plugins to set their own vars to template ...
+ $content = $template->parse($handle, true);
- $output = '';
- foreach ($this->files as $input_file)
+ if ($this->is_css)
+ $content = self::process_css($content, dirname($combinable->path) );
+ else
+ $content = self::process_js($content, $combinable->path );
+
+ if ($return_content)
+ return $content;
+ file_put_contents( PHPWG_ROOT_PATH.$file, $content );
+ $combinable->path = $file;
+ }
+ elseif ($return_content)
{
- $output .= "/*BEGIN $input_file */\n";
- if ($is_css)
- $output .= self::process_css($input_file);
+ $content = file_get_contents(PHPWG_ROOT_PATH . $combinable->path);
+ if ($this->is_css)
+ $content = self::process_css($content, dirname($combinable->path) );
else
- $output .= self::process_js($input_file);
- $output .= "\n";
+ $content = self::process_js($content, $combinable->path );
+ return $content;
}
-
- mkgetdir( dirname(PHPWG_ROOT_PATH.$file) );
- file_put_contents( PHPWG_ROOT_PATH.$file, $output );
- @chmod(PHPWG_ROOT_PATH.$file, 0644);
- $out_file = $file;
- $out_version = false;
- $this->clear();
- return 2;
}
- private static function process_js($file)
+ private static function process_js($js, $file)
{
- $js = file_get_contents(PHPWG_ROOT_PATH . $file);
if (strpos($file, '.min')===false and strpos($file, '.packed')===false )
{
require_once(PHPWG_ROOT_PATH.'include/jshrink.class.php');
@@ -1438,9 +1466,9 @@ final class FileCombiner
return trim($js, " \t\r\n;").";\n";
}
- private static function process_css($file)
+ private static function process_css($css, $dir)
{
- $css = self::process_css_rec($file);
+ $css = self::process_css_rec($css, $dir);
if (version_compare(PHP_VERSION, '5.2.4', '>='))
{
require_once(PHPWG_ROOT_PATH.'include/cssmin.class.php');
@@ -1450,10 +1478,10 @@ final class FileCombiner
return $css;
}
- private static function process_css_rec($file)
+ private static function process_css_rec($css, $dir)
{
static $PATTERN = "#url\(\s*['|\"]{0,1}(.*?)['|\"]{0,1}\s*\)#";
- $css = file_get_contents(PHPWG_ROOT_PATH . $file);
+
if (preg_match_all($PATTERN, $css, $matches, PREG_SET_ORDER))
{
$search = $replace = array();
@@ -1461,7 +1489,7 @@ final class FileCombiner
{
if ( !url_is_remote($match[1]) && $match[1][0] != '/')
{
- $relative = dirname($file) . "/$match[1]";
+ $relative = $dir . "/$match[1]";
$search[] = $match[0];
$replace[] = 'url('.embellish_url(get_absolute_root_url(false).$relative).')';
}
@@ -1476,12 +1504,14 @@ final class FileCombiner
foreach ($matches as $match)
{
$search[] = $match[0];
- $replace[] = self::process_css_rec(dirname($file) . "/$match[1]");
+ $sub_css = file_get_contents(PHPWG_ROOT_PATH . $dir . "/$match[1]");
+ $replace[] = self::process_css_rec($sub_css, dirname($dir . "/$match[1]") );
}
$css = str_replace($search, $replace, $css);
}
return $css;
}
+
}
?> \ No newline at end of file