Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ExtensionAttributesFactory.php
Go to the documentation of this file.
1 <?php
7 namespace Magento\Framework\Api;
8 
13 {
14  const EXTENSIBLE_INTERFACE_NAME = \Magento\Framework\Api\ExtensibleDataInterface::class;
15 
21  protected $objectManager;
22 
28  private $classInterfaceMap = [];
29 
36  {
37  $this->objectManager = $objectManager;
38  }
39 
47  public function create($extensibleClassName, $data = [])
48  {
49  $interfaceReflection = new \ReflectionClass($this->getExtensibleInterfaceName($extensibleClassName));
50 
51  $methodReflection = $interfaceReflection->getMethod('getExtensionAttributes');
52  if ($methodReflection->getDeclaringClass()->getName() === self::EXTENSIBLE_INTERFACE_NAME) {
53  throw new \LogicException(
54  "Method 'getExtensionAttributes' must be overridden in the interfaces "
55  . "which extend '" . self::EXTENSIBLE_INTERFACE_NAME . "'. "
56  . "Concrete return type should be specified."
57  );
58  }
59 
60  $interfaceName = '\\' . $interfaceReflection->getName();
61  $extensionClassName = substr($interfaceName, 0, -strlen('Interface')) . 'Extension';
62  $extensionInterfaceName = $extensionClassName . 'Interface';
63 
65  $methodDocBlock = $methodReflection->getDocComment();
66  $pattern = "/@return\s+" . str_replace('\\', '\\\\', $extensionInterfaceName) . "/";
67  if (!preg_match($pattern, $methodDocBlock)) {
68  throw new \LogicException(
69  "Method 'getExtensionAttributes' must be overridden in the interfaces "
70  . "which extend '" . self::EXTENSIBLE_INTERFACE_NAME . "'. "
71  . "Concrete return type must be specified. Please fix :" . $interfaceName
72  );
73  }
74 
75  $extensionFactoryName = $extensionClassName . 'Factory';
76  $extensionFactory = $this->objectManager->create($extensionFactoryName);
77  return $extensionFactory->create($data);
78  }
79 
86  public function getExtensibleInterfaceName($extensibleClassName)
87  {
88  $exceptionMessage = "Class '{$extensibleClassName}' must implement an interface, "
89  . "which extends from '" . self::EXTENSIBLE_INTERFACE_NAME . "'";
90  $notExtensibleClassFlag = '';
91 
92  if (isset($this->classInterfaceMap[$extensibleClassName])) {
93  if ($notExtensibleClassFlag === $this->classInterfaceMap[$extensibleClassName]) {
94  throw new \LogicException($exceptionMessage);
95  } else {
96  return $this->classInterfaceMap[$extensibleClassName];
97  }
98  }
99  $modelReflection = new \ReflectionClass($extensibleClassName);
100  if ($modelReflection->isInterface()
101  && $modelReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME)
102  && $modelReflection->hasMethod('getExtensionAttributes')
103  ) {
104  $this->classInterfaceMap[$extensibleClassName] = $extensibleClassName;
105  return $this->classInterfaceMap[$extensibleClassName];
106  }
107  foreach ($modelReflection->getInterfaces() as $interfaceReflection) {
108  if ($interfaceReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME)
109  && $interfaceReflection->hasMethod('getExtensionAttributes')
110  ) {
111  $this->classInterfaceMap[$extensibleClassName] = $interfaceReflection->getName();
112  return $this->classInterfaceMap[$extensibleClassName];
113  }
114  }
115  $this->classInterfaceMap[$extensibleClassName] = $notExtensibleClassFlag;
116  throw new \LogicException($exceptionMessage);
117  }
118 }
$pattern
Definition: website.php:22
__construct(\Magento\Framework\ObjectManagerInterface $objectManager)