AttributeRepository.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Eav\Model;
  7. use Magento\Framework\Api\SearchCriteria\CollectionProcessor;
  8. use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
  9. use Magento\Framework\Exception\InputException;
  10. use Magento\Framework\Exception\NoSuchEntityException;
  11. use Magento\Framework\Exception\StateException;
  12. /**
  13. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  14. */
  15. class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterface
  16. {
  17. /**
  18. * @var \Magento\Eav\Model\Config
  19. */
  20. protected $eavConfig;
  21. /**
  22. * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute
  23. */
  24. protected $eavResource;
  25. /**
  26. * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory
  27. */
  28. protected $attributeCollectionFactory;
  29. /**
  30. * @var \Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory
  31. */
  32. protected $searchResultsFactory;
  33. /**
  34. * @var Entity\AttributeFactory
  35. */
  36. protected $attributeFactory;
  37. /**
  38. * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface
  39. */
  40. protected $joinProcessor;
  41. /**
  42. * @var CollectionProcessorInterface
  43. */
  44. private $collectionProcessor;
  45. /**
  46. * @param Config $eavConfig
  47. * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute $eavResource
  48. * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory $attributeCollectionFactory
  49. * @param \Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory $searchResultsFactory
  50. * @param Entity\AttributeFactory $attributeFactory
  51. * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor
  52. * @param CollectionProcessorInterface $collectionProcessor
  53. * @codeCoverageIgnore
  54. */
  55. public function __construct(
  56. \Magento\Eav\Model\Config $eavConfig,
  57. \Magento\Eav\Model\ResourceModel\Entity\Attribute $eavResource,
  58. \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory $attributeCollectionFactory,
  59. \Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory $searchResultsFactory,
  60. \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory,
  61. \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor,
  62. CollectionProcessorInterface $collectionProcessor = null
  63. ) {
  64. $this->eavConfig = $eavConfig;
  65. $this->eavResource = $eavResource;
  66. $this->attributeCollectionFactory = $attributeCollectionFactory;
  67. $this->searchResultsFactory = $searchResultsFactory;
  68. $this->attributeFactory = $attributeFactory;
  69. $this->joinProcessor = $joinProcessor;
  70. $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor();
  71. }
  72. /**
  73. * {@inheritdoc}
  74. */
  75. public function save(\Magento\Eav\Api\Data\AttributeInterface $attribute)
  76. {
  77. try {
  78. $this->eavResource->save($attribute);
  79. } catch (\Exception $e) {
  80. throw new StateException(__("The attribute can't be saved."));
  81. }
  82. return $attribute;
  83. }
  84. /**
  85. * {@inheritdoc}
  86. */
  87. public function getList($entityTypeCode, \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
  88. {
  89. if (!$entityTypeCode) {
  90. throw InputException::requiredField('entity_type_code');
  91. }
  92. /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $attributeCollection */
  93. $attributeCollection = $this->attributeCollectionFactory->create();
  94. $this->joinProcessor->process($attributeCollection);
  95. $attributeCollection->addFieldToFilter('entity_type_code', ['eq' => $entityTypeCode]);
  96. $attributeCollection->join(
  97. ['entity_type' => $attributeCollection->getTable('eav_entity_type')],
  98. 'main_table.entity_type_id = entity_type.entity_type_id',
  99. []
  100. );
  101. $attributeCollection->joinLeft(
  102. ['eav_entity_attribute' => $attributeCollection->getTable('eav_entity_attribute')],
  103. 'main_table.attribute_id = eav_entity_attribute.attribute_id',
  104. []
  105. );
  106. $entityType = $this->eavConfig->getEntityType($entityTypeCode);
  107. $additionalTable = $entityType->getAdditionalAttributeTable();
  108. if ($additionalTable) {
  109. $attributeCollection->join(
  110. ['additional_table' => $attributeCollection->getTable($additionalTable)],
  111. 'main_table.attribute_id = additional_table.attribute_id',
  112. []
  113. );
  114. }
  115. $this->collectionProcessor->process($searchCriteria, $attributeCollection);
  116. // Group attributes by id to prevent duplicates with different attribute sets
  117. $attributeCollection->addAttributeGrouping();
  118. $attributes = [];
  119. /** @var \Magento\Eav\Api\Data\AttributeInterface $attribute */
  120. foreach ($attributeCollection as $attribute) {
  121. $attributes[] = $this->get($entityTypeCode, $attribute->getAttributeCode());
  122. }
  123. /** @var \Magento\Eav\Api\Data\AttributeSearchResultsInterface $searchResults */
  124. $searchResults = $this->searchResultsFactory->create();
  125. $searchResults->setSearchCriteria($searchCriteria);
  126. $searchResults->setItems($attributes);
  127. // if $searchCriteria has no page size - we can use count() on $attributeCollection
  128. // otherwise - we have to use getSize() on $attributeCollection
  129. // with this approach we can eliminate excessive COUNT requests in case page size is empty
  130. if ($searchCriteria->getPageSize()) {
  131. $searchResults->setTotalCount($attributeCollection->getSize());
  132. } else {
  133. $searchResults->setTotalCount(count($attributeCollection));
  134. }
  135. return $searchResults;
  136. }
  137. /**
  138. * {@inheritdoc}
  139. */
  140. public function get($entityTypeCode, $attributeCode)
  141. {
  142. /** @var \Magento\Eav\Api\Data\AttributeInterface $attribute */
  143. $attribute = $this->eavConfig->getAttribute($entityTypeCode, $attributeCode);
  144. if (!$attribute || !$attribute->getAttributeId()) {
  145. throw new NoSuchEntityException(
  146. __(
  147. 'The attribute with a "%1" attributeCode doesn\'t exist. Verify the attribute and try again.',
  148. $attributeCode
  149. )
  150. );
  151. }
  152. return $attribute;
  153. }
  154. /**
  155. * {@inheritdoc}
  156. */
  157. public function delete(\Magento\Eav\Api\Data\AttributeInterface $attribute)
  158. {
  159. try {
  160. $this->eavResource->delete($attribute);
  161. } catch (\Exception $e) {
  162. throw new StateException(__("The attribute can't be deleted."));
  163. }
  164. return true;
  165. }
  166. /**
  167. * {@inheritdoc}
  168. */
  169. public function deleteById($attributeId)
  170. {
  171. /** @var \Magento\Eav\Model\Entity\Attribute $attribute */
  172. $attribute = $this->attributeFactory->create();
  173. $this->eavResource->load($attribute, $attributeId);
  174. if (!$attribute->getAttributeId()) {
  175. throw new NoSuchEntityException(
  176. __('The attribute with a "%1" ID doesn\'t exist. Verify the attribute and try again.', $attributeId)
  177. );
  178. }
  179. $this->delete($attribute);
  180. return true;
  181. }
  182. /**
  183. * Retrieve collection processor
  184. *
  185. * @deprecated 101.0.0
  186. * @return CollectionProcessorInterface
  187. */
  188. private function getCollectionProcessor()
  189. {
  190. if (!$this->collectionProcessor) {
  191. $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get(
  192. CollectionProcessor::class
  193. );
  194. }
  195. return $this->collectionProcessor;
  196. }
  197. }