Skip to content

Commit 65a806a

Browse files
author
Eric Bohanon
committed
MAGETWO-89246: Fix out of stock filter for products resolution
1 parent 8d9b565 commit 65a806a

File tree

25 files changed

+551
-497
lines changed

25 files changed

+551
-497
lines changed

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php

Lines changed: 10 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,11 @@
88
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider;
99

1010
use Magento\Catalog\Model\Product\Visibility;
11-
use Magento\Catalog\Model\ResourceModel\CategoryProduct;
12-
use Magento\Framework\Api\SearchCriteriaBuilder;
1311
use Magento\Framework\Api\SearchCriteriaInterface;
1412
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
15-
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
16-
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
1713
use Magento\Catalog\Api\Data\ProductSearchResultsInterfaceFactory;
1814
use Magento\Framework\Api\SearchResultsInterface;
15+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
1916

2017
/**
2118
* Product field data provider, used for GraphQL resolver processing.
@@ -27,40 +24,15 @@ class Product
2724
*/
2825
private $collectionFactory;
2926

30-
/**
31-
* @var JoinProcessorInterface
32-
*/
33-
private $joinProcessor;
34-
35-
/**
36-
* @var CollectionProcessorInterface
37-
*/
38-
private $collectionProcessor;
39-
4027
/**
4128
* @var ProductSearchResultsInterfaceFactory
4229
*/
4330
private $searchResultsFactory;
4431

4532
/**
46-
* @var CategoryProduct
47-
*/
48-
private $categoryProduct;
49-
50-
/**
51-
* @var SearchCriteriaBuilder
52-
*/
53-
private $searchCriteriaBuilder;
54-
55-
/**
56-
* @var \Magento\Catalog\Model\Layer\Resolver
57-
*/
58-
private $layerResolver;
59-
60-
/**
61-
* @var \Magento\Catalog\Model\ProductRepository
33+
* @var CollectionProcessorInterface
6234
*/
63-
private $productRepository;
35+
private $collectionProcessor;
6436

6537
/**
6638
* @var Visibility
@@ -69,32 +41,20 @@ class Product
6941

7042
/**
7143
* @param CollectionFactory $collectionFactory
72-
* @param JoinProcessorInterface $joinProcessor
73-
* @param CollectionProcessorInterface $collectionProcessor
7444
* @param ProductSearchResultsInterfaceFactory $searchResultsFactory
75-
* @param CategoryProduct $categoryProduct
76-
* @param SearchCriteriaBuilder $searchCriteriaBuilder
45+
* @param Visibility $visibility
46+
* @param CollectionProcessorInterface $collectionProcessor
7747
*/
7848
public function __construct(
7949
CollectionFactory $collectionFactory,
80-
JoinProcessorInterface $joinProcessor,
81-
CollectionProcessorInterface $collectionProcessor,
8250
ProductSearchResultsInterfaceFactory $searchResultsFactory,
83-
CategoryProduct $categoryProduct,
84-
SearchCriteriaBuilder $searchCriteriaBuilder,
85-
\Magento\Catalog\Model\Layer\Resolver $layerResolver,
86-
\Magento\Catalog\Model\ProductRepository $productRepository,
87-
Visibility $visibility
51+
Visibility $visibility,
52+
CollectionProcessorInterface $collectionProcessor
8853
) {
8954
$this->collectionFactory = $collectionFactory;
90-
$this->joinProcessor = $joinProcessor;
91-
$this->collectionProcessor = $collectionProcessor;
9255
$this->searchResultsFactory = $searchResultsFactory;
93-
$this->categoryProduct = $categoryProduct;
94-
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
9556
$this->visibility = $visibility;
96-
$this->layerResolver = $layerResolver;
97-
$this->productRepository = $productRepository;
57+
$this->collectionProcessor = $collectionProcessor;
9858
}
9959

10060
/**
@@ -114,29 +74,17 @@ public function getList(
11474
): SearchResultsInterface {
11575
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */
11676
$collection = $this->collectionFactory->create();
117-
$this->joinProcessor->process($collection);
11877

119-
foreach ($attributes as $attributeCode) {
120-
$collection->addAttributeToSelect($attributeCode);
121-
}
122-
$collection->addAttributeToSelect('special_price');
123-
$collection->addAttributeToSelect('special_price_from');
124-
$collection->addAttributeToSelect('special_price_to');
125-
$collection->addAttributeToSelect('tax_class_id');
126-
$collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
127-
$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
78+
$this->collectionProcessor->process($collection, $searchCriteria, $attributes);
12879

12980
if (!$isChildSearch) {
13081
$visibilityIds
13182
= $isSearch ? $this->visibility->getVisibleInSearchIds() : $this->visibility->getVisibleInCatalogIds();
13283
$collection->setVisibility($visibilityIds);
13384
}
134-
135-
$this->collectionProcessor->process($searchCriteria, $collection);
136-
$collection->addWebsiteNamesToResult();
13785
$collection->load();
13886

