Skip to content
2 changes: 1 addition & 1 deletion smartoptimizer/.htaccess
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
php_flag zlib.output_compression Off
php_flag output_buffering Off
php_value output_handler NULL
php_value output_handler None
38 changes: 28 additions & 10 deletions smartoptimizer/config.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
/*
* SmartOptimizer Configuration File
**/
*/

//base dir (a relative path to the base directory)
$settings['baseDir'] = '../';
Expand Down Expand Up @@ -58,19 +58,37 @@
$settings['clientCacheCheck'] = false;

//Minifier to use when parsing js files. Add yours in /minifiers directory, and implement function minify_js($text_to_minify)
//We have 2 js minifiers - the original coded by farahdi(js) or Dean Edwards Packer(packer).
$settings['jsMinifier'] = 'packer';

//Minifier to use when parsing css files. Add yours in /minifiers directory, and implement function minify_css($text_to_minify)
$settings['cssMinifier'] = 'css';

//To use groups effectively, include your files with absolute paths. Define constants for easy access.
//define('MY_JS_DIR', $_SERVER['DOCUMENT_ROOT'] . '/tkitt/js/');
//define('MY_CSS_DIR', $_SERVER['DOCUMENT_ROOT'] . '/tkitt/css/');
$settings['htmlMinifier'] = 'html';

/*
//To use groups effectively, include your files with absolute paths. Define constants for easy access.
define('MY_JS_DIR', $_SERVER['DOCUMENT_ROOT'] . 'cuisinesearch/');
define('MY_CSS_DIR', $_SERVER['DOCUMENT_ROOT'] . 'cuisinesearch/css/');
*/
//groups configuration. Call a group by using /path/to/smartoptimizer/?group.group_name.
//Tip: If you use 'test.js' as your group name, you'll get a nifty file name like 'group.test.js'
//$settings['groups'] = array(
// 'test.js' => array(MY_JS_DIR.'test.js', MY_JS_DIR.'test2.js'),
// 'test.css' => array(MY_JS_DIR.'style.css', MY_JS_DIR.'print.css')
//);
/*
$settings['groups'] = array(
'alljs.js' => array(MY_JS_DIR.'js/getDataService.js',
MY_JS_DIR.'js/recettes_directive.js',
MY_JS_DIR.'js/search_directive.js',
MY_JS_DIR.'js/cloud_directive.js',
MY_JS_DIR.'js/paginate_directive3.js'
),
'test.css' => array(MY_JS_DIR.'style.css', MY_JS_DIR.'print.css')
);*/

$settings['myrootpath']=implode('/',array_slice(explode('/',$_SERVER["SCRIPT_FILENAME"]),0, -2));

$smartoptimizerPath=$settings['myrootpath'].'/smartoptimizer';

$settings['js_group_name'] = 'group.alljs.js';
$settings['alljs'] = $smartoptimizerPath."/".$settings['cacheDir']."alljs.txt";

$settings['css_group_name'] = 'group.allcss.css';
$settings['allcss'] = $smartoptimizerPath."/".$settings['cacheDir']."allcss.txt";
199 changes: 83 additions & 116 deletions smartoptimizer/index.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
/** SmartOptimizer v1.8
/* SmartOptimizer v1.8
* SmartOptimizer enhances your website performance using techniques
* such as compression, concatenation, minifying, caching, and embedding on demand.
*
Expand All @@ -9,13 +9,7 @@
*
* Author: Ali Farhadi (a.farhadi@gmail.com)
* Website: http://farhadi.ir/
*
*
*
* @todo SET A MINIMUM FILE SIZE WHICH WILL NOT BE GZIPPED OR MINIFIED.
* @todo EXCLUDE FILES WITH .min. in the filename - from minifying (they are already done)
*
**/
*/

//Default settings
$settings = array(
Expand Down Expand Up @@ -56,30 +50,13 @@
"swf" => "application/x-shockwave-flash",
"ico" => "image/x-icon",
);
/**Processs a time in a string
*
* @param datetime $time
* @return string Date formatted
*/

function gmdatestr($time = null) {
if (is_null($time)){ $time = time();}
return gmdate("D, d M Y H:i:s", $time) . " GMT";
}
/**Adds a status header and then exits
*
* @param string $status
*/

