Crosssell.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Checkout\Block\Cart;
  7. use Magento\CatalogInventory\Helper\Stock as StockHelper;
  8. /**
  9. * Cart crosssell list
  10. *
  11. * @api
  12. * @author Magento Core Team <core@magentocommerce.com>
  13. * @since 100.0.2
  14. */
  15. class Crosssell extends \Magento\Catalog\Block\Product\AbstractProduct
  16. {
  17. /**
  18. * Items quantity will be capped to this value
  19. *
  20. * @var int
  21. */
  22. protected $_maxItemCount = 4;
  23. /**
  24. * @var \Magento\Checkout\Model\Session
  25. */
  26. protected $_checkoutSession;
  27. /**
  28. * @var \Magento\Catalog\Model\Product\Visibility
  29. */
  30. protected $_productVisibility;
  31. /**
  32. * @var StockHelper
  33. */
  34. protected $stockHelper;
  35. /**
  36. * @var \Magento\Catalog\Model\Product\LinkFactory
  37. */
  38. protected $_productLinkFactory;
  39. /**
  40. * @var \Magento\Quote\Model\Quote\Item\RelatedProducts
  41. */
  42. protected $_itemRelationsList;
  43. /**
  44. * @param \Magento\Catalog\Block\Product\Context $context
  45. * @param \Magento\Checkout\Model\Session $checkoutSession
  46. * @param \Magento\Catalog\Model\Product\Visibility $productVisibility
  47. * @param \Magento\Catalog\Model\Product\LinkFactory $productLinkFactory
  48. * @param \Magento\Quote\Model\Quote\Item\RelatedProducts $itemRelationsList
  49. * @param StockHelper $stockHelper
  50. * @param array $data
  51. *
  52. * @codeCoverageIgnore
  53. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  54. */
  55. public function __construct(
  56. \Magento\Catalog\Block\Product\Context $context,
  57. \Magento\Checkout\Model\Session $checkoutSession,
  58. \Magento\Catalog\Model\Product\Visibility $productVisibility,
  59. \Magento\Catalog\Model\Product\LinkFactory $productLinkFactory,
  60. \Magento\Quote\Model\Quote\Item\RelatedProducts $itemRelationsList,
  61. StockHelper $stockHelper,
  62. array $data = []
  63. ) {
  64. $this->_checkoutSession = $checkoutSession;
  65. $this->_productVisibility = $productVisibility;
  66. $this->_productLinkFactory = $productLinkFactory;
  67. $this->_itemRelationsList = $itemRelationsList;
  68. $this->stockHelper = $stockHelper;
  69. parent::__construct(
  70. $context,
  71. $data
  72. );
  73. $this->_isScopePrivate = true;
  74. }
  75. /**
  76. * Get crosssell items
  77. *
  78. * @return array
  79. */
  80. public function getItems()
  81. {
  82. $items = $this->getData('items');
  83. if ($items === null) {
  84. $items = [];
  85. $ninProductIds = $this->_getCartProductIds();
  86. if ($ninProductIds) {
  87. $lastAdded = (int)$this->_getLastAddedProductId();
  88. if ($lastAdded) {
  89. $collection = $this->_getCollection()->addProductFilter($lastAdded);
  90. if (!empty($ninProductIds)) {
  91. $collection->addExcludeProductFilter($ninProductIds);
  92. }
  93. $collection->setPositionOrder()->load();
  94. foreach ($collection as $item) {
  95. $ninProductIds[] = $item->getId();
  96. $items[] = $item;
  97. }
  98. }
  99. if (count($items) < $this->_maxItemCount) {
  100. $filterProductIds = array_merge(
  101. $this->_getCartProductIds(),
  102. $this->_itemRelationsList->getRelatedProductIds($this->getQuote()->getAllItems())
  103. );
  104. $collection = $this->_getCollection()->addProductFilter(
  105. $filterProductIds
  106. )->addExcludeProductFilter(
  107. $ninProductIds
  108. )->setPageSize(
  109. $this->_maxItemCount - count($items)
  110. )->setGroupBy()->setPositionOrder()->load();
  111. foreach ($collection as $item) {
  112. $items[] = $item;
  113. }
  114. }
  115. }
  116. $this->setData('items', $items);
  117. }
  118. return $items;
  119. }
  120. /**
  121. * Count items
  122. *
  123. * @return int
  124. * @codeCoverageIgnore
  125. */
  126. public function getItemCount()
  127. {
  128. return count($this->getItems());
  129. }
  130. /**
  131. * Get ids of products that are in cart
  132. *
  133. * @return array
  134. */
  135. protected function _getCartProductIds()
  136. {
  137. $ids = $this->getData('_cart_product_ids');
  138. if ($ids === null) {
  139. $ids = [];
  140. foreach ($this->getQuote()->getAllItems() as $item) {
  141. $product = $item->getProduct();
  142. if ($product) {
  143. $ids[] = $product->getId();
  144. }
  145. }
  146. $this->setData('_cart_product_ids', $ids);
  147. }
  148. return $ids;
  149. }
  150. /**
  151. * Get last product ID that was added to cart and remove this information from session
  152. *
  153. * @return int
  154. * @codeCoverageIgnore
  155. */
  156. protected function _getLastAddedProductId()
  157. {
  158. return $this->_checkoutSession->getLastAddedProductId(true);
  159. }
  160. /**
  161. * Get quote instance
  162. *
  163. * @return \Magento\Quote\Model\Quote
  164. * @codeCoverageIgnore
  165. */
  166. public function getQuote()
  167. {
  168. return $this->_checkoutSession->getQuote();
  169. }
  170. /**
  171. * Get crosssell products collection
  172. *
  173. * @return \Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection
  174. */
  175. protected function _getCollection()
  176. {
  177. /** @var \Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection $collection */
  178. $collection = $this->_productLinkFactory->create()->useCrossSellLinks()->getProductCollection()->setStoreId(
  179. $this->_storeManager->getStore()->getId()
  180. )->addStoreFilter()->setPageSize(
  181. $this->_maxItemCount
  182. )->setVisibility(
  183. $this->_productVisibility->getVisibleInCatalogIds()
  184. );
  185. $this->_addProductAttributesAndPrices($collection);
  186. return $collection;
  187. }
  188. }