Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
PluginList.php
Go to the documentation of this file.
1 <?php
7 
13 use Magento\Framework\Interception\PluginListInterface as InterceptionPluginList;
20 
26 class PluginList extends Scoped implements InterceptionPluginList
27 {
33  protected $_inherited = [];
34 
40  protected $_processed;
41 
47  protected $_omConfig;
48 
54  protected $_relations;
55 
61  protected $_definitions;
62 
68  protected $_classDefinitions;
69 
73  protected $_objectManager;
74 
78  protected $_pluginInstances = [];
79 
83  private $logger;
84 
88  private $serializer;
89 
106  public function __construct(
107  ReaderInterface $reader,
108  ScopeInterface $configScope,
109  CacheInterface $cache,
110  RelationsInterface $relations,
111  ConfigInterface $omConfig,
112  DefinitionInterface $definitions,
114  ClassDefinitions $classDefinitions,
115  array $scopePriorityScheme = ['global'],
116  $cacheId = 'plugins',
117  SerializerInterface $serializer = null
118  ) {
119  $this->serializer = $serializer ?: $objectManager->get(Serialize::class);
120  parent::__construct($reader, $configScope, $cache, $cacheId, $this->serializer);
121  $this->_omConfig = $omConfig;
122  $this->_relations = $relations;
123  $this->_definitions = $definitions;
124  $this->_classDefinitions = $classDefinitions;
125  $this->_scopePriorityScheme = $scopePriorityScheme;
126  $this->_objectManager = $objectManager;
127  }
128 
138  protected function _inheritPlugins($type)
139  {
140  $type = ltrim($type, '\\');
141  if (!array_key_exists($type, $this->_inherited)) {
142  $realType = $this->_omConfig->getOriginalInstanceType($type);
143 
144  if ($realType !== $type) {
145  $plugins = $this->_inheritPlugins($realType);
146  } elseif ($this->_relations->has($type)) {
147  $relations = $this->_relations->getParents($type);
148  $plugins = [];
149  foreach ($relations as $relation) {
150  if ($relation) {
151  $relationPlugins = $this->_inheritPlugins($relation);
152  if ($relationPlugins) {
153  $plugins = array_replace_recursive($plugins, $relationPlugins);
154  }
155  }
156  }
157  } else {
158  $plugins = [];
159  }
160  if (isset($this->_data[$type])) {
161  if (!$plugins) {
162  $plugins = $this->_data[$type];
163  } else {
164  $plugins = array_replace_recursive($plugins, $this->_data[$type]);
165  }
166  }
167  $this->_inherited[$type] = null;
168  if (is_array($plugins) && count($plugins)) {
169  $this->filterPlugins($plugins);
170  uasort($plugins, [$this, '_sort']);
171  $this->trimInstanceStartingBackslash($plugins);
172  $this->_inherited[$type] = $plugins;
173  $lastPerMethod = [];
174  foreach ($plugins as $key => $plugin) {
175  // skip disabled plugins
176  if (isset($plugin['disabled']) && $plugin['disabled']) {
177  unset($plugins[$key]);
178  continue;
179  }
180  $pluginType = $this->_omConfig->getOriginalInstanceType($plugin['instance']);
181  if (!class_exists($pluginType)) {
182  throw new \InvalidArgumentException('Plugin class ' . $pluginType . ' doesn\'t exist');
183  }
184  foreach ($this->_definitions->getMethodList($pluginType) as $pluginMethod => $methodTypes) {
185  $current = isset($lastPerMethod[$pluginMethod]) ? $lastPerMethod[$pluginMethod] : '__self';
186  $currentKey = $type . '_' . $pluginMethod . '_' . $current;
187  if ($methodTypes & DefinitionInterface::LISTENER_AROUND) {
188  $this->_processed[$currentKey][DefinitionInterface::LISTENER_AROUND] = $key;
189  $lastPerMethod[$pluginMethod] = $key;
190  }
191  if ($methodTypes & DefinitionInterface::LISTENER_BEFORE) {
192  $this->_processed[$currentKey][DefinitionInterface::LISTENER_BEFORE][] = $key;
193  }
194  if ($methodTypes & DefinitionInterface::LISTENER_AFTER) {
195  $this->_processed[$currentKey][DefinitionInterface::LISTENER_AFTER][] = $key;
196  }
197  }
198  }
199  }
200  return $plugins;
201  }
202  return $this->_inherited[$type];
203  }
204 
211  private function trimInstanceStartingBackslash(&$plugins)
212  {
213  foreach ($plugins as &$plugin) {
214  $plugin['instance'] = ltrim($plugin['instance'], '\\');
215  }
216  }
217 
225  protected function _sort($itemA, $itemB)
226  {
227  if (isset($itemA['sortOrder'])) {
228  if (isset($itemB['sortOrder'])) {
229  return $itemA['sortOrder'] - $itemB['sortOrder'];
230  }
231  return $itemA['sortOrder'];
232  } elseif (isset($itemB['sortOrder'])) {
233  return (0 - (int)$itemB['sortOrder']);
234  } else {
235  return 0;
236  }
237  }
238 
246  public function getPlugin($type, $code)
247  {
248  if (!isset($this->_pluginInstances[$type][$code])) {
249  $this->_pluginInstances[$type][$code] = $this->_objectManager->get(
250  $this->_inherited[$type][$code]['instance']
251  );
252  }
253  return $this->_pluginInstances[$type][$code];
254  }
255 
264  public function getNext($type, $method, $code = '__self')
265  {
266  $this->_loadScopedData();
267  if (!isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) {
268  $this->_inheritPlugins($type);
269  }
270  $key = $type . '_' . lcfirst($method) . '_' . $code;
271  return $this->_processed[$key] ?? null;
272  }
273 
280  protected function _loadScopedData()
281  {
282  $scope = $this->_configScope->getCurrentScope();
283  if (false == isset($this->_loadedScopes[$scope])) {
284  if (false == in_array($scope, $this->_scopePriorityScheme)) {
285  $this->_scopePriorityScheme[] = $scope;
286  }
287  $cacheId = implode('|', $this->_scopePriorityScheme) . "|" . $this->_cacheId;
288  $data = $this->_cache->load($cacheId);
289  if ($data) {
290  list($this->_data, $this->_inherited, $this->_processed) = $this->serializer->unserialize($data);
291  foreach ($this->_scopePriorityScheme as $scopeCode) {
292  $this->_loadedScopes[$scopeCode] = true;
293  }
294  } else {
295  $virtualTypes = [];
296  foreach ($this->_scopePriorityScheme as $scopeCode) {
297  if (false == isset($this->_loadedScopes[$scopeCode])) {
298  $data = $this->_reader->read($scopeCode) ?: [];
299  unset($data['preferences']);
300  if (count($data) > 0) {
301  $this->_inherited = [];
302  $this->_processed = [];
303  $this->merge($data);
304  foreach ($data as $class => $config) {
305  if (isset($config['type'])) {
306  $virtualTypes[] = $class;
307  }
308  }
309  }
310  $this->_loadedScopes[$scopeCode] = true;
311  }
312  if ($this->isCurrentScope($scopeCode)) {
313  break;
314  }
315  }
316  foreach ($virtualTypes as $class) {
317  $this->_inheritPlugins($class);
318  }
319  foreach ($this->getClassDefinitions() as $class) {
320  $this->_inheritPlugins($class);
321  }
322  $this->_cache->save(
323  $this->serializer->serialize([$this->_data, $this->_inherited, $this->_processed]),
324  $cacheId
325  );
326  }
327  $this->_pluginInstances = [];
328  }
329  }
330 
337  protected function isCurrentScope($scopeCode)
338  {
339  return $this->_configScope->getCurrentScope() == $scopeCode;
340  }
341 
347  protected function getClassDefinitions()
348  {
349  return $this->_classDefinitions->getClasses();
350  }
351 
358  public function merge(array $config)
359  {
360  foreach ($config as $type => $typeConfig) {
361  if (isset($typeConfig['plugins'])) {
362  $type = ltrim($type, '\\');
363  if (isset($this->_data[$type])) {
364  $this->_data[$type] = array_replace_recursive($this->_data[$type], $typeConfig['plugins']);
365  } else {
366  $this->_data[$type] = $typeConfig['plugins'];
367  }
368  }
369  }
370  }
371 
378  private function filterPlugins(array &$plugins)
379  {
380  foreach ($plugins as $name => $plugin) {
381  if (empty($plugin['instance'])) {
382  unset($plugins[$name]);
383  $this->getLogger()->info("Reference to undeclared plugin with name '{$name}'.");
384  }
385  }
386  }
387 
394  private function getLogger()
395  {
396  if ($this->logger === null) {
397  $this->logger = $this->_objectManager->get(\Psr\Log\LoggerInterface::class);
398  }
399  return $this->logger;
400  }
401 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$objectManager
Definition: bootstrap.php:17
$config
Definition: fraud_order.php:17
$type
Definition: item.phtml:13
$_option $_optionId $class
Definition: date.phtml:13
__construct(ReaderInterface $reader, ScopeInterface $configScope, CacheInterface $cache, RelationsInterface $relations, ConfigInterface $omConfig, DefinitionInterface $definitions, ObjectManagerInterface $objectManager, ClassDefinitions $classDefinitions, array $scopePriorityScheme=['global'], $cacheId='plugins', SerializerInterface $serializer=null)
Definition: PluginList.php:106
$method
Definition: info.phtml:13
$code
Definition: info.phtml:12
if(!isset($_GET['name'])) $name
Definition: log.php:14