ProductImage.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Swatches\Model\Plugin;
  7. use Magento\Catalog\Model\Product;
  8. use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
  9. use Magento\Swatches\Helper\Data;
  10. use Magento\Eav\Model\Config;
  11. use Magento\Framework\App\Request\Http;
  12. use Magento\Catalog\Block\Product\AbstractProduct;
  13. use Magento\Catalog\Model\Product as ProductModel;
  14. use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
  15. /**
  16. * Class ProductImage replace original configurable product with first child
  17. */
  18. class ProductImage
  19. {
  20. /**
  21. * Determine context of creation image block
  22. * which defined in catalog/product/list.phtml
  23. */
  24. const CATEGORY_PAGE_GRID_LOCATION = 'category_page_grid';
  25. const CATEGORY_PAGE_LIST_LOCATION = 'category_page_list';
  26. /**
  27. * Data helper to get child product image
  28. *
  29. * @var Data $productHelper
  30. */
  31. protected $swatchHelperData;
  32. /**
  33. * @var Config
  34. */
  35. protected $eavConfig;
  36. /**
  37. * @var Http
  38. */
  39. protected $request;
  40. /**
  41. * @param Data $swatchesHelperData
  42. * @param Config $eavConfig
  43. * @param Http $request
  44. */
  45. public function __construct(
  46. Data $swatchesHelperData,
  47. Config $eavConfig,
  48. Http $request
  49. ) {
  50. $this->swatchHelperData = $swatchesHelperData;
  51. $this->eavConfig = $eavConfig;
  52. $this->request = $request;
  53. }
  54. /**
  55. * Replace original configurable product with first child
  56. *
  57. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  58. * @param AbstractProduct $subject
  59. * @param ProductModel $product
  60. * @param string $location
  61. * @param array $attributes
  62. * @return array
  63. */
  64. public function beforeGetImage(
  65. AbstractProduct $subject,
  66. ProductModel $product,
  67. $location,
  68. array $attributes = []
  69. ) {
  70. if ($product->getTypeId() == Configurable::TYPE_CODE
  71. && ($location == self::CATEGORY_PAGE_GRID_LOCATION || $location == self::CATEGORY_PAGE_LIST_LOCATION)) {
  72. $request = $this->request->getParams();
  73. if (is_array($request)) {
  74. $filterArray = $this->getFilterArray($request, $product);
  75. if (!empty($filterArray)) {
  76. $product = $this->loadSimpleVariation($product, $filterArray);
  77. }
  78. }
  79. }
  80. return [$product, $location, $attributes];
  81. }
  82. /**
  83. * @param Product $parentProduct
  84. * @param array $filterArray
  85. * @return bool|Product
  86. */
  87. private function loadSimpleVariation(Product $parentProduct, array $filterArray)
  88. {
  89. $childProduct = $this->swatchHelperData->loadVariationByFallback($parentProduct, $filterArray);
  90. if ($childProduct && !$childProduct->getImage()) {
  91. $childProduct = $this->swatchHelperData->loadFirstVariationWithImage($parentProduct, $filterArray);
  92. }
  93. if (!$childProduct) {
  94. $childProduct = $parentProduct;
  95. }
  96. return $childProduct;
  97. }
  98. /**
  99. * Get filters from request
  100. *
  101. * @param array $request
  102. * @param \Magento\Catalog\Model\Product $product
  103. * @return array
  104. */
  105. private function getFilterArray(array $request, Product $product)
  106. {
  107. $filterArray = [];
  108. $attributes = $this->eavConfig->getEntityAttributes(Product::ENTITY, $product);
  109. foreach ($request as $code => $value) {
  110. if (isset($attributes[$code])) {
  111. $attribute = $attributes[$code];
  112. if ($this->canReplaceImageWithSwatch($attribute)) {
  113. $filterArray[$code] = $value;
  114. }
  115. }
  116. }
  117. return $filterArray;
  118. }
  119. /**
  120. * Check if we can replace original image with swatch image on catalog/category/list page
  121. *
  122. * @param Attribute $attribute
  123. * @return bool
  124. */
  125. private function canReplaceImageWithSwatch($attribute)
  126. {
  127. $result = true;
  128. if (!$this->swatchHelperData->isSwatchAttribute($attribute)) {
  129. $result = false;
  130. }
  131. if (!$attribute->getUsedInProductListing()
  132. || !$attribute->getIsFilterable()
  133. || !$attribute->getData('update_product_preview_image')
  134. ) {
  135. $result = false;
  136. }
  137. return $result;
  138. }
  139. }