Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concatenate all js files on the fly without specifying files names #5

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
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 ([email protected])
* 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