Skip to content

Commit eed98dc

Browse files
committed
ACP2E-4294: Restricted Category Products Still Counted in Wishlist After Customer Group Update
1 parent 11d5e0e commit eed98dc

File tree

2 files changed

+76
-55
lines changed

2 files changed

+76
-55
lines changed

app/code/Magento/Wishlist/Block/Customer/Wishlist.php

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33
* Copyright 2013 Adobe
44
* All Rights Reserved.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Wishlist\Block\Customer;
89

910
use Magento\Catalog\Block\Product\Context;
1011
use Magento\Catalog\Helper\Product\ConfigurationPool;
1112
use Magento\Customer\Helper\Session\CurrentCustomer;
12-
use Magento\Framework\Api\SearchCriteriaBuilder;
13-
use Magento\Catalog\Api\ProductRepositoryInterface;
14-
use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver;
1513
use Magento\Framework\App\ObjectManager;
1614
use Magento\Framework\Data\Helper\PostHelper;
15+
use Magento\Wishlist\Model\WishlistItemSellableCollectionProcessor;
1716

1817
/**
1918
* Wishlist block customer items.
@@ -23,21 +22,6 @@
2322
*/
2423
class Wishlist extends \Magento\Wishlist\Block\AbstractBlock
2524
{
26-
/**
27-
* @var ProductRepositoryInterface
28-
*/
29-
private ProductRepositoryInterface $productRepository;
30-
31-
/**
32-
* @var SalableResolver
33-
*/
34-
private SalableResolver $salableResolver;
35-
36-
/**
37-
* @var SearchCriteriaBuilder
38-
*/
39-
private SearchCriteriaBuilder $searchCriteriaBuilder;
40-
4125
/**
4226
* List of product options rendering configurations by product type
4327
*
@@ -66,15 +50,18 @@ class Wishlist extends \Magento\Wishlist\Block\AbstractBlock
6650
*/
6751
protected $postDataHelper;
6852

53+
/**
54+
* @var WishlistItemSellableCollectionProcessor
55+
*/
56+
private WishlistItemSellableCollectionProcessor $sellableCollectionProcessor;
57+
6958
/**
7059
* @param Context $context
7160
* @param \Magento\Framework\App\Http\Context $httpContext
7261
* @param ConfigurationPool $helperPool
7362
* @param CurrentCustomer $currentCustomer
7463
* @param PostHelper $postDataHelper
75-
* @param ProductRepositoryInterface|null $productRepository
76-
* @param SalableResolver|null $salableResolver
77-
* @param SearchCriteriaBuilder|null $searchCriteriaBuilder
64+
* @param WishlistItemSellableCollectionProcessor|null $sellableCollectionProcessor
7865
* @param array $data
7966
*/
8067
public function __construct(
@@ -83,9 +70,7 @@ public function __construct(
8370
\Magento\Catalog\Helper\Product\ConfigurationPool $helperPool,
8471
\Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer,
8572
\Magento\Framework\Data\Helper\PostHelper $postDataHelper,
86-
?ProductRepositoryInterface $productRepository = null,
87-
?SalableResolver $salableResolver = null,
88-
?SearchCriteriaBuilder $searchCriteriaBuilder = null,
73+
?WishlistItemSellableCollectionProcessor $sellableCollectionProcessor = null,
8974
array $data = []
9075
) {
9176
parent::__construct(
@@ -96,12 +81,8 @@ public function __construct(
9681
$this->_helperPool = $helperPool;
9782
$this->currentCustomer = $currentCustomer;
9883
$this->postDataHelper = $postDataHelper;
99-
$this->productRepository = $productRepository ?? ObjectManager::getInstance()
100-
->get(ProductRepositoryInterface::class);
101-
$this->salableResolver = $salableResolver ?? ObjectManager::getInstance()
102-
->get(SalableResolver::class);
103-
$this->searchCriteriaBuilder = $searchCriteriaBuilder ?? ObjectManager::getInstance()
104-
->get(SearchCriteriaBuilder::class);
84+
$this->sellableCollectionProcessor = $sellableCollectionProcessor ??
85+
ObjectManager::getInstance()->get(WishlistItemSellableCollectionProcessor::class);
10586
}
10687

10788
/**
@@ -114,31 +95,7 @@ public function __construct(
11495
protected function _prepareCollection($collection)
11596
{
11697
$collection->setInStockFilter()->setOrder('added_at', 'ASC');
117-
$items = $collection->getItems();
118-
$productIds = array_map(static fn($item) => $item->getProductId(), $items);
119-
$searchCriteria = $this->searchCriteriaBuilder
120-
->addFilter('entity_id', $productIds, 'in')
121-
->create();
122-
$productCollection = $this->productRepository->getList($searchCriteria);
123-
$products = array_combine(
124-
array_map(fn($p) => $p->getId(), $productCollection->getItems()),
125-
$productCollection->getItems()
126-
);
127-
128-
$validItems = [];
129-
$collection->removeAllItems();
130-
foreach ($items as $item) {
131-
if (!isset($products[$item->getProductId()]) ||
132-
!$this->salableResolver->isSalable($products[$item->getProductId()])
133-
) {
134-
continue;
135-
}
136-
$validItems[] = $item->getProductId();
137-
$collection->addItem($item);
138-
}
139-
if (!empty($validItems)) {
140-
$collection->addFieldToFilter('main_table.product_id', ['in' => $validItems]);
141-
}
98+
$this->sellableCollectionProcessor->execute($collection);
14299

143100
return $this;
144101
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Wishlist\Model;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver;
12+
use Magento\Framework\Api\SearchCriteriaBuilder;
13+
use Magento\Wishlist\Model\ResourceModel\Item\Collection;
14+
15+
class WishlistItemSellableCollectionProcessor
16+
{
17+
/**
18+
* @param ProductRepositoryInterface $productRepository
19+
* @param SalableResolver $salableResolver
20+
* @param SearchCriteriaBuilder $searchCriteriaBuilder
21+
*/
22+
public function __construct(
23+
private readonly ProductRepositoryInterface $productRepository,
24+
private readonly SalableResolver $salableResolver,
25+
private readonly SearchCriteriaBuilder $searchCriteriaBuilder
26+
) {
27+
}
28+
29+
/**
30+
* @param Collection $collection
31+
* @return Collection
32+
* @throws \Exception
33+
*/
34+
public function execute(Collection $collection): Collection
35+
{
36+
$items = $collection->getItems();
37+
$productIds = array_map(static fn ($item) => $item->getProductId(), $items);
38+
$searchCriteria = $this->searchCriteriaBuilder
39+
->addFilter('entity_id', $productIds, 'in')
40+
->create();
41+
$productCollection = $this->productRepository->getList($searchCriteria);
42+
$products = array_combine(
43+
array_map(fn ($p) => $p->getId(), $productCollection->getItems()),
44+
$productCollection->getItems()
45+
);
46+
47+
$validItems = [];
48+
$collection->removeAllItems();
49+
foreach ($items as $item) {
50+
if (!isset($products[$item->getProductId()]) ||
51+
!$this->salableResolver->isSalable($products[$item->getProductId()])
52+
) {
53+
continue;
54+
}
55+
$validItems[] = $item->getProductId();
56+
$collection->addItem($item);
57+
}
58+
if (!empty($validItems)) {
59+
$collection->addFieldToFilter('main_table.product_id', ['in' => $validItems]);
60+
}
61+
62+
return $collection;
63+
}
64+
}

0 commit comments

Comments
 (0)