Skip to content

Commit ba25897

Browse files
authored
Merge pull request #5853 from magento-engcom/2.4-develop-graphql-prs
[GraphQL] Partners Acceleration Program Contributions - 2.4-develop
2 parents 78a236b + db55e32 commit ba25897

File tree

50 files changed

+1402
-147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1402
-147
lines changed

app/code/Magento/Catalog/Model/Layer/Filter/Price/Render.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public function renderRangeLabel($fromPrice, $toPrice)
7272
}
7373

7474
/**
75+
* Prepare range data
76+
*
7577
* @param int $range
7678
* @param int[] $dbRanges
7779
* @return array
@@ -81,12 +83,10 @@ public function renderRangeData($range, $dbRanges)
8183
if (empty($dbRanges)) {
8284
return [];
8385
}
84-
$lastIndex = array_keys($dbRanges);
85-
$lastIndex = $lastIndex[count($lastIndex) - 1];
8686

8787
foreach ($dbRanges as $index => $count) {
88-
$fromPrice = $index == 1 ? '' : ($index - 1) * $range;
89-
$toPrice = $index == $lastIndex ? '' : $index * $range;
88+
$fromPrice = $index == 1 ? 0 : ($index - 1) * $range;
89+
$toPrice = $index * $range;
9090
$this->itemDataBuilder->addItemData(
9191
$this->renderRangeLabel($fromPrice, $toPrice),
9292
$fromPrice . '-' . $toPrice,

app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
namespace Magento\CatalogGraphQl\Model;
99

1010
use GraphQL\Language\AST\FieldNode;
11+
use GraphQL\Language\AST\InlineFragmentNode;
12+
use GraphQL\Language\AST\NodeKind;
1113
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
14+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1215

1316
/**
1417
* Joins attributes for provided field node field names.
@@ -43,11 +46,12 @@ public function __construct(array $fieldToAttributeMap = [])
4346
*
4447
* @param FieldNode $fieldNode
4548
* @param AbstractCollection $collection
49+
* @param ResolveInfo $resolveInfo
4650
* @return void
4751
*/
48-
public function join(FieldNode $fieldNode, AbstractCollection $collection): void
52+
public function join(FieldNode $fieldNode, AbstractCollection $collection, ResolveInfo $resolveInfo): void
4953
{
50-
foreach ($this->getQueryFields($fieldNode) as $field) {
54+
foreach ($this->getQueryFields($fieldNode, $resolveInfo) as $field) {
5155
$this->addFieldToCollection($collection, $field);
5256
}
5357
}
@@ -56,26 +60,70 @@ public function join(FieldNode $fieldNode, AbstractCollection $collection): void
5660
* Get an array of queried fields.
5761
*
5862
* @param FieldNode $fieldNode
63+
* @param ResolveInfo $resolveInfo
5964
* @return string[]
6065
*/
61-
public function getQueryFields(FieldNode $fieldNode): array
66+
public function getQueryFields(FieldNode $fieldNode, ResolveInfo $resolveInfo): array
6267
{
6368
if (null === $this->getFieldNodeSelections($fieldNode)) {
6469
$query = $fieldNode->selectionSet->selections;
6570
$selectedFields = [];
71+
$fragmentFields = [];
6672
/** @var FieldNode $field */
6773
foreach ($query as $field) {
68-
if ($field->kind === 'InlineFragment') {
69-
continue;
74+
if ($field->kind === NodeKind::INLINE_FRAGMENT) {
75+
$fragmentFields[] = $this->addInlineFragmentFields($resolveInfo, $field);
76+
} elseif ($field->kind === NodeKind::FRAGMENT_SPREAD &&
77+
($spreadFragmentNode = $resolveInfo->fragments[$field->name->value])) {
78+
79+
foreach ($spreadFragmentNode->selectionSet->selections as $spreadNode) {
80+
if (isset($spreadNode->selectionSet->selections)) {
81+
$fragmentFields[] = $this->getQueryFields($spreadNode, $resolveInfo);
82+
} else {
83+
$selectedFields[] = $spreadNode->name->value;
84+
}
85+
}
86+
} else {
87+
$selectedFields[] = $field->name->value;
7088
}
71-
$selectedFields[] = $field->name->value;
7289
}
73-
$this->setSelectionsForFieldNode($fieldNode, $selectedFields);
90+
if ($fragmentFields) {
91+
$selectedFields = array_merge($selectedFields, array_merge(...$fragmentFields));
92+
}
93+
$this->setSelectionsForFieldNode($fieldNode, array_unique($selectedFields));
7494
}
7595

7696
return $this->getFieldNodeSelections($fieldNode);
7797
}
7898

99+
/**
100+
* Add fields from inline fragment nodes
101+
*
102+
* @param ResolveInfo $resolveInfo
103+
* @param InlineFragmentNode $inlineFragmentField
104+
* @param array $inlineFragmentFields
105+
* @return string[]
106+
*/
107+
private function addInlineFragmentFields(
108+
ResolveInfo $resolveInfo,
109+
InlineFragmentNode $inlineFragmentField,
110+
$inlineFragmentFields = []
111+
): array {
112+
$query = $inlineFragmentField->selectionSet->selections;
113+
/** @var FieldNode $field */
114+
foreach ($query as $field) {
115+
if ($field->kind === NodeKind::INLINE_FRAGMENT) {
116+
$this->addInlineFragmentFields($resolveInfo, $field, $inlineFragmentFields);
117+
} elseif (isset($field->selectionSet->selections)) {
118+
continue;
119+
} else {
120+
$inlineFragmentFields[] = $field->name->value;
121+
}
122+
}
123+
124+
return array_unique($inlineFragmentFields);
125+
}
126+
79127
/**
80128
* Add field to collection select
81129
*

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

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
namespace Magento\CatalogGraphQl\Model\Category;
99

1010
use GraphQL\Language\AST\FieldNode;
11+
use GraphQL\Language\AST\InlineFragmentNode;
12+
use GraphQL\Language\AST\NodeKind;
13+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1114

1215
/**
1316
* Used for determining the depth information for a requested category tree in a GraphQL request
@@ -17,22 +20,57 @@ class DepthCalculator
1720
/**
1821
* Calculate the total depth of a category tree inside a GraphQL request
1922
*
23+
* @param ResolveInfo $resolveInfo
2024
* @param FieldNode $fieldNode
2125
* @return int
2226
*/
23-
public function calculate(FieldNode $fieldNode) : int
27+
public function calculate(ResolveInfo $resolveInfo, FieldNode $fieldNode) : int
2428
{
2529
$selections = $fieldNode->selectionSet->selections ?? [];
2630
$depth = count($selections) ? 1 : 0;
2731
$childrenDepth = [0];
2832
foreach ($selections as $node) {
29-
if ($node->kind === 'InlineFragment' || null !== $node->alias) {
33+
if (isset($node->alias) && null !== $node->alias) {
3034
continue;
3135
}
3236

33-
$childrenDepth[] = $this->calculate($node);
37+
if ($node->kind === NodeKind::INLINE_FRAGMENT) {
38+
$childrenDepth[] = $this->addInlineFragmentDepth($resolveInfo, $node);
39+
} elseif ($node->kind === NodeKind::FRAGMENT_SPREAD && isset($resolveInfo->fragments[$node->name->value])) {
40+
foreach ($resolveInfo->fragments[$node->name->value]->selectionSet->selections as $spreadNode) {
41+
$childrenDepth[] = $this->calculate($resolveInfo, $spreadNode);
42+
}
43+
} else {
44+
$childrenDepth[] = $this->calculate($resolveInfo, $node);
45+
}
3446
}
3547

3648
return $depth + max($childrenDepth);
3749
}
50+
51+
/**
52+
* Add inline fragment fields into calculating of category depth
53+
*
54+
* @param ResolveInfo $resolveInfo
55+
* @param InlineFragmentNode $inlineFragmentField
56+
* @param array $depth
57+
* @return int
58+
*/
59+
private function addInlineFragmentDepth(
60+
ResolveInfo $resolveInfo,
61+
InlineFragmentNode $inlineFragmentField,
62+
$depth = []
63+
): int {
64+
$selections = $inlineFragmentField->selectionSet->selections;
65+
/** @var FieldNode $field */
66+
foreach ($selections as $field) {
67+
if ($field->kind === NodeKind::INLINE_FRAGMENT) {
68+
$depth[] = $this->addInlineFragmentDepth($resolveInfo, $field, $depth);
69+
} elseif ($field->selectionSet && $field->selectionSet->selections) {
70+
$depth[] = $this->calculate($resolveInfo, $field);
71+
}
72+
}
73+
74+
return $depth ? max($depth) : 0;
75+
}
3876
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@
77

88
namespace Magento\CatalogGraphQl\Model\Resolver;
99

10-
use Magento\CatalogGraphQl\Model\Resolver\Product\ProductCategories;
11-
use Magento\Framework\Exception\LocalizedException;
12-
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1310
use Magento\Catalog\Api\Data\CategoryInterface;
1411
use Magento\Catalog\Model\ResourceModel\Category\Collection;
1512
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
1613
use Magento\CatalogGraphQl\Model\AttributesJoiner;
14+
use Magento\CatalogGraphQl\Model\Category\Hydrator as CategoryHydrator;
15+
use Magento\CatalogGraphQl\Model\Resolver\Product\ProductCategories;
1716
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CustomAttributesFlattener;
17+
use Magento\Framework\Exception\LocalizedException;
1818
use Magento\Framework\GraphQl\Config\Element\Field;
19-
use Magento\Framework\GraphQl\Query\ResolverInterface;
2019
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
21-
use Magento\CatalogGraphQl\Model\Category\Hydrator as CategoryHydrator;
20+
use Magento\Framework\GraphQl\Query\ResolverInterface;
21+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
2222
use Magento\Store\Model\StoreManagerInterface;
2323

2424
/**
@@ -121,7 +121,7 @@ function () use ($that, $categoryIds, $info) {
121121
}
122122

123123
if (!$this->collection->isLoaded()) {
124-
$that->attributesJoiner->join($info->fieldNodes[0], $this->collection);
124+
$that->attributesJoiner->join($info->fieldNodes[0], $this->collection, $info);
125125
$this->collection->addIdFilter($this->categoryIds);
126126
}
127127
/** @var CategoryInterface | \Magento\Catalog\Model\Category $item */
@@ -130,7 +130,7 @@ function () use ($that, $categoryIds, $info) {
130130
// Try to extract all requested fields from the loaded collection data
131131
$categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true);
132132
$categories[$item->getId()]['model'] = $item;
133-
$requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]);
133+
$requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0], $info);
134134
$extractedFields = array_keys($categories[$item->getId()]);
135135
$foundFields = array_intersect($requestedFields, $extractedFields);
136136
if (count($requestedFields) === count($foundFields)) {

app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\CatalogGraphQl\Model\Resolver\Product;
99

10+
use GraphQL\Language\AST\NodeKind;
1011
use Magento\Framework\GraphQl\Query\FieldTranslator;
1112
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1213

@@ -43,9 +44,9 @@ public function getProductFieldsFromInfo(ResolveInfo $info, string $productNodeN
4344
continue;
4445
}
4546
foreach ($node->selectionSet->selections as $selectionNode) {
46-
if ($selectionNode->kind === 'InlineFragment') {
47+
if ($selectionNode->kind === NodeKind::INLINE_FRAGMENT) {
4748
foreach ($selectionNode->selectionSet->selections as $inlineSelection) {
48-
if ($inlineSelection->kind === 'InlineFragment') {
49+
if ($inlineSelection->kind === NodeKind::INLINE_FRAGMENT) {
4950
continue;
5051
}
5152
$fieldNames[] = $this->fieldTranslator->translate($inlineSelection->name->value);

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

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider;
99

1010
use GraphQL\Language\AST\FieldNode;
11-
use Magento\CatalogGraphQl\Model\Category\DepthCalculator;
12-
use Magento\CatalogGraphQl\Model\Category\LevelCalculator;
13-
use Magento\Framework\EntityManager\MetadataPool;
14-
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
11+
use GraphQL\Language\AST\NodeKind;
1512
use Magento\Catalog\Api\Data\CategoryInterface;
13+
use Magento\Catalog\Model\Category;
1614
use Magento\Catalog\Model\ResourceModel\Category\Collection;
1715
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
1816
use Magento\CatalogGraphQl\Model\AttributesJoiner;
19-
use Magento\Catalog\Model\Category;
17+
use Magento\CatalogGraphQl\Model\Category\DepthCalculator;
18+
use Magento\CatalogGraphQl\Model\Category\LevelCalculator;
19+
use Magento\Framework\EntityManager\MetadataPool;
20+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
2021

2122
/**
2223
* Category tree data provider
@@ -85,8 +86,8 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId): \Iterato
8586
{
8687
$categoryQuery = $resolveInfo->fieldNodes[0];
8788
$collection = $this->collectionFactory->create();
88-
$this->joinAttributesRecursively($collection, $categoryQuery);
89-
$depth = $this->depthCalculator->calculate($categoryQuery);
89+
$this->joinAttributesRecursively($collection, $categoryQuery, $resolveInfo);
90+
$depth = $this->depthCalculator->calculate($resolveInfo, $categoryQuery);
9091
$level = $this->levelCalculator->calculate($rootCategoryId);
9192

9293
// If root category is being filter, we've to remove first slash
@@ -124,24 +125,27 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId): \Iterato
124125
*
125126
* @param Collection $collection
126127
* @param FieldNode $fieldNode
128+
* @param ResolveInfo $resolveInfo
127129
* @return void
128130
*/
129-
private function joinAttributesRecursively(Collection $collection, FieldNode $fieldNode) : void
130-
{
131+
private function joinAttributesRecursively(
132+
Collection $collection,
133+
FieldNode $fieldNode,
134+
ResolveInfo $resolveInfo
135+
): void {
131136
if (!isset($fieldNode->selectionSet->selections)) {
132137
return;
133138
}
134139

135140
$subSelection = $fieldNode->selectionSet->selections;
136-
$this->attributesJoiner->join($fieldNode, $collection);
141+
$this->attributesJoiner->join($fieldNode, $collection, $resolveInfo);
137142

138143
/** @var FieldNode $node */
139144
foreach ($subSelection as $node) {
140-
if ($node->kind === 'InlineFragment') {
145+
if ($node->kind === NodeKind::INLINE_FRAGMENT || $node->kind === NodeKind::FRAGMENT_SPREAD) {
141146
continue;
142147
}
143-
144-
$this->joinAttributesRecursively($collection, $node);
148+
$this->joinAttributesRecursively($collection, $node, $resolveInfo);
145149
}
146150
}
147151
}

app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,16 @@ public function getCurrencyRate()
176176
*
177177
* @param float|string $fromPrice
178178
* @param float|string $toPrice
179+
* @param boolean $isLast
179180
* @return float|\Magento\Framework\Phrase
180181
*/
181-
protected function _renderRangeLabel($fromPrice, $toPrice)
182+
protected function _renderRangeLabel($fromPrice, $toPrice, $isLast = false)
182183
{
183184
$fromPrice = empty($fromPrice) ? 0 : $fromPrice * $this->getCurrencyRate();
184185
$toPrice = empty($toPrice) ? $toPrice : $toPrice * $this->getCurrencyRate();
185186

186187
$formattedFromPrice = $this->priceCurrency->format($fromPrice);
187-
if ($toPrice === '') {
188+
if ($isLast) {
188189
return __('%1 and above', $formattedFromPrice);
189190
} elseif ($fromPrice == $toPrice && $this->dataProvider->getOnePriceIntervalValue()) {
190191
return $formattedFromPrice;
@@ -215,12 +216,15 @@ protected function _getItemsData()
215216

216217
$data = [];
217218
if (count($facets) > 1) { // two range minimum
219+
$lastFacet = array_key_last($facets);
218220
foreach ($facets as $key => $aggregation) {
219221
$count = $aggregation['count'];
220222
if (strpos($key, '_') === false) {
221223
continue;
222224
}
223-
$data[] = $this->prepareData($key, $count, $data);
225+
226+
$isLast = $lastFacet === $key;
227+
$data[] = $this->prepareData($key, $count, $isLast);
224228
}
225229
}
226230

@@ -264,18 +268,13 @@ protected function getFrom($from)
264268
*
265269
* @param string $key
266270
* @param int $count
271+
* @param boolean $isLast
267272
* @return array
268273
*/
269-
private function prepareData($key, $count)
274+
private function prepareData($key, $count, $isLast = false)
270275
{
271-
list($from, $to) = explode('_', $key);
272-
if ($from == '*') {
273-
$from = $this->getFrom($to);
274-
}
275-
if ($to == '*') {
276-
$to = $this->getTo($to);
277-
}
278-
$label = $this->_renderRangeLabel($from, $to);
276+
[$from, $to] = explode('_', $key);
277+
$label = $this->_renderRangeLabel($from, $to, $isLast);
279278
$value = $from . '-' . $to . $this->dataProvider->getAdditionalRequestData();
280279

281280
$data = [

0 commit comments

Comments
 (0)