RenderLayered.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Swatches\Block\LayeredNavigation;
  7. use Magento\Eav\Model\Entity\Attribute;
  8. use Magento\Catalog\Model\ResourceModel\Layer\Filter\AttributeFactory;
  9. use Magento\Framework\View\Element\Template;
  10. use Magento\Eav\Model\Entity\Attribute\Option;
  11. use Magento\Catalog\Model\Layer\Filter\Item as FilterItem;
  12. /**
  13. * Class RenderLayered Render Swatches at Layered Navigation
  14. * @api
  15. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  16. * @since 100.0.2
  17. */
  18. class RenderLayered extends Template
  19. {
  20. /**
  21. * For `Filterable (with results)` setting
  22. */
  23. const FILTERABLE_WITH_RESULTS = '1';
  24. /**
  25. * Path to template file.
  26. *
  27. * @var string
  28. */
  29. protected $_template = 'Magento_Swatches::product/layered/renderer.phtml';
  30. /**
  31. * @var \Magento\Eav\Model\Attribute
  32. */
  33. protected $eavAttribute;
  34. /**
  35. * @var \Magento\Catalog\Model\Layer\Filter\AbstractFilter
  36. */
  37. protected $filter;
  38. /**
  39. * @var AttributeFactory
  40. */
  41. protected $layerAttribute;
  42. /**
  43. * @var \Magento\Swatches\Helper\Data
  44. */
  45. protected $swatchHelper;
  46. /**
  47. * @var \Magento\Swatches\Helper\Media
  48. */
  49. protected $mediaHelper;
  50. /**
  51. * @param Template\Context $context
  52. * @param Attribute $eavAttribute
  53. * @param AttributeFactory $layerAttribute
  54. * @param \Magento\Swatches\Helper\Data $swatchHelper
  55. * @param \Magento\Swatches\Helper\Media $mediaHelper
  56. * @param array $data
  57. */
  58. public function __construct(
  59. \Magento\Framework\View\Element\Template\Context $context,
  60. Attribute $eavAttribute,
  61. AttributeFactory $layerAttribute,
  62. \Magento\Swatches\Helper\Data $swatchHelper,
  63. \Magento\Swatches\Helper\Media $mediaHelper,
  64. array $data = []
  65. ) {
  66. $this->eavAttribute = $eavAttribute;
  67. $this->layerAttribute = $layerAttribute;
  68. $this->swatchHelper = $swatchHelper;
  69. $this->mediaHelper = $mediaHelper;
  70. parent::__construct($context, $data);
  71. }
  72. /**
  73. * @param \Magento\Catalog\Model\Layer\Filter\AbstractFilter $filter
  74. * @return $this
  75. * @throws \Magento\Framework\Exception\LocalizedException
  76. */
  77. public function setSwatchFilter(\Magento\Catalog\Model\Layer\Filter\AbstractFilter $filter)
  78. {
  79. $this->filter = $filter;
  80. $this->eavAttribute = $filter->getAttributeModel();
  81. return $this;
  82. }
  83. /**
  84. * @return array
  85. */
  86. public function getSwatchData()
  87. {
  88. if (false === $this->eavAttribute instanceof Attribute) {
  89. throw new \RuntimeException('Magento_Swatches: RenderLayered: Attribute has not been set.');
  90. }
  91. $attributeOptions = [];
  92. foreach ($this->eavAttribute->getOptions() as $option) {
  93. if ($currentOption = $this->getFilterOption($this->filter->getItems(), $option)) {
  94. $attributeOptions[$option->getValue()] = $currentOption;
  95. } elseif ($this->isShowEmptyResults()) {
  96. $attributeOptions[$option->getValue()] = $this->getUnusedOption($option);
  97. }
  98. }
  99. $attributeOptionIds = array_keys($attributeOptions);
  100. $swatches = $this->swatchHelper->getSwatchesByOptionsId($attributeOptionIds);
  101. $data = [
  102. 'attribute_id' => $this->eavAttribute->getId(),
  103. 'attribute_code' => $this->eavAttribute->getAttributeCode(),
  104. 'attribute_label' => $this->eavAttribute->getStoreLabel(),
  105. 'options' => $attributeOptions,
  106. 'swatches' => $swatches,
  107. ];
  108. return $data;
  109. }
  110. /**
  111. * @param string $attributeCode
  112. * @param int $optionId
  113. * @return string
  114. */
  115. public function buildUrl($attributeCode, $optionId)
  116. {
  117. $query = [$attributeCode => $optionId];
  118. return $this->_urlBuilder->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true, '_query' => $query]);
  119. }
  120. /**
  121. * @param Option $swatchOption
  122. * @return array
  123. */
  124. protected function getUnusedOption(Option $swatchOption)
  125. {
  126. return [
  127. 'label' => $swatchOption->getLabel(),
  128. 'link' => 'javascript:void();',
  129. 'custom_style' => 'disabled'
  130. ];
  131. }
  132. /**
  133. * @param FilterItem[] $filterItems
  134. * @param Option $swatchOption
  135. * @return array
  136. */
  137. protected function getFilterOption(array $filterItems, Option $swatchOption)
  138. {
  139. $resultOption = false;
  140. $filterItem = $this->getFilterItemById($filterItems, $swatchOption->getValue());
  141. if ($filterItem && $this->isOptionVisible($filterItem)) {
  142. $resultOption = $this->getOptionViewData($filterItem, $swatchOption);
  143. }
  144. return $resultOption;
  145. }
  146. /**
  147. * @param FilterItem $filterItem
  148. * @param Option $swatchOption
  149. * @return array
  150. */
  151. protected function getOptionViewData(FilterItem $filterItem, Option $swatchOption)
  152. {
  153. $customStyle = '';
  154. $linkToOption = $this->buildUrl($this->eavAttribute->getAttributeCode(), $filterItem->getValue());
  155. if ($this->isOptionDisabled($filterItem)) {
  156. $customStyle = 'disabled';
  157. $linkToOption = 'javascript:void();';
  158. }
  159. return [
  160. 'label' => $swatchOption->getLabel(),
  161. 'link' => $linkToOption,
  162. 'custom_style' => $customStyle
  163. ];
  164. }
  165. /**
  166. * @param FilterItem $filterItem
  167. * @return bool
  168. */
  169. protected function isOptionVisible(FilterItem $filterItem)
  170. {
  171. return $this->isOptionDisabled($filterItem) && $this->isShowEmptyResults() ? false : true;
  172. }
  173. /**
  174. * @return bool
  175. */
  176. protected function isShowEmptyResults()
  177. {
  178. return $this->eavAttribute->getIsFilterable() != self::FILTERABLE_WITH_RESULTS;
  179. }
  180. /**
  181. * @param FilterItem $filterItem
  182. * @return bool
  183. */
  184. protected function isOptionDisabled(FilterItem $filterItem)
  185. {
  186. return !$filterItem->getCount();
  187. }
  188. /**
  189. * @param FilterItem[] $filterItems
  190. * @param integer $id
  191. * @return bool|FilterItem
  192. */
  193. protected function getFilterItemById(array $filterItems, $id)
  194. {
  195. foreach ($filterItems as $item) {
  196. if ($item->getValue() == $id) {
  197. return $item;
  198. }
  199. }
  200. return false;
  201. }
  202. /**
  203. * @param string $type
  204. * @param string $filename
  205. * @return string
  206. */
  207. public function getSwatchPath($type, $filename)
  208. {
  209. $imagePath = $this->mediaHelper->getSwatchAttributeImage($type, $filename);
  210. return $imagePath;
  211. }
  212. }