config->has('component-baseurl')) { $this->baseUrl = $this->config->get('component-baseurl'); } return $output; } /** * {@inheritdoc} */ public function process() { // Construct the require.js and stick it in the destination. $json = $this->requireJson($this->packages, $this->config); $requireConfig = $this->requireJs($json); // Attempt to write the require.config.js file. $destination = $this->componentDir . '/require.config.js'; $this->fs->ensureDirectoryExists(dirname($destination)); if (file_put_contents($destination, $requireConfig) === FALSE) { $this->io->write('Error writing require.config.js'); return false; } // Read in require.js to prepare the final require.js. if (!file_exists(dirname(__DIR__) . '/Resources/require.js')) { $this->io->write('Error reading in require.js'); return false; } $assets = $this->newAssetCollection(); $assets->add(new FileAsset(dirname(__DIR__) . '/Resources/require.js')); $assets->add(new StringAsset($requireConfig)); // Append the config to the require.js and write it. if (file_put_contents($this->componentDir . '/require.js', $assets->dump()) === FALSE) { $this->io->write('Error writing require.js to the components directory'); return false; } return null; } /** * Creates a require.js configuration from an array of packages. * * @param $packages * An array of packages from the composer.lock file. * * @return array * The built JSON array. */ public function requireJson(array $packages) { $json = array(); // Construct the packages configuration. foreach ($packages as $package) { // Retrieve information from the extra options. $extra = isset($package['extra']) ? $package['extra'] : array(); $options = isset($extra['component']) ? $extra['component'] : array(); // Construct the base details. $name = $this->getComponentName($package['name'], $extra); $component = array( 'name' => $name, ); // Build the "main" directive. $scripts = isset($options['scripts']) ? $options['scripts'] : array(); if (!empty($scripts)) { // Put all scripts into a build.js file. $result = $this->aggregateScripts($package, $scripts, $name.DIRECTORY_SEPARATOR.$name.'-built.js'); if ($result) { // If the aggregation was successful, add the script to the // packages array. $component['main'] = $name.'-built.js'; // Add the component to the packages array. $json['packages'][] = $component; } } // Add the shim definition for the package. $shim = isset($options['shim']) ? $options['shim'] : array(); if (!empty($shim)) { $json['shim'][$name] = $shim; } // Add the config definition for the package. $packageConfig = isset($options['config']) ? $options['config'] : array(); if (!empty($packageConfig)) { $json['config'][$name] = $packageConfig; } } // Provide the baseUrl. $json['baseUrl'] = $this->baseUrl; // Merge in configuration options from the root. if ($this->config->has('component')) { $config = $this->config->get('component'); if (isset($config) && is_array($config)) { // Use a recursive, distict array merge. $json = $this->arrayMergeRecursiveDistinct($json, $config); } } return $json; } /** * Concatenate all scripts together into one destination file. * * @param array $package * @param array $scripts * @param string $file * @return bool */ public function aggregateScripts($package, array $scripts, $file) { $assets = $this->newAssetCollection(); foreach ($scripts as $script) { // Collect each candidate from a glob file search. $path = $this->getVendorDir($package).DIRECTORY_SEPARATOR.$script; $matches = $this->fs->recursiveGlobFiles($path); foreach ($matches as $match) { $assets->add(new FileAsset($match)); } } $js = $assets->dump(); // Write the file if there are any JavaScript assets. if (!empty($js)) { $destination = $this->componentDir.DIRECTORY_SEPARATOR.$file; $this->fs->ensureDirectoryExists(dirname($destination)); return file_put_contents($destination, $js); } return false; } /** * Constructs the require.js file from the provided require.js JSON array. * * @param $json * The require.js JSON configuration. * * @return string * The RequireJS JavaScript configuration. */ public function requireJs(array $json = array()) { // Encode the array to a JSON array. $js = JsonFile::encode($json); // Construct the JavaScript output. $output = << &$value) { if(is_numeric($key)){ $merged[] = $value; } else { if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) { $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value); } else { $merged[$key] = $value; } } } return $merged; } /** * @return AssetCollection */ protected function newAssetCollection() { // Aggregate all the assets into one file. $assets = new AssetCollection(); if ($this->config->has('component-scriptFilters')) { $filters = $this->config->get('component-scriptFilters'); if (isset($filters) && is_array($filters)) { foreach ($filters as $filter => $filterParams) { $reflection = new \ReflectionClass($filter); /** @var \Assetic\Filter\FilterInterface $filter */ $filter = $reflection->newInstanceArgs($filterParams); $assets->ensureFilter($filter); } } } return $assets; } }