Skip to content

Commit

Permalink
Merge pull request #3703 from magento-engcom/graphql-develop-prs
Browse files Browse the repository at this point in the history
[EngCom] Public Pull Requests - GraphQL
  • Loading branch information
naydav authored Feb 11, 2019
2 parents b2f1417 + 81ba7a1 commit 92118f5
Show file tree
Hide file tree
Showing 34 changed files with 1,024 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@
namespace Magento\BundleGraphQl\Model;

use Magento\Framework\GraphQl\Query\Resolver\TypeResolverInterface;
use Magento\Bundle\Model\Product\Type as Type;

/**
* {@inheritdoc}
* @inheritdoc
*/
class BundleProductTypeResolver implements TypeResolverInterface
{
const BUNDLE_PRODUCT = 'BundleProduct';

/**
* {@inheritdoc}
* @inheritdoc
*/
public function resolveType(array $data) : string
{
if (isset($data['type_id']) && $data['type_id'] == 'bundle') {
return 'BundleProduct';
if (isset($data['type_id']) && $data['type_id'] == Type::TYPE_CODE) {
return self::BUNDLE_PRODUCT;
}
return '';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,21 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId): \Iterato

$collection->addFieldToFilter('level', ['gt' => $level]);
$collection->addFieldToFilter('level', ['lteq' => $level + $depth - self::DEPTH_OFFSET]);
$collection->addAttributeToFilter('is_active', 1, "left");
$collection->setOrder('level');
$collection->setOrder(
'position',
$collection::SORT_ORDER_DESC
);
$collection->getSelect()->orWhere(
$this->metadata->getMetadata(CategoryInterface::class)->getIdentifierField() . ' = ?',
$collection->getSelect()
->getConnection()
->quoteIdentifier(
'e.' . $this->metadata->getMetadata(CategoryInterface::class)->getIdentifierField()
) . ' = ?',
$rootCategoryId
);

return $collection->getIterator();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ class ExtractDataFromCategoryTree
*/
private $categoryHydrator;

/**
* @var CategoryInterface
*/
private $iteratingCategory;

/**
* @var int
*/
private $startCategoryFetchLevel = 1;

/**
* @param Hydrator $categoryHydrator
*/
Expand All @@ -42,14 +52,60 @@ public function execute(\Iterator $iterator): array
/** @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);
$pathElements = explode("/", $category->getPath());
if (empty($tree)) {
$this->startCategoryFetchLevel = count($pathElements) - 1;
}
$this->iteratingCategory = $category;
$currentLevelTree = $this->explodePathToArray($pathElements, $this->startCategoryFetchLevel);
if (empty($tree)) {
$tree = $currentLevelTree;
}
$tree = $this->mergeCategoriesTrees($currentLevelTree, $tree);
}
return $tree;
}

/**
* Merge together complex categories trees
*
* @param array $tree1
* @param array $tree2
* @return array
*/
private function mergeCategoriesTrees(array &$tree1, array &$tree2): array
{
$mergedTree = $tree1;
foreach ($tree2 as $currentKey => &$value) {
if (is_array($value) && isset($mergedTree[$currentKey]) && is_array($mergedTree[$currentKey])) {
$mergedTree[$currentKey] = $this->mergeCategoriesTrees($mergedTree[$currentKey], $value);
} else {
$mergedTree[$currentKey] = $value;
}
}
return $mergedTree;
}

/**
* Recursive method to generate tree for one category path
*
* @param array $pathElements
* @param int $index
* @return array
*/
private function explodePathToArray(array $pathElements, int $index): array
{
$tree = [];
$tree[$pathElements[$index]]['id'] = $pathElements[$index];
if ($index === count($pathElements) - 1) {
$tree[$pathElements[$index]] = $this->categoryHydrator->hydrateCategory($this->iteratingCategory);
$tree[$pathElements[$index]]['model'] = $this->iteratingCategory;
}
$currentIndex = $index;
$index++;
if (isset($pathElements[$index])) {
$tree[$pathElements[$currentIndex]]['children'] = $this->explodePathToArray($pathElements, $index);
}
return $tree;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ private function fetch() : array
$this->attributeMap[$productId][$attribute->getId()]['attribute_code']
= $attribute->getProductAttribute()->getAttributeCode();
$this->attributeMap[$productId][$attribute->getId()]['values'] = $attributeData['options'];
$this->attributeMap[$productId][$attribute->getId()]['label']
= $attribute->getProductAttribute()->getStoreLabel();
}

return $this->attributeMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ public function __construct(
}

/**
* Fetch and format configurable variants.
*
* {@inheritDoc}
* @inheritdoc
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
Expand All @@ -85,7 +83,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
return $this->valueFactory->create($result);
}

$this->variantCollection->addParentId((int)$value[$linkField]);
$this->variantCollection->addParentProduct($value['model']);
$fields = $this->getProductFields($info);
$matchedFields = $this->attributeCollection->getRequestAttributes($fields);
$this->variantCollection->addEavAttributes($matchedFields);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace Magento\ConfigurableProductGraphQl\Model\Resolver\Variant;

use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
Expand All @@ -17,9 +19,17 @@
class Attributes implements ResolverInterface
{
/**
* @inheritdoc
*
* Format product's option data to conform to GraphQL schema
*
* {@inheritdoc}
* @param Field $field
* @param ContextInterface $context
* @param ResolveInfo $info
* @param array|null $value
* @param array|null $args
* @throws \Exception
* @return mixed|Value
*/
public function resolve(
Field $field,
Expand All @@ -35,12 +45,12 @@ public function resolve(
$data = [];
foreach ($value['options'] as $option) {
$code = $option['attribute_code'];
if (!isset($value['product'][$code])) {
if (!isset($value['product']['model'][$code])) {
continue;
}

foreach ($option['values'] as $optionValue) {
if ($optionValue['value_index'] != $value['product'][$code]) {
if ($optionValue['value_index'] != $value['product']['model'][$code]) {
continue;
}
$data[] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product;
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory;
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ChildCollection;
use Magento\Catalog\Model\ProductFactory;
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ChildCollection;
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product as DataProvider;
Expand Down Expand Up @@ -47,9 +47,9 @@ class Collection
private $metadataPool;

/**
* @var int[]
* @var Product[]
*/
private $parentIds = [];
private $parentProducts = [];

/**
* @var array
Expand Down Expand Up @@ -83,19 +83,21 @@ public function __construct(
}

/**
* Add parent Id to collection filter
* Add parent to collection filter
*
* @param int $id
* @param Product $product
* @return void
*/
public function addParentId(int $id) : void
public function addParentProduct(Product $product) : void
{
if (!in_array($id, $this->parentIds) && !empty($this->childrenMap)) {
if (isset($this->parentProducts[$product->getId()])) {
return;
}

if (!empty($this->childrenMap)) {
$this->childrenMap = [];
$this->parentIds[] = $id;
} elseif (!in_array($id, $this->parentIds)) {
$this->parentIds[] = $id;
}
$this->parentProducts[$product->getId()] = $product;
}

/**
Expand Down Expand Up @@ -130,20 +132,23 @@ public function getChildProductsByParentId(int $id) : array
* Fetch all children products from parent id's.
*
* @return array
* @throws \Exception
*/
private function fetch() : array
{
if (empty($this->parentIds) || !empty($this->childrenMap)) {
if (empty($this->parentProducts) || !empty($this->childrenMap)) {
return $this->childrenMap;
}

$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
foreach ($this->parentIds as $id) {
foreach ($this->parentProducts as $product) {
$attributeData = $this->getAttributesCodes($product);
/** @var ChildCollection $childCollection */
$childCollection = $this->childCollectionFactory->create();
$childCollection->addAttributeToSelect($attributeData);

/** @var Product $product */
$product = $this->productFactory->create();
$product->setData($linkField, $id);
$product->setData($linkField, $product->getId());
$childCollection->setProductFilter($product);

/** @var Product $childProduct */
Expand All @@ -160,4 +165,24 @@ private function fetch() : array

return $this->childrenMap;
}

/**
* Get attributes code
*
* @param \Magento\Catalog\Model\Product $currentProduct
* @return array
*/
private function getAttributesCodes(Product $currentProduct): array
{
$attributeCodes = [];
$allowAttributes = $currentProduct->getTypeInstance()->getConfigurableAttributes($currentProduct);
foreach ($allowAttributes as $attribute) {
$productAttribute = $attribute->getProductAttribute();
if (!\in_array($productAttribute->getAttributeCode(), $attributeCodes)) {
$attributeCodes[] = $productAttribute->getAttributeCode();
}
}

return $attributeCodes;
}
}
63 changes: 63 additions & 0 deletions app/code/Magento/DirectoryGraphQl/Model/Resolver/Countries.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\DirectoryGraphQl\Model\Resolver;

use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\Reflection\DataObjectProcessor;
use Magento\Directory\Api\CountryInformationAcquirerInterface;
use Magento\Directory\Api\Data\CountryInformationInterface;

/**
* Countries field resolver, used for GraphQL request processing.
*/
class Countries implements ResolverInterface
{
/**
* @var DataObjectProcessor
*/
private $dataProcessor;

/**
* @var CountryInformationAcquirerInterface
*/
private $countryInformationAcquirer;

/**
* @param DataObjectProcessor $dataProcessor
* @param CountryInformationAcquirerInterface $countryInformationAcquirer
*/
public function __construct(
DataObjectProcessor $dataProcessor,
CountryInformationAcquirerInterface $countryInformationAcquirer
) {
$this->dataProcessor = $dataProcessor;
$this->countryInformationAcquirer = $countryInformationAcquirer;
}

/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
$countries = $this->countryInformationAcquirer->getCountriesInfo();

$output = [];
foreach ($countries as $country) {
$output[] = $this->dataProcessor->buildOutputDataArray($country, CountryInformationInterface::class);
}

return $output;
}
}
Loading

0 comments on commit 92118f5

Please sign in to comment.