Skip to content

Commit 589b1d2

Browse files
Merge branch '2.4-develop' into dcmm2020
2 parents 6b1837b + a92dee7 commit 589b1d2

File tree

20 files changed

+741
-93
lines changed

20 files changed

+741
-93
lines changed

app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ public function resolve(
110110
}
111111

112112
$product = $value['model'];
113+
114+
if ($product->hasData('can_show_price') && $product->getData('can_show_price') === false) {
115+
return [];
116+
}
117+
113118
$productId = $product->getId();
114119
$this->tiers->addProductFilter($productId);
115120

app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php

Lines changed: 58 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7,78 +7,101 @@
77

88
namespace Magento\CatalogGraphQl\Model\Category;
99

10-
use Magento\Catalog\Api\CategoryListInterface;
11-
use Magento\Catalog\Api\Data\CategoryInterface;
12-
use Magento\Framework\App\Config\ScopeConfigInterface;
10+
use Magento\Catalog\Api\CategoryRepositoryInterface;
11+
use Magento\Catalog\Api\Data\CategorySearchResultsInterface;
12+
use Magento\Catalog\Api\Data\CategorySearchResultsInterfaceFactory;
13+
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
14+
use Magento\CatalogGraphQl\Model\Resolver\Categories\DataProvider\Category\CollectionProcessorInterface;
15+
use Magento\CatalogGraphQl\Model\Category\Filter\SearchCriteria;
16+
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
1317
use Magento\Framework\Exception\InputException;
1418
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
15-
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\ArgumentApplier\Filter;
16-
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\ArgumentApplier\Sort;
17-
use Magento\Search\Model\Query;
19+
use Magento\GraphQl\Model\Query\ContextInterface;
1820
use Magento\Store\Api\Data\StoreInterface;
19-
use Magento\Store\Model\ScopeInterface;
20-
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\Builder;
2121

