From dc20d5f2f34c860c5170a04d135561ae884ef016 Mon Sep 17 00:00:00 2001 From: Estevao Soares dos Santos Date: Mon, 23 Jul 2012 08:14:45 +0100 Subject: [PATCH 1/5] * Corrected composer.json file to reflect original authors * Merged latest changes to original repository (mrclay/minify) --- composer.json | 46 +++++-- min/lib/Minify.php | 6 +- min/lib/Minify/ClosureCompiler.php | 121 +++++++++++++++++++ min/lib/Minify/Controller/MinApp.php | 11 +- min/lib/Minify/YUICompressor.php | 4 +- min_unit_tests/_test_files/html/before.html | 100 +++++++-------- min_unit_tests/_test_files/html/before2.html | 3 +- 7 files changed, 224 insertions(+), 67 deletions(-) create mode 100644 min/lib/Minify/ClosureCompiler.php diff --git a/composer.json b/composer.json index b4b2357f..1c0db5df 100644 --- a/composer.json +++ b/composer.json @@ -1,14 +1,36 @@ { - "name": "oyatel/minify", - "description": "Minify is a PHP5 app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers", - "authors": [ - { - "name": "Even Andre Fiskvik", - "email": "eaf@oyatel.com" - } - ], - "require": {}, - "autoload": { - "classmap": ["min/lib/"] + "name": "minify/minify", + "description": "Minify is a PHP5 app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers", + "keywords": ["js","javascript"], + "homepage": "http://code.google.com/p/minify/", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Ryan Groove", + "email": "ryan@wonko.com", + "homepage": "http://code.google.com/p/minify/", + "role": "Original Author" + }, + { + "name": "Steve Clay", + "email": "steve@mrclay.org", + "homepage": "http://code.google.com/p/minify/", + "role": "Original Author" + }, + { + "name": "Even Andre Fiskvik", + "email": "eaf@oyatel.com", + "role": "Mantainer, Composer Adaptation" + }, + { + "name": "Estevão Soares dos Santos", + "email": "estevao.santos@ci2.pt", + "homepage": "http://www.ci2.pt/", + "role": "Mantainer, Composer Adaptation" } -} + ], + "autoload": { + "classmap": ["min/lib/"] + } +} \ No newline at end of file diff --git a/min/lib/Minify.php b/min/lib/Minify.php index 2900e43b..c840ab21 100644 --- a/min/lib/Minify.php +++ b/min/lib/Minify.php @@ -155,9 +155,11 @@ public static function setCache($cache = '', $fileLocking = true) * * @param array $options controller/serve options * - * @return mixed null, or, if the 'quiet' option is set to true, an array + * @return null|array if the 'quiet' option is set to true, an array * with keys "success" (bool), "statusCode" (int), "content" (string), and * "headers" (array). + * + * @throws Exception */ public static function serve($controller, $options = array()) { @@ -290,7 +292,7 @@ public static function serve($controller, $options = array()) throw $e; } self::$_cache->store($cacheId, $content); - if (function_exists('gzencode')) { + if (function_exists('gzencode') && self::$_options['encodeMethod']) { self::$_cache->store($cacheId . '.gz', gzencode($content, self::$_options['encodeLevel'])); } } diff --git a/min/lib/Minify/ClosureCompiler.php b/min/lib/Minify/ClosureCompiler.php new file mode 100644 index 00000000..76354adf --- /dev/null +++ b/min/lib/Minify/ClosureCompiler.php @@ -0,0 +1,121 @@ + + * Minify_ClosureCompiler::$jarFile = '/path/to/closure-compiler-20120123.jar'; + * Minify_ClosureCompiler::$tempDir = '/tmp'; + * $code = Minify_ClosureCompiler::minify( + * $code, + * array('compilation_level' => 'SIMPLE_OPTIMIZATIONS') + * ); + * + * --compilation_level WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS, ADVANCED_OPTIMIZATIONS + * + * + * + * @todo unit tests, $options docs + * @todo more options support (or should just passthru them all?) + * + * @package Minify + * @author Stephen Clay + * @author Elan Ruusamäe + */ +class Minify_ClosureCompiler { + + /** + * Filepath of the Closure Compiler jar file. This must be set before + * calling minifyJs(). + * + * @var string + */ + public static $jarFile = null; + + /** + * Writable temp directory. This must be set before calling minifyJs(). + * + * @var string + */ + public static $tempDir = null; + + /** + * Filepath of "java" executable (may be needed if not in shell's PATH) + * + * @var string + */ + public static $javaExecutable = 'java'; + + /** + * Minify a Javascript string + * + * @param string $js + * + * @param array $options (verbose is ignored) + * + * @see https://code.google.com/p/closure-compiler/source/browse/trunk/README + * + * @return string + */ + public static function minify($js, $options = array()) + { + self::_prepare(); + if (! ($tmpFile = tempnam(self::$tempDir, 'cc_'))) { + throw new Exception('Minify_ClosureCompiler : could not create temp file.'); + } + file_put_contents($tmpFile, $js); + exec(self::_getCmd($options, $tmpFile), $output, $result_code); + unlink($tmpFile); + if ($result_code != 0) { + throw new Exception('Minify_ClosureCompiler : Closure Compiler execution failed.'); + } + return implode("\n", $output); + } + + private static function _getCmd($userOptions, $tmpFile) + { + $o = array_merge( + array( + 'charset' => 'utf-8', + 'compilation_level' => 'SIMPLE_OPTIMIZATIONS', + ), + $userOptions + ); + $cmd = self::$javaExecutable . ' -jar ' . escapeshellarg(self::$jarFile) + . (preg_match('/^[\\da-zA-Z0-9\\-]+$/', $o['charset']) + ? " --charset {$o['charset']}" + : ''); + + foreach (array('compilation_level') as $opt) { + if ($o[$opt]) { + $cmd .= " --{$opt} ". escapeshellarg($o[$opt]); + } + } + return $cmd . ' ' . escapeshellarg($tmpFile); + } + + private static function _prepare() + { + if (! is_file(self::$jarFile)) { + throw new Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not a valid file.'); + } + if (! is_readable(self::$jarFile)) { + throw new Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not readable.'); + } + if (! is_dir(self::$tempDir)) { + throw new Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not a valid direcotry.'); + } + if (! is_writable(self::$tempDir)) { + throw new Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not writable.'); + } + } +} diff --git a/min/lib/Minify/Controller/MinApp.php b/min/lib/Minify/Controller/MinApp.php index e9dac7d1..4b8c32e8 100644 --- a/min/lib/Minify/Controller/MinApp.php +++ b/min/lib/Minify/Controller/MinApp.php @@ -37,6 +37,10 @@ public function setupSources($options) { $firstMissingResource = null; if (isset($_GET['g'])) { + if (! is_string($_GET['g'])) { + $this->log("GET param 'g' was invalid"); + return $options; + } // add group(s) $this->selectionId .= 'g=' . $_GET['g']; $keys = explode(',', $_GET['g']); @@ -91,6 +95,10 @@ public function setupSources($options) { } } if (! $cOptions['groupsOnly'] && isset($_GET['f'])) { + if (! is_string($_GET['f'])) { + $this->log("GET param 'f' was invalid"); + return $options; + } // try user files // The following restrictions are to limit the URLs that minify will // respond to. @@ -119,7 +127,8 @@ public function setupSources($options) { } if (isset($_GET['b'])) { // check for validity - if (preg_match('@^[^/]+(?:/[^/]+)*$@', $_GET['b']) + if (is_string($_GET['b']) + && preg_match('@^[^/]+(?:/[^/]+)*$@', $_GET['b']) && false === strpos($_GET['b'], '..') && $_GET['b'] !== '.') { // valid base diff --git a/min/lib/Minify/YUICompressor.php b/min/lib/Minify/YUICompressor.php index c5bd8a1e..ef446294 100644 --- a/min/lib/Minify/YUICompressor.php +++ b/min/lib/Minify/YUICompressor.php @@ -134,8 +134,8 @@ private static function _prepare() if (! is_file(self::$jarFile)) { throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not a valid file.'); } - if (! is_executable(self::$jarFile)) { - throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not executable.'); + if (! is_readable(self::$jarFile)) { + throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not readable.'); } if (! is_dir(self::$tempDir)) { throw new Exception('Minify_YUICompressor : $tempDir('.self::$tempDir.') is not a valid direcotry.'); diff --git a/min_unit_tests/_test_files/html/before.html b/min_unit_tests/_test_files/html/before.html index 3b06d181..ba612500 100644 --- a/min_unit_tests/_test_files/html/before.html +++ b/min_unit_tests/_test_files/html/before.html @@ -11,57 +11,59 @@ css Zen Garden: The Beauty in CSS Design - - - - - + + + + + css Zen Garden: The Beauty in CSS Design -