123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\ObjectManager\Config;
- use Magento\Framework\Serialize\SerializerInterface;
- use Magento\Framework\ObjectManager\ConfigCacheInterface;
- use Magento\Framework\ObjectManager\DefinitionInterface;
- use Magento\Framework\ObjectManager\RelationsInterface;
- class Config implements \Magento\Framework\ObjectManager\ConfigInterface
- {
- /**
- * Config cache
- *
- * @var ConfigCacheInterface
- */
- protected $_cache;
- /**
- * Class definitions
- *
- * @var \Magento\Framework\ObjectManager\DefinitionInterface
- */
- protected $_definitions;
- /**
- * Current cache key
- *
- * @var string
- */
- protected $_currentCacheKey;
- /**
- * Interface preferences
- *
- * @var array
- */
- protected $_preferences = [];
- /**
- * Virtual types
- *
- * @var array
- */
- protected $_virtualTypes = [];
- /**
- * Instance arguments
- *
- * @var array
- */
- protected $_arguments = [];
- /**
- * Type shareability
- *
- * @var array
- */
- protected $_nonShared = [];
- /**
- * List of relations
- *
- * @var RelationsInterface
- */
- protected $_relations;
- /**
- * List of merged arguments
- *
- * @var array
- */
- protected $_mergedArguments;
- /**
- * @var \Magento\Framework\Serialize\SerializerInterface
- */
- private $serializer;
- /**
- * @param RelationsInterface $relations
- * @param DefinitionInterface $definitions
- */
- public function __construct(RelationsInterface $relations = null, DefinitionInterface $definitions = null)
- {
- $this->_relations = $relations ?: new \Magento\Framework\ObjectManager\Relations\Runtime();
- $this->_definitions = $definitions ?: new \Magento\Framework\ObjectManager\Definition\Runtime();
- }
- /**
- * Set class relations
- *
- * @param RelationsInterface $relations
- * @return void
- */
- public function setRelations(RelationsInterface $relations)
- {
- $this->_relations = $relations;
- }
- /**
- * Set cache instance
- *
- * @param ConfigCacheInterface $cache
- * @return void
- */
- public function setCache(ConfigCacheInterface $cache)
- {
- $this->_cache = $cache;
- }
- /**
- * Retrieve list of arguments per type
- *
- * @param string $type
- * @return array
- */
- public function getArguments($type)
- {
- if (isset($this->_mergedArguments[$type])) {
- return $this->_mergedArguments[$type];
- }
- return $this->_collectConfiguration($type);
- }
- /**
- * Check whether type is shared
- *
- * @param string $type
- * @return bool
- */
- public function isShared($type)
- {
- return !isset($this->_nonShared[$type]);
- }
- /**
- * Retrieve instance type
- *
- * @param string $instanceName
- * @return mixed
- */
- public function getInstanceType($instanceName)
- {
- while (isset($this->_virtualTypes[$instanceName])) {
- $instanceName = $this->_virtualTypes[$instanceName];
- }
- return $instanceName;
- }
- /**
- * Retrieve preference for type
- *
- * @param string $type
- * @return string
- * @throws \LogicException
- */
- public function getPreference($type)
- {
- $type = ltrim($type, '\\');
- $preferencePath = [];
- while (isset($this->_preferences[$type])) {
- if (isset($preferencePath[$this->_preferences[$type]])) {
- throw new \LogicException(
- 'Circular type preference: ' .
- $type .
- ' relates to ' .
- $this->_preferences[$type] .
- ' and viceversa.'
- );
- }
- $type = $this->_preferences[$type];
- $preferencePath[$type] = 1;
- }
- return $type;
- }
- /**
- * Collect parent types configuration for requested type
- *
- * @param string $type
- * @return array
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- protected function _collectConfiguration($type)
- {
- if (!isset($this->_mergedArguments[$type])) {
- if (isset($this->_virtualTypes[$type])) {
- $arguments = $this->_collectConfiguration($this->_virtualTypes[$type]);
- } elseif ($this->_relations->has($type)) {
- $relations = $this->_relations->getParents($type);
- $arguments = [];
- foreach ($relations as $relation) {
- if ($relation) {
- $relationArguments = $this->_collectConfiguration($relation);
- if ($relationArguments) {
- $arguments = array_replace($arguments, $relationArguments);
- }
- }
- }
- } else {
- $arguments = [];
- }
- if (isset($this->_arguments[$type])) {
- if ($arguments && count($arguments)) {
- $arguments = array_replace_recursive($arguments, $this->_arguments[$type]);
- } else {
- $arguments = $this->_arguments[$type];
- }
- }
- $this->_mergedArguments[$type] = $arguments;
- return $arguments;
- }
- return $this->_mergedArguments[$type];
- }
- /**
- * Merge configuration
- *
- * @param array $configuration
- * @return void
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- protected function _mergeConfiguration(array $configuration)
- {
- foreach ($configuration as $key => $curConfig) {
- switch ($key) {
- case 'preferences':
- foreach ($curConfig as $for => $to) {
- $this->_preferences[ltrim($for, '\\')] = ltrim($to, '\\');
- }
- break;
- default:
- $key = ltrim($key, '\\');
- if (isset($curConfig['type'])) {
- $this->_virtualTypes[$key] = ltrim($curConfig['type'], '\\');
- }
- if (isset($curConfig['arguments'])) {
- if (!empty($this->_mergedArguments)) {
- $this->_mergedArguments = [];
- }
- if (isset($this->_arguments[$key])) {
- $this->_arguments[$key] = array_replace($this->_arguments[$key], $curConfig['arguments']);
- } else {
- $this->_arguments[$key] = $curConfig['arguments'];
- }
- }
- if (isset($curConfig['shared'])) {
- if (!$curConfig['shared']) {
- $this->_nonShared[$key] = 1;
- } else {
- unset($this->_nonShared[$key]);
- }
- }
- break;
- }
- }
- }
- /**
- * Extend configuration
- *
- * @param array $configuration
- * @return void
- */
- public function extend(array $configuration)
- {
- if ($this->_cache) {
- if (!$this->_currentCacheKey) {
- $this->_currentCacheKey = md5(
- $this->getSerializer()->serialize(
- [$this->_arguments, $this->_nonShared, $this->_preferences, $this->_virtualTypes]
- )
- );
- }
- $key = md5($this->_currentCacheKey . $this->getSerializer()->serialize($configuration));
- $cached = $this->_cache->get($key);
- if ($cached) {
- list(
- $this->_arguments,
- $this->_nonShared,
- $this->_preferences,
- $this->_virtualTypes,
- $this->_mergedArguments
- ) = $cached;
- } else {
- $this->_mergeConfiguration($configuration);
- if (!$this->_mergedArguments) {
- foreach ($this->_definitions->getClasses() as $class) {
- $this->_collectConfiguration($class);
- }
- }
- $this->_cache->save(
- [
- $this->_arguments,
- $this->_nonShared,
- $this->_preferences,
- $this->_virtualTypes,
- $this->_mergedArguments,
- ],
- $key
- );
- }
- $this->_currentCacheKey = $key;
- } else {
- $this->_mergeConfiguration($configuration);
- }
- }
- /**
- * Returns list of virtual types
- *
- * @return array
- */
- public function getVirtualTypes()
- {
- return $this->_virtualTypes;
- }
- /**
- * Returns list on preferences
- *
- * @return array
- */
- public function getPreferences()
- {
- return $this->_preferences;
- }
- /**
- * Get serializer
- *
- * @return \Magento\Framework\Serialize\SerializerInterface
- * @deprecated 101.0.0
- */
- private function getSerializer()
- {
- if ($this->serializer === null) {
- $this->serializer = \Magento\Framework\App\ObjectManager::getInstance()
- ->get(SerializerInterface::class);
- }
- return $this->serializer;
- }
- }
|