-
<?php
-
-
/**
-
* @desc Allows Javascript and CSS to be compressed, cached and outputted (optionally with gzip)
-
* @author DKi Design <darkimmortal@dkimmortal.com>
-
*
-
* FYI: Cache creation and/or updates will fail if only one location/url combo is changed (to use multiple instances, both the CSS and JS locations and urls must be changed).
-
*/
-
class jcCache {
-
-
/**
-
* @var array Stores the CSS files (location, modification date)
-
*/
-
public $css=array("l"=>array(),"d"=>array());
-
-
/**
-
* @var array Stores the JS files (location, modification date)
-
*/
-
public $js=array("l"=>array(),"d"=>array());
-
-
/**
-
* @var bool Skip files that are too large (would most likely crash server)
-
*/
-
public $toobig=true;
-
-
/**
-
* @var string Error log (accessible through showErrors())
-
*/
-
public $errors="";
-
-
/**
-
* @var time Timestamp of modification data of CSS cache
-
*/
-
private $csscache;
-
-
/**
-
* @var time Timestamp of modification data of JS cache
-
*/
-
private $jscache;
-
-
/**
-
* @var int Number of extra caches used due to insufficent server memory for the javascript compressor to run on all of it at once
-
*/
-
private $extraCaches;
-
-
/**
-
* @var string CSS Cache location
-
*/
-
public $cssCacheLocation="jccache.css";
-
-
/**
-
* @var string JS Cache location
-
*/
-
public $jsCacheLocation="jccache.js";
-
-
/**
-
* @var string CSS Cache location as URL (if relative then relative to page that is outputting)
-
*/
-
public $cssCacheURL="jccache.css";
-
-
/**
-
* @var string JS Cache location as URL (if relative then relative to page that is outputting)
-
*/
-
public $jsCacheURL="jccache.js";
-
-
/**
-
* @var bool Made new JS Cache?
-
*/
-
private $jsCacheMade=false;
-
-
/**
-
* @var bool Made new CSS Cache?
-
*/
-
private $cssCacheMade=false;
-
-
/**
-
* @var bool Force cache regeneration? (not intended for live script)
-
*/
-
public $forceCacheRegen=false;
-
-
/**
-
* @var bool Prevent cache regeneration? (dunno why but its there anyway)
-
*/
-
public $preventCacheRegen=false;
-
-
/**
-
* @var bool Minify js/css?
-
*/
-
public $compress=true;
-
-
-
/**
-
* @desc Initialises the cache files and prepares the class for use. Must be called AFTER properties are set but BEFORE any methods are used.
-
*/
-
public function init(){
-
if(!file_exists($this->cssCacheLocation)){
-
$this->errors.="\nNOTICE: CSS cache ({$this->cssCacheLocation}) not found - writing new file";
-
$cssh=@fopen($this->cssCacheLocation,'w');
-
if(!$cssh){
-
$this->errors.="\nFATAL ERROR: CSS cache could not be created at: {$this->cssCacheLocation}";
-
$this->showErrors();
-
die();
-
}
-
fclose($cssh);
-
$this->forceCacheRegen=true;
-
-
if(!@touch($this->cssCacheLocation,1)){
-
$this->errors.="\nWARNING: Access time of the CSS cache ({$this->cssCacheLocation}) could not be changed. It must be forcefully updated via the forceCacheRegen option.";
-
} else {
-
$this->errors.="\nNOTICE: Access time of the CSS cache ({$this->cssCacheLocation}) was changed successfully.";
-
}
-
}
-
if(!file_exists($this->jsCacheLocation) || filesize($this->jsCacheLocation) < 1){
-
$this->errors.="\nNOTICE: JS cache ({$this->jsCacheLocation}) not found / too small - writing new file";
-
$jsh=fopen($this->jsCacheLocation,'w');
-
if(!$jsh){
-
$this->errors.="\nFATAL ERROR: JS cache could not be created at: {$this->jsCacheLocation}";
-
$this->showErrors();
-
die();
-
}
-
fclose($jsh);
-
$this->forceCacheRegen=true;
-
-
if(!@touch($this->jsCacheLocation,1)){
-
$this->errors.="\nWARNING: Access time of the JS cache ({$this->jsCacheLocation}) could not be changed. It must be forcefully updated via the forceCacheRegen option.";
-
} else {
-
$this->errors.="\nNOTICE: Access time of the JS cache ({$this->jsCacheLocation}) was changed successfully.";
-
}
-
}
-
if(!is_writable($this->cssCacheLocation)){
-
$this->errors.="\nFATAL ERROR: CSS cache ({$this->cssCacheLocation}) is not writable.";
-
$this->showErrors();
-
die();
-
}
-
if(!is_writable($this->jsCacheLocation)){
-
$this->errors.="\nFATAL ERROR: JS cache ({$this->jsCacheLocation}) is not writable.";
-
$this->showErrors();
-
die();
-
}
-
$this->csscache=filemtime($this->cssCacheLocation);
-
-
$this->jscache=filemtime($this->jsCacheLocation);
-
$this->errors.="\nNOTICE: CSS Cache ready for reading/writing at {$this->cssCacheLocation} and was last updated at ".date(DATE_RFC2822,$this->csscache);
-
$this->errors.="\nNOTICE: JS Cache ready for reading/writing at {$this->jsCacheLocation} and was last updated at ".date(DATE_RFC2822,$this->jscache);
-
-
}
-
-
-
/**
-
* @desc Adds a Javascript file
-
* @param Server-side location of file
-
*/
-
public function addJS($file){
-
if(file_exists($file) and is_readable($file)){
-
array_push($this->js["l"],$file);
-
array_push($this->js["d"],filemtime($file));
-
} else {
-
$this->errors.="\nError loading Javascript file: $file";
-
}
-
}
-
-
/**
-
* @desc Adds a CSS file
-
* @param Server-side location of file
-
*/
-
public function addCSS($file){
-
if(file_exists($file) and is_readable($file)){
-
array_push($this->css["l"],$file);
-
array_push($this->css["d"],filemtime($file));
-
} else {
-
$this->errors.="\nError loading CSS file: $file";
-
}
-
}
-
-
/**
-
* @desc Compresses CSS code (removes comments and whitespace)
-
* @param string CSS code
-
*
-
* @return string Compressed CSS Code
-
*/
-
public function compressCSS($css){
-
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
-
$css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $css);
-
$css = str_replace(array("('",'("'), '(', $css);
-
$css = str_replace(array("')",'")'), ')', $css);
-
return $css;
-
}
-
-
/**
-
* @desc Compresses Javascript code (via rgrove's high-speed PHP5 Javascript Minifier)
-
* @param string Javascript code
-
* @param bool Compress?
-
*
-
* @return string Minified Javascript Code
-
*/
-
public function compressJS($js,$compress=true){
-
if(!$compress)
-
return $js;
-
return JSMin::minify($js);
-
}
-
-
/**
-
* @desc Outputs JS files
-
*/
-
public function outputJS(){
-
//foreach($this->js["d"] as $date){
-
$date=max($this->js["d"]);
-
if(($date > $this->jscache or $this->forceCacheRegen) and !$this->jsCacheMade and !$this->preventCacheRegen){
-
$this->errors.="\n".$this->js['l']." LAST UPDATED: ".date(DATE_RFC2822,$date);
-
-
$this->jsCacheMade=true;
-
$this->newJS();
-
}
-
//}
-
//echo "<script type='text/javascript' src='{$this->jsCacheURL}?". ($this->jsCacheMade) ? random_string::output() : "" ."' ></script>";
-
$randcode=$this->jsCacheMade ? "?r=" . random_string::output() : "";
-
$compress="";//$this->compress ? "cp.php?type=js&compress=true&filename=" : "";
-
echo "\n<script type='text/javascript' src='$compress{$this->jsCacheURL}$randcode'></script>";
-
//for($curr = 1; $curr <= $this->extraCaches; $curr++){
-
//}
-
-
}
-
-
/**
-
* @desc Outputs CSS files
-
*/
-
public function outputCSS(){
-
foreach($this->css["d"] as $date){
-
if(($date > $this->csscache or $this->forceCacheRegen) and !$this->cssCacheMade and !$this->preventCacheRegen){
-
$this->cssCacheMade=true;
-
$this->newCSS();
-
}
-
}
-
//echo "<link rel='stylesheet' type='text/css' href='{$this->cssCacheURL}?". ($this->cssCacheMade) ? random_string::output() : "" ."' />";
-
$randcode=$this->cssCacheMade ? "?r=" . random_string::output() : "";
-
$compress=$this->compress ? "cp.php?type=css&compress=true&filename=" : "";
-
//echo "\n<link rel='stylesheet' type='text/css' href='$compress{$this->cssCacheURL}$randcode' />";
-
echo "\n<link rel='stylesheet' type='text/css' href='".$this->cssCacheURL."' />";
-
}
-
-
/**
-
* @desc Outputs everything
-
*/
-
public function output(){
-
$this->outputCSS();
-
$this->outputJS();
-
}
-
-
/**
-
* @desc Generates new JS cache
-
*/
-
public function newJS(){
-
foreach($this->js["l"] as $loc){
-
$js2=@file_get_contents($loc,null,null,0,$this->toobig?5000000:null);
-
if(!$js2)
-
$this->errors.="\nWARNING: JS File at $loc could not be read and so is not part of the cache and will not be received by browsers.";
-
else
-
$js.=$js2;
-
}
-
$meme=round(str_ireplace("M","",ini_get("memory_limit"))*1024*1024/100, 0);
-
//$meme=10000;
-
$this->errors.="\n$meme\n";
-
if(strlen($js) > $meme){
-
$this->extraCaches=ceil(strlen($js)/$meme)+1;
-
$this->errors.="\ngay {$this->extraCaches}\n";
-
for($cac = 1; $cac <= $this->extraCaches; $cac++){
-
$jspart=substr($js,($cac-1)*$meme,$cac*$meme);
-
$cache=$this->compressJS($jspart);
-
file_put_contents($this->jsCacheLocation."_".$cac,$cache);
-
}
-
$js="";
-
for($cac = 1; $cac <= $this->extraCaches; $cac++){
-
$loc=$this->jsCacheLocation."_".$cac;
-
$js2 = @file_get_contents($loc,null,null,0,$this->toobig?5000000:null);
-
if(!$js2)
-
$this->errors.="\nWARNING: JS File at $loc could not be read and so is not part of the cache and will not be received by browsers.";
-
else
-
$cache.=$js2;
-
unlink($loc);
-
}
-
} else {
-
$cache=$this->compressJS($js, $this->compress);
-
/* $totalsize=strlen($cache);
-
$dun=0;
-
//$cursize=0;
-
//while($cursize <= $totalsize){
-
for($cursize = 0; $cursize <= $totalsize; $cursize+=$this->perFile){
-
$dun++;
-
file_put_contents(str_replace(".js",$dun.".js",$this->jsCacheLocation),substr($cache, $cursize, $this->perFile));
-
//$currsize+=$this->perFile;
-
}
-
$this->extraCaches=$dun;*/
-
-
}
-
//touch($this->jsCacheLocation, filemtime($this->jsCacheLocation) - 24*3600); // time zone difference
-
// debug($cache);
-
//file_put_contents($this->jsCacheLocation,$cache);
-
file_put_contents($this->jsCacheLocation, $cache);
-
$this->errors.="\nNOTICE: New Javascript cache written successfully";
-
-
}
-
-
/**
-
* @desc Generates new CSS cache
-
*/
-
public function newCSS(){
-
foreach($this->css["l"] as $loc){
-
$css2=@file_get_contents($loc,null,null,0,$this->toobig?5000000:null);
-
if(!$css2)
-
$this->errors.="\nWARNING: CSS File at $loc could not be read and so is not part of the cache and will not be received by browsers.";
-
else
-
$css.=$css2;
-
}
-
$cache=$this->compressCSS($css);
-
file_put_contents($this->cssCacheLocation,$cache);
-
//touch($this->cssCacheLocation, filemtime($this->cssCacheLocation) - 24*3600); // time zone difference
-
$this->errors.="\nNOTICE: New CSS cache written successfully";
-
}
-
} // End Class
-
-
-
-
?>