function headerExit($status) {
header("HTTP/1.0 $status");
exit();
}
/**
* Adds Headers to a returning HTTP response that tells a server not to cache the file ever
**/
function headerNoCache()
{

function headerNoCache() {
// already expired
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

Expand All @@ -97,124 +74,113 @@ function headerNoCache()
//generate a unique Etag each time
header('Etag: '.microtime());
}
/**
* Adds header to the response informing that the file never expires cache it forever.
*/

function headerNeverExpire() {
$exptime = time() + 31557600;
$curtime = time();
header("Expires: " . gmdatestr($exptime));
header("Cache-Control: public, max-age=31557600");
header("Last-Modified: " . gmdatestr($curtime));
header("Vary: Accept-Encoding");
function headerNeverExpire(){
header("Expires: " . gmdatestr(time() + 315360000));
header("Cache-Control: max-age=315360000");
}

/**
* Adds Headers to a file pls echo a Error that smartoptimizer couldnt process the file
* If Debug is set true this will 404 the file else it will return the file with a Script header.
*
* @global array $settings
* @param string $msg The message to ruturn if Debug is false
*/
function debugExit($msg) {
global $settings;
if (!$settings['debug']) {
headerExit('404 Not Found');
}
headerNoCache();
header('Content-Type: text/html; charset=' . $settings['charSet']);
header("Content-Encoding: none");
echo "//<script>\n";
echo "alert('SmartOptimizer Error: " . str_replace("\n", "\\n", addslashes($msg)) . "');\n";
echo "//</script>\n";
exit();
function debugExit($msg){
global $settings;
if (!$settings['debug']) {
headerExit('404 Not Found');
}
headerNoCache();
header('Content-Type: text/html; charset='.$settings['charSet']);
header("Content-Encoding: none");
echo "//<script>\n";
echo "alert('SmartOptimizer Error: ".str_replace("\n", "\\n", addslashes($msg))."');\n";
echo "//</script>\n";
exit();
}

/**Gets the input files modification time and compares it to the modification time of /smartoptimizer/index.php and config.php
* and returns the larges of the 3 (ie the most recent time)
*
* @global array $files
* @global string $fileType
* @staticvar datetime $filesmtime
* @return datetime
**/
function gmdatestr($time = null) {
if (is_null($time)) $time = time();
return gmdate("D, d M Y H:i:s", $time) . " GMT";
}

function filesmtime() {
global $files, $fileMinifier;
static $filesmtime;
if ($filesmtime){return $filesmtime;}
$filesmtime = max(filemtime("minifiers/$fileMinifier.php"), filemtime('index.php'), filemtime('config.php'));
if ($filesmtime) return $filesmtime;
$filesmtime = max(@filemtime("minifiers/$fileMinifier.php"), filemtime('index.php'), filemtime('config.php'));
foreach ($files as $file) {
if (!file_exists($file)) {debugExit("File not found ($file).");}
if (!file_exists($file)) debugExit("File not found ($file).");
$filesmtime = max(filemtime($file), $filesmtime);
}
return $filesmtime;
}

function getFileList($listFile)
{
global $settings;

$fileNames=array();
if(file_exists($listFile)) {

$fp=fopen($listFile,'r');

while (($buffer = fgets($fp, 4096)) !== false) {
$fileNames[]=str_replace("\n","",$settings['myrootpath'].'/'.$buffer);
}
if (!feof($fp)) {
echo "Erreur: fgets() a échoué\n";
}
fclose($fp);
}

return $fileNames;
}

require 'config.php';

list($query) = explode('?', urldecode($_SERVER['QUERY_STRING']));

//if(isset($settings['groups']) && substr($query, 0, 6) == 'group.'){
// //we have a pre-defined group to include
// $group_name = str_replace('group.','',$query);
// if(isset($settings['groups'][$group_name])){
// $fileNames = $settings['groups'][$group_name];
// $fileDir = '';
// }
// else {debugExit("Group ($group_name) not set. Please edit config.");}
//} else {
if (preg_match('/^\/?(.+\/)?(.+)$/', $query, $matchResult)) {
$fileNames = $matchResult[2];
$fileDir = $settings['baseDir'] . $matchResult[1];
} else {
debugExit("Invalid file name ($query)");
}
//}
//check the file exists and is relative to the base directory.
if (strpos(realpath($fileDir), realpath($settings['baseDir'])) !== 0) {debugExit("File is out of base directory.");}

if ($settings['concatenate']) {
if(!is_array($fileNames)){
$files = explode($settings['separator'], $fileNames);
} else {
$files = $fileNames;
}
$settings['concatenate'] = count($files) > 1;
} else {$files = array($fileNames);}
if ($settings['concatenate'] && $query == $settings['js_group_name'] ) {
$fileDir = '';
$files=getFileList($settings['alljs']);
// $files=array_merge($files,getFileList($settings['alljs']));

} elseif ($settings['concatenate'] && $query == $settings['css_group_name'] ) {
$fileDir = '';
$files=getFileList($settings['allcss']);
}else {
if (preg_match('/^\/?(.+\/)?(.+)$/', $query, $matchResult)) {
$fileNames = $matchResult[2];
$fileDir = $settings['baseDir'].$matchResult[1];
} else debugExit("Invalid file name ($query)");
$files = array($fileNames);
}

foreach ($files as $key => $file) {
if (preg_match('/^[^\x00]+\.([a-z0-9]+)$/i', $file, $matchResult)) {
$fileTypes[] = strtolower($matchResult[1]);
} else {debugExit("Unsupported file ($file)");}
} else debugExit("Unsupported file ($file)");

$files[$key] = $fileDir.$file;
}

if ($settings['concatenate']) {
if (count(array_unique($fileTypes)) > 1) {debugExit("Files must be of the same type.");}
if (count(array_unique($fileTypes)) > 1) debugExit("Files must be of the same type.");
}
//check we have a minifier

$fileType = $fileTypes[0];
$fileMinifier = $settings[$fileType.'Minifier'];
if(!file_exists('minifiers/'.$fileMinifier.'.php')) {debugExit($fileType.'Minifier not found. Please create "minifiers/'.$fileMinifier.'.php" or change minifier in config.php');}
//check the file meets our filetypes list or
if (!isset($mimeTypes[$fileType])){ debugExit("Unsupported file type ($fileType)");}
if(!file_exists('minifiers/'.$fileMinifier.'.php')) debugExit($fileType.'Minifier not found. Please create "minifiers/'.$fileMinifier.'.php" or change minifier in config.php');

if (!isset($mimeTypes[$fileType])) debugExit("Unsupported file type ($fileType)");
header("Content-Type: {$mimeTypes[$fileType]}; charset=".$settings['charSet']);
// lets check and see if the client accepts compression and change our variable if it doesnt also check the filetype to ensure we want to compress.

$settings['gzip'] =
($settings['gzip'] &&
!in_array($fileType, $settings['gzipExceptions']) &&
in_array('gzip', array_map('trim', explode(',' , htmlspecialchars($_SERVER['HTTP_ACCEPT_ENCODING'], ENT_QUOTES)))) &&
in_array('gzip', array_map('trim', explode(',' , @$_SERVER['HTTP_ACCEPT_ENCODING']))) &&
function_exists('gzencode'));
// ok client likes compression - lets tell it we are sending a compressed file.
if ($settings['gzip']){ header("Content-Encoding: gzip");}
//check we have a minifier

if ($settings['gzip']) header("Content-Encoding: gzip");

$settings['minify'] = $settings['minify'] && file_exists('minifiers/'.$fileMinifier.'.php');
//if its css and we have an opera browser embed the css
$settings['embed'] = $settings['embed'] && $fileType == 'css' && (!preg_match('/msie/i', htmlspecialchars($_SERVER['HTTP_USER_AGENT'])) || preg_match('/msie 8|opera/i', htmlspecialchars($_SERVER['HTTP_USER_AGENT'])));
//check if we want to call the cache.
$settings['embed'] = $settings['embed'] && $fileType == 'css' && (!preg_match('/msie/i', $_SERVER['HTTP_USER_AGENT']) || preg_match('/msie 8|opera/i', $_SERVER['HTTP_USER_AGENT']));
$settings['serverCache'] = $settings['serverCache'] && ($settings['minify'] || $settings['gzip'] || $settings['concatenate'] || $settings['embed']);

if ($settings['serverCache']) {
Expand All @@ -225,9 +191,9 @@ function_exists('gzencode'));
($settings['serverCache'] && (!file_exists($cachedFile) || ($settings['serverCacheCheck'] && filesmtime() > filemtime($cachedFile)))));

if ($settings['clientCache'] && $settings['clientCacheCheck']) {
if ($settings['serverCache'] && !$generateContent) {$mtime = filemtime($cachedFile);}
elseif ($settings['serverCache']) {$mtime = time();}
else {$mtime = filesmtime();}
if ($settings['serverCache'] && !$generateContent) $mtime = filemtime($cachedFile);
elseif ($settings['serverCache']) $mtime = time();
else $mtime = filesmtime();
$mtimestr = gmdatestr($mtime);
}

Expand All @@ -237,18 +203,18 @@ function_exists('gzencode'));
header("Cache-Control: must-revalidate");
} elseif ($settings['clientCache']) {
headerNeverExpire();
} else { headerNoCache();}
} else headerNoCache();

if ($generateContent) {
if ($settings['minify']){
include 'minifiers/'.$fileMinifier.'.php';

}
$content = array();
foreach ($files as $file){(($content[] = file_get_contents($file)) !== false) || debugExit("File not found ($file).");}
foreach ($files as $file) (($content[] = @file_get_contents($file)) !== false) || debugExit("File not found ($file).");
$content = implode("\n", $content);
if ($settings['minify']) {$content = call_user_func('minify_' . $fileType, $content);}
if ($settings['gzip']){ $content = gzencode($content, $settings['compressionLevel']);}
if ($settings['minify']) $content = call_user_func('minify_' . $fileType, $content);
if ($settings['gzip']) $content = gzencode($content, $settings['compressionLevel']);
if ($settings['serverCache']) {
$handle = @fopen($cachedFile, 'w') or debugExit("Could not create cache file($cachedFile).");
fwrite($handle, $content);
Expand All @@ -260,4 +226,5 @@ function_exists('gzencode'));
header('Content-Length: ' . filesize($cachedFile));
readfile($cachedFile);
}
} else {headerExit('304 Not Modified');}
} else headerExit('304 Not Modified');
?>
Loading