2222
/**
2323
* Category filter allows filtering category results by attributes.
2424
*/
2525
class CategoryFilter
2626
{
2727
/**
28-
* @var string
28+
* @var CollectionFactory
2929
*/
30-
private const SPECIAL_CHARACTERS = '-+~/\\<>\'":*$#@()!,.?`=%&^';
30+
private $categoryCollectionFactory;
3131

3232
/**
33-
* @var ScopeConfigInterface
33+
* @var CollectionProcessorInterface
3434
*/
35-
private $scopeConfig;
35+
private $collectionProcessor;
3636

3737
/**
38-
* @var CategoryListInterface
38+
* @var JoinProcessorInterface
3939
*/
40-
private $categoryList;
40+
private $extensionAttributesJoinProcessor;
4141

4242
/**
43-
* @var Builder
43+
* @var CategorySearchResultsInterfaceFactory
4444
*/
45-
private $searchCriteriaBuilder;
45+
private $categorySearchResultsFactory;
4646

4747
/**
48-
* @param ScopeConfigInterface $scopeConfig
49-
* @param CategoryListInterface $categoryList
50-
* @param Builder $searchCriteriaBuilder
48+
* @var CategoryRepositoryInterface
49+
*/
50+
private $categoryRepository;
51+
52+
/**
53+
* @var SearchCriteria
54+
*/
55+
private $searchCriteria;
56+
57+
/**
58+
* @param CollectionFactory $categoryCollectionFactory
59+
* @param CollectionProcessorInterface $collectionProcessor
60+
* @param JoinProcessorInterface $extensionAttributesJoinProcessor
61+
* @param CategorySearchResultsInterfaceFactory $categorySearchResultsFactory
62+
* @param CategoryRepositoryInterface $categoryRepository
63+
* @param SearchCriteria $searchCriteria
5164
*/
5265
public function __construct(
53-
ScopeConfigInterface $scopeConfig,
54-
CategoryListInterface $categoryList,
55-
Builder $searchCriteriaBuilder
66+
CollectionFactory $categoryCollectionFactory,
67+
CollectionProcessorInterface $collectionProcessor,
68+
JoinProcessorInterface $extensionAttributesJoinProcessor,
69+
CategorySearchResultsInterfaceFactory $categorySearchResultsFactory,
70+
CategoryRepositoryInterface $categoryRepository,
71+
SearchCriteria $searchCriteria
5672
) {
57-
$this->scopeConfig = $scopeConfig;
58-
$this->categoryList = $categoryList;
59-
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
73+
$this->categoryCollectionFactory = $categoryCollectionFactory;
74+
$this->collectionProcessor = $collectionProcessor;
75+
$this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
76+
$this->categorySearchResultsFactory = $categorySearchResultsFactory;
77+
$this->categoryRepository = $categoryRepository;
78+
$this->searchCriteria = $searchCriteria;
6079
}
6180

6281
/**
6382
* Search for categories
6483
*
6584
* @param array $criteria
6685
* @param StoreInterface $store
86+
* @param array $attributeNames
87+
* @param ContextInterface $context
6788
* @return int[]
6889
* @throws InputException
6990
*/
70-
public function getResult(array $criteria, StoreInterface $store)
91+
public function getResult(array $criteria, StoreInterface $store, array $attributeNames, ContextInterface $context)
7192
{
72-
$categoryIds = [];
73-
$criteria[Filter::ARGUMENT_NAME] = $this->formatMatchFilters($criteria['filters'], $store);
74-
$criteria[Filter::ARGUMENT_NAME][CategoryInterface::KEY_IS_ACTIVE] = ['eq' => 1];
75-
$criteria[Sort::ARGUMENT_NAME][CategoryInterface::KEY_POSITION] = ['ASC'];
76-
$searchCriteria = $this->searchCriteriaBuilder->build('categoryList', $criteria);
77-
$pageSize = $criteria['pageSize'] ?? 20;
78-
$currentPage = $criteria['currentPage'] ?? 1;
79-
$searchCriteria->setPageSize($pageSize)->setCurrentPage($currentPage);
93+
$searchCriteria = $this->searchCriteria->buildCriteria($criteria, $store);
94+
$collection = $this->categoryCollectionFactory->create();
95+
$this->extensionAttributesJoinProcessor->process($collection);
96+
$this->collectionProcessor->process($collection, $searchCriteria, $attributeNames, $context);
97+
98+
/** @var CategorySearchResultsInterface $searchResult */
99+
$categories = $this->categorySearchResultsFactory->create();
100+
$categories->setSearchCriteria($searchCriteria);
101+
$categories->setItems($collection->getItems());
102+
$categories->setTotalCount($collection->getSize());
80103

81-
$categories = $this->categoryList->getList($searchCriteria);
104+
$categoryIds = [];
82105
foreach ($categories->getItems() as $category) {
83106
$categoryIds[] = (int)$category->getId();
84107
}
@@ -106,35 +129,4 @@ public function getResult(array $criteria, StoreInterface $store)
106129
]
107130
];
108131
}
109-
110-
/**
111-
* Format match filters to behave like fuzzy match
112-
*
113-
* @param array $filters
114-
* @param StoreInterface $store
115-
* @return array
116-
* @throws InputException
117-
*/
118-
private function formatMatchFilters(array $filters, StoreInterface $store): array
119-
{
120-
$minQueryLength = $this->scopeConfig->getValue(
121-
Query::XML_PATH_MIN_QUERY_LENGTH,
122-
ScopeInterface::SCOPE_STORE,
123-
$store
124-
);
125-
126-
foreach ($filters as $filter => $condition) {
127-
$conditionType = current(array_keys($condition));
128-
if ($conditionType === 'match') {
129-
$searchValue = trim(str_replace(self::SPECIAL_CHARACTERS, '', $condition[$conditionType]));
130-
$matchLength = strlen($searchValue);
131-
if ($matchLength < $minQueryLength) {
132-
throw new InputException(__('Invalid match filter. Minimum length is %1.', $minQueryLength));
133-
}
134-
unset($filters[$filter]['match']);
135-
$filters[$filter]['like'] = '%' . $searchValue . '%';
136-
}
137-
}
138-
return $filters;
139-
}
140132
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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\Category\Filter;
9+
10+
use Magento\Catalog\Api\Data\CategoryInterface;
11+
use Magento\Framework\Api\Search\SearchCriteriaInterface;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Framework\Exception\InputException;
14+
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\ArgumentApplier\Filter;
15+
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\ArgumentApplier\Sort;
16+
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\Builder;
17+
use Magento\Search\Model\Query;
18+
use Magento\Store\Api\Data\StoreInterface;
19+
use Magento\Store\Model\ScopeInterface;
20+
21+
/**
22+
* Utility to help transform raw criteria data into SearchCriteriaInterface
23+
*/
24+
class SearchCriteria
25+
{
26+
/**
27+
* @var string
28+
*/
29+
private const SPECIAL_CHARACTERS = '-+~/\\<>\'":*$#@()!,.?`=%&^';
30+
31+
/**
32+
* @var ScopeConfigInterface
33+
*/
34+
private $scopeConfig;
35+
36+
/**
37+
* @var Builder
38+
*/
39+
private $searchCriteriaBuilder;
40+
41+
/**
42+
* @param ScopeConfigInterface $scopeConfig
43+
* @param Builder $searchCriteriaBuilder
44+
*/
45+
public function __construct(
46+
ScopeConfigInterface $scopeConfig,
47+
Builder $searchCriteriaBuilder
48+
) {
49+
$this->scopeConfig = $scopeConfig;
50+
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
51+
}
52+
53+
/**
54+
* Transform raw criteria data into SearchCriteriaInterface
55+
*
56+
* @param array $criteria
57+
* @param StoreInterface $store
58+
* @return SearchCriteriaInterface
59+
* @throws InputException
60+
*/
61+
public function buildCriteria(array $criteria, StoreInterface $store): SearchCriteriaInterface
62+
{
63+
$criteria[Filter::ARGUMENT_NAME] = $this->formatMatchFilters($criteria['filters'], $store);
64+
$criteria[Filter::ARGUMENT_NAME][CategoryInterface::KEY_IS_ACTIVE] = ['eq' => 1];
65+
$criteria[Sort::ARGUMENT_NAME][CategoryInterface::KEY_POSITION] = ['ASC'];
66+
67+
$searchCriteria = $this->searchCriteriaBuilder->build('categoryList', $criteria);
68+
$pageSize = $criteria['pageSize'] ?? 20;
69+
$currentPage = $criteria['currentPage'] ?? 1;
70+
$searchCriteria->setPageSize($pageSize)->setCurrentPage($currentPage);
71+
72+
return $searchCriteria;
73+
}
74+
75+
/**
76+
* Format match filters to behave like fuzzy match
77+
*
78+
* @param array $filters
79+
* @param StoreInterface $store
80+
* @return array
81+
* @throws InputException
82+
*/
83+
private function formatMatchFilters(array $filters, StoreInterface $store): array
84+
{
85+
$minQueryLength = $this->scopeConfig->getValue(
86+
Query::XML_PATH_MIN_QUERY_LENGTH,
87+
ScopeInterface::SCOPE_STORE,
88+
$store
89+
);
90+
91+
foreach ($filters as $filter => $condition) {
92+
$conditionType = current(array_keys($condition));
93+
if ($conditionType === 'match') {
94+
$searchValue = trim(str_replace(self::SPECIAL_CHARACTERS, '', $condition[$conditionType]));
95+
$matchLength = strlen($searchValue);
96+
if ($matchLength < $minQueryLength) {
97+
throw new InputException(__('Invalid match filter. Minimum length is %1.', $minQueryLength));
98+
}
99+
unset($filters[$filter]['match']);
100+
$filters[$filter]['like'] = '%' . $searchValue . '%';
101+
}
102+
}
103+
return $filters;
104+
}
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Categories\DataProvider\Category\CollectionProcessor;
9+
10+
use Magento\Catalog\Model\ResourceModel\Category\Collection;
11+
use Magento\CatalogGraphQl\Model\Resolver\Categories\DataProvider\Category\CollectionProcessorInterface;
12+
use Magento\Framework\Api\SearchCriteriaInterface;
13+
use Magento\GraphQl\Model\Query\ContextInterface;
14+
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface as SearchCriteriaCollectionProcessor;
15+
16+
/**
17+
* Apply pre-defined catalog filtering
18+
*
19+
* {@inheritdoc}
20+
*/
21+
class CatalogProcessor implements CollectionProcessorInterface
22+
{
23+
/** @var SearchCriteriaCollectionProcessor */
24+
private $collectionProcessor;
25+
26+
/**
27+
* @param SearchCriteriaCollectionProcessor $collectionProcessor
28+
*/
29+
public function __construct(
30+
SearchCriteriaCollectionProcessor $collectionProcessor
31+
) {
32+
$this->collectionProcessor = $collectionProcessor;
33+
}
34+
35+
/**
36+
* Process collection to add additional joins, attributes, and clauses to a category collection.
37+
*
38+
* @param Collection $collection
39+
* @param SearchCriteriaInterface $searchCriteria
40+
* @param array $attributeNames
41+
* @param ContextInterface|null $context
42+
* @return Collection
43+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
44+
*/
45+
public function process(
46+
Collection $collection,
47+
SearchCriteriaInterface $searchCriteria,
48+
array $attributeNames,
49+
ContextInterface $context = null
50+
): Collection {
51+
$this->collectionProcessor->process($searchCriteria, $collection);
52+
53+
return $collection;
54+
}
55+
}
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\Categories\DataProvider\Category;
9+
10+
use Magento\Catalog\Model\ResourceModel\Category\Collection;
11+
use Magento\Framework\Api\SearchCriteriaInterface;
12+
use Magento\GraphQl\Model\Query\ContextInterface;
13+
14+
/**
15+
* Add additional joins, attributes, and clauses to a category collection.
16+
*/
17+
interface CollectionProcessorInterface
18+
{
19+
/**
20+
* Process collection to add additional joins, attributes, and clauses to a category collection.
21+
*
22+
* @param Collection $collection
23+
* @param SearchCriteriaInterface $searchCriteria
24+
* @param array $attributeNames
25+
* @param ContextInterface|null $context
26+
* @return Collection
27+
*/
28+
public function process(
29+
Collection $collection,
30+
SearchCriteriaInterface $searchCriteria,
31+
array $attributeNames,
32+
ContextInterface $context = null
33+
): Collection;
34+
}

0 commit comments

Comments
 (0)