ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
RequireJsProcess.php
Go to the documentation of this file.
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
13
15use Composer\Config;
16use Composer\Json\JsonFile;
19
24{
28 protected $baseUrl = 'components';
29
33 public function init()
34 {
35 $output = parent::init();
36 if ($this->config->has('component-baseurl')) {
37 $this->baseUrl = $this->config->get('component-baseurl');
38 }
39
40 return $output;
41 }
42
46 public function process()
47 {
48 // Construct the require.js and stick it in the destination.
49 $json = $this->requireJson($this->packages, $this->config);
50 $requireConfig = $this->requireJs($json);
51
52 // Attempt to write the require.config.js file.
53 $destination = $this->componentDir . '/require.config.js';
54 $this->fs->ensureDirectoryExists(dirname($destination));
55 if (file_put_contents($destination, $requireConfig) === FALSE) {
56 $this->io->write('<error>Error writing require.config.js</error>');
57
58 return false;
59 }
60
61 // Read in require.js to prepare the final require.js.
62 if (!file_exists(dirname(__DIR__) . '/Resources/require.js')) {
63 $this->io->write('<error>Error reading in require.js</error>');
64
65 return false;
66 }
67
68 $assets = $this->newAssetCollection();
69 $assets->add(new FileAsset(dirname(__DIR__) . '/Resources/require.js'));
70 $assets->add(new StringAsset($requireConfig));
71
72 // Append the config to the require.js and write it.
73 if (file_put_contents($this->componentDir . '/require.js', $assets->dump()) === FALSE) {
74 $this->io->write('<error>Error writing require.js to the components directory</error>');
75
76 return false;
77 }
78
79 return null;
80 }
81
91 public function requireJson(array $packages)
92 {
93 $json = array();
94
95 // Construct the packages configuration.
96 foreach ($packages as $package) {
97 // Retrieve information from the extra options.
98 $extra = isset($package['extra']) ? $package['extra'] : array();
99 $options = isset($extra['component']) ? $extra['component'] : array();
100
101 // Construct the base details.
102 $name = $this->getComponentName($package['name'], $extra);
103 $component = array(
104 'name' => $name,
105 );
106
107 // Build the "main" directive.
108 $scripts = isset($options['scripts']) ? $options['scripts'] : array();
109 if (!empty($scripts)) {
110 // Put all scripts into a build.js file.
111 $result = $this->aggregateScripts($package, $scripts, $name.DIRECTORY_SEPARATOR.$name.'-built.js');
112 if ($result) {
113 // If the aggregation was successful, add the script to the
114 // packages array.
115 $component['main'] = $name.'-built.js';
116
117 // Add the component to the packages array.
118 $json['packages'][] = $component;
119 }
120 }
121
122 // Add the shim definition for the package.
123 $shim = isset($options['shim']) ? $options['shim'] : array();
124 if (!empty($shim)) {
125 $json['shim'][$name] = $shim;
126 }
127
128 // Add the config definition for the package.
129 $packageConfig = isset($options['config']) ? $options['config'] : array();
130 if (!empty($packageConfig)) {
131 $json['config'][$name] = $packageConfig;
132 }
133 }
134
135 // Provide the baseUrl.
136 $json['baseUrl'] = $this->baseUrl;
137
138 // Merge in configuration options from the root.
139 if ($this->config->has('component')) {
140 $config = $this->config->get('component');
141 if (isset($config) && is_array($config)) {
142 // Use a recursive, distict array merge.
143 $json = $this->arrayMergeRecursiveDistinct($json, $config);
144 }
145 }
146
147 return $json;
148 }
149
158 public function aggregateScripts($package, array $scripts, $file)
159 {
160 $assets = $this->newAssetCollection();
161
162 foreach ($scripts as $script) {
163 // Collect each candidate from a glob file search.
164 $path = $this->getVendorDir($package).DIRECTORY_SEPARATOR.$script;
165 $matches = $this->fs->recursiveGlobFiles($path);
166 foreach ($matches as $match) {
167 $assets->add(new FileAsset($match));
168 }
169 }
170 $js = $assets->dump();
171
172 // Write the file if there are any JavaScript assets.
173 if (!empty($js)) {
174 $destination = $this->componentDir.DIRECTORY_SEPARATOR.$file;
175 $this->fs->ensureDirectoryExists(dirname($destination));
176
177 return file_put_contents($destination, $js);
178 }
179
180 return false;
181 }
182
192 public function requireJs(array $json = array())
193 {
194 // Encode the array to a JSON array.
195 $js = JsonFile::encode($json);
196
197 // Construct the JavaScript output.
198 $output = <<<EOT
199var components = $js;
200if (typeof require !== "undefined" && require.config) {
201 require.config(components);
202} else {
203 var require = components;
204}
205if (typeof exports !== "undefined" && typeof module !== "undefined") {
206 module.exports = components;
207}
208EOT;
209
210 return $output;
211 }
212
223 protected function arrayMergeRecursiveDistinct(array &$array1, array &$array2)
224 {
225 $merged = $array1;
226
227 foreach ($array2 as $key => &$value) {
228 if(is_numeric($key)){
229 $merged[] = $value;
230 } else {
231 if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
232 $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value);
233 }
234 else {
235 $merged[$key] = $value;
236 }
237 }
238 }
239
240 return $merged;
241 }
242
246 protected function newAssetCollection()
247 {
248 // Aggregate all the assets into one file.
249 $assets = new AssetCollection();
250 if ($this->config->has('component-scriptFilters')) {
251 $filters = $this->config->get('component-scriptFilters');
252 if (isset($filters) && is_array($filters)) {
253 foreach ($filters as $filter => $filterParams) {
254 $reflection = new \ReflectionClass($filter);
256 $filter = $reflection->newInstanceArgs($filterParams);
257 $assets->ensureFilter($filter);
258 }
259 }
260 }
261
262 return $assets;
263 }
264}
$result
$path
Definition: aliased.php:25
A collection of assets.
Represents an asset loaded from a file.
Definition: FileAsset.php:23
Represents a string asset.
Definition: StringAsset.php:22
An exception for terminatinating execution or to throw for unit testing.
The base Process type.
Definition: Process.php:27
getComponentName($prettyName, array $extra=array())
Retrieves the component name for the component.
Definition: Process.php:154
getVendorDir(array $package)
Retrieves the given package's vendor directory, where it's installed.
Definition: Process.php:199
Builds the require.js configuration.
init()
{Initialize the process before its run.boolean Whether or not the process should continue after initi...
$baseUrl
The base URL for the require.js configuration.
process()
{{Called when running through the process.boolean True or false depending on whether the process was ...
arrayMergeRecursiveDistinct(array &$array1, array &$array2)
Merges two arrays without changing string array keys.
aggregateScripts($package, array $scripts, $file)
Concatenate all scripts together into one destination file.
requireJson(array $packages)
Creates a require.js configuration from an array of packages.
requireJs(array $json=array())
Constructs the require.js file from the provided require.js JSON array.
$js
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
if(!is_array($argv)) $options