CustomOptionProcessor.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Model\CustomOptions;
  7. use Magento\Framework\DataObject;
  8. use Magento\Quote\Api\Data\CartItemInterface;
  9. use Magento\Quote\Model\Quote\Item\CartItemProcessorInterface;
  10. use Magento\Quote\Api\Data\ProductOptionExtensionFactory;
  11. use Magento\Quote\Model\Quote\ProductOptionFactory;
  12. class CustomOptionProcessor implements CartItemProcessorInterface
  13. {
  14. /**
  15. * @var \Magento\Framework\DataObject\Factory
  16. */
  17. protected $objectFactory;
  18. /**
  19. * @var \Magento\Quote\Model\Quote\ProductOptionFactory
  20. */
  21. protected $productOptionFactory;
  22. /**
  23. * @var \Magento\Quote\Api\Data\ProductOptionExtensionFactory
  24. */
  25. protected $extensionFactory;
  26. /**
  27. * @var \Magento\Catalog\Model\CustomOptions\CustomOptionFactory
  28. */
  29. protected $customOptionFactory;
  30. /**
  31. * @var \Magento\Catalog\Model\Product\Option\UrlBuilder
  32. */
  33. private $urlBuilder;
  34. /**
  35. * Serializer interface instance.
  36. *
  37. * @var \Magento\Framework\Serialize\Serializer\Json
  38. */
  39. private $serializer;
  40. /**
  41. * @param DataObject\Factory $objectFactory
  42. * @param ProductOptionFactory $productOptionFactory
  43. * @param ProductOptionExtensionFactory $extensionFactory
  44. * @param CustomOptionFactory $customOptionFactory
  45. * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
  46. */
  47. public function __construct(
  48. \Magento\Framework\DataObject\Factory $objectFactory,
  49. \Magento\Quote\Model\Quote\ProductOptionFactory $productOptionFactory,
  50. \Magento\Quote\Api\Data\ProductOptionExtensionFactory $extensionFactory,
  51. \Magento\Catalog\Model\CustomOptions\CustomOptionFactory $customOptionFactory,
  52. \Magento\Framework\Serialize\Serializer\Json $serializer = null
  53. ) {
  54. $this->objectFactory = $objectFactory;
  55. $this->productOptionFactory = $productOptionFactory;
  56. $this->extensionFactory = $extensionFactory;
  57. $this->customOptionFactory = $customOptionFactory;
  58. $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
  59. ->get(\Magento\Framework\Serialize\Serializer\Json::class);
  60. }
  61. /**
  62. * @inheritDoc
  63. */
  64. public function convertToBuyRequest(CartItemInterface $cartItem)
  65. {
  66. if ($cartItem->getProductOption()
  67. && $cartItem->getProductOption()->getExtensionAttributes()
  68. && $cartItem->getProductOption()->getExtensionAttributes()->getCustomOptions()) {
  69. $customOptions = $cartItem->getProductOption()->getExtensionAttributes()->getCustomOptions();
  70. if (!empty($customOptions) && is_array($customOptions)) {
  71. $requestData = [];
  72. foreach ($customOptions as $option) {
  73. $requestData['options'][$option->getOptionId()] = $option->getOptionValue();
  74. }
  75. return $this->objectFactory->create($requestData);
  76. }
  77. }
  78. return null;
  79. }
  80. /**
  81. * @inheritDoc
  82. */
  83. public function processOptions(CartItemInterface $cartItem)
  84. {
  85. $options = $this->getOptions($cartItem);
  86. if (!empty($options) && is_array($options)) {
  87. $this->updateOptionsValues($options);
  88. $productOption = $cartItem->getProductOption()
  89. ? $cartItem->getProductOption()
  90. : $this->productOptionFactory->create();
  91. /** @var \Magento\Quote\Api\Data\ProductOptionExtensionInterface $extensibleAttribute */
  92. $extensibleAttribute = $productOption->getExtensionAttributes()
  93. ? $productOption->getExtensionAttributes()
  94. : $this->extensionFactory->create();
  95. $extensibleAttribute->setCustomOptions($options);
  96. $productOption->setExtensionAttributes($extensibleAttribute);
  97. $cartItem->setProductOption($productOption);
  98. }
  99. return $cartItem;
  100. }
  101. /**
  102. * Receive custom option from buy request
  103. *
  104. * @param CartItemInterface $cartItem
  105. * @return array
  106. */
  107. protected function getOptions(CartItemInterface $cartItem)
  108. {
  109. $buyRequest = !empty($cartItem->getOptionByCode('info_buyRequest'))
  110. ? $this->serializer->unserialize($cartItem->getOptionByCode('info_buyRequest')->getValue())
  111. : null;
  112. return is_array($buyRequest) && isset($buyRequest['options'])
  113. ? $buyRequest['options']
  114. : [];
  115. }
  116. /**
  117. * Update options values
  118. *
  119. * @param array $options
  120. * @return null
  121. */
  122. protected function updateOptionsValues(array &$options)
  123. {
  124. foreach ($options as $optionId => &$optionValue) {
  125. /** @var \Magento\Catalog\Model\CustomOptions\CustomOption $option */
  126. $option = $this->customOptionFactory->create();
  127. $option->setOptionId($optionId);
  128. if (is_array($optionValue)) {
  129. $optionValue = $this->processFileOptionValue($optionValue);
  130. $optionValue = $this->processDateOptionValue($optionValue);
  131. $optionValue = implode(',', $optionValue);
  132. }
  133. $option->setOptionValue($optionValue);
  134. $optionValue = $option;
  135. }
  136. }
  137. /**
  138. * Returns option value with file built URL
  139. *
  140. * @param array $optionValue
  141. * @return array
  142. */
  143. private function processFileOptionValue(array $optionValue)
  144. {
  145. if (array_key_exists('url', $optionValue) &&
  146. array_key_exists('route', $optionValue['url']) &&
  147. array_key_exists('params', $optionValue['url'])
  148. ) {
  149. $optionValue['url'] = $this->getUrlBuilder()->getUrl(
  150. $optionValue['url']['route'],
  151. $optionValue['url']['params']
  152. );
  153. }
  154. return $optionValue;
  155. }
  156. /**
  157. * Returns date option value only with 'date_internal data
  158. *
  159. * @param array $optionValue
  160. * @return array
  161. */
  162. private function processDateOptionValue(array $optionValue)
  163. {
  164. if (array_key_exists('date_internal', $optionValue)
  165. ) {
  166. $closure = function ($key) {
  167. return $key === 'date_internal';
  168. };
  169. $optionValue = array_filter($optionValue, $closure, ARRAY_FILTER_USE_KEY);
  170. }
  171. return $optionValue;
  172. }
  173. /**
  174. * @return \Magento\Catalog\Model\Product\Option\UrlBuilder
  175. *
  176. * @deprecated 101.0.0
  177. */
  178. private function getUrlBuilder()
  179. {
  180. if ($this->urlBuilder === null) {
  181. $this->urlBuilder = \Magento\Framework\App\ObjectManager::getInstance()
  182. ->get(\Magento\Catalog\Model\Product\Option\UrlBuilder::class);
  183. }
  184. return $this->urlBuilder;
  185. }
  186. }