| 1 |
<?php |
| 2 |
/** |
| 3 |
* Class Minify_YUICompressor |
| 4 |
* @package Minify |
| 5 |
*/ |
| 6 |
|
| 7 |
/** |
| 8 |
* Compress Javascript/CSS using the YUI Compressor |
| 9 |
* |
| 10 |
* You must set $jarFile and $tempDir before calling the minify functions. |
| 11 |
* Also, depending on your shell's environment, you may need to specify |
| 12 |
* the full path to java in $javaExecutable or use putenv() to setup the |
| 13 |
* Java environment. |
| 14 |
* |
| 15 |
* <code> |
| 16 |
* Minify_YUICompressor::$jarFile = '/path/to/yuicompressor-2.4.6.jar'; |
| 17 |
* Minify_YUICompressor::$tempDir = '/tmp'; |
| 18 |
* $code = Minify_YUICompressor::minifyJs( |
| 19 |
* $code |
| 20 |
* ,array('nomunge' => true, 'line-break' => 1000) |
| 21 |
* ); |
| 22 |
* </code> |
| 23 |
* |
| 24 |
* Note: In case you run out stack (default is 512k), you may increase stack size in $options: |
| 25 |
* array('stack-size' => '2048k') |
| 26 |
* |
| 27 |
* @todo unit tests, $options docs |
| 28 |
* |
| 29 |
* @package Minify |
| 30 |
* @author Stephen Clay <[email protected]> |
| 31 |
*/ |
| 32 |
class Minify_YUICompressor |
| 33 |
{ |
| 34 |
|
| 35 |
/** |
| 36 |
* Filepath of the YUI Compressor jar file. This must be set before |
| 37 |
* calling minifyJs() or minifyCss(). |
| 38 |
* |
| 39 |
* @var string |
| 40 |
*/ |
| 41 |
public static $jarFile; |
| 42 |
|
| 43 |
/** |
| 44 |
* Writable temp directory. This must be set before calling minifyJs() |
| 45 |
* or minifyCss(). |
| 46 |
* |
| 47 |
* @var string |
| 48 |
*/ |
| 49 |
public static $tempDir; |
| 50 |
|
| 51 |
/** |
| 52 |
* Filepath of "java" executable (may be needed if not in shell's PATH) |
| 53 |
* |
| 54 |
* @var string |
| 55 |
*/ |
| 56 |
public static $javaExecutable = 'java'; |
| 57 |
|
| 58 |
/** |
| 59 |
* Minify a Javascript string |
| 60 |
* |
| 61 |
* @param string $js |
| 62 |
* |
| 63 |
* @param array $options (verbose is ignored) |
| 64 |
* |
| 65 |
* @see http://www.julienlecomte.net/yuicompressor/README |
| 66 |
* |
| 67 |
* @return string |
| 68 |
*/ |
| 69 |
public static function minifyJs($js, $options = array()) |
| 70 |
{ |
| 71 |
return self::_minify('js', $js, $options); |
| 72 |
} |
| 73 |
|
| 74 |
/** |
| 75 |
* Minify a CSS string |
| 76 |
* |
| 77 |
* @param string $css |
| 78 |
* |
| 79 |
* @param array $options (verbose is ignored) |
| 80 |
* |
| 81 |
* @see http://www.julienlecomte.net/yuicompressor/README |
| 82 |
* |
| 83 |
* @return string |
| 84 |
*/ |
| 85 |
public static function minifyCss($css, $options = array()) |
| 86 |
{ |
| 87 |
return self::_minify('css', $css, $options); |
| 88 |
} |
| 89 |
|
| 90 |
private static function _minify($type, $content, $options) |
| 91 |
{ |
| 92 |
self::_prepare(); |
| 93 |
if (! ($tmpFile = tempnam(self::$tempDir, 'yuic_'))) { |
| 94 |
throw new Exception('Minify_YUICompressor : could not create temp file in "'.self::$tempDir.'".'); |
| 95 |
} |
| 96 |
|
| 97 |
file_put_contents($tmpFile, $content); |
| 98 |
exec(self::_getCmd($options, $type, $tmpFile), $output, $result_code); |
| 99 |
unlink($tmpFile); |
| 100 |
if ($result_code != 0) { |
| 101 |
throw new Exception('Minify_YUICompressor : YUI compressor execution failed.'); |
| 102 |
} |
| 103 |
|
| 104 |
return implode("\n", $output); |
| 105 |
} |
| 106 |
|
| 107 |
private static function _getCmd($userOptions, $type, $tmpFile) |
| 108 |
{ |
| 109 |
$defaults = array( |
| 110 |
'charset' => '', |
| 111 |
'line-break' => 5000, |
| 112 |
'type' => $type, |
| 113 |
'nomunge' => false, |
| 114 |
'preserve-semi' => false, |
| 115 |
'disable-optimizations' => false, |
| 116 |
'stack-size' => '', |
| 117 |
); |
| 118 |
$o = array_merge($defaults, $userOptions); |
| 119 |
|
| 120 |
$cmd = self::$javaExecutable |
| 121 |
. (!empty($o['stack-size']) ? ' -Xss' . $o['stack-size'] : '') |
| 122 |
. ' -jar ' . escapeshellarg(self::$jarFile) |
| 123 |
. " --type {$type}" |
| 124 |
. (preg_match('/^[\\da-zA-Z0-9\\-]+$/', $o['charset']) |
| 125 |
? " --charset {$o['charset']}" |
| 126 |
: '') |
| 127 |
. (is_numeric($o['line-break']) && $o['line-break'] >= 0 |
| 128 |
? ' --line-break ' . (int)$o['line-break'] |
| 129 |
: ''); |
| 130 |
if ($type === 'js') { |
| 131 |
foreach (array('nomunge', 'preserve-semi', 'disable-optimizations') as $opt) { |
| 132 |
$cmd .= $o[$opt] |
| 133 |
? " --{$opt}" |
| 134 |
: ''; |
| 135 |
} |
| 136 |
} |
| 137 |
|
| 138 |
return $cmd . ' ' . escapeshellarg($tmpFile); |
| 139 |
} |
| 140 |
|
| 141 |
private static function _prepare() |
| 142 |
{ |
| 143 |
if (! is_file(self::$jarFile)) { |
| 144 |
throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not a valid file.'); |
| 145 |
} |
| 146 |
if (! is_readable(self::$jarFile)) { |
| 147 |
throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not readable.'); |
| 148 |
} |
| 149 |
if (! is_dir(self::$tempDir)) { |
| 150 |
throw new Exception('Minify_YUICompressor : $tempDir('.self::$tempDir.') is not a valid direcotry.'); |
| 151 |
} |
| 152 |
if (! is_writable(self::$tempDir)) { |
| 153 |
throw new Exception('Minify_YUICompressor : $tempDir('.self::$tempDir.') is not writable.'); |
| 154 |
} |
| 155 |
} |
| 156 |
} |
| 157 |
|