forked from bcit-ci/CodeIgniter
-
Notifications
You must be signed in to change notification settings - Fork 26
Asset Gzip cache serve
Derek Jones edited this page Jul 5, 2012
·
41 revisions
Categories:Helpers | Categories:Helpers::Community | Categories:Helpers::Cache
This helper can be used if you wish
- to reduce your assets size
- cache your assets
- to hide the full path of assets in your html
- all of the above to be done with as little effort as possible
File:gz_asset_helper_example.zip
The only area you need to change is the settings area at the beginning of the class.
var $debug = FALSE;
set for true to output all the settings instead of the asset
Hence the name debug
var $headers = array();
var $target_file = array();
var $sysValues = array();
set some arrays for storing values
var $set = array(
'VERSION' => '0.75',
'path2assets' => APPPATH,
'asset_exp' => 25920000,
'uri' => '',
);
path2assests: is the path to your assets folders asset_exp: is the expiry date of the cached asset (in milliseconds)
var $asset_types = array(
"htm" => "text/html",
"html" => "text/html",
"js" => "text/javascript",
"css" => "text/css",
"xml" => "text/xml",
"gif" => "image/gif",
"jpg" => "image/jpeg",
"jpeg" => "image/jpeg",
"png" => "image/png",
"txt" => "text/plain"
);
asset_types: asset content types
var $assets_folder = array(
'js'=>'assets/js/',
'css'=>'assets/css/',
'gif'=>'assets/images/',
'jpg'=>'assets/images/',
'jpeg'=>'assets/images/',
'png'=>'assets/images/'
);
assets_folder: folders where assets can be found.
after document root e.g. IF: home/www/directory/my_application/cache_folder THEN: directory/my_application/cache_folder
var $cache_folder = array(
'js'=>'system/cache/',
'css'=>'system/cache/',
'gif'=>'system/cache/',
'jpg'=>'system/cache/',
'jpeg'=>'system/cache/',
'png'=>'system/cache/',
'swf'=>'system/cache/'
);
cache_folder: the folders that the assets will be cached
<?php
function krunch()
{
$this->set['uri'] = $_SERVER['REQUEST_URI'];
$this->check_file();
$this->initialize();
}
function check_file()
{
$this->target_file = pathinfo( $this->set['uri']);
// @ used to suppress errors. is_real = '' will stop the script
$this->target_file['dirname'] = @$this->assets_folder[ $this->target_file['extension'] ];//rewrite dirname
$this->target_file['fullpath'] = @$this->set['path2assets'] .$this->target_file['dirname']. $this->target_file['basename'] ;
$this->target_file['is_real'] = @file_exists( $this->target_file['fullpath'] );
}//EOF
function initialize()
{
$this->_check_writable();
//if file exists and cache folder is writable
if( $this->target_file['is_real'] == TRUE && $this->sysValues['cache_writable'] == TRUE )
{
$this->_get_settings();
$this->_get_target_type();
$this->set_caching();
$this->output();
}
else
{
header( 'HTTP/1.1 404 Not Found' );
if($this->target_file['is_real'] == FALSE)
{
echo "<H3>file ".$this->target_file['basename']." with extension ".$this->target_file['extension']." was not found</H3>";
}
elseif($this->sysValues['cache_writable'] == FALSE)
{
echo "<H3>The cache folder is not writable. Sorry!</H3>";
}
exit;
}
}//EOF
function _check_writable()
{
$this->sysValues['cache_folder'] = $_SERVER['DOCUMENT_ROOT'].'/'.$this->cache_folder[ $this->target_file['extension'] ];
$this->sysValues['cache_writable'] = is_writable( $this->sysValues['cache_folder'] );
// Check if windows because windows does not support chmod(cache_folder, 0777)
$this->sysValues['OS'] = strtoupper( substr( PHP_OS, 0, 3 ) );
if(! $this->sysValues['cache_writable'] && $this->sysValues['OS'] !== 'WIN' )
{
$this->sysValues['cache_writable'] = @chmod($this->sysValues['cache_folder'], 0777);
}
}
function _get_settings()
{
$this->sysValues['gzip'] = extension_loaded('zlib');
$this->sysValues['gzip'] = isset($_SERVER['HTTP_ACCEPT_ENCODING']);
$this->sysValues['gzip'] = ( strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE )? TRUE: FALSE;
$this->sysValues['gzip_target'] = $this->sysValues['cache_folder'] . $this->target_file['basename'].'.gz';
$this->sysValues['gzip'] = file_exists( $this->sysValues['gzip_target'] );
if($this->sysValues['gzip'])
{
$this->sysValues['new'] = ( filemtime($this->target_file['fullpath']) > filemtime($this->sysValues['gzip_target']) )? TRUE : FALSE;
if($this->sysValues['new'])
{
unlink( $this->sysValues['gzip_target'] );
$this->sysValues['gzip'] = FALSE; //cause I deleted it
}
else
{
return FALSE;
}
}
}
function set_caching()
{
$age = $this->set['asset_exp'];
$file_used_last = filemtime( $this->target_file['fullpath'] );
$this->headers['headers'][]= "Last-Modified: " . date( "r", $file_used_last );
$this->headers['headers'][] = "Expires: " . date( "r", ( $age + $file_used_last ) );
$this->headers['headers'][] = "ETag: " . dechex($file_used_last);
$this->headers['headers'][] = "Cache-Control: " . "public, must-revalidate, proxy-revalidate, max-age=" . $age . ", s-maxage=" . $age;
$this->headers['headers'][] = "Content-Type: " . $this->asset_types[ $this->target_file['extension'] ];
$this->headers['headers'][] = "Content-Length: " . filesize( $this->target_file['fullpath'] ) ;
} //EOF set_caching
function output()
{
if($this->debug)
{
echo "<pre>";
print_r($this->_debugger());
echo "</pre>";
exit;
}
elseif(!$this->debug)
{
ob_start();
foreach( $this->headers['headers'] as $headers)
{
header( $headers );
}
readfile($this->target_file['fullpath']);
ob_end_flush();
exit;
}
}//EOF output
// Private method _get_target_type
function _get_target_type()
{
if($this->sysValues['gzip'])//gzip version found
{
$this->target_file['modify'] = filemtime( $this->sysValues['gzip_target'] );
$this->headers['headers'][] = "Content-Encoding: gzip";
$this->target_file['fullpath'] = $this->sysValues['gzip_target'];
}
elseif(!$this->sysValues['gzip'])//gzip version NOT found
{
$this->_compressor( $this->target_file['fullpath'], $this->sysValues['gzip_target'] );
$this->target_file['modify'] = filemtime( $this->sysValues['gzip_target'] );
$this->headers['headers'][] = "Content-Encoding: gzip";
$this->target_file['fullpath'] = $this->sysValues['gzip_target'];
}
}//EOF
// Private method _compressor
function _compressor( $srcFileName, $dstFileName )
{
if(strlen($srcFileName) >= 1000)
{
//too small to gzip
return;
}
else
{
if ( $file_out = gzopen( $dstFileName, "wb" ) )
{
if ( $file_in = fopen( $srcFileName, "rb" ) )
{
while( !feof( $file_in ) )
{
gzwrite( $file_out, fread( $file_in, 1024*512 ) );
}
fclose( $file_in );
}
}
}
}
// Private method _uncompressor
// This method is note being used... maybe later at some stage!
function _uncompressor( $srcFileName, $dstFileName, $fileSize )
{
// getting content of the compressed file
$zp = gzopen( $srcFileName, "r" );
$data = fread ( $zp, $fileSize );
gzclose( $zp );
// writing uncompressed file
$fp = fopen( $dstFileName, "w" );
fwrite( $fp, $data );
fclose( $fp );
}
// Private method _debug
function _debugger( $temp=array() )
{
$temp['sysValues'] = $this->sysValues;
$temp['cache_folder'] = $this->cache_folder;
$temp['set'] = $this->set;
$temp['Headers'] = $this->headers;
$temp['target_file'] = $this->target_file;
$temp['assest_types'] = $this->asset_types;
$temp['assets_folder'] = $this->assets_folder;
return $temp;
}
}//end Krunch