diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php
index 9ce34abe..b586dd56 100644
--- a/core/imageboard.pack.php
+++ b/core/imageboard.pack.php
@@ -93,6 +93,7 @@ class Image {
public static function by_random($tags=array()) {
assert(is_array($tags));
$max = Image::count_images($tags);
+ if ($max < 1) return null; // From Issue #22 - opened by HungryFeline on May 30, 2011.
$rand = mt_rand(0, $max-1);
$set = Image::find_images($rand, 1, $tags);
if(count($set) > 0) return $set[0];
diff --git a/core/page.class.php b/core/page.class.php
index d3879853..ae801576 100644
--- a/core/page.class.php
+++ b/core/page.class.php
@@ -167,8 +167,8 @@ class Page {
public function display() {
global $page;
- $this->add_http_header("Content-type: {$this->type}", 1);
- $this->add_http_header("X-Powered-By: SCore-".SCORE_VERSION, 2);
+ header("Content-type: ".$this->type);
+ header("X-Powered-By: SCore-".SCORE_VERSION);
if (!headers_sent()) {
foreach($this->http_headers as $head){ header($head); }
@@ -200,29 +200,132 @@ class Page {
break;
}
}
-
+
protected function add_auto_html_headers() {
$data_href = get_base_href();
-
- foreach(glob("lib/*.css") as $css) {
- $this->add_html_header("");
+
+ /* Attempt to cache the CSS & JavaScript files */
+ if ($this->add_cached_auto_html_headers() === FALSE) {
+ // caching failed, add all files to html_headers.
+
+ 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("");
+ }
+ }
+
+ 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("");
+ }
+ }
}
- $css_files = glob("ext/*/style.css");
- if($css_files) {
- foreach($css_files as $css_file) {
- $this->add_html_header("");
+ }
+
+ /*
+ 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.
+ */
+ private function add_cached_auto_html_headers()
+ {
+ $cache_location = 'data/cache/';
+ $data_href = get_base_href();
+
+ if(!file_exists($cache_location)) {
+ if (!mkdir($cache_location, 0750, true)) {
+ return false; // failed to create directory
}
}
- foreach(glob("lib/*.js") as $js) {
- $this->add_html_header("");
+ /* ----- 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('');
+
+
+ /* ----- JavaScript Files ----- */
+ $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) {
- $this->add_html_header("");
+ $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;
}
+
}
?>