diff --git a/core/page.class.php b/core/page.class.php
index ae801576..b2a8d662 100644
--- a/core/page.class.php
+++ b/core/page.class.php
@@ -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('');
+ $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('');
+ } else {
+ // Caching of CSS disabled.
+ foreach(glob("lib/*.css") as $css) {
+ $this->add_html_header("");
+ }
+ $css_files = glob("ext/*/style.css");
+ if($css_files) {
+ foreach($css_files as $css_file) {
+ $this->add_html_header("");
+ }
+ }
+ }
+
/* ----- 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('');
+ } else {
+ // Caching of Javascript disabled.
+ foreach(glob("lib/*.js") as $js) {
+ $this->add_html_header("");
+ }
+ $js_files = glob("ext/*/script.js");
+ if($js_files) {
+ foreach($js_files as $js_file) {
+ $this->add_html_header("");
+ }
}
}
- $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('');
return true;
}
diff --git a/core/util.inc.php b/core/util.inc.php
index 18aa859a..ca8a1c05 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -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;
diff --git a/ext/setup/main.php b/ext/setup/main.php
index efedd1a0..e53061b1 100644
--- a/ext/setup/main.php
+++ b/ext/setup/main.php
@@ -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", " Private key: ");
$sb->add_text_option("api_recaptcha_pubkey", " Public key: ");
$event->panel->add_block($sb);
+
+
+ // Options for Automatic Caching & Minifying
+ $minifyscript = "";
+
+ $sb = new SetupBlock("Automatic Caching of CSS & JS");
+ $sb->add_text_option("autocache_location", "Location: ");
+ $sb->add_label(" This location needs to be writeable by the webserver.");
+ $sb->add_bool_option("autocache_css", " Automatic caching of CSS: ");
+ $sb->add_bool_option("autocache_js", " Automatic caching of JS: ");
+ $sb->add_bool_option("autocache_min_css", " Minimize CSS files: ");
+ $sb->add_bool_option("autocache_min_js", " Minimize JS files: ");
+ $sb->add_label(" Minifying currently not supported.$minifyscript");
+ $event->panel->add_block($sb);
}
public function onConfigSave($event) {