7
7
8
8
namespace Magento \CatalogGraphQl \Model \Category ;
9
9
10
+ use Magento \Catalog \Api \CategoryListInterface ;
10
11
use Magento \Catalog \Api \Data \CategoryInterface ;
11
- use Magento \Catalog \Model \ResourceModel \Category \Collection ;
12
12
use Magento \Framework \App \Config \ScopeConfigInterface ;
13
13
use Magento \Framework \Exception \InputException ;
14
+ use Magento \Framework \GraphQl \Query \Resolver \Argument \SearchCriteria \ArgumentApplier \Filter ;
15
+ use Magento \Search \Model \Query ;
14
16
use Magento \Store \Api \Data \StoreInterface ;
15
17
use Magento \Store \Model \ScopeInterface ;
16
- use Magento \Search \ Model \Query ;
18
+ use Magento \Framework \ GraphQl \Query \ Resolver \ Argument \ SearchCriteria \ Builder ;
17
19
18
20
/**
19
21
* Category filter allows to filter collection using 'id, url_key, name' from search criteria.
@@ -25,78 +27,86 @@ class CategoryFilter
25
27
*/
26
28
private $ scopeConfig ;
27
29
30
+ /**
31
+ * @var CategoryListInterface
32
+ */
33
+ private $ categoryList ;
34
+
35
+ /**
36
+ * @var Builder
37
+ */
38
+ private $ searchCriteriaBuilder ;
39
+
28
40
/**
29
41
* @param ScopeConfigInterface $scopeConfig
42
+ * @param CategoryListInterface $categoryList
43
+ * @param Builder $searchCriteriaBuilder
30
44
*/
31
45
public function __construct (
32
- ScopeConfigInterface $ scopeConfig
46
+ ScopeConfigInterface $ scopeConfig ,
47
+ CategoryListInterface $ categoryList ,
48
+ Builder $ searchCriteriaBuilder
33
49
) {
34
50
$ this ->scopeConfig = $ scopeConfig ;
51
+ $ this ->categoryList = $ categoryList ;
52
+ $ this ->searchCriteriaBuilder = $ searchCriteriaBuilder ;
35
53
}
36
54
37
55
/**
38
- * Filter for filtering the requested categories id's based on url_key, ids, name in the result.
56
+ * Search for categories, return list of ids
39
57
*
40
- * @param array $args
41
- * @param Collection $categoryCollection
58
+ * @param array $criteria
42
59
* @param StoreInterface $store
43
- * @throws InputException
60
+ * @return int[]
44
61
*/
45
- public function applyFilters (array $ args , Collection $ categoryCollection , StoreInterface $ store )
62
+ public function getCategoryIds (array $ criteria , StoreInterface $ store ): array
46
63
{
47
- $ categoryCollection ->addAttributeToFilter (CategoryInterface::KEY_IS_ACTIVE , ['eq ' => 1 ]);
48
- foreach ($ args ['filters ' ] as $ field => $ cond ) {
49
- foreach ($ cond as $ condType => $ value ) {
50
- if ($ field === 'ids ' ) {
51
- $ categoryCollection ->addIdFilter ($ value );
52
- } else {
53
- $ this ->addAttributeFilter ($ categoryCollection , $ field , $ condType , $ value , $ store );
54
- }
55
- }
64
+ $ categoryIds = [];
65
+ try {
66
+ $ criteria [Filter::ARGUMENT_NAME ] = $ this ->formatMatchFilters ($ criteria ['filters ' ], $ store );
67
+ } catch (InputException $ e ) {
68
+ //Return empty set when match filter is too short. (matches search api behavior)
69
+ return $ categoryIds ;
56
70
}
57
- }
71
+ $ criteria [Filter:: ARGUMENT_NAME ][CategoryInterface:: KEY_IS_ACTIVE ] = [ ' eq ' => 1 ];
58
72
59
- /**
60
- * Add filter to category collection
61
- *
62
- * @param Collection $categoryCollection
63
- * @param string $field
64
- * @param string $condType
65
- * @param string|array $value
66
- * @param StoreInterface $store
67
- * @throws InputException
68
- */
69
- private function addAttributeFilter ($ categoryCollection , $ field , $ condType , $ value , $ store )
70
- {
71
- if ($ condType === 'match ' ) {
72
- $ this ->addMatchFilter ($ categoryCollection , $ field , $ value , $ store );
73
- return ;
73
+ $ searchCriteria = $ this ->searchCriteriaBuilder ->build ('categoryList ' , $ criteria );
74
+ $ categories = $ this ->categoryList ->getList ($ searchCriteria );
75
+ foreach ($ categories ->getItems () as $ category ) {
76
+ $ categoryIds [] = (int )$ category ->getId ();
74
77
}
75
- $ categoryCollection -> addAttributeToFilter ( $ field , [ $ condType => $ value ]) ;
78
+ return $ categoryIds ;
76
79
}
77
80
78
81
/**
79
- * Add match filter to collection
82
+ * Format match filters to behave like fuzzy match
80
83
*
81
- * @param Collection $categoryCollection
82
- * @param string $field
83
- * @param string $value
84
+ * @param array $filters
84
85
* @param StoreInterface $store
86
+ * @return array
85
87
* @throws InputException
86
88
*/
87
- private function addMatchFilter ( $ categoryCollection , $ field , $ value , $ store )
89
+ private function formatMatchFilters ( array $ filters , StoreInterface $ store ): array
88
90
{
89
91
$ minQueryLength = $ this ->scopeConfig ->getValue (
90
92
Query::XML_PATH_MIN_QUERY_LENGTH ,
91
93
ScopeInterface::SCOPE_STORE ,
92
94
$ store
93
95
);
94
- $ searchValue = str_replace ('% ' , '' , $ value );
95
- $ matchLength = strlen ($ searchValue );
96
- if ($ matchLength < $ minQueryLength ) {
97
- throw new InputException (__ ('Invalid match filter ' ));
98
- }
99
96
100
- $ categoryCollection ->addAttributeToFilter ($ field , ['like ' => "% {$ searchValue }% " ]);
97
+ foreach ($ filters as $ filter => $ condition ) {
98
+ $ conditionType = array_keys ($ condition )[0 ];
99
+ if ($ conditionType === 'match ' ) {
100
+ $ searchValue = $ condition [$ conditionType ];
101
+ $ matchLength = strlen (trim ($ searchValue ));
102
+ if ($ matchLength < $ minQueryLength ) {
103
+ throw new InputException (__ ('Invalid match filter ' ));
104
+ }
105
+ unset($ filters [$ filter ]['match ' ]);
106
+ $ filters [$ filter ]['like ' ] = '% ' . $ searchValue . '% ' ;
107
+
108
+ }
109
+ }
110
+ return $ filters ;
101
111
}
102
112
}
0 commit comments