Skip to content

Commit

Permalink
Merge pull request #8417 from magento-lynx/eav-graphql
Browse files Browse the repository at this point in the history
  • Loading branch information
svera committed Jul 28, 2023
2 parents ca30c47 + 7b33900 commit 0a834cc
Show file tree
Hide file tree
Showing 59 changed files with 2,197 additions and 996 deletions.
69 changes: 61 additions & 8 deletions app/code/Magento/Catalog/Test/Fixture/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@
use Magento\Catalog\Api\ProductAttributeManagementInterface;
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Attribute as ResourceModelAttribute;
use Magento\Catalog\Model\ResourceModel\Eav\Attribute as EavAttribute;
use Magento\Eav\Model\AttributeFactory;
use Magento\Eav\Setup\EavSetup;
use Magento\Framework\DataObject;
use Magento\TestFramework\Fixture\Api\DataMerger;
use Magento\TestFramework\Fixture\Api\ServiceFactory;
use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface;
use Magento\TestFramework\Fixture\Data\ProcessorInterface;
Expand All @@ -30,12 +34,12 @@ class Attribute implements RevertibleDataFixtureInterface
'is_filterable_in_grid' => true,
'position' => 0,
'apply_to' => [],
'is_searchable' => '0',
'is_visible_in_advanced_search' => '0',
'is_comparable' => '0',
'is_used_for_promo_rules' => '0',
'is_visible_on_front' => '0',
'used_in_product_listing' => '0',
'is_searchable' => false,
'is_visible_in_advanced_search' => false,
'is_comparable' => false,
'is_used_for_promo_rules' => false,
'is_visible_on_front' => false,
'used_in_product_listing' => false,
'is_visible' => true,
'scope' => 'store',
'attribute_code' => 'product_attribute%uniqid%',
Expand All @@ -49,7 +53,6 @@ class Attribute implements RevertibleDataFixtureInterface
'backend_type' => 'varchar',
'is_unique' => '0',
'validation_rules' => []

];

private const DEFAULT_ATTRIBUTE_SET_DATA = [
Expand Down Expand Up @@ -78,29 +81,59 @@ class Attribute implements RevertibleDataFixtureInterface
*/
private $productAttributeManagement;

/**
* @var AttributeFactory
*/
private AttributeFactory $attributeFactory;

/**
* @var DataMerger
*/
private DataMerger $dataMerger;

/**
* @var ResourceModelAttribute
*/
private ResourceModelAttribute $resourceModelAttribute;

/**
* @param ServiceFactory $serviceFactory
* @param ProcessorInterface $dataProcessor
* @param EavSetup $eavSetup
* @param ProductAttributeManagementInterface $productAttributeManagement
* @param AttributeFactory $attributeFactory
* @param DataMerger $dataMerger
* @param ResourceModelAttribute $resourceModelAttribute
*/
public function __construct(
ServiceFactory $serviceFactory,
ProcessorInterface $dataProcessor,
EavSetup $eavSetup,
ProductAttributeManagementInterface $productAttributeManagement
ProductAttributeManagementInterface $productAttributeManagement,
AttributeFactory $attributeFactory,
DataMerger $dataMerger,
ResourceModelAttribute $resourceModelAttribute
) {
$this->serviceFactory = $serviceFactory;
$this->dataProcessor = $dataProcessor;
$this->eavSetup = $eavSetup;
$this->productAttributeManagement = $productAttributeManagement;
$this->attributeFactory = $attributeFactory;
$this->dataMerger = $dataMerger;
$this->resourceModelAttribute = $resourceModelAttribute;
}

/**
* {@inheritdoc}
* @param array $data Parameters. Same format as Attribute::DEFAULT_DATA.
* @return DataObject|null
*/
public function apply(array $data = []): ?DataObject
{
if (array_key_exists('additional_data', $data)) {
return $this->applyAttributeWithAdditionalData($data);
}

$service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'save');

/**
Expand Down Expand Up @@ -139,6 +172,26 @@ public function revert(DataObject $data): void
);
}

/**
* @param array $data Parameters. Same format as Attribute::DEFAULT_DATA.
* @return DataObject|null
*/
private function applyAttributeWithAdditionalData(array $data = []): ?DataObject
{
$defaultData = array_merge(self::DEFAULT_DATA, ['additional_data' => null]);
/** @var EavAttribute $attr */
$attr = $this->attributeFactory->createAttribute(EavAttribute::class, $defaultData);
$mergedData = $this->dataProcessor->process($this, $this->dataMerger->merge($defaultData, $data));

$attributeSetData = $this->prepareAttributeSetData(
array_intersect_key($data, self::DEFAULT_ATTRIBUTE_SET_DATA)
);

$attr->setData(array_merge($mergedData, $attributeSetData));
$this->resourceModelAttribute->save($attr);
return $attr;
}

/**
* Prepare attribute data
*
Expand Down
22 changes: 16 additions & 6 deletions app/code/Magento/CatalogGraphQl/Model/Output/AttributeMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,32 @@ public function execute(
}

$metadata = [
'is_searchable' => $attribute->getIsSearchable() === "1",
'is_filterable' => $attribute->getIsFilterable() === "1",
'is_comparable' => $attribute->getIsComparable() === "1",
'is_filterable' => $attribute->getIsFilterable() === "1",
'is_filterable_in_search' => $attribute->getIsFilterableInSearch() === "1",
'is_searchable' => $attribute->getIsSearchable() === "1",
'is_html_allowed_on_front' => $attribute->getIsHtmlAllowedOnFront() === "1",
'is_used_for_price_rules' => $attribute->getIsUsedForPriceRules() === "1",
'is_filterable_in_search' => $attribute->getIsFilterableInSearch() === "1",
'used_in_product_listing' => $attribute->getUsedInProductListing() === "1",
'is_wysiwyg_enabled' => $attribute->getIsWysiwygEnabled() === "1",
'is_used_for_promo_rules' => $attribute->getIsUsedForPromoRules() === "1",
'apply_to' => null,
'is_visible_in_advanced_search' => $attribute->getIsVisibleInAdvancedSearch() === "1",
'is_visible_on_front' => $attribute->getIsVisibleOnFront() === "1",
'is_wysiwyg_enabled' => $attribute->getIsWysiwygEnabled() === "1",
'used_in_product_listing' => $attribute->getUsedInProductListing() === "1",
'apply_to' => null
];

if (!empty($attribute->getApplyTo())) {
$metadata['apply_to'] = array_map('strtoupper', $attribute->getApplyTo());
}

if (!empty($attribute->getAdditionalData())) {
$additionalData = json_decode($attribute->getAdditionalData(), true);
$metadata = array_merge(
$metadata,
array_map('strtoupper', $additionalData)
);
}

return $metadata;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
use Magento\Catalog\Model\Product;
use Magento\CatalogGraphQl\Model\ProductDataProvider;
use Magento\Eav\Api\Data\AttributeInterface;
use Magento\Eav\Model\AttributeRepository;
use Magento\EavGraphQl\Model\Output\Value\GetAttributeValueInterface;
use Magento\EavGraphQl\Model\Resolver\AttributeFilter;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\EavGraphQl\Model\Resolver\GetFilteredAttributes;
use Magento\GraphQl\Model\Query\ContextInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
Expand All @@ -27,16 +25,6 @@
*/
class ProductCustomAttributes implements ResolverInterface
{
/**
* @var AttributeRepository
*/
private AttributeRepository $attributeRepository;

/**
* @var SearchCriteriaBuilder
*/
private SearchCriteriaBuilder $searchCriteriaBuilder;

/**
* @var GetAttributeValueInterface
*/
Expand All @@ -48,36 +36,30 @@ class ProductCustomAttributes implements ResolverInterface
private ProductDataProvider $productDataProvider;

/**
* @var AttributeFilter
* @var GetFilteredAttributes
*/
private AttributeFilter $attributeFilter;
private GetFilteredAttributes $getFilteredAttributes;

/**
* @var FilterProductCustomAttribute
*/
private FilterProductCustomAttribute $filterCustomAttribute;

/**
* @param AttributeRepository $attributeRepository
* @param SearchCriteriaBuilder $searchCriteriaBuilder
* @param GetAttributeValueInterface $getAttributeValue
* @param ProductDataProvider $productDataProvider
* @param AttributeFilter $attributeFilter
* @param GetFilteredAttributes $getFilteredAttributes
* @param FilterProductCustomAttribute $filterCustomAttribute
*/
public function __construct(
AttributeRepository $attributeRepository,
SearchCriteriaBuilder $searchCriteriaBuilder,
GetAttributeValueInterface $getAttributeValue,
ProductDataProvider $productDataProvider,
AttributeFilter $attributeFilter,
GetFilteredAttributes $getFilteredAttributes,
FilterProductCustomAttribute $filterCustomAttribute
) {
$this->attributeRepository = $attributeRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->getAttributeValue = $getAttributeValue;
$this->productDataProvider = $productDataProvider;
$this->attributeFilter = $attributeFilter;
$this->getFilteredAttributes = $getFilteredAttributes;
$this->filterCustomAttribute = $filterCustomAttribute;
}

Expand All @@ -99,25 +81,18 @@ public function resolve(
array $value = null,
array $args = null
) {
$filterArgs = $args['filter'] ?? [];
$filtersArgs = $args['filters'] ?? [];

$searchCriteriaBuilder = $this->attributeFilter->execute($filterArgs, $this->searchCriteriaBuilder);

$searchCriteriaBuilder = $searchCriteriaBuilder
->addFilter('is_visible', true)
->addFilter('backend_type', 'static', 'neq')
->create();

$productCustomAttributes = $this->attributeRepository->getList(
ProductAttributeInterface::ENTITY_TYPE_CODE,
$searchCriteriaBuilder
)->getItems();
$productCustomAttributes = $this->getFilteredAttributes->execute(
$filtersArgs,
ProductAttributeInterface::ENTITY_TYPE_CODE
);

$attributeCodes = array_map(
function (AttributeInterface $customAttribute) {
return $customAttribute->getAttributeCode();
},
$productCustomAttributes
$productCustomAttributes['items']
);

$filteredAttributeCodes = $this->filterCustomAttribute->execute(array_flip($attributeCodes));
Expand All @@ -141,15 +116,18 @@ function (AttributeInterface $customAttribute) {
];
}

return array_map(
function (array $customAttribute) {
return $this->getAttributeValue->execute(
ProductAttributeInterface::ENTITY_TYPE_CODE,
$customAttribute['attribute_code'],
$customAttribute['value']
);
},
$customAttributes
);
return [
'items' => array_map(
function (array $customAttribute) {
return $this->getAttributeValue->execute(
ProductAttributeInterface::ENTITY_TYPE_CODE,
$customAttribute['attribute_code'],
$customAttribute['value']
);
},
$customAttributes
),
'errors' => $productCustomAttributes['errors']
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,46 +114,44 @@ public function testBuild(): void
->method('getAttribute')
->with(Product::ENTITY, 'price')
->willReturn($attributeInterface);
$sortOrderList = ['relevance','_id'];
$sortIncrementIndex = 0;
foreach ($sortOrderList as $sortList) {
$this->sortOrderBuilder->expects($this->at($sortIncrementIndex++))
->method('setField')
->with($sortList)
->willReturnSelf();
$this->sortOrderBuilder->expects($this->at($sortIncrementIndex++))
->method('setDirection')
->with('DESC')
->willReturnSelf();
$this->sortOrderBuilder->expects($this->at($sortIncrementIndex++))
->method('create')
->willReturn([]);
}
$filterOrderList = [1=>'search_term', 2=>'visibility'];
$filterIncrementIndex = 0;
foreach ($filterOrderList as $index => $filterList) {
$this->filterBuilder->expects($this->at($filterIncrementIndex++))
->method('setField')
->with($filterList)
->willReturnSelf();
$this->filterBuilder->expects($this->at($filterIncrementIndex++))
->method('setValue')
->with('')
->willReturnSelf();
if ($index==2) {
$this->filterBuilder->expects($this->at($filterIncrementIndex++))
->method('setConditionType')
->with('in')
->willReturnSelf();
} else {
$this->filterBuilder->expects($this->at($filterIncrementIndex++))
->method('setConditionType')
->with('')
->willReturnSelf();
}

$this->filterBuilder->expects($this->at($filterIncrementIndex++))->method('create')->willReturn($filter);
}
$sortOrderList = ['relevance', '_id'];

$this->sortOrderBuilder->expects($this->exactly(2))
->method('setField')
->withConsecutive([$sortOrderList[0]], [$sortOrderList[1]])
->willReturnSelf();

$this->sortOrderBuilder->expects($this->exactly(2))
->method('setDirection')
->with('DESC')
->willReturnSelf();

$this->sortOrderBuilder->expects($this->exactly(2))
->method('create')
->willReturn([]);

$filterOrderList = ['search_term', 'visibility'];

$this->filterBuilder->expects($this->exactly(2))
->method('setField')
->withConsecutive([$filterOrderList[0]], [$filterOrderList[1]])
->willReturnSelf();

$this->filterBuilder->expects($this->exactly(2))
->method('setValue')
->with('')
->willReturnSelf();

$this->filterBuilder->expects($this->exactly(2))
->method('setConditionType')
->withConsecutive([''], ['in'])
->willReturnSelf();

$this->filterBuilder
->expects($this->exactly(2))
->method('create')
->willReturn($filter);

$this->filterGroupBuilder->expects($this->any())
->method('addFilter')
->with($filter)
Expand Down
Loading

0 comments on commit 0a834cc

Please sign in to comment.