diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php index 6d9f5e33dd55..4e3a8403f313 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php @@ -7,6 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ExtractDataFromCategoryTree; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; @@ -27,16 +28,26 @@ class CategoryTree implements ResolverInterface */ private $categoryTree; + /** + * @var ExtractDataFromCategoryTree + */ + private $extractDataFromCategoryTree; + /** * @param \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree $categoryTree + * @param ExtractDataFromCategoryTree $extractDataFromCategoryTree */ public function __construct( - \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree $categoryTree + \Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree $categoryTree, + ExtractDataFromCategoryTree $extractDataFromCategoryTree ) { $this->categoryTree = $categoryTree; + $this->extractDataFromCategoryTree = $extractDataFromCategoryTree; } /** + * Get category id + * * @param array $args * @return int * @throws GraphQlInputException @@ -62,7 +73,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $rootCategoryId = $this->getCategoryId($args); $categoriesTree = $this->categoryTree->getTree($info, $rootCategoryId); if (!empty($categoriesTree)) { - return current($categoriesTree); + $result = $this->extractDataFromCategoryTree->execute($categoriesTree); + return current($result); } else { return null; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php index 07d8996838e9..f2634574a2d1 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php @@ -9,7 +9,6 @@ use GraphQL\Language\AST\FieldNode; use Magento\CatalogGraphQl\Model\Category\DepthCalculator; -use Magento\CatalogGraphQl\Model\Category\Hydrator; use Magento\CatalogGraphQl\Model\Category\LevelCalculator; use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -17,6 +16,7 @@ use Magento\Catalog\Model\ResourceModel\Category\Collection; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; use Magento\CatalogGraphQl\Model\AttributesJoiner; +use Magento\Catalog\Model\Category; /** * Category tree data provider @@ -53,33 +53,25 @@ class CategoryTree */ private $metadata; - /** - * @var Hydrator - */ - private $hydrator; - /** * @param CollectionFactory $collectionFactory * @param AttributesJoiner $attributesJoiner * @param DepthCalculator $depthCalculator * @param LevelCalculator $levelCalculator * @param MetadataPool $metadata - * @param Hydrator $hydrator */ public function __construct( CollectionFactory $collectionFactory, AttributesJoiner $attributesJoiner, DepthCalculator $depthCalculator, LevelCalculator $levelCalculator, - MetadataPool $metadata, - Hydrator $hydrator + MetadataPool $metadata ) { $this->collectionFactory = $collectionFactory; $this->attributesJoiner = $attributesJoiner; $this->depthCalculator = $depthCalculator; $this->levelCalculator = $levelCalculator; $this->metadata = $metadata; - $this->hydrator = $hydrator; } /** @@ -87,17 +79,26 @@ public function __construct( * * @param ResolveInfo $resolveInfo * @param int $rootCategoryId - * @return array + * @return \Iterator */ - public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId) : array + public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId): \Iterator { $categoryQuery = $resolveInfo->fieldNodes[0]; $collection = $this->collectionFactory->create(); $this->joinAttributesRecursively($collection, $categoryQuery); $depth = $this->depthCalculator->calculate($categoryQuery); $level = $this->levelCalculator->calculate($rootCategoryId); + + // If root category is being filter, we've to remove first slash + if ($rootCategoryId == Category::TREE_ROOT_ID) { + $regExpPathFilter = sprintf('.*%s/[/0-9]*$', $rootCategoryId); + } else { + $regExpPathFilter = sprintf('.*/%s/[/0-9]*$', $rootCategoryId); + } + //Search for desired part of category tree - $collection->addPathFilter(sprintf('.*/%s/[/0-9]*$', $rootCategoryId)); + $collection->addPathFilter($regExpPathFilter); + $collection->addFieldToFilter('level', ['gt' => $level]); $collection->addFieldToFilter('level', ['lteq' => $level + $depth - self::DEPTH_OFFSET]); $collection->setOrder('level'); @@ -105,35 +106,11 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId) : array $this->metadata->getMetadata(CategoryInterface::class)->getIdentifierField() . ' = ?', $rootCategoryId ); - return $this->processTree($collection->getIterator()); - } - - /** - * Iterates through category tree - * - * @param \Iterator $iterator - * @return array - */ - private function processTree(\Iterator $iterator) : array - { - $tree = []; - while ($iterator->valid()) { - /** @var CategoryInterface $category */ - $category = $iterator->current(); - $iterator->next(); - $nextCategory = $iterator->current(); - $tree[$category->getId()] = $this->hydrator->hydrateCategory($category); - $tree[$category->getId()]['model'] = $category; - if ($nextCategory && (int) $nextCategory->getLevel() !== (int) $category->getLevel()) { - $tree[$category->getId()]['children'] = $this->processTree($iterator); - } - } - - return $tree; + return $collection->getIterator(); } /** - * Joins EAV attributes recursively + * Join attributes recursively * * @param Collection $collection * @param FieldNode $fieldNode diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ExtractDataFromCategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ExtractDataFromCategoryTree.php new file mode 100644 index 000000000000..ac8d5709c85b --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ExtractDataFromCategoryTree.php @@ -0,0 +1,55 @@ +categoryHydrator = $categoryHydrator; + } + + /** + * Extract data from category tree + * + * @param \Iterator $iterator + * @return array + */ + public function execute(\Iterator $iterator): array + { + $tree = []; + while ($iterator->valid()) { + /** @var CategoryInterface $category */ + $category = $iterator->current(); + $iterator->next(); + $nextCategory = $iterator->current(); + $tree[$category->getId()] = $this->categoryHydrator->hydrateCategory($category); + $tree[$category->getId()]['model'] = $category; + if ($nextCategory && (int) $nextCategory->getLevel() !== (int) $category->getLevel()) { + $tree[$category->getId()]['children'] = $this->execute($iterator); + } + } + + return $tree; + } +}