Merge branch 'master' of github.com:shish/shimmie2

This commit is contained in:
Shish 2011-10-09 12:10:22 +01:00
commit eb7927b3b1
3 changed files with 197 additions and 80 deletions

View File

@ -150,6 +150,24 @@ class Page {
$this->http_headers[$position] = $line; $this->http_headers[$position] = $line;
} }
/**
* Get all the HTML headers that are currently set and return as a string.
*/
public function get_all_html_headers() {
$data = '';
foreach ($this->html_headers as $line) {
$data .= $line . "\n";
}
return $data;
}
/**
* Removes all currently set HTML headers. (Be careful..)
*/
public function delete_all_html_headers() {
$this->html_headers = array();
}
/** /**
* Add a Block of data * Add a Block of data
*/ */
@ -230,54 +248,87 @@ class Page {
} }
} }
/* /**
This function caches the CSS and JavaScript files. * Automatic caching of CSS and Javascript files
This is done to reduce the number of HTTP requests (recommended by *
the Yahoo high-performance guidelines). It combines all of the CSS * Allows site admins to have Shimmie automatically cache and minify all CSS and JS files.
and JavaScript files into one for each type, and stores them in * This is done to reduce the number of HTTP requests (recommended by the Yahoo high-performance
cached files to serve the client. Changes to the CSS or JavaScript * guidelines). It combines all of the CSS and JavaScript files into one for each type, and
files are caught by taking the md5sum of the concatenated files. * stores them in cached files to serve the client. Changes to the CSS or JavaScript files are
* caught by taking the md5sum of the concatenated files.
*
* Note: This can be somewhat problematic, as it edits the links to your CSS files (as well
* as the links to images inside them).
* Also, the directory cache directory needs to be writeable by the php/webserver user.
* PLEASE: Ensure that you test your site out throughly after enabling this module!
* Either that, or don't use this module unless you are sure of what it is doing.
*
* TODO: Add support for minify-ing CSS and Javascript files. (similar to Minify. See: http://code.google.com/p/minify/ or https://github.com/mrclay/minify)
* TODO: For performance reasons: Before performing the regex's, compute the md5 of the CSS & JS files and store somewhere to check later.
*
* @return
* This function returns FALSE if it failed to cache the files,
* and returns TRUE if it was successful.
*/ */
private function add_cached_auto_html_headers() private function add_cached_auto_html_headers()
{ {
$cache_location = 'data/cache/'; global $config;
$data_href = get_base_href();
if (!$config->get_bool("autocache_css") && !$config->get_bool("autocache_js")) {
return false; // caching disabled
}
$cache_location = $config->get_string("autocache_location", 'data/cache');
// Detect is there is a trailing slash, and add one if not.
$cache_location = ((strrpos($cache_location, '/') + 1) == strlen($cache_location)) ? $cache_location : $cache_location.'/';
// Create directory if needed.
if(!file_exists($cache_location)) { if(!file_exists($cache_location)) {
if (!mkdir($cache_location, 0750, true)) { if (!mkdir($cache_location, 0750, true)) {
return false; // failed to create directory return false; // failed to create directory
} }
} }
$data_href = get_base_href();
/* ----- CSS Files ----- */ /* ----- CSS Files ----- */
if ($config->get_bool("autocache_css"))
{
// First get all the CSS from the lib directory // First get all the CSS from the lib directory
$data_1 = ''; $contents_from_lib = '';
$css_files = glob("lib/*.css"); $css_files = glob("lib/*.css");
if($css_files) { if($css_files) {
foreach($css_files as $css_file) { foreach($css_files as $css_file) {
$data_1 .= file_get_contents($css_file); $contents_from_lib .= file_get_contents($css_file);
} }
// Can't directly cache the CSS files, as they might have relative locations to images, etc. in them. // Can't directly cache the CSS files, as they might have relative locations to images, etc. in them.
// We have to adjust the URLs accordingly before saving the cached file. // We have to adjust the URLs accordingly before saving the cached file.
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/'; $pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
$replace = 'url("../../lib/${1}")'; $replace = 'url("../../lib/${1}")';
$data_1 = preg_replace($pattern, $replace, $data_1); $contents_from_lib = preg_replace($pattern, $replace, $contents_from_lib);
} }
// Next get all the CSS from the extensions // Next get all the CSS from the extensions
$data_2 = ''; $contents_from_extensions = '';
$css_files = glob("ext/*/style.css"); $css_files = glob("ext/*/style.css");
if($css_files) { if($css_files) {
foreach($css_files as $css_file) { foreach($css_files as $css_file) {
$data_2 .= file_get_contents($css_file); $contents_from_extensions .= file_get_contents($css_file);
} }
// Can't directly cache the CSS files, as they might have relative locations to images, etc. in them. // Can't directly cache the CSS files, as they might have relative locations to images, etc. in them.
// We have to adjust the URLs accordingly before saving the cached file. // We have to adjust the URLs accordingly before saving the cached file.
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/'; $pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
$replace = 'url("../../${1}")'; $replace = 'url("../../${1}")';
$data_2 = preg_replace($pattern, $replace, $data_2); $contents_from_extensions = preg_replace($pattern, $replace, $contents_from_extensions);
} }
// Combine the two // Combine the two
$data = $data_1 . $data_2; $data = $contents_from_lib .' '. $contents_from_extensions;
// Minify the CSS if enabled.
if ($config->get_bool("autocache_min_css")){
// not supported yet.
// TODO: add support for Minifying CSS files.
}
// compute the MD5 sum of the concatenated CSS files // compute the MD5 sum of the concatenated CSS files
$md5sum = md5($data); $md5sum = md5($data);
@ -288,14 +339,28 @@ class Page {
// output the combined file // output the combined file
if (file_put_contents($cache_location.$md5sum.'.css', $data, LOCK_EX) === FALSE) { if (file_put_contents($cache_location.$md5sum.'.css', $data, LOCK_EX) === FALSE) {
return false; return false; // failed to write the file
} }
} }
// tell the client where to get the css cache file // tell the client where to get the css cache file
$this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$cache_location.$md5sum.'.css'.'" type="text/css">'); $this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$cache_location.$md5sum.'.css'.'" type="text/css">');
} else {
// Caching of CSS disabled.
foreach(glob("lib/*.css") as $css) {
$this->add_html_header("<link rel='stylesheet' href='$data_href/$css' type='text/css'>");
}
$css_files = glob("ext/*/style.css");
if($css_files) {
foreach($css_files as $css_file) {
$this->add_html_header("<link rel='stylesheet' href='$data_href/$css_file' type='text/css'>");
}
}
}
/* ----- JavaScript Files ----- */ /* ----- JavaScript Files ----- */
if ($config->get_bool("autocache_js"))
{
$data = ''; $data = '';
$js_files = glob("lib/*.js"); $js_files = glob("lib/*.js");
if($js_files) { if($js_files) {
@ -309,6 +374,12 @@ class Page {
$data .= file_get_contents($js_file); $data .= file_get_contents($js_file);
} }
} }
// Minify the JS if enabled.
if ($config->get_bool("autocache_min_js")){
// not supported yet.
// TODO: add support for Minifying CSS files.
}
// compute the MD5 sum of the concatenated JavaScript files // compute the MD5 sum of the concatenated JavaScript files
$md5sum = md5($data); $md5sum = md5($data);
@ -323,6 +394,18 @@ class Page {
} }
// tell the client where to get the js cache file // tell the client where to get the js cache file
$this->add_html_header('<script src="'.$data_href.'/'.$cache_location.$md5sum.'.js'.'" type="text/javascript"></script>'); $this->add_html_header('<script src="'.$data_href.'/'.$cache_location.$md5sum.'.js'.'" type="text/javascript"></script>');
} else {
// Caching of Javascript disabled.
foreach(glob("lib/*.js") as $js) {
$this->add_html_header("<script src='$data_href/$js' type='text/javascript'></script>");
}
$js_files = glob("ext/*/script.js");
if($js_files) {
foreach($js_files as $js_file) {
$this->add_html_header("<script src='$data_href/$js_file' type='text/javascript'></script>");
}
}
}
return true; return true;
} }

View File

@ -555,11 +555,15 @@ function array_remove($array, $to_remove) {
} }
/** /**
* Add an item to an array * Adds an item to an array.
*
* Also removes duplicate values from the array.
* *
* @retval array * @retval array
*/ */
function array_add($array, $element) { function array_add($array, $element) {
// Could we just use array_push() ?
// http://www.php.net/manual/en/function.array-push.php
$array[] = $element; $array[] = $element;
$array = array_unique($array); $array = array_unique($array);
return $array; return $array;

View File

@ -173,6 +173,12 @@ class Setup extends SimpleExtension {
$config->set_default_bool("word_wrap", true); $config->set_default_bool("word_wrap", true);
$config->set_default_bool("use_captchas", false); $config->set_default_bool("use_captchas", false);
$config->set_default_string("autodate_format", "F j, Y"); $config->set_default_string("autodate_format", "F j, Y");
// Automatic caching is disabled by default
$config->set_default_string("autocache_location", "data/cache");
$config->set_default_bool("autocache_css", false);
$config->set_default_bool("autocache_jss", false);
$config->set_default_bool("autocache_min_css", false);
$config->set_default_bool("autocache_min_js", false);
} }
public function onPageRequest($event) { public function onPageRequest($event) {
@ -280,6 +286,30 @@ class Setup extends SimpleExtension {
$sb->add_text_option("api_recaptcha_privkey", "<br>Private key: "); $sb->add_text_option("api_recaptcha_privkey", "<br>Private key: ");
$sb->add_text_option("api_recaptcha_pubkey", "<br>Public key: "); $sb->add_text_option("api_recaptcha_pubkey", "<br>Public key: ");
$event->panel->add_block($sb); $event->panel->add_block($sb);
// Options for Automatic Caching & Minifying
$minifyscript = "<script language='javascript'>
checkbox_css = document.getElementById('autocache_min_css');
checkbox_js = document.getElementById('autocache_min_js');
$(document).ready(function() {
checkbox_css.disabled = true;
checkbox_css.checked = false;
checkbox_js.disabled = true;
checkbox_js.checked = false;
});
</script>";
$sb = new SetupBlock("Automatic Caching of CSS & JS");
$sb->add_text_option("autocache_location", "Location: ");
$sb->add_label("<br><i>This location needs to be writeable by the webserver.</i>");
$sb->add_bool_option("autocache_css", "<br>Automatic caching of CSS: ");
$sb->add_bool_option("autocache_js", "<br>Automatic caching of JS: ");
$sb->add_bool_option("autocache_min_css", "<br>Minimize CSS files: ");
$sb->add_bool_option("autocache_min_js", "<br>Minimize JS files: ");
$sb->add_label("<br><span id='autocache_minify'><i>Minifying currently not supported.</i></span>$minifyscript");
$event->panel->add_block($sb);
} }
public function onConfigSave($event) { public function onConfigSave($event) {