Completed
Push — master ( 43b9f7...b73028 )
by Josh
18:39
created

ClosureCompilerApplication::testFilepaths()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
ccs 8
cts 8
cp 1
rs 9.4286
cc 3
eloc 5
nc 3
nop 0
crap 3
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2016 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Configurator\JavaScript\Minifiers;
9
10
use RuntimeException;
11
use s9e\TextFormatter\Configurator\JavaScript\Minifier;
12
13
class ClosureCompilerApplication extends Minifier
14
{
15
	/**
16
	* @var string Path to the Closure Compiler application
17
	*/
18
	public $closureCompilerBin;
19
20
	/**
21
	* @var string Closure Compiler's compilation level
22
	*/
23
	public $compilationLevel = 'ADVANCED_OPTIMIZATIONS';
24
25
	/**
26
	* @var bool Whether to exclude Closure Compiler's default externs
27
	*/
28
	public $excludeDefaultExterns = true;
29
30
	/**
31
	* @var string Path to java interpreter
32
	*/
33
	public $javaBin = 'java';
34
35
	/**
36
	* @var string Extra options to be passed to the Closure Compiler application
37
	*/
38
	public $options = '--use_types_for_optimization';
39
40
	/**
41
	* Constructor
42
	*
43
	* @param  string $filepath Path to the Closure Compiler .jar
44
	* @return void
45
	*/
46 13
	public function __construct($filepath = null)
47
	{
48 13
		if (isset($filepath))
49 13
		{
50 11
			$this->closureCompilerBin = $filepath;
51 11
			$this->testFilepaths();
52 10
		}
53 12
	}
54
55
	/**
56
	* {@inheritdoc}
57
	*/
58 7
	public function getCacheDifferentiator()
59
	{
60
		$key = [
61 7
			$this->compilationLevel,
62 7
			$this->excludeDefaultExterns,
63 7
			$this->options,
64 7
			crc32(file_get_contents($this->closureCompilerBin))
65 7
		];
66
67 7
		if ($this->excludeDefaultExterns)
68 7
		{
69 7
			$key[] = file_get_contents(__DIR__ . '/../externs.application.js');
70 7
		}
71
72 7
		return $key;
73
	}
74
75
	/**
76
	* Compile given JavaScript source via the Closure Compiler application
77
	*
78
	* @param  string $src JavaScript source
79
	* @return string      Compiled source
80
	*/
81 5
	public function minify($src)
82
	{
83 5
		$this->testFilepaths();
84 3
		$options = ($this->options) ? ' ' . $this->options : '';
85
86
		// Add our custom externs if default externs are disabled
87 3
		if ($this->excludeDefaultExterns && $this->compilationLevel === 'ADVANCED_OPTIMIZATIONS')
88 3
		{
89 1
			$options .= ' --externs ' . __DIR__ . '/../externs.application.js --env=CUSTOM';
90 1
		}
91
92 3
		$crc     = crc32($src);
93 3
		$inFile  = sys_get_temp_dir() . '/' . $crc . '.js';
94 3
		$outFile = sys_get_temp_dir() . '/' . $crc . '.min.js';
95
96 3
		file_put_contents($inFile, $src);
97
98 3
		$cmd = escapeshellcmd($this->javaBin)
99 3
		     . ' -jar ' . escapeshellarg($this->closureCompilerBin)
100 3
		     . ' --compilation_level ' . escapeshellarg($this->compilationLevel)
101 3
		     . $options
102 3
		     . ' --js ' . escapeshellarg($inFile)
103 3
		     . ' --js_output_file ' . escapeshellarg($outFile);
104
105 3
		exec($cmd . ' 2>/dev/null', $output, $return);
106 3
		unlink($inFile);
107
108 3
		if (file_exists($outFile))
109 3
		{
110 2
			$src = trim(file_get_contents($outFile));
111 2
			unlink($outFile);
112 2
		}
113
114 3
		if (!empty($return))
115 3
		{
116 1
			throw new RuntimeException('An error occured during minification');
117
		}
118
119 2
		return $src;
120
	}
121
122
	/**
123
	* Test that the Closure Compiler file exists
124
	*
125
	* @return void
126
	*/
127 13
	protected function testFilepaths()
128
	{
129 13
		if (!isset($this->closureCompilerBin))
130 13
		{
131 1
			throw new RuntimeException('No path set for Closure Compiler');
132
		}
133 12
		if (!file_exists($this->closureCompilerBin))
134 12
		{
135 2
			throw new RuntimeException('Cannot find Closure Compiler at ' . $this->closureCompilerBin);
136
		}
137
	}
138
}