Skip to content

Commit

Permalink
Merge pull request #7970 from magento-arcticfoxes/B2B-2463
Browse files Browse the repository at this point in the history
B2B-2463: Improve custom attributes metadata fetching for category models in graphql
  • Loading branch information
dhaecker authored Nov 18, 2022
2 parents f3e1661 + 87beb1d commit 7e90ca5
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 76 deletions.
41 changes: 25 additions & 16 deletions app/code/Magento/Catalog/Model/Category/AttributeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ class AttributeRepository implements CategoryAttributeRepositoryInterface
*/
private $eavConfig;

/**
* @var array
*/
private $metadataCache;

/**
* @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
* @param \Magento\Framework\Api\FilterBuilder $filterBuilder
Expand All @@ -48,7 +53,7 @@ public function __construct(
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
{
Expand All @@ -59,7 +64,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function get($attributeCode)
{
Expand All @@ -70,23 +75,27 @@ public function get($attributeCode)
}

/**
* {@inheritdoc}
* @inheritdoc
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function getCustomAttributesMetadata($dataObjectClassName = null)
{
$defaultAttributeSetId = $this->eavConfig
->getEntityType(\Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE)
->getDefaultAttributeSetId();
$searchCriteria = $this->searchCriteriaBuilder->addFilters(
[
$this->filterBuilder
->setField('attribute_set_id')
->setValue($defaultAttributeSetId)
->create(),
]
);

return $this->getList($searchCriteria->create())->getItems();
if (!isset($this->metadataCache[$dataObjectClassName])) {
$defaultAttributeSetId = $this->eavConfig
->getEntityType(\Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE)
->getDefaultAttributeSetId();
$searchCriteria = $this->searchCriteriaBuilder->addFilters(
[
$this->filterBuilder
->setField('attribute_set_id')
->setValue($defaultAttributeSetId)
->create(),
]
);
$this->metadataCache[$dataObjectClassName] = $this->getList($searchCriteria->create())
->getItems();
}
return $this->metadataCache[$dataObjectClassName];
}
}
45 changes: 13 additions & 32 deletions app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@

namespace Magento\CatalogGraphQl\Model\Category;

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Api\Data\CategorySearchResultsInterface;
use Magento\Catalog\Api\Data\CategorySearchResultsInterfaceFactory;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\CatalogGraphQl\Model\Resolver\Categories\DataProvider\Category\CollectionProcessorInterface;
use Magento\CatalogGraphQl\Model\Category\Filter\SearchCriteria;
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
use Magento\Framework\DB\Select;
use Magento\Framework\Exception\InputException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\GraphQl\Model\Query\ContextInterface;
Expand All @@ -39,16 +37,6 @@ class CategoryFilter
*/
private $extensionAttributesJoinProcessor;

/**
* @var CategorySearchResultsInterfaceFactory
*/
private $categorySearchResultsFactory;

/**
* @var CategoryRepositoryInterface
*/
private $categoryRepository;

/**
* @var SearchCriteria
*/
Expand All @@ -58,23 +46,17 @@ class CategoryFilter
* @param CollectionFactory $categoryCollectionFactory
* @param CollectionProcessorInterface $collectionProcessor
* @param JoinProcessorInterface $extensionAttributesJoinProcessor
* @param CategorySearchResultsInterfaceFactory $categorySearchResultsFactory
* @param CategoryRepositoryInterface $categoryRepository
* @param SearchCriteria $searchCriteria
*/
public function __construct(
CollectionFactory $categoryCollectionFactory,
CollectionProcessorInterface $collectionProcessor,
JoinProcessorInterface $extensionAttributesJoinProcessor,
CategorySearchResultsInterfaceFactory $categorySearchResultsFactory,
CategoryRepositoryInterface $categoryRepository,
SearchCriteria $searchCriteria
) {
$this->categoryCollectionFactory = $categoryCollectionFactory;
$this->collectionProcessor = $collectionProcessor;
$this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
$this->categorySearchResultsFactory = $categorySearchResultsFactory;
$this->categoryRepository = $categoryRepository;
$this->searchCriteria = $searchCriteria;
}

Expand All @@ -95,22 +77,21 @@ public function getResult(array $criteria, StoreInterface $store, array $attribu
$this->extensionAttributesJoinProcessor->process($collection);
$this->collectionProcessor->process($collection, $searchCriteria, $attributeNames, $context);

/** @var CategorySearchResultsInterface $searchResult */
$categories = $this->categorySearchResultsFactory->create();
$categories->setSearchCriteria($searchCriteria);
$categories->setItems($collection->getItems());
$categories->setTotalCount($collection->getSize());
// only fetch necessary category entity id
$collection
->getSelect()
->reset(Select::COLUMNS)
->columns(
'e.entity_id'
);

$categoryIds = [];
foreach ($categories->getItems() as $category) {
$categoryIds[] = (int)$category->getId();
}
$categoryIds = $collection->load()->getLoadedIds();

$totalPages = 0;
if ($categories->getTotalCount() > 0 && $searchCriteria->getPageSize() > 0) {
$totalPages = ceil($categories->getTotalCount() / $searchCriteria->getPageSize());
if ($collection->getSize() > 0 && $searchCriteria->getPageSize() > 0) {
$totalPages = ceil($collection->getSize() / $searchCriteria->getPageSize());
}
if ($searchCriteria->getCurrentPage() > $totalPages && $categories->getTotalCount() > 0) {
if ($searchCriteria->getCurrentPage() > $totalPages && $collection->getSize() > 0) {
throw new GraphQlInputException(
__(
'currentPage value %1 specified is greater than the %2 page(s) available.',
Expand All @@ -121,7 +102,7 @@ public function getResult(array $criteria, StoreInterface $store, array $attribu

return [
'category_ids' => $categoryIds,
'total_count' => $categories->getTotalCount(),
'total_count' => $collection->getSize(),
'page_info' => [
'total_pages' => $totalPages,
'page_size' => $searchCriteria->getPageSize(),
Expand Down
6 changes: 5 additions & 1 deletion app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@ public function hydrateCategory(Category $category, $basicFieldsOnly = false) :
if ($basicFieldsOnly) {
$categoryData = $category->getData();
} else {
$categoryData = $this->dataObjectProcessor->buildOutputDataArray($category, CategoryInterface::class);
$categoryData = $this->dataObjectProcessor->buildOutputDataArray(
$category,
CategoryInterface::class
);
}

$categoryData['id'] = $category->getId();
$categoryData['uid'] = $this->uidEncoder->encode((string) $category->getId());
$categoryData['children'] = [];
Expand Down
17 changes: 17 additions & 0 deletions app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@
<type name="Magento\Catalog\Api\ProductRepositoryInterface">
<plugin name="availableProductsFilter" type="Magento\CatalogGraphQl\Plugin\AvailableProductsFilter" />
</type>
<type name="Magento\CatalogGraphQl\Model\Category\Hydrator">
<arguments>
<argument name="dataObjectProcessor" xsi:type="object">Magento\CatalogGraphQl\Category\DataObjectProcessor</argument>
</arguments>
</type>
<virtualType name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ChildProduct"
type="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product">
<arguments>
Expand All @@ -207,4 +212,16 @@
</argument>
</arguments>
</virtualType>
<virtualType
name="Magento\CatalogGraphQl\Category\DataObjectProcessor"
type="Magento\Framework\Reflection\DataObjectProcessor"
>
<arguments>
<argument name="excludedMethodsClassMap" xsi:type="array">
<item name="Magento\Catalog\Api\Data\CategoryInterface" xsi:type="array">
<item name="getChildren" xsi:type="string">getChildren</item>
</item>
</argument>
</arguments>
</virtualType>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,36 @@ class DataObjectProcessor
*/
private $processors;

/**
* @var array[]
*/
private $excludedMethodsClassMap;

/**
* @param MethodsMap $methodsMapProcessor
* @param TypeCaster $typeCaster
* @param FieldNamer $fieldNamer
* @param CustomAttributesProcessor $customAttributesProcessor
* @param ExtensionAttributesProcessor $extensionAttributesProcessor
* @param array $processors
* @param array $excludedMethodsClassMap
*/
public function __construct(
MethodsMap $methodsMapProcessor,
TypeCaster $typeCaster,
FieldNamer $fieldNamer,
CustomAttributesProcessor $customAttributesProcessor,
ExtensionAttributesProcessor $extensionAttributesProcessor,
array $processors = []
array $processors = [],
array $excludedMethodsClassMap = []
) {
$this->methodsMapProcessor = $methodsMapProcessor;
$this->typeCaster = $typeCaster;
$this->fieldNamer = $fieldNamer;
$this->extensionAttributesProcessor = $extensionAttributesProcessor;
$this->customAttributesProcessor = $customAttributesProcessor;
$this->processors = $processors;
$this->excludedMethodsClassMap = $excludedMethodsClassMap;
}

/**
Expand All @@ -84,7 +92,13 @@ public function buildOutputDataArray($dataObject, $dataObjectType)
$methods = $this->methodsMapProcessor->getMethodsMap($dataObjectType);
$outputData = [];

$excludedMethodsForDataObjectType = $this->excludedMethodsClassMap[$dataObjectType] ?? [];

foreach (array_keys($methods) as $methodName) {
if (in_array($methodName, $excludedMethodsForDataObjectType)) {
continue;
}

if (!$this->methodsMapProcessor->isMethodValidForDataField($dataObjectType, $methodName)) {
continue;
}
Expand Down
Loading

0 comments on commit 7e90ca5

Please sign in to comment.