OptionManagement.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Eav\Model\Entity\Attribute;
  7. use Magento\Framework\Exception\InputException;
  8. use Magento\Framework\Exception\NoSuchEntityException;
  9. use Magento\Framework\Exception\StateException;
  10. /**
  11. * Eav Option Management
  12. */
  13. class OptionManagement implements \Magento\Eav\Api\AttributeOptionManagementInterface
  14. {
  15. /**
  16. * @var \Magento\Eav\Model\AttributeRepository
  17. */
  18. protected $attributeRepository;
  19. /**
  20. * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute
  21. */
  22. protected $resourceModel;
  23. /**
  24. * @param \Magento\Eav\Model\AttributeRepository $attributeRepository
  25. * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute $resourceModel
  26. * @codeCoverageIgnore
  27. */
  28. public function __construct(
  29. \Magento\Eav\Model\AttributeRepository $attributeRepository,
  30. \Magento\Eav\Model\ResourceModel\Entity\Attribute $resourceModel
  31. ) {
  32. $this->attributeRepository = $attributeRepository;
  33. $this->resourceModel = $resourceModel;
  34. }
  35. /**
  36. * @inheritdoc
  37. */
  38. public function add($entityType, $attributeCode, $option)
  39. {
  40. if (empty($attributeCode)) {
  41. throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
  42. }
  43. $attribute = $this->attributeRepository->get($entityType, $attributeCode);
  44. if (!$attribute->usesSource()) {
  45. throw new StateException(__('The "%1" attribute doesn\'t work with options.', $attributeCode));
  46. }
  47. $optionLabel = $option->getLabel();
  48. $optionId = $this->getOptionId($option);
  49. $options = [];
  50. $options['value'][$optionId][0] = $optionLabel;
  51. $options['order'][$optionId] = $option->getSortOrder();
  52. if (is_array($option->getStoreLabels())) {
  53. foreach ($option->getStoreLabels() as $label) {
  54. $options['value'][$optionId][$label->getStoreId()] = $label->getLabel();
  55. }
  56. }
  57. if ($option->getIsDefault()) {
  58. $attribute->setDefault([$optionId]);
  59. }
  60. $attribute->setOption($options);
  61. try {
  62. $this->resourceModel->save($attribute);
  63. if ($optionLabel && $attribute->getAttributeCode()) {
  64. $this->setOptionValue($option, $attribute, $optionLabel);
  65. }
  66. } catch (\Exception $e) {
  67. throw new StateException(__('The "%1" attribute can\'t be saved.', $attributeCode));
  68. }
  69. return $this->getOptionId($option);
  70. }
  71. /**
  72. * @inheritdoc
  73. */
  74. public function delete($entityType, $attributeCode, $optionId)
  75. {
  76. if (empty($attributeCode)) {
  77. throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
  78. }
  79. $attribute = $this->attributeRepository->get($entityType, $attributeCode);
  80. if (!$attribute->usesSource()) {
  81. throw new StateException(__('The "%1" attribute has no option.', $attributeCode));
  82. }
  83. $this->validateOption($attribute, $optionId);
  84. $removalMarker = [
  85. 'option' => [
  86. 'value' => [$optionId => []],
  87. 'delete' => [$optionId => '1'],
  88. ],
  89. ];
  90. $attribute->addData($removalMarker);
  91. try {
  92. $this->resourceModel->save($attribute);
  93. } catch (\Exception $e) {
  94. throw new StateException(__('The "%1" attribute can\'t be saved.', $attributeCode));
  95. }
  96. return true;
  97. }
  98. /**
  99. * @inheritdoc
  100. */
  101. public function getItems($entityType, $attributeCode)
  102. {
  103. if (empty($attributeCode)) {
  104. throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
  105. }
  106. $attribute = $this->attributeRepository->get($entityType, $attributeCode);
  107. try {
  108. $options = $attribute->getOptions();
  109. } catch (\Exception $e) {
  110. throw new StateException(__('The options for "%1" attribute can\'t be loaded.', $attributeCode));
  111. }
  112. return $options;
  113. }
  114. /**
  115. * Validate option
  116. *
  117. * @param \Magento\Eav\Api\Data\AttributeInterface $attribute
  118. * @param int $optionId
  119. * @throws NoSuchEntityException
  120. * @return void
  121. */
  122. protected function validateOption($attribute, $optionId)
  123. {
  124. if ($attribute->getSource()->getOptionText($optionId) === false) {
  125. throw new NoSuchEntityException(
  126. __(
  127. 'The "%1" attribute doesn\'t include an option with "%2" ID.',
  128. $attribute->getAttributeCode(),
  129. $optionId
  130. )
  131. );
  132. }
  133. }
  134. /**
  135. * Returns option id
  136. *
  137. * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
  138. * @return string
  139. */
  140. private function getOptionId(\Magento\Eav\Api\Data\AttributeOptionInterface $option) : string
  141. {
  142. return 'id_' . ($option->getValue() ?: 'new_option');
  143. }
  144. /**
  145. * Set option value
  146. *
  147. * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
  148. * @param \Magento\Eav\Api\Data\AttributeInterface $attribute
  149. * @param string $optionLabel
  150. * @return void
  151. */
  152. private function setOptionValue(
  153. \Magento\Eav\Api\Data\AttributeOptionInterface $option,
  154. \Magento\Eav\Api\Data\AttributeInterface $attribute,
  155. string $optionLabel
  156. ) {
  157. $optionId = $attribute->getSource()->getOptionId($optionLabel);
  158. if ($optionId) {
  159. $option->setValue($attribute->getSource()->getOptionId($optionId));
  160. } elseif (is_array($option->getStoreLabels())) {
  161. foreach ($option->getStoreLabels() as $label) {
  162. if ($optionId = $attribute->getSource()->getOptionId($label->getLabel())) {
  163. $option->setValue($attribute->getSource()->getOptionId($optionId));
  164. break;
  165. }
  166. }
  167. }
  168. }
  169. }