Skip to content

Commit

Permalink
Merge pull request #5853 from magento-engcom/2.4-develop-graphql-prs
Browse files Browse the repository at this point in the history
[GraphQL] Partners Acceleration Program Contributions - 2.4-develop
  • Loading branch information
cpartica authored Jun 27, 2020
2 parents 78a236b + db55e32 commit ba25897
Show file tree
Hide file tree
Showing 50 changed files with 1,402 additions and 147 deletions.
8 changes: 4 additions & 4 deletions app/code/Magento/Catalog/Model/Layer/Filter/Price/Render.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public function renderRangeLabel($fromPrice, $toPrice)
}

/**
* Prepare range data
*
* @param int $range
* @param int[] $dbRanges
* @return array
Expand All @@ -81,12 +83,10 @@ public function renderRangeData($range, $dbRanges)
if (empty($dbRanges)) {
return [];
}
$lastIndex = array_keys($dbRanges);
$lastIndex = $lastIndex[count($lastIndex) - 1];

foreach ($dbRanges as $index => $count) {
$fromPrice = $index == 1 ? '' : ($index - 1) * $range;
$toPrice = $index == $lastIndex ? '' : $index * $range;
$fromPrice = $index == 1 ? 0 : ($index - 1) * $range;
$toPrice = $index * $range;
$this->itemDataBuilder->addItemData(
$this->renderRangeLabel($fromPrice, $toPrice),
$fromPrice . '-' . $toPrice,
Expand Down
62 changes: 55 additions & 7 deletions app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
namespace Magento\CatalogGraphQl\Model;

use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\InlineFragmentNode;
use GraphQL\Language\AST\NodeKind;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Joins attributes for provided field node field names.
Expand Down Expand Up @@ -43,11 +46,12 @@ public function __construct(array $fieldToAttributeMap = [])
*
* @param FieldNode $fieldNode
* @param AbstractCollection $collection
* @param ResolveInfo $resolveInfo
* @return void
*/
public function join(FieldNode $fieldNode, AbstractCollection $collection): void
public function join(FieldNode $fieldNode, AbstractCollection $collection, ResolveInfo $resolveInfo): void
{
foreach ($this->getQueryFields($fieldNode) as $field) {
foreach ($this->getQueryFields($fieldNode, $resolveInfo) as $field) {
$this->addFieldToCollection($collection, $field);
}
}
Expand All @@ -56,26 +60,70 @@ public function join(FieldNode $fieldNode, AbstractCollection $collection): void
* Get an array of queried fields.
*
* @param FieldNode $fieldNode
* @param ResolveInfo $resolveInfo
* @return string[]
*/
public function getQueryFields(FieldNode $fieldNode): array
public function getQueryFields(FieldNode $fieldNode, ResolveInfo $resolveInfo): array
{
if (null === $this->getFieldNodeSelections($fieldNode)) {
$query = $fieldNode->selectionSet->selections;
$selectedFields = [];
$fragmentFields = [];
/** @var FieldNode $field */
foreach ($query as $field) {
if ($field->kind === 'InlineFragment') {
continue;
if ($field->kind === NodeKind::INLINE_FRAGMENT) {
$fragmentFields[] = $this->addInlineFragmentFields($resolveInfo, $field);
} elseif ($field->kind === NodeKind::FRAGMENT_SPREAD &&
($spreadFragmentNode = $resolveInfo->fragments[$field->name->value])) {

foreach ($spreadFragmentNode->selectionSet->selections as $spreadNode) {
if (isset($spreadNode->selectionSet->selections)) {
$fragmentFields[] = $this->getQueryFields($spreadNode, $resolveInfo);
} else {
$selectedFields[] = $spreadNode->name->value;
}
}
} else {
$selectedFields[] = $field->name->value;
}
$selectedFields[] = $field->name->value;
}
$this->setSelectionsForFieldNode($fieldNode, $selectedFields);
if ($fragmentFields) {
$selectedFields = array_merge($selectedFields, array_merge(...$fragmentFields));
}
$this->setSelectionsForFieldNode($fieldNode, array_unique($selectedFields));
}

return $this->getFieldNodeSelections($fieldNode);
}

/**
* Add fields from inline fragment nodes
*
* @param ResolveInfo $resolveInfo
* @param InlineFragmentNode $inlineFragmentField
* @param array $inlineFragmentFields
* @return string[]
*/
private function addInlineFragmentFields(
ResolveInfo $resolveInfo,
InlineFragmentNode $inlineFragmentField,
$inlineFragmentFields = []
): array {
$query = $inlineFragmentField->selectionSet->selections;
/** @var FieldNode $field */
foreach ($query as $field) {
if ($field->kind === NodeKind::INLINE_FRAGMENT) {
$this->addInlineFragmentFields($resolveInfo, $field, $inlineFragmentFields);
} elseif (isset($field->selectionSet->selections)) {
continue;
} else {
$inlineFragmentFields[] = $field->name->value;
}
}

return array_unique($inlineFragmentFields);
}

/**
* Add field to collection select
*
Expand Down
44 changes: 41 additions & 3 deletions app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
namespace Magento\CatalogGraphQl\Model\Category;

use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\InlineFragmentNode;
use GraphQL\Language\AST\NodeKind;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Used for determining the depth information for a requested category tree in a GraphQL request
Expand All @@ -17,22 +20,57 @@ class DepthCalculator
/**
* Calculate the total depth of a category tree inside a GraphQL request
*
* @param ResolveInfo $resolveInfo
* @param FieldNode $fieldNode
* @return int
*/
public function calculate(FieldNode $fieldNode) : int
public function calculate(ResolveInfo $resolveInfo, FieldNode $fieldNode) : int
{
$selections = $fieldNode->selectionSet->selections ?? [];
$depth = count($selections) ? 1 : 0;
$childrenDepth = [0];
foreach ($selections as $node) {
if ($node->kind === 'InlineFragment' || null !== $node->alias) {
if (isset($node->alias) && null !== $node->alias) {
continue;
}

$childrenDepth[] = $this->calculate($node);
if ($node->kind === NodeKind::INLINE_FRAGMENT) {
$childrenDepth[] = $this->addInlineFragmentDepth($resolveInfo, $node);
} elseif ($node->kind === NodeKind::FRAGMENT_SPREAD && isset($resolveInfo->fragments[$node->name->value])) {
foreach ($resolveInfo->fragments[$node->name->value]->selectionSet->selections as $spreadNode) {
$childrenDepth[] = $this->calculate($resolveInfo, $spreadNode);
}
} else {
$childrenDepth[] = $this->calculate($resolveInfo, $node);
}
}

return $depth + max($childrenDepth);
}

/**
* Add inline fragment fields into calculating of category depth
*
* @param ResolveInfo $resolveInfo
* @param InlineFragmentNode $inlineFragmentField
* @param array $depth
* @return int
*/
private function addInlineFragmentDepth(
ResolveInfo $resolveInfo,
InlineFragmentNode $inlineFragmentField,
$depth = []
): int {
$selections = $inlineFragmentField->selectionSet->selections;
/** @var FieldNode $field */
foreach ($selections as $field) {
if ($field->kind === NodeKind::INLINE_FRAGMENT) {
$depth[] = $this->addInlineFragmentDepth($resolveInfo, $field, $depth);
} elseif ($field->selectionSet && $field->selectionSet->selections) {
$depth[] = $this->calculate($resolveInfo, $field);
}
}

return $depth ? max($depth) : 0;
}
}
14 changes: 7 additions & 7 deletions app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@

namespace Magento\CatalogGraphQl\Model\Resolver;

use Magento\CatalogGraphQl\Model\Resolver\Product\ProductCategories;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Catalog\Api\Data\CategoryInterface;
use Magento\Catalog\Model\ResourceModel\Category\Collection;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\CatalogGraphQl\Model\AttributesJoiner;
use Magento\CatalogGraphQl\Model\Category\Hydrator as CategoryHydrator;
use Magento\CatalogGraphQl\Model\Resolver\Product\ProductCategories;
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CustomAttributesFlattener;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\CatalogGraphQl\Model\Category\Hydrator as CategoryHydrator;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Store\Model\StoreManagerInterface;

/**
Expand Down Expand Up @@ -121,7 +121,7 @@ function () use ($that, $categoryIds, $info) {
}

if (!$this->collection->isLoaded()) {
$that->attributesJoiner->join($info->fieldNodes[0], $this->collection);
$that->attributesJoiner->join($info->fieldNodes[0], $this->collection, $info);
$this->collection->addIdFilter($this->categoryIds);
}
/** @var CategoryInterface | \Magento\Catalog\Model\Category $item */
Expand All @@ -130,7 +130,7 @@ function () use ($that, $categoryIds, $info) {
// Try to extract all requested fields from the loaded collection data
$categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true);
$categories[$item->getId()]['model'] = $item;
$requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]);
$requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0], $info);
$extractedFields = array_keys($categories[$item->getId()]);
$foundFields = array_intersect($requestedFields, $extractedFields);
if (count($requestedFields) === count($foundFields)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Magento\CatalogGraphQl\Model\Resolver\Product;

use GraphQL\Language\AST\NodeKind;
use Magento\Framework\GraphQl\Query\FieldTranslator;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

Expand Down Expand Up @@ -43,9 +44,9 @@ public function getProductFieldsFromInfo(ResolveInfo $info, string $productNodeN
continue;
}
foreach ($node->selectionSet->selections as $selectionNode) {
if ($selectionNode->kind === 'InlineFragment') {
if ($selectionNode->kind === NodeKind::INLINE_FRAGMENT) {
foreach ($selectionNode->selectionSet->selections as $inlineSelection) {
if ($inlineSelection->kind === 'InlineFragment') {
if ($inlineSelection->kind === NodeKind::INLINE_FRAGMENT) {
continue;
}
$fieldNames[] = $this->fieldTranslator->translate($inlineSelection->name->value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider;

use GraphQL\Language\AST\FieldNode;
use Magento\CatalogGraphQl\Model\Category\DepthCalculator;
use Magento\CatalogGraphQl\Model\Category\LevelCalculator;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use GraphQL\Language\AST\NodeKind;
use Magento\Catalog\Api\Data\CategoryInterface;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\ResourceModel\Category\Collection;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\CatalogGraphQl\Model\AttributesJoiner;
use Magento\Catalog\Model\Category;
use Magento\CatalogGraphQl\Model\Category\DepthCalculator;
use Magento\CatalogGraphQl\Model\Category\LevelCalculator;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Category tree data provider
Expand Down Expand Up @@ -85,8 +86,8 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId): \Iterato
{
$categoryQuery = $resolveInfo->fieldNodes[0];
$collection = $this->collectionFactory->create();
$this->joinAttributesRecursively($collection, $categoryQuery);
$depth = $this->depthCalculator->calculate($categoryQuery);
$this->joinAttributesRecursively($collection, $categoryQuery, $resolveInfo);
$depth = $this->depthCalculator->calculate($resolveInfo, $categoryQuery);
$level = $this->levelCalculator->calculate($rootCategoryId);

// If root category is being filter, we've to remove first slash
Expand Down Expand Up @@ -124,24 +125,27 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId): \Iterato
*
* @param Collection $collection
* @param FieldNode $fieldNode
* @param ResolveInfo $resolveInfo
* @return void
*/
private function joinAttributesRecursively(Collection $collection, FieldNode $fieldNode) : void
{
private function joinAttributesRecursively(
Collection $collection,
FieldNode $fieldNode,
ResolveInfo $resolveInfo
): void {
if (!isset($fieldNode->selectionSet->selections)) {
return;
}

$subSelection = $fieldNode->selectionSet->selections;
$this->attributesJoiner->join($fieldNode, $collection);
$this->attributesJoiner->join($fieldNode, $collection, $resolveInfo);

/** @var FieldNode $node */
foreach ($subSelection as $node) {
if ($node->kind === 'InlineFragment') {
if ($node->kind === NodeKind::INLINE_FRAGMENT || $node->kind === NodeKind::FRAGMENT_SPREAD) {
continue;
}

$this->joinAttributesRecursively($collection, $node);
$this->joinAttributesRecursively($collection, $node, $resolveInfo);
}
}
}
23 changes: 11 additions & 12 deletions app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,16 @@ public function getCurrencyRate()
*
* @param float|string $fromPrice
* @param float|string $toPrice
* @param boolean $isLast
* @return float|\Magento\Framework\Phrase
*/
protected function _renderRangeLabel($fromPrice, $toPrice)
protected function _renderRangeLabel($fromPrice, $toPrice, $isLast = false)
{
$fromPrice = empty($fromPrice) ? 0 : $fromPrice * $this->getCurrencyRate();
$toPrice = empty($toPrice) ? $toPrice : $toPrice * $this->getCurrencyRate();

$formattedFromPrice = $this->priceCurrency->format($fromPrice);
if ($toPrice === '') {
if ($isLast) {
return __('%1 and above', $formattedFromPrice);
} elseif ($fromPrice == $toPrice && $this->dataProvider->getOnePriceIntervalValue()) {
return $formattedFromPrice;
Expand Down Expand Up @@ -215,12 +216,15 @@ protected function _getItemsData()

$data = [];
if (count($facets) > 1) { // two range minimum
$lastFacet = array_key_last($facets);
foreach ($facets as $key => $aggregation) {
$count = $aggregation['count'];
if (strpos($key, '_') === false) {
continue;
}
$data[] = $this->prepareData($key, $count, $data);

$isLast = $lastFacet === $key;
$data[] = $this->prepareData($key, $count, $isLast);
}
}

Expand Down Expand Up @@ -264,18 +268,13 @@ protected function getFrom($from)
*
* @param string $key
* @param int $count
* @param boolean $isLast
* @return array
*/
private function prepareData($key, $count)
private function prepareData($key, $count, $isLast = false)
{
list($from, $to) = explode('_', $key);
if ($from == '*') {
$from = $this->getFrom($to);
}
if ($to == '*') {
$to = $this->getTo($to);
}
$label = $this->_renderRangeLabel($from, $to);
[$from, $to] = explode('_', $key);
$label = $this->_renderRangeLabel($from, $to, $isLast);
$value = $from . '-' . $to . $this->dataProvider->getAdditionalRequestData();

$data = [
Expand Down
Loading

0 comments on commit ba25897

Please sign in to comment.