139-
// Methods that perform extra fetches
87+
// Methods that perform extra fetches post-load
14088
$collection->addCategoryIds();
14189
$collection->addMediaGalleryData();
14290
$collection->addOptionsToResult();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor;
9+
10+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
11+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
12+
use Magento\Framework\Api\SearchCriteriaInterface;
13+
14+
/**
15+
* Adds passed in attributes to product collection results
16+
*
17+
* {@inheritdoc}
18+
*/
19+
class AttributeProcessor implements CollectionProcessorInterface
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function process(
25+
Collection $collection,
26+
SearchCriteriaInterface $searchCriteria,
27+
array $attributeNames
28+
): Collection {
29+
foreach ($attributeNames as $name) {
30+
$collection->addAttributeToSelect($name);
31+
}
32+
33+
return $collection;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor;
9+
10+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
11+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
12+
use Magento\Framework\Api\SearchCriteriaInterface;
13+
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
14+
15+
/**
16+
* Add necessary joins for extensible entities.
17+
*
18+
* {@inheritdoc}
19+
*/
20+
class ExtensibleEntityProcessor implements CollectionProcessorInterface
21+
{
22+
/**
23+
* @var JoinProcessorInterface
24+
*/
25+
private $joinProcessor;
26+
27+
/**
28+
* @param JoinProcessorInterface $joinProcessor
29+
*/
30+
public function __construct(JoinProcessorInterface $joinProcessor)
31+
{
32+
$this->joinProcessor = $joinProcessor;
33+
}
34+
35+
public function process(
36+
Collection $collection,
37+
SearchCriteriaInterface $searchCriteria,
38+
array $attributeNames
39+
): Collection {
40+
$this->joinProcessor->process($collection);
41+
42+
return $collection;
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor;
9+
10+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
11+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
12+
use Magento\Framework\Api\SearchCriteriaInterface;
13+
14+
/**
15+
* Add attributes required for every GraphQL product resolution process.
16+
*
17+
* {@inheritdoc}
18+
*/
19+
class RequiredColumnsProcessor implements CollectionProcessorInterface
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function process(
25+
Collection $collection,
26+
SearchCriteriaInterface $searchCriteria,
27+
array $attributeNames
28+
): Collection {
29+
$collection->addAttributeToSelect('special_price');
30+
$collection->addAttributeToSelect('special_price_from');
31+
$collection->addAttributeToSelect('special_price_to');
32+
$collection->addAttributeToSelect('tax_class_id');
33+
$collection->addWebsiteNamesToResult();
34+
35+
return $collection;
36+
}
37+
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor;
9+
10+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
11+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
12+
use Magento\Framework\Api\SearchCriteriaInterface;
13+
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface as SearchCriteriaApplier;
14+
15+
/**
16+
* Apply search criteria data to passed in collection.
17+
*
18+
* {@inheritdoc}
19+
*/
20+
class SearchCriteriaProcessor implements CollectionProcessorInterface
21+
{
22+
/**
23+
* @var SearchCriteriaApplier
24+
*/
25+
private $searchCriteriaApplier;
26+
27+
/**
28+
* @param SearchCriteriaApplier $searchCriteriaApplier
29+
*/
30+
public function __construct(SearchCriteriaApplier $searchCriteriaApplier)
31+
{
32+
$this->searchCriteriaApplier = $searchCriteriaApplier;
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function process(
39+
Collection $collection,
40+
SearchCriteriaInterface $searchCriteria,
41+
array $attributeNames
42+
): Collection {
43+
$this->searchCriteriaApplier->process($searchCriteria, $collection);
44+
45+
return $collection;
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor;
9+
10+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
11+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
12+
use Magento\Framework\Api\SearchCriteriaInterface;
13+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
14+
use Magento\CatalogInventory\Model\ResourceModel\Stock\Status as StockStatusResource;
15+
16+
/**
17+
* Add stock filtering if configuration requires it.
18+
*
19+
* {@inheritdoc}
20+
*/
21+
class StockProcessor implements CollectionProcessorInterface
22+
{
23+
/**
24+
* @var StockConfigurationInterface
25+
*/
26+
private $stockConfig;
27+
28+
/**
29+
* @var StockStatusResource
30+
*/
31+
private $stockStatusResource;
32+
33+
/**
34+
* @param StockConfigurationInterface $stockConfig
35+
* @param StockStatusResource $stockStatusResource
36+
*/
37+
public function __construct(StockConfigurationInterface $stockConfig, StockStatusResource $stockStatusResource)
38+
{
39+
$this->stockConfig = $stockConfig;
40+
$this->stockStatusResource = $stockStatusResource;
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function process(
47+
Collection $collection,
48+
SearchCriteriaInterface $searchCriteria,
49+
array $attributeNames
50+
): Collection {
51+
if (!$this->stockConfig->isShowOutOfStock()) {
52+
$this->stockStatusResource->addIsInStockFilterToCollection($collection);
53+
}
54+
55+
return $collection;
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor;
9+
10+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
11+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
12+
use Magento\Framework\Api\SearchCriteriaInterface;
13+
14+
/**
15+
* Join visibility and status tables to product collection
16+
*
17+
* {@inheritdoc}
18+
*/
19+
class VisibilityStatusProcessor implements CollectionProcessorInterface
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function process(
25+
Collection $collection,
26+
SearchCriteriaInterface $searchCriteria,
27+
array $attributeNames
28+
): Collection {
29+
$collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
30+
$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
31+
32+
return $collection;
33+
}
34+
}

0 commit comments

Comments
 (0)