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;
}
/**
* 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
*/
@ -230,99 +248,164 @@ class Page {
}
}
/*
This function caches the 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
and JavaScript files into one for each type, and 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.
*/
/**
* Automatic caching of CSS and Javascript files
*
* Allows site admins to have Shimmie automatically cache and minify all CSS and JS files.
* This is done to reduce the number of HTTP requests (recommended by the Yahoo high-performance
* guidelines). It combines all of the CSS and JavaScript files into one for each type, and
* 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()
{
$cache_location = 'data/cache/';
$data_href = get_base_href();
global $config;
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 (!mkdir($cache_location, 0750, true)) {
return false; // failed to create directory
}
}
/* ----- CSS Files ----- */
// First get all the CSS from the lib directory
$data_1 = '';
$css_files = glob("lib/*.css");
if($css_files) {
foreach($css_files as $css_file) {
$data_1 .= file_get_contents($css_file);
}
// 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.
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
$replace = 'url("../../lib/${1}")';
$data_1 = preg_replace($pattern, $replace, $data_1);
}
// Next get all the CSS from the extensions
$data_2 = '';
$css_files = glob("ext/*/style.css");
if($css_files) {
foreach($css_files as $css_file) {
$data_2 .= file_get_contents($css_file);
}
// 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.
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
$replace = 'url("../../${1}")';
$data_2 = preg_replace($pattern, $replace, $data_2);
}
// Combine the two
$data = $data_1 . $data_2;
// compute the MD5 sum of the concatenated CSS files
$md5sum = md5($data);
if (!file_exists($cache_location.$md5sum.'.css')) {
// remove any old cached CSS files.
$mask = '*.css';
array_map( 'unlink', glob( $mask ) );
// output the combined file
if (file_put_contents($cache_location.$md5sum.'.css', $data, LOCK_EX) === FALSE) {
return false;
}
}
// 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">');
$data_href = get_base_href();
/* ----- CSS Files ----- */
if ($config->get_bool("autocache_css"))
{
// First get all the CSS from the lib directory
$contents_from_lib = '';
$css_files = glob("lib/*.css");
if($css_files) {
foreach($css_files as $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.
// We have to adjust the URLs accordingly before saving the cached file.
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
$replace = 'url("../../lib/${1}")';
$contents_from_lib = preg_replace($pattern, $replace, $contents_from_lib);
}
// Next get all the CSS from the extensions
$contents_from_extensions = '';
$css_files = glob("ext/*/style.css");
if($css_files) {
foreach($css_files as $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.
// We have to adjust the URLs accordingly before saving the cached file.
$pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/';
$replace = 'url("../../${1}")';
$contents_from_extensions = preg_replace($pattern, $replace, $contents_from_extensions);
}
// Combine the two
$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
$md5sum = md5($data);
if (!file_exists($cache_location.$md5sum.'.css')) {
// remove any old cached CSS files.
$mask = '*.css';
array_map( 'unlink', glob( $mask ) );
// output the combined file
if (file_put_contents($cache_location.$md5sum.'.css', $data, LOCK_EX) === FALSE) {
return false; // failed to write the 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">');
} 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 ----- */
$data = '';
$js_files = glob("lib/*.js");
if($js_files) {
foreach($js_files as $js_file) {
$data .= file_get_contents($js_file);
if ($config->get_bool("autocache_js"))
{
$data = '';
$js_files = glob("lib/*.js");
if($js_files) {
foreach($js_files as $js_file) {
$data .= file_get_contents($js_file);
}
}
$js_files = glob("ext/*/script.js");
if($js_files) {
foreach($js_files as $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
$md5sum = md5($data);
if (!file_exists($cache_location.$md5sum.'.js')) {
// remove any old cached js files.
$mask = '*.js';
array_map( 'unlink', glob( $mask ) );
// output the combined file
if (file_put_contents($cache_location.$md5sum.'.js', $data, LOCK_EX) === FALSE) {
return false;
}
}
// 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>');
} 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>");
}
}
}
$js_files = glob("ext/*/script.js");
if($js_files) {
foreach($js_files as $js_file) {
$data .= file_get_contents($js_file);
}
}
// compute the MD5 sum of the concatenated JavaScript files
$md5sum = md5($data);
if (!file_exists($cache_location.$md5sum.'.js')) {
// remove any old cached js files.
$mask = '*.js';
array_map( 'unlink', glob( $mask ) );
// output the combined file
if (file_put_contents($cache_location.$md5sum.'.js', $data, LOCK_EX) === FALSE) {
return false;
}
}
// 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>');
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
*/
function array_add($array, $element) {
// Could we just use array_push() ?
// http://www.php.net/manual/en/function.array-push.php
$array[] = $element;
$array = array_unique($array);
return $array;

View file

@ -173,6 +173,12 @@ class Setup extends SimpleExtension {
$config->set_default_bool("word_wrap", true);
$config->set_default_bool("use_captchas", false);
$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) {
@ -280,6 +286,30 @@ class Setup extends SimpleExtension {
$sb->add_text_option("api_recaptcha_privkey", "<br>Private key: ");
$sb->add_text_option("api_recaptcha_pubkey", "<br>Public key: ");
$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) {