00001 <?php
00014 class ScriptServer {
00022 public static function sendScript($scriptName) {
00023 if (false === ereg('^[A-Za-z_][A-Za-z0-9_\.]*.js$', $scriptName))
00024 return false;
00025
00026
00027 $config = Config::instance();
00028 $docRoot = $config->documentRoot();
00029 $scriptDir = $docRoot.$config->scriptDir();
00030 $cacheDir = $docRoot.$config->cacheDir();
00031
00032
00033 $sourceScript = $scriptDir.'/'.$scriptName;
00034 $cachedScript = $cacheDir.'/'.$scriptName;
00035
00036
00037 if (!file_exists($sourceScript))
00038 return false;
00039 if (!file_exists($cachedScript) ||
00040 filemtime($sourceScript) > filemtime($cachedScript))
00041 self::generate($sourceScript, $cachedScript);
00042
00043
00044 Header('Content-type: text/javascript; charset=utf-8');
00045 readfile($cachedScript);
00046 return true;
00047 }
00048 private static function generate($src, $dest) {
00049 $fSrc = fopen ($src, 'r');
00050 $fDest = fopen ($dest, 'w');
00051
00052
00053 $startTS = microtime(true);
00054 fwrite($fDest, '
00055 fwrite($fDest, '
00056
00057
00058 define('ST_INIT', 0);
00059 define('ST_LONG_COMMENT', 1);
00060 define('ST_INLINE_COMMENT', 2);
00061 define('ST_SLASH_READED', 3);
00062 define('ST_ASTERIX_READED', 4);
00063 define('ST_LINE_BEGIN', 5);
00064 $state = ST_INIT;
00065 $last = '';
00066 $ignoreInlineComment = false;
00067 while (false !== ($c = fgetc($fSrc))) {
00068 switch ($state) {
00069 case ST_INIT:
00070 if ($c == '/') {
00071 $state = ST_SLASH_READED;
00072 $ignoreInlineComment = false;
00073 } else {
00074 if ($c == "\n")
00075 $state = ST_LINE_BEGIN;
00076 if ($c != "\n" || $last != "\n")
00077 fwrite($fDest, $last = $c);
00078 }
00079 break;
00080 case ST_LINE_BEGIN:
00081 if ($c == '/') {
00082 $state = ST_SLASH_READED;
00083 $ignoreInlineComment = true;
00084 }
00085 else if (trim($c)==$c) {
00086 $state = ST_INIT;
00087 if ($c != "\n" || $last != "\n")
00088 fwrite($fDest, $last = $c);
00089 }
00090 break;
00091 case ST_SLASH_READED:
00092 if ($ignoreInlineComment && $c == '/')
00093 $state = ST_INLINE_COMMENT;
00094 else if ($c == '*')
00095 $state = ST_LONG_COMMENT;
00096 else {
00097 if ($c == "\n")
00098 $state = ST_LINE_BEGIN;
00099 else
00100 $state = ST_INIT;
00101 fwrite($fDest, '/'.($last=$c));
00102 }
00103 break;
00104 case ST_INLINE_COMMENT:
00105 if ($c == "\n") {
00106 $state = ST_LINE_BEGIN;
00107 if ($last != "\n")
00108 fwrite($fDest, $last = "\n");
00109 }
00110 break;
00111 case ST_LONG_COMMENT:
00112 if ($c == '*')
00113 $state = ST_ASTERIX_READED;
00114 break;
00115 case ST_ASTERIX_READED:
00116 if ($c == '/')
00117 $state = ST_INIT;
00118 else if ($c != '*')
00119 $state = ST_LONG_COMMENT;
00120 break;
00121 }
00122 }
00123
00124 $timeElapsed = microtime(true)-$startTS;
00125 fprintf($fDest, "\n// File generated in %.3f s\n", $timeElapsed);
00126
00127 fclose($fSrc);
00128 fclose($fDest);
00129 }
00130
00131 private function __construct() { }
00132 }