PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.2.5
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.2.5
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
wp-optimize / vendor / robloach / component-installer / src / ComponentInstaller / Process / RequireJsProcess.php

RequireJsProcess.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.2.5, at vendor/robloach/component-installer/src/ComponentInstaller/Process/RequireJsProcess.php

228 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of Component Installer.
5 *
6 * (c) Rob Loach (http://robloach.net)
7 *
8 * For the full copyright and license information, please view the LICENSE.md
9 * file that was distributed with this source code.
10 */
11
12 namespace ComponentInstaller\Process;
13
14 use Composer\Composer;
15 use Composer\Config;
16 use Composer\Package\Package;
17 use Composer\Json\JsonFile;
18 use Assetic\Asset\AssetCollection;
19 use Assetic\Asset\FileAsset;
20
21 /**
22 * Builds the require.js configuration.
23 */
24 class RequireJsProcess extends Process
25 {
26 /**
27 * The base URL for the require.js configuration.
28 */
29 protected $baseUrl = 'components';
30
31 /**
32 * {@inheritdoc}
33 */
34 public function init()
35 {
36 $output = parent::init();
37 if ($this->config->has('component-baseurl')) {
38 $this->baseUrl = $this->config->get('component-baseurl');
39 }
40
41 return $output;
42 }
43
44 /**
45 * {@inheritdoc}
46 */
47 public function process()
48 {
49 // Construct the require.js and stick it in the destination.
50 $json = $this->requireJson($this->packages, $this->config);
51 $requireConfig = $this->requireJs($json);
52
53 // Attempt to write the require.config.js file.
54 $destination = $this->componentDir . '/require.config.js';
55 $this->fs->ensureDirectoryExists(dirname($destination));
56 if (file_put_contents($destination, $requireConfig) === FALSE) {
57 $this->io->write('<error>Error writing require.config.js</error>');
58
59 return false;
60 }
61
62 // Read in require.js to prepare the final require.js.
63 $requirejs = file_get_contents(dirname(__DIR__) . '/Resources/require.js');
64 if ($requirejs === FALSE) {
65 $this->io->write('<error>Error reading in require.js</error>');
66
67 return false;
68 }
69
70 // Append the config to the require.js and write it.
71 if (file_put_contents($this->componentDir . '/require.js', $requirejs . $requireConfig) === FALSE) {
72 $this->io->write('<error>Error writing require.js to the components directory</error>');
73
74 return false;
75 }
76 }
77
78 /**
79 * Creates a require.js configuration from an array of packages.
80 *
81 * @param $packages
82 * An array of packages from the composer.lock file.
83 * @param $config
84 * The Composer Config object.
85 *
86 * @return array
87 * The built JSON array.
88 */
89 public function requireJson(array $packages)
90 {
91 $json = array();
92
93 // Construct the packages configuration.
94 foreach ($packages as $package) {
95 // Retrieve information from the extra options.
96 $extra = isset($package['extra']) ? $package['extra'] : array();
97 $options = isset($extra['component']) ? $extra['component'] : array();
98
99 // Construct the base details.
100 $name = $this->getComponentName($package['name'], $extra);
101 $component = array(
102 'name' => $name,
103 );
104
105 // Build the "main" directive.
106 $scripts = isset($options['scripts']) ? $options['scripts'] : array();
107 if (!empty($scripts)) {
108 // Put all scripts into a build.js file.
109 $result = $this->aggregateScripts($package, $scripts, $name.DIRECTORY_SEPARATOR.$name.'-built.js');
110 if ($result) {
111 // If the aggregation was successful, add the script to the
112 // packages array.
113 $component['main'] = $name.'-built.js';
114
115 // Add the component to the packages array.
116 $json['packages'][] = $component;
117 }
118 }
119
120 // Add the shim definition for the package.
121 $shim = isset($options['shim']) ? $options['shim'] : array();
122 if (!empty($shim)) {
123 $json['shim'][$name] = $shim;
124 }
125
126 // Add the config definition for the package.
127 $packageConfig = isset($options['config']) ? $options['config'] : array();
128 if (!empty($packageConfig)) {
129 $json['config'][$name] = $packageConfig;
130 }
131 }
132
133 // Provide the baseUrl.
134 $json['baseUrl'] = $this->baseUrl;
135
136 // Merge in configuration options from the root.
137 if ($this->config->has('component')) {
138 $config = $this->config->get('component');
139 if (isset($config) && is_array($config)) {
140 // Use a recursive, distict array merge.
141 $json = $this->arrayMergeRecursiveDistinct($json, $config);
142 }
143 }
144
145 return $json;
146 }
147
148 /**
149 * Concatenate all scripts together into one destination file.
150 */
151 public function aggregateScripts($package, array $scripts, $file)
152 {
153 // Aggregate all the assets into one file.
154 $assets = new AssetCollection();
155 foreach ($scripts as $script) {
156 // Collect each candidate from a glob file search.
157 $path = $this->getVendorDir($package).DIRECTORY_SEPARATOR.$script;
158 $matches = $this->fs->recursiveGlobFiles($path);
159 foreach ($matches as $match) {
160 $assets->add(new FileAsset($match));
161 }
162 }
163 $js = $assets->dump();
164
165 // Write the file if there are any JavaScript assets.
166 if (!empty($js)) {
167 $destination = $this->componentDir.DIRECTORY_SEPARATOR.$file;
168 $this->fs->ensureDirectoryExists(dirname($destination));
169
170 return file_put_contents($destination, $js);
171 }
172
173 return false;
174 }
175
176 /**
177 * Constructs the require.js file from the provided require.js JSON array.
178 *
179 * @param $json
180 * The require.js JSON configuration.
181 *
182 * @return string
183 * The RequireJS JavaScript configuration.
184 */
185 public function requireJs(array $json = array())
186 {
187 // Encode the array to a JSON array.
188 $js = JsonFile::encode($json);
189
190 // Construct the JavaScript output.
191 $output = <<<EOT
192 var components = $js;
193 if (typeof require !== "undefined" && require.config) {
194 require.config(components);
195 } else {
196 var require = components;
197 }
198 if (typeof exports !== "undefined" && typeof module !== "undefined") {
199 module.exports = components;
200 }
201 EOT;
202
203 return $output;
204 }
205
206 /**
207 * Merges two arrays without switching individual values to arrays.
208 *
209 * @see array_merge()
210 * @see array_merge_recursive()
211 */
212 protected function arrayMergeRecursiveDistinct(array &$array1, array &$array2)
213 {
214 $merged = $array1;
215
216 foreach ($array2 as $key => &$value) {
217 if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
218 $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value);
219 }
220 else {
221 $merged[$key] = $value;
222 }
223 }
224
225 return $merged;
226 }
227 }
228