AbstractExtensibleObject.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Api;
  7. use \Magento\Framework\Api\AttributeValueFactory;
  8. /**
  9. * Base Class for extensible data Objects
  10. *
  11. * @SuppressWarnings(PHPMD.NumberOfChildren)
  12. * @api
  13. * @since 100.0.2
  14. */
  15. abstract class AbstractExtensibleObject extends AbstractSimpleObject implements CustomAttributesDataInterface
  16. {
  17. /**
  18. * Array key for custom attributes
  19. */
  20. const CUSTOM_ATTRIBUTES_KEY = 'custom_attributes';
  21. /**
  22. * @var \Magento\Framework\Api\ExtensionAttributesFactory
  23. */
  24. protected $extensionFactory;
  25. /**
  26. * @var AttributeValueFactory
  27. */
  28. protected $attributeValueFactory;
  29. /**
  30. * @var string[]
  31. */
  32. protected $customAttributesCodes;
  33. /**
  34. * Initialize internal storage
  35. *
  36. * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
  37. * @param AttributeValueFactory $attributeValueFactory
  38. * @param array $data
  39. */
  40. public function __construct(
  41. \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
  42. AttributeValueFactory $attributeValueFactory,
  43. $data = []
  44. ) {
  45. $this->extensionFactory = $extensionFactory;
  46. $this->attributeValueFactory = $attributeValueFactory;
  47. parent::__construct($data);
  48. if (isset($data[self::EXTENSION_ATTRIBUTES_KEY]) && is_array($data[self::EXTENSION_ATTRIBUTES_KEY])) {
  49. $this->populateExtensionAttributes($data[self::EXTENSION_ATTRIBUTES_KEY]);
  50. }
  51. }
  52. /**
  53. * Get an attribute value.
  54. *
  55. * @param string $attributeCode
  56. * @return \Magento\Framework\Api\AttributeInterface|null null if the attribute has not been set
  57. */
  58. public function getCustomAttribute($attributeCode)
  59. {
  60. return isset($this->_data[self::CUSTOM_ATTRIBUTES])
  61. && isset($this->_data[self::CUSTOM_ATTRIBUTES][$attributeCode])
  62. ? $this->_data[self::CUSTOM_ATTRIBUTES][$attributeCode]
  63. : null;
  64. }
  65. /**
  66. * Retrieve custom attributes values.
  67. *
  68. * @return \Magento\Framework\Api\AttributeInterface[]|null
  69. */
  70. public function getCustomAttributes()
  71. {
  72. return $this->_data[self::CUSTOM_ATTRIBUTES] ?? [];
  73. }
  74. /**
  75. * Set array of custom attributes
  76. *
  77. * @param \Magento\Framework\Api\AttributeInterface[] $attributes
  78. * @return $this
  79. * @throws \LogicException
  80. */
  81. public function setCustomAttributes(array $attributes)
  82. {
  83. $customAttributesCodes = $this->getCustomAttributesCodes();
  84. foreach ($attributes as $attribute) {
  85. if (!$attribute instanceof AttributeValue) {
  86. throw new \LogicException('Custom Attribute array elements can only be type of AttributeValue');
  87. }
  88. $attributeCode = $attribute->getAttributeCode();
  89. if (in_array($attributeCode, $customAttributesCodes)) {
  90. $this->_data[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY][$attributeCode] = $attribute;
  91. }
  92. }
  93. return $this;
  94. }
  95. /**
  96. * Set an attribute value for a given attribute code
  97. *
  98. * @param string $attributeCode
  99. * @param mixed $attributeValue
  100. * @return $this
  101. */
  102. public function setCustomAttribute($attributeCode, $attributeValue)
  103. {
  104. $customAttributesCodes = $this->getCustomAttributesCodes();
  105. /* If key corresponds to custom attribute code, populate custom attributes */
  106. if (in_array($attributeCode, $customAttributesCodes)) {
  107. /** @var AttributeValue $attribute */
  108. $attribute = $this->attributeValueFactory->create();
  109. $attribute->setAttributeCode($attributeCode)
  110. ->setValue($attributeValue);
  111. $this->_data[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY][$attributeCode] = $attribute;
  112. }
  113. return $this;
  114. }
  115. /**
  116. * Get a list of custom attribute codes.
  117. *
  118. * By default, entity can be extended only using extension attributes functionality.
  119. *
  120. * @return string[]
  121. */
  122. protected function getCustomAttributesCodes()
  123. {
  124. return $this->customAttributesCodes ?? [];
  125. }
  126. /**
  127. * Receive a list of EAV attributes using provided metadata service.
  128. *
  129. * Can be used in child classes, which represent EAV entities.
  130. *
  131. * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
  132. * @return string[]
  133. */
  134. protected function getEavAttributesCodes(\Magento\Framework\Api\MetadataServiceInterface $metadataService)
  135. {
  136. $attributeCodes = [];
  137. $customAttributesMetadata = $metadataService->getCustomAttributesMetadata(get_class($this));
  138. if (is_array($customAttributesMetadata)) {
  139. /** @var $attribute \Magento\Framework\Api\MetadataObjectInterface */
  140. foreach ($customAttributesMetadata as $attribute) {
  141. $attributeCodes[] = $attribute->getAttributeCode();
  142. }
  143. }
  144. return $attributeCodes;
  145. }
  146. /**
  147. * Retrieve existing extension attributes object or create a new one.
  148. *
  149. * @return \Magento\Framework\Api\ExtensionAttributesInterface
  150. */
  151. protected function _getExtensionAttributes()
  152. {
  153. if (!$this->_get(self::EXTENSION_ATTRIBUTES_KEY)) {
  154. $this->populateExtensionAttributes([]);
  155. }
  156. return $this->_get(self::EXTENSION_ATTRIBUTES_KEY);
  157. }
  158. /**
  159. * Instantiate extension attributes object and populate it with the provided data.
  160. *
  161. * @param array $extensionAttributesData
  162. * @return void
  163. */
  164. private function populateExtensionAttributes(array $extensionAttributesData = [])
  165. {
  166. $extensionAttributes = $this->extensionFactory->create(get_class($this), $extensionAttributesData);
  167. $this->_setExtensionAttributes($extensionAttributes);
  168. }
  169. /**
  170. * Set an extension attributes object.
  171. *
  172. * @param \Magento\Framework\Api\ExtensionAttributesInterface $extensionAttributes
  173. * @return $this
  174. */
  175. protected function _setExtensionAttributes(\Magento\Framework\Api\ExtensionAttributesInterface $extensionAttributes)
  176. {
  177. $this->_data[self::EXTENSION_ATTRIBUTES_KEY] = $extensionAttributes;
  178. return $this;
  179. }
  180. }