Completed
Push — master ( 7d42f0...b1f906 )
by Josh
17:22
created

ClosureCompilerApplication   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 92.31%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 1
dl 0
loc 169
ccs 48
cts 52
cp 0.9231
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 4
A getCacheDifferentiator() 0 19 3
B minify() 0 47 7
A getClosureCompilerBinHash() 0 11 2
A testFilepaths() 0 15 4
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2018 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
	* @deprecated 1.3.0 Set a command instead
18
	*/
19
	public $closureCompilerBin;
20
21
	/**
22
	* @var string Command used to invoke the Closure Compiler application
23
	*/
24
	public $command;
25
26
	/**
27
	* @var string Closure Compiler's compilation level
28
	*/
29
	public $compilationLevel = 'ADVANCED_OPTIMIZATIONS';
30
31
	/**
32
	* @var bool Whether to exclude Closure Compiler's default externs
33
	*/
34
	public $excludeDefaultExterns = true;
35
36
	/**
37
	* @var string Path to java interpreter
38
	* @deprecated 1.3.0 Set a command instead
39
	*/
40
	public $javaBin = 'java';
41
42
	/**
43
	* @var string Extra options to be passed to the Closure Compiler application
44
	*/
45
	public $options = '--use_types_for_optimization';
46
47
	/**
48
	* Constructor
49
	*
50
	* @param  string $filepathOrCommand Path to the Closure Compiler .jar or command to execute
51
	*/
52 10
	public function __construct($filepathOrCommand = null)
53
	{
54 10
		if (isset($filepathOrCommand))
55
		{
56 8
			if (file_exists($filepathOrCommand) && substr($filepathOrCommand, -4) === '.jar')
57
			{
58 8
				$this->closureCompilerBin = $filepathOrCommand;
1 ignored issue
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
59
			}
60
			else
61
			{
62
				$this->command = $filepathOrCommand;
63
			}
64
		}
65 10
	}
66
67
	/**
68
	* {@inheritdoc}
69
	*/
70 6
	public function getCacheDifferentiator()
71
	{
72
		$key = [
73 6
			$this->compilationLevel,
74 6
			$this->excludeDefaultExterns,
75 6
			$this->options
76
		];
77 6
		if (isset($this->closureCompilerBin))
1 ignored issue
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
78
		{
79 6
			$key[] = $this->getClosureCompilerBinHash();
80
		}
81
82 6
		if ($this->excludeDefaultExterns)
83
		{
84 6
			$key[] = file_get_contents(__DIR__ . '/../externs.application.js');
85
		}
86
87 6
		return $key;
88
	}
89
90
	/**
91
	* Compile given JavaScript source via the Closure Compiler application
92
	*
93
	* @param  string $src JavaScript source
94
	* @return string      Compiled source
95
	*/
96 4
	public function minify($src)
97
	{
98 4
		$this->testFilepaths();
99 2
		$options = ($this->options) ? ' ' . $this->options : '';
100
101
		// Add our custom externs if default externs are disabled
102 2
		if ($this->excludeDefaultExterns && $this->compilationLevel === 'ADVANCED_OPTIMIZATIONS')
103
		{
104 1
			$options .= ' --externs ' . __DIR__ . '/../externs.application.js --env=CUSTOM';
105
		}
106
107 2
		$crc     = crc32($src);
108 2
		$inFile  = sys_get_temp_dir() . '/' . $crc . '.js';
109 2
		$outFile = sys_get_temp_dir() . '/' . $crc . '.min.js';
110
111 2
		file_put_contents($inFile, $src);
112
113 2
		if (isset($this->command))
114
		{
115
			$cmd = $this->command;
116
		}
117
		else
118
		{
119 2
			$cmd = escapeshellcmd($this->javaBin) . ' -jar ' . escapeshellarg($this->closureCompilerBin);
2 ignored issues
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...erApplication::$javaBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
120
		}
121
122 2
		$cmd .= ' --compilation_level ' . escapeshellarg($this->compilationLevel)
123 2
		     . $options
124 2
		     . ' --js ' . escapeshellarg($inFile)
125 2
		     . ' --js_output_file ' . escapeshellarg($outFile);
126
127 2
		exec($cmd . ' 2>&1', $output, $return);
128 2
		unlink($inFile);
129
130 2
		if (file_exists($outFile))
131
		{
132 2
			$src = trim(file_get_contents($outFile));
133 2
			unlink($outFile);
134
		}
135
136 2
		if (!empty($return))
137
		{
138
			throw new RuntimeException('An error occured during minification: ' . implode("\n", $output));
139
		}
140
141 2
		return $src;
142
	}
143
144
	/**
145
	* Compute and return the hash for current Closure Compiler binary
146
	*
147
	* @return string
148
	*/
149 6
	protected function getClosureCompilerBinHash()
150
	{
151
		// Caching the value saves time during testing but has little to no real-world impact
152 6
		static $cache = [];
153 6
		if (!isset($cache[$this->closureCompilerBin]))
1 ignored issue
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
154
		{
155 2
			$cache[$this->closureCompilerBin] = md5_file($this->closureCompilerBin);
1 ignored issue
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
156
		}
157
158 6
		return $cache[$this->closureCompilerBin];
1 ignored issue
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
159
	}
160
161
	/**
162
	* Test that the Closure Compiler file exists
163
	*
164
	* @return void
165
	*/
166 4
	protected function testFilepaths()
167
	{
168 4
		if (isset($this->command))
169
		{
170
			return;
171
		}
172 4
		if (!isset($this->closureCompilerBin))
1 ignored issue
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
173
		{
174 1
			throw new RuntimeException('No path set for Closure Compiler');
175
		}
176 3
		if (!file_exists($this->closureCompilerBin))
1 ignored issue
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
177
		{
178 1
			throw new RuntimeException('Cannot find Closure Compiler at ' . $this->closureCompilerBin);
1 ignored issue
show
Deprecated Code introduced by
The property s9e\TextFormatter\Config...on::$closureCompilerBin has been deprecated with message: 1.3.0 Set a command instead

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
179
		}
180
	}
181
}