PageRenderTime 41ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/magento/module-catalog/Model/ProductLink/Repository.php

https://bitbucket.org/sergiu-tot-fb/vendors
PHP | 279 lines | 177 code | 23 blank | 79 comment | 9 complexity | 1c14a6146d5465387de35c7ed51e9145 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, MIT, Apache-2.0
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Model\ProductLink;
  7. use Magento\Catalog\Api\Data\ProductInterface;
  8. use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory;
  9. use Magento\Catalog\Api\Data\ProductLinkExtensionFactory;
  10. use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks as LinksInitializer;
  11. use Magento\Catalog\Model\Product\LinkTypeProvider;
  12. use Magento\Framework\Exception\CouldNotSaveException;
  13. use Magento\Framework\Exception\NoSuchEntityException;
  14. use Magento\Framework\EntityManager\MetadataPool;
  15. use Magento\Framework\App\ObjectManager;
  16. /**
  17. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  18. */
  19. class Repository implements \Magento\Catalog\Api\ProductLinkRepositoryInterface
  20. {
  21. /**
  22. * @var MetadataPool
  23. */
  24. protected $metadataPool;
  25. /**
  26. * @var \Magento\Catalog\Model\ResourceModel\Product\Relation
  27. */
  28. protected $catalogProductRelation;
  29. /**
  30. * @var \Magento\Catalog\Model\ResourceModel\Product\Link
  31. */
  32. protected $linkResource;
  33. /**
  34. * @var LinkTypeProvider
  35. */
  36. protected $linkTypeProvider;
  37. /**
  38. * @var \Magento\Catalog\Api\ProductRepositoryInterface
  39. */
  40. protected $productRepository;
  41. /**
  42. * @var CollectionProvider
  43. */
  44. protected $entityCollectionProvider;
  45. /**
  46. * @var LinksInitializer
  47. */
  48. protected $linkInitializer;
  49. /**
  50. * @var Management
  51. */
  52. protected $linkManagement;
  53. /**
  54. * @var \Magento\Framework\Reflection\DataObjectProcessor
  55. */
  56. protected $dataObjectProcessor;
  57. /**
  58. * @var ProductLinkInterfaceFactory
  59. */
  60. protected $productLinkFactory;
  61. /**
  62. * @var ProductLinkExtensionFactory
  63. */
  64. protected $productLinkExtensionFactory;
  65. /**
  66. * Constructor
  67. *
  68. * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
  69. * @param CollectionProvider $entityCollectionProvider
  70. * @param LinksInitializer $linkInitializer
  71. * @param Management $linkManagement
  72. * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
  73. * @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory|null $productLinkFactory
  74. * @param \Magento\Catalog\Api\Data\ProductLinkExtensionFactory|null $productLinkExtensionFactory
  75. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  76. */
  77. public function __construct(
  78. \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
  79. \Magento\Catalog\Model\ProductLink\CollectionProvider $entityCollectionProvider,
  80. \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $linkInitializer,
  81. \Magento\Catalog\Model\ProductLink\Management $linkManagement,
  82. \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor,
  83. \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory = null,
  84. \Magento\Catalog\Api\Data\ProductLinkExtensionFactory $productLinkExtensionFactory = null
  85. ) {
  86. $this->productRepository = $productRepository;
  87. $this->entityCollectionProvider = $entityCollectionProvider;
  88. $this->linkInitializer = $linkInitializer;
  89. $this->linkManagement = $linkManagement;
  90. $this->dataObjectProcessor = $dataObjectProcessor;
  91. $this->productLinkFactory = $productLinkFactory ?: ObjectManager::getInstance()
  92. ->get(\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory::class);
  93. $this->productLinkExtensionFactory = $productLinkExtensionFactory ?: ObjectManager::getInstance()
  94. ->get(\Magento\Catalog\Api\Data\ProductLinkExtensionFactory::class);
  95. }
  96. /**
  97. * {@inheritdoc}
  98. */
  99. public function save(\Magento\Catalog\Api\Data\ProductLinkInterface $entity)
  100. {
  101. $linkedProduct = $this->productRepository->get($entity->getLinkedProductSku());
  102. $product = $this->productRepository->get($entity->getSku());
  103. $links = [];
  104. $extensions = $this->dataObjectProcessor->buildOutputDataArray(
  105. $entity->getExtensionAttributes(),
  106. \Magento\Catalog\Api\Data\ProductLinkExtensionInterface::class
  107. );
  108. $extensions = is_array($extensions) ? $extensions : [];
  109. $data = $entity->__toArray();
  110. foreach ($extensions as $attributeCode => $attribute) {
  111. $data[$attributeCode] = $attribute;
  112. }
  113. unset($data['extension_attributes']);
  114. $data['product_id'] = $linkedProduct->getId();
  115. $links[$linkedProduct->getId()] = $data;
  116. try {
  117. $linkTypesToId = $this->getLinkTypeProvider()->getLinkTypes();
  118. $productData = $this->getMetadataPool()->getHydrator(ProductInterface::class)->extract($product);
  119. $this->getLinkResource()->saveProductLinks(
  120. $productData[$this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()],
  121. $links,
  122. $linkTypesToId[$entity->getLinkType()]
  123. );
  124. } catch (\Exception $exception) {
  125. throw new CouldNotSaveException(__('Invalid data provided for linked products'));
  126. }
  127. return true;
  128. }
  129. /**
  130. * Get product links list
  131. *
  132. * @param \Magento\Catalog\Api\Data\ProductInterface $product
  133. * @return \Magento\Catalog\Api\Data\ProductLinkInterface[]
  134. */
  135. public function getList(\Magento\Catalog\Api\Data\ProductInterface $product)
  136. {
  137. $output = [];
  138. $linkTypes = $this->getLinkTypeProvider()->getLinkTypes();
  139. foreach (array_keys($linkTypes) as $linkTypeName) {
  140. $collection = $this->entityCollectionProvider->getCollection($product, $linkTypeName);
  141. foreach ($collection as $item) {
  142. /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */
  143. $productLink = $this->productLinkFactory->create();
  144. $productLink->setSku($product->getSku())
  145. ->setLinkType($linkTypeName)
  146. ->setLinkedProductSku($item['sku'])
  147. ->setLinkedProductType($item['type'])
  148. ->setPosition($item['position']);
  149. if (isset($item['custom_attributes'])) {
  150. $productLinkExtension = $productLink->getExtensionAttributes();
  151. if ($productLinkExtension === null) {
  152. $productLinkExtension = $this->productLinkExtensionFactory()->create();
  153. }
  154. foreach ($item['custom_attributes'] as $option) {
  155. $name = $option['attribute_code'];
  156. $value = $option['value'];
  157. $setterName = 'set'.ucfirst($name);
  158. // Check if setter exists
  159. if (method_exists($productLinkExtension, $setterName)) {
  160. call_user_func([$productLinkExtension, $setterName], $value);
  161. }
  162. }
  163. $productLink->setExtensionAttributes($productLinkExtension);
  164. }
  165. $output[] = $productLink;
  166. }
  167. }
  168. return $output;
  169. }
  170. /**
  171. * {@inheritdoc}
  172. */
  173. public function delete(\Magento\Catalog\Api\Data\ProductLinkInterface $entity)
  174. {
  175. $linkedProduct = $this->productRepository->get($entity->getLinkedProductSku());
  176. $product = $this->productRepository->get($entity->getSku());
  177. $linkTypesToId = $this->getLinkTypeProvider()->getLinkTypes();
  178. $productData = $this->getMetadataPool()->getHydrator(ProductInterface::class)->extract($product);
  179. $linkId = $this->getLinkResource()->getProductLinkId(
  180. $productData[$this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()],
  181. $linkedProduct->getId(),
  182. $linkTypesToId[$entity->getLinkType()]
  183. );
  184. if (!$linkId) {
  185. throw new NoSuchEntityException(
  186. __(
  187. 'Product with SKU \'%1\' is not linked to product with SKU \'%2\'',
  188. $entity->getLinkedProductSku(),
  189. $entity->getSku()
  190. )
  191. );
  192. }
  193. try {
  194. $this->getLinkResource()->deleteProductLink($linkId);
  195. } catch (\Exception $exception) {
  196. throw new CouldNotSaveException(__('Invalid data provided for linked products'));
  197. }
  198. return true;
  199. }
  200. /**
  201. * {@inheritdoc}
  202. */
  203. public function deleteById($sku, $type, $linkedProductSku)
  204. {
  205. $linkItems = $this->linkManagement->getLinkedItemsByType($sku, $type);
  206. /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $linkItem */
  207. foreach ($linkItems as $linkItem) {
  208. if ($linkItem->getLinkedProductSku() == $linkedProductSku) {
  209. return $this->delete($linkItem);
  210. }
  211. }
  212. throw new NoSuchEntityException(
  213. __(
  214. 'Product %1 doesn\'t have linked %2 as %3',
  215. [
  216. $sku,
  217. $linkedProductSku,
  218. $type
  219. ]
  220. )
  221. );
  222. }
  223. /**
  224. * @return \Magento\Catalog\Model\ResourceModel\Product\Link
  225. */
  226. private function getLinkResource()
  227. {
  228. if (null === $this->linkResource) {
  229. $this->linkResource = \Magento\Framework\App\ObjectManager::getInstance()
  230. ->get(\Magento\Catalog\Model\ResourceModel\Product\Link::class);
  231. }
  232. return $this->linkResource;
  233. }
  234. /**
  235. * @return LinkTypeProvider
  236. */
  237. private function getLinkTypeProvider()
  238. {
  239. if (null === $this->linkTypeProvider) {
  240. $this->linkTypeProvider = \Magento\Framework\App\ObjectManager::getInstance()
  241. ->get(\Magento\Catalog\Model\Product\LinkTypeProvider::class);
  242. }
  243. return $this->linkTypeProvider;
  244. }
  245. /**
  246. * @return \Magento\Framework\EntityManager\MetadataPool
  247. */
  248. private function getMetadataPool()
  249. {
  250. if (null === $this->metadataPool) {
  251. $this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance()
  252. ->get(\Magento\Framework\EntityManager\MetadataPool::class);
  253. }
  254. return $this->metadataPool;
  255. }
  256. }