Created
September 19, 2012 11:41
-
-
Save meglio/3749224 to your computer and use it in GitHub Desktop.
js.php Joins and minifies js files from html template into cached.js and controls Cache-Control headers based on mtime of all files engaged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
header('Content-Type: text/javascript'); | |
$cacheFile = __DIR__.'/js/cached.js'; | |
$listFile = __DIR__.'/js/cached-list.txt'; | |
$htmlFile = __DIR__.'/tmpl/web/html5.twig'; | |
$htmlTime = filemtime($htmlFile); | |
$cacheTime = file_exists($cacheFile)? filemtime($cacheFile) : 0; | |
# Update list of cached js files if it does not exist yet or if html file changed | |
if (!file_exists($listFile) || filemtime($listFile) < $htmlTime) | |
{ | |
$html = file_get_contents($htmlFile); | |
preg_match('|<body.+</body\s*?>|is', $html, $m); | |
$body = $m[0]; | |
$regex = <<<REGEX | |
/{{\s*js\s*\(\s*('|")(?P<link1>[^)'"]+)('|")\s*\)\s*}}|<script[^>]+src\s*=\s*('|")(?P<link2>.+?)('|")/is | |
REGEX; | |
preg_match_all($regex, $body, $matches, PREG_SET_ORDER); | |
$files = []; | |
foreach($matches as $match) | |
{ | |
$link = empty($match['link1'])? $match['link2'] : $match['link1']; | |
if (strtolower(substr($link, -3)) == '.js' && file_exists($filePath = __DIR__.$link)) | |
$files[] = $filePath; | |
} | |
if (file_exists($listFile)) | |
unlink($listFile); | |
file_put_contents($listFile, join("\n", $files)); | |
$forceUpdate = true; | |
} | |
if (!file_exists($cacheFile)) | |
$forceUpdate = true; | |
# ?update=1 in DEBUG mode forces update, even if cached.js already exists | |
if (!isset($forceUpdate) && file_exists($cacheFile) && array_key_exists('update', $_GET)) | |
{ | |
$configFile = __DIR__.'/proj/config.php'; | |
if (file_exists($configFile) && is_readable($configFile)) | |
{ | |
require $configFile; | |
if (defined('DEBUG') && DEBUG) | |
$forceUpdate = true; | |
} | |
} | |
# Update if filemtime() for any of files from the list is changed | |
if (!isset($forceUpdate)) | |
{ | |
if (!isset($files)) | |
$files = file($listFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); | |
$maxTime = 0; | |
foreach($files as $f) | |
$maxTime = max($maxTime, filemtime($f)); | |
if ($maxTime > $cacheTime) | |
$forceUpdate = true; | |
} | |
# Generate cached.js | |
if (isset($forceUpdate)) | |
{ | |
if (!isset($files)) | |
$files = file($listFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); | |
$js = ''; | |
foreach($files as $file) | |
$js .= file_get_contents($file)."\n"; | |
require(__DIR__.'/proj/utils/JSmin.php'); | |
$result = JSMin::minify($js); | |
if (file_exists($cacheFile)) | |
unlink($cacheFile); // unlink clears the cache automatically | |
file_put_contents($cacheFile, $result); | |
$cacheTime = filemtime($cacheFile); | |
} | |
# Output | |
if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $cacheTime) | |
{ | |
header('HTTP/1.1 304 Not Modified'); | |
die(); | |
} | |
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $cacheTime).' GMT'); | |
$offset = 3600 * 24 * 30; | |
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . ' GMT'); | |
header("Cache-Control: public, max-age=3600, must-revalidate"); | |
die(file_get_contents($cacheFile)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment