123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\View\Asset;
- use Magento\Framework\App\ObjectManager;
- /**
- * \Iterator that aggregates one or more assets and provides a single public file with equivalent behavior
- */
- class Merged implements \Iterator
- {
- /**
- * Directory for dynamically generated public view files, relative to STATIC_VIEW
- */
- const CACHE_VIEW_REL = '_cache';
- /**
- * @var \Psr\Log\LoggerInterface
- */
- protected $logger;
- /**
- * @var MergeStrategyInterface
- */
- protected $mergeStrategy;
- /**
- * @var \Magento\Framework\View\Asset\Repository
- */
- private $assetRepo;
- /**
- * @var MergeableInterface[]
- */
- protected $assets;
- /**
- * @var string
- */
- protected $contentType;
- /**
- * @var \Magento\Framework\App\View\Deployment\Version\StorageInterface
- */
- private $versionStorage;
- /**
- * @var bool
- */
- protected $isInitialized = false;
- /**
- * Merged constructor.
- *
- * @param \Psr\Log\LoggerInterface $logger
- * @param MergeStrategyInterface $mergeStrategy
- * @param \Magento\Framework\View\Asset\Repository $assetRepo
- * @param MergeableInterface[] $assets
- * @param \Magento\Framework\App\View\Deployment\Version\StorageInterface $versionStorage
- * @throws \InvalidArgumentException
- */
- public function __construct(
- \Psr\Log\LoggerInterface $logger,
- MergeStrategyInterface $mergeStrategy,
- \Magento\Framework\View\Asset\Repository $assetRepo,
- array $assets,
- \Magento\Framework\App\View\Deployment\Version\StorageInterface $versionStorage = null
- ) {
- $this->logger = $logger;
- $this->mergeStrategy = $mergeStrategy;
- $this->assetRepo = $assetRepo;
- $this->versionStorage = $versionStorage ?: ObjectManager::getInstance()->get(
- \Magento\Framework\App\View\Deployment\Version\StorageInterface::class
- );
- if (!$assets) {
- throw new \InvalidArgumentException('At least one asset has to be passed for merging.');
- }
- /** @var $asset MergeableInterface */
- foreach ($assets as $asset) {
- if (!($asset instanceof MergeableInterface)) {
- throw new \InvalidArgumentException(
- 'Asset has to implement \Magento\Framework\View\Asset\MergeableInterface.'
- );
- }
- if (!$this->contentType) {
- $this->contentType = $asset->getContentType();
- } elseif ($asset->getContentType() != $this->contentType) {
- throw new \InvalidArgumentException(
- "Content type '{$asset->getContentType()}' cannot be merged with '{$this->contentType}'."
- );
- }
- }
- $this->assets = $assets;
- }
- /**
- * Attempt to merge assets, falling back to original non-merged ones, if merging fails
- *
- * @return void
- */
- protected function initialize()
- {
- if (!$this->isInitialized) {
- $this->isInitialized = true;
- try {
- $mergedAsset = $this->createMergedAsset($this->assets);
- $this->mergeStrategy->merge($this->assets, $mergedAsset);
- $this->assets = [$mergedAsset];
- } catch (\Exception $e) {
- $this->logger->critical($e);
- }
- }
- }
- /**
- * Create an asset object for merged file
- *
- * @param array $assets
- * @return MergeableInterface
- */
- private function createMergedAsset(array $assets)
- {
- $paths = [];
- /** @var MergeableInterface $asset */
- foreach ($assets as $asset) {
- $paths[] = $asset->getPath();
- }
- $paths = array_unique($paths);
- $version = $this->versionStorage->load();
- if ($version) {
- $paths[] = $version;
- }
- $filePath = md5(implode('|', $paths)) . '.' . $this->contentType;
- return $this->assetRepo->createArbitrary($filePath, self::getRelativeDir());
- }
- /**
- * {@inheritdoc}
- *
- * @return AssetInterface
- */
- public function current()
- {
- $this->initialize();
- return current($this->assets);
- }
- /**
- * {@inheritdoc}
- */
- public function key()
- {
- $this->initialize();
- return key($this->assets);
- }
- /**
- * {@inheritdoc}
- */
- public function next()
- {
- $this->initialize();
- next($this->assets);
- }
- /**
- * {@inheritdoc}
- */
- public function rewind()
- {
- $this->initialize();
- reset($this->assets);
- }
- /**
- * {@inheritdoc}
- */
- public function valid()
- {
- $this->initialize();
- return (bool)current($this->assets);
- }
- /**
- * Returns directory for storing merged files relative to STATIC_VIEW
- *
- * @return string
- */
- public static function getRelativeDir()
- {
- return self::CACHE_VIEW_REL . '/merged';
- }
- }
|