Skip to content

Commit

Permalink
Write intercepted mapping to generated/metadata during compilation
Browse files Browse the repository at this point in the history
This prevents the intercepted cache from being cleared following compilation.
The mapping is stored in the frontend cache when the mapping metadata file is
not present, ie developer, default modes.

Fixes #17680
  • Loading branch information
pmclain committed Oct 25, 2018
1 parent 5916c5a commit 86a30b6
Showing 1 changed file with 89 additions and 22 deletions.
111 changes: 89 additions & 22 deletions lib/internal/Magento/Framework/Interception/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ class Config implements \Magento\Framework\Interception\ConfigInterface
*/
private $serializer;

/**
* @var \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem
*/
private $configWriter;

/**
* @var \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled
*/
private $compiledLoader;

/**
* Config constructor
*
Expand All @@ -89,6 +99,8 @@ class Config implements \Magento\Framework\Interception\ConfigInterface
* @param \Magento\Framework\ObjectManager\DefinitionInterface $classDefinitions
* @param string $cacheId
* @param SerializerInterface|null $serializer
* @param \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem $configWriter
* @param \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader
*/
public function __construct(
\Magento\Framework\Config\ReaderInterface $reader,
Expand All @@ -98,7 +110,9 @@ public function __construct(
\Magento\Framework\Interception\ObjectManager\ConfigInterface $omConfig,
\Magento\Framework\ObjectManager\DefinitionInterface $classDefinitions,
$cacheId = 'interception',
SerializerInterface $serializer = null
SerializerInterface $serializer = null,
\Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem $configWriter = null,
\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader = null
) {
$this->_omConfig = $omConfig;
$this->_relations = $relations;
Expand All @@ -109,11 +123,15 @@ public function __construct(
$this->_scopeList = $scopeList;
$this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(Serialize::class);
$intercepted = $this->_cache->load($this->_cacheId);
$this->configWriter = $configWriter ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem::class);
$this->compiledLoader = $compiledLoader ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class);
$intercepted = $this->loadIntercepted();
if ($intercepted !== false) {
$this->_intercepted = $this->serializer->unserialize($intercepted);
$this->_intercepted = $intercepted;
} else {
$this->initialize($this->_classDefinitions->getClasses());
$this->initializeUncompiled($this->_classDefinitions->getClasses());
}
}

Expand All @@ -125,24 +143,9 @@ public function __construct(
*/
public function initialize($classDefinitions = [])
{
$this->_cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_TAG, [$this->_cacheId]);
$config = [];
foreach ($this->_scopeList->getAllScopes() as $scope) {
$config = array_replace_recursive($config, $this->_reader->read($scope));
}
unset($config['preferences']);
foreach ($config as $typeName => $typeConfig) {
if (!empty($typeConfig['plugins'])) {
$this->_intercepted[ltrim($typeName, '\\')] = true;
}
}
foreach ($config as $typeName => $typeConfig) {
$this->hasPlugins($typeName);
}
foreach ($classDefinitions as $class) {
$this->hasPlugins($class);
}
$this->_cache->save($this->serializer->serialize($this->_intercepted), $this->_cacheId);
$this->generateIntercepted($classDefinitions);

$this->configWriter->write($this->_cacheId, $this->_intercepted);
}

/**
Expand Down Expand Up @@ -188,4 +191,68 @@ public function hasPlugins($type)
}
return $this->_inheritInterception($type);
}

/**
* Write interception config to cache
*
* @param array $classDefinitions
*/
private function initializeUncompiled($classDefinitions = [])
{
$this->_cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_TAG, [$this->_cacheId]);

$this->generateIntercepted($classDefinitions);

$this->_cache->save($this->serializer->serialize($this->_intercepted), $this->_cacheId);
}

/**
* Generate intercepted array to store in compiled metadata or frontend cache
*
* @param $classDefinitions
*/
private function generateIntercepted($classDefinitions)
{
$config = [];
foreach ($this->_scopeList->getAllScopes() as $scope) {
$config = array_replace_recursive($config, $this->_reader->read($scope));
}
unset($config['preferences']);
foreach ($config as $typeName => $typeConfig) {
if (!empty($typeConfig['plugins'])) {
$this->_intercepted[ltrim($typeName, '\\')] = true;
}
}
foreach ($config as $typeName => $typeConfig) {
$this->hasPlugins($typeName);
}
foreach ($classDefinitions as $class) {
$this->hasPlugins($class);
}
}

/**
* Load the interception config from cache
*
* @return array|false
*/
private function loadIntercepted()
{
if ($this->isCompiled()) {
return $this->compiledLoader->load($this->_cacheId);
}

$intercepted = $this->_cache->load($this->_cacheId);
return $intercepted ? $this->serializer->unserialize($intercepted) : false;
}

/**
* Check for the compiled config with the generated metadata
*
* @return bool
*/
private function isCompiled()
{
return file_exists(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::getFilePath($this->_cacheId));
}
}

0 comments on commit 86a30b6

Please sign in to comment.