PluginProbe
WP Super Minify • Minify, Compress and Cache HTML, CSS & JavaScript / trunk
WP Super Minify • Minify, Compress and Cache HTML, CSS & JavaScript vtrunk
trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.4 1.5 1.5.1 1.6 2.0 2.0.1
wp-super-minify / includes / min / lib / Minify / ClosureCompiler.php

ClosureCompiler.php in WP Super Minify • Minify, Compress and Cache HTML, CSS & JavaScript trunk, at includes/min/lib/Minify/ClosureCompiler.php

241 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class Minify_ClosureCompiler
4 * @package Minify
5 */
6
7 /**
8 * Compress Javascript using the Closure Compiler
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_ClosureCompiler::$jarFile = '/path/to/closure-compiler-20120123.jar';
17 * Minify_ClosureCompiler::$tempDir = '/tmp';
18 * $code = Minify_ClosureCompiler::minify(
19 * $code,
20 * array('compilation_level' => 'SIMPLE_OPTIMIZATIONS')
21 * );
22 *
23 * --compilation_level WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS, ADVANCED_OPTIMIZATIONS
24 *
25 * </code>
26 *
27 * @package Minify
28 * @author Stephen Clay <steve@mrclay.org>
29 * @author Elan Ruusamäe <glen@delfi.ee>
30 */
31 class Minify_ClosureCompiler
32 {
33 public static $isDebug = false;
34
35 /**
36 * Filepath of the Closure Compiler jar file. This must be set before
37 * calling minifyJs().
38 *
39 * @var string
40 */
41 public static $jarFile;
42
43 /**
44 * Writable temp directory. This must be set before calling minifyJs().
45 *
46 * @var string
47 */
48 public static $tempDir;
49
50 /**
51 * Filepath of "java" executable (may be needed if not in shell's PATH)
52 *
53 * @var string
54 */
55 public static $javaExecutable = 'java';
56
57 /**
58 * Default command line options passed to closure-compiler
59 *
60 * @var array
61 */
62 public static $defaultOptions = array(
63 'charset' => 'utf-8',
64 'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
65 'warning_level' => 'QUIET',
66 );
67
68 /**
69 * Minify a Javascript string
70 *
71 * @param string $js
72 * @param array $options (verbose is ignored)
73 * @see https://code.google.com/p/closure-compiler/source/browse/trunk/README
74 * @return string
75 * @throws Minify_ClosureCompiler_Exception
76 */
77 public static function minify($js, $options = array())
78 {
79 $min = new static();
80
81 return $min->process($js, $options);
82 }
83
84 /**
85 * Process $js using $options.
86 *
87 * @param string $js
88 * @param array $options
89 * @return string
90 * @throws Exception
91 * @throws Minify_ClosureCompiler_Exception
92 */
93 public function process($js, $options)
94 {
95 $tmpFile = $this->dumpFile(self::$tempDir, $js);
96 try {
97 $result = $this->compile($tmpFile, $options);
98 } catch (Exception $e) {
99 unlink($tmpFile);
100 throw $e;
101 }
102 unlink($tmpFile);
103
104 return $result;
105 }
106
107 /**
108 * @param string $tmpFile
109 * @param array $options
110 * @return string
111 * @throws Minify_ClosureCompiler_Exception
112 */
113 protected function compile($tmpFile, $options)
114 {
115 $command = $this->getCommand($options, $tmpFile);
116
117 return implode("\n", $this->shell($command));
118 }
119
120 /**
121 * @param array $userOptions
122 * @param string $tmpFile
123 * @return string
124 */
125 protected function getCommand($userOptions, $tmpFile)
126 {
127 $args = array_merge(
128 $this->getCompilerCommandLine(),
129 $this->getOptionsCommandLine($userOptions)
130 );
131
132 return implode(' ', $args) . ' ' . escapeshellarg($tmpFile);
133 }
134
135 /**
136 * @return array
137 * @throws Minify_ClosureCompiler_Exception
138 */
139 protected function getCompilerCommandLine()
140 {
141 $this->checkJar(self::$jarFile);
142 $server = array(
143 self::$javaExecutable,
144 '-jar',
145 escapeshellarg(self::$jarFile)
146 );
147
148 return $server;
149 }
150
151 /**
152 * @param array $userOptions
153 * @return array
154 */
155 protected function getOptionsCommandLine($userOptions)
156 {
157 $args = array();
158
159 $options = array_merge(
160 static::$defaultOptions,
161 $userOptions
162 );
163
164 foreach ($options as $key => $value) {
165 $args[] = "--{$key} " . escapeshellarg($value);
166 }
167
168 return $args;
169 }
170
171 /**
172 * @param string $jarFile
173 * @throws Minify_ClosureCompiler_Exception
174 */
175 protected function checkJar($jarFile)
176 {
177 if (!is_file($jarFile)) {
178 throw new Minify_ClosureCompiler_Exception('$jarFile(' . $jarFile . ') is not a valid file.');
179 }
180 if (!is_readable($jarFile)) {
181 throw new Minify_ClosureCompiler_Exception('$jarFile(' . $jarFile . ') is not readable.');
182 }
183 }
184
185 /**
186 * @param string $tempDir
187 * @throws Minify_ClosureCompiler_Exception
188 */
189 protected function checkTempdir($tempDir)
190 {
191 if ($tempDir === null || !is_dir($tempDir)) {
192 throw new Minify_ClosureCompiler_Exception('$tempDir(' . $tempDir . ') is not a valid direcotry.');
193 }
194 if (!is_writable($tempDir)) {
195 throw new Minify_ClosureCompiler_Exception('$tempDir(' . $tempDir . ') is not writable.');
196 }
197 }
198
199 /**
200 * Write $content to a temporary file residing in $dir.
201 *
202 * @param string $dir
203 * @param string $content
204 * @return string
205 * @throws Minify_ClosureCompiler_Exception
206 */
207 protected function dumpFile($dir, $content)
208 {
209 $this->checkTempdir($dir);
210 $tmpFile = tempnam($dir, 'cc_');
211 if (!$tmpFile) {
212 throw new Minify_ClosureCompiler_Exception('Could not create temp file in "' . $dir . '".');
213 }
214 file_put_contents($tmpFile, $content);
215
216 return $tmpFile;
217 }
218
219 /**
220 * Execute command, throw if exit code is not in $expectedCodes array
221 *
222 * @param string $command
223 * @param array $expectedCodes
224 * @return mixed
225 * @throws Minify_ClosureCompiler_Exception
226 */
227 protected function shell($command, $expectedCodes = array(0))
228 {
229 exec($command, $output, $result_code);
230 if (!in_array($result_code, $expectedCodes)) {
231 throw new Minify_ClosureCompiler_Exception("Unpexpected return code: $result_code");
232 }
233
234 return $output;
235 }
236 }
237
238 class Minify_ClosureCompiler_Exception extends Exception
239 {
240 }
241