123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Deploy\Package\Bundle;
- use Magento\Deploy\Config\BundleConfig;
- use Magento\Deploy\Package\BundleInterface;
- use Magento\Framework\Filesystem;
- use \Magento\Framework\Filesystem\File\WriteInterface;
- use Magento\Framework\App\Filesystem\DirectoryList;
- use Magento\Framework\View\Asset\Minification;
- /**
- * RequireJs static files bundle object
- *
- * All files added will be bundled to multiple bundle files compatible with RequireJS AMD format
- */
- class RequireJs implements BundleInterface
- {
- /**
- * Static files Bundling configuration class
- *
- * @var BundleConfig
- */
- private $bundleConfig;
- /**
- * Helper class for static files minification related processes
- *
- * @var Minification
- */
- private $minification;
- /**
- * Static content directory writable interface
- *
- * @var WriteInterface
- */
- private $staticDir;
- /**
- * Package area
- *
- * @var string
- */
- private $area;
- /**
- * Package theme
- *
- * @var string
- */
- private $theme;
- /**
- * Package locale
- *
- * @var string
- */
- private $locale;
- /**
- * Bundle content pools
- *
- * @var string[]
- */
- private $contentPools = [
- 'js' => 'jsbuild',
- 'html' => 'text'
- ];
- /**
- * Files to be bundled
- *
- * @var array[]
- */
- private $files = [
- 'jsbuild' => [],
- 'text' => []
- ];
- /**
- * Files content cache
- *
- * @var string[]
- */
- private $fileContent = [];
- /**
- * Incremental index of bundle file
- *
- * Chosen bundling strategy may result in creating multiple bundle files instead of one
- *
- * @var int
- */
- private $bundleFileIndex = 0;
- /**
- * Relative path to directory where bundle files should be created
- *
- * @var string
- */
- private $pathToBundleDir;
- /**
- * Bundle constructor
- *
- * @param Filesystem $filesystem
- * @param BundleConfig $bundleConfig
- * @param Minification $minification
- * @param string $area
- * @param string $theme
- * @param string $locale
- * @param array $contentPools
- */
- public function __construct(
- Filesystem $filesystem,
- BundleConfig $bundleConfig,
- Minification $minification,
- $area,
- $theme,
- $locale,
- array $contentPools = []
- ) {
- $this->filesystem = $filesystem;
- $this->bundleConfig = $bundleConfig;
- $this->minification = $minification;
- $this->staticDir = $filesystem->getDirectoryWrite(DirectoryList::STATIC_VIEW);
- $this->area = $area;
- $this->theme = $theme;
- $this->locale = $locale;
- $this->contentPools = array_merge($this->contentPools, $contentPools);
- $this->pathToBundleDir = $this->area . '/' . $this->theme . '/' . $this->locale . '/' . self::BUNDLE_JS_DIR;
- }
- /**
- * @inheritdoc
- */
- public function addFile($filePath, $sourcePath, $contentType)
- {
- // all unknown content types designated to "text" pool
- $contentPoolName = isset($this->contentPools[$contentType]) ? $this->contentPools[$contentType] : 'text';
- $this->files[$contentPoolName][$filePath] = $sourcePath;
- return true;
- }
- /**
- * @inheritdoc
- */
- public function flush()
- {
- $this->bundleFileIndex = 0;
- $bundleFile = null;
- foreach ($this->files as $contentPoolName => $files) {
- if (empty($files)) {
- continue;
- }
- $content = [];
- $freeSpace = $this->getBundleFileMaxSize();
- $bundleFile = $this->startNewBundleFile($contentPoolName);
- foreach ($files as $filePath => $sourcePath) {
- $fileContent = $this->getFileContent($sourcePath);
- $size = mb_strlen($fileContent, 'utf-8') / 1024;
- if ($freeSpace > $size) {
- $freeSpace -= $size;
- $content[$this->minification->addMinifiedSign($filePath)] = $fileContent;
- } else {
- $this->endBundleFile($bundleFile, $content);
- $freeSpace = $this->getBundleFileMaxSize();
- $freeSpace -= $size;
- $content = [
- $this->minification->addMinifiedSign($filePath) => $fileContent
- ];
- $bundleFile = $this->startNewBundleFile($contentPoolName);
- }
- }
- $this->endBundleFile($bundleFile, $content);
- }
- if ($bundleFile) {
- $bundleFile->write($this->getInitJs());
- }
- $this->files = [];
- }
- /**
- * @inheritdoc
- */
- public function clear()
- {
- $this->staticDir->delete($this->pathToBundleDir);
- }
- /**
- * Create new bundle file and write beginning content to it
- *
- * @param string $contentPoolName
- * @return WriteInterface
- */
- private function startNewBundleFile($contentPoolName)
- {
- $bundleFile = $this->staticDir->openFile(
- $this->minification->addMinifiedSign($this->pathToBundleDir . '/bundle' . $this->bundleFileIndex . '.js')
- );
- $bundleFile->write("require.config({\"config\": {\n");
- $bundleFile->write(" \"{$contentPoolName}\":");
- ++$this->bundleFileIndex;
- return $bundleFile;
- }
- /**
- * Write ending content to bundle file
- *
- * @param WriteInterface $bundleFile
- * @param array $contents
- * @return bool true on success
- */
- private function endBundleFile(WriteInterface $bundleFile, array $contents)
- {
- if ($contents) {
- $content = json_encode($contents, JSON_UNESCAPED_SLASHES);
- $bundleFile->write("{$content}\n");
- } else {
- $bundleFile->write("{}\n");
- }
- $bundleFile->write("}});\n");
- return true;
- }
- /**
- * Get content of static file
- *
- * @param string $sourcePath
- * @return string
- */
- private function getFileContent($sourcePath)
- {
- if (!isset($this->fileContent[$sourcePath])) {
- $content = $this->staticDir->readFile($this->minification->addMinifiedSign($sourcePath));
- if (mb_detect_encoding($content) !== "UTF-8") {
- $content = mb_convert_encoding($content, "UTF-8");
- }
- $this->fileContent[$sourcePath] = $content;
- }
- return $this->fileContent[$sourcePath];
- }
- /**
- * Get max size of bundle files (in KB)
- *
- * @return int
- */
- private function getBundleFileMaxSize()
- {
- return $this->bundleConfig->getBundleFileMaxSize($this->area, $this->theme);
- }
- /**
- * Bundle initialization script content (this must be added to the latest bundle file at the very end)
- *
- * @return string
- */
- private function getInitJs()
- {
- return "require.config({\n" .
- " bundles: {\n" .
- " 'mage/requirejs/static': [\n" .
- " 'jsbuild',\n" .
- " 'buildTools',\n" .
- " 'text',\n" .
- " 'statistician'\n" .
- " ]\n" .
- " },\n" .
- " deps: [\n" .
- " 'jsbuild'\n" .
- " ]\n" .
- "});\n";
- }
- }
|