Skip to content

Commit

Permalink
Added: new module
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdanwalek committed Oct 19, 2022
1 parent 10d5860 commit 8938a5b
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## [1.0.0] - 2022-10-19
### Added
- created new module.

20 changes: 20 additions & 0 deletions Model/IgnoredFields.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);

namespace StorefrontX\ProductAttributesGraphQl\Model;

class IgnoredFields
{
private array $ignoredFields;

public function __construct(
array $ignoredFields = []
) {
$this->ignoredFields = $ignoredFields;
}

public function getIgnoredFields(): array
{
return $this->ignoredFields;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);

namespace StorefrontX\ProductAttributesGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessorInterface;
use Magento\Eav\Api\Data\AttributeInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\GraphQl\Model\Query\ContextInterface;
use Magento\Eav\Api\AttributeRepositoryInterface;
use Magento\Framework\Api\FilterBuilder;
use Magento\Catalog\Api\Data\ProductAttributeInterface;
use StorefrontX\ProductAttributesGraphQl\Model\IgnoredFields;

class SFXAttributesProcessor implements CollectionProcessorInterface
{
private IgnoredFields $ignoredFields;
private AttributeRepositoryInterface $attributeRepository;
private SearchCriteriaBuilder $searchCriteriaBuilder;
private FilterBuilder $filterBuilder;

public const SFX_ATTR_KEY = 'sfx_attributes';

public function __construct(
AttributeRepositoryInterface $attributeRepository,
SearchCriteriaBuilder $searchCriteriaBuilder,
FilterBuilder $filterBuilder,
IgnoredFields $ignoredFields
) {
$this->attributeRepository = $attributeRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->filterBuilder = $filterBuilder;
$this->ignoredFields = $ignoredFields;
}

/**
* Process collection to add additional joins, attributes, and clauses to a product collection.
*
* @param Collection $collection
* @param SearchCriteriaInterface $searchCriteria
* @param array $attributeNames
* @param ContextInterface|null $context
* @return Collection
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function process(
Collection $collection,
SearchCriteriaInterface $searchCriteria,
array $attributeNames,
ContextInterface $context = null
): Collection {

if (in_array(self::SFX_ATTR_KEY, $attributeNames)) {
$attributes = $this->getAttributes();
foreach ($attributes as $attribute) {
if (!in_array($attribute->getAttributeCode(), $this->ignoredFields->getIgnoredFields())) {
$collection->addAttributeToSelect($attribute->getAttributeCode(), true);
}
}
}

return $collection;
}

/**
* @return AttributeInterface[]
*/
private function getAttributes(): array
{
$attributes = $this->attributeRepository->getList(
ProductAttributeInterface::ENTITY_TYPE_CODE,
$this->searchCriteriaBuilder
->addFilter('is_visible_on_front', 1)
->create()
);
return $attributes->getItems();
}
}
119 changes: 119 additions & 0 deletions Model/Resolver/SFXProductAttributesGraphQl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);

namespace StorefrontX\ProductAttributesGraphQl\Model\Resolver;

use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Exception\LocalizedException;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Model\Product;
use Psr\Log\LoggerInterface;
use StorefrontX\ProductAttributesGraphQl\Model\IgnoredFields;

class SFXProductAttributesGraphQl implements ResolverInterface
{

protected StoreManagerInterface $storeManager;
protected LoggerInterface $logger;
protected array $cachedAttributes = [];
protected IgnoredFields $ignoredFields;

public function __construct(
StoreManagerInterface $storeManager,
LoggerInterface $logger,
IgnoredFields $ignoredFields
) {
$this->storeManager = $storeManager;
$this->logger = $logger;
$this->ignoredFields = $ignoredFields;
}

public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
): array {

if (!isset($value['model'])) {
throw new LocalizedException(__('"model" value should be specified'));
}

$attributesArray = [];
/** @var Product $product */
$product = $value['model'];

$attributes = $this->getAttributes($product);
foreach ($attributes as $key => $attribute) {
$value = $product->getData($attribute->getAttributeCode());
if ($attribute->getFrontendInput() === "multiselect") {
if ($value) {
$valueForTransform = explode(",", $value);
} else {
$valueForTransform = [];
}
} elseif ($attribute->getFrontendInput() === "select") {
$valueForTransform = ($value !== null) ? [$value] : null;
} else {
$attributesArray[] = [
'attribute_code' => $attribute->getAttributeCode(),
'frontend_label' => $attribute->getStoreLabel(),
'value' => $value,
'attribute_options' => null,
];
continue;
}
$attributeOptions = [];
$source = $attribute->getSource();
if ($valueForTransform) {
foreach ($valueForTransform as $option) {
$attributeOptions[] = [
'options_id' => (int)$option,
'option_value' => $source->getOptionText($option)
];
}
}
$attributesArray[] = [
'attribute_code' => $attribute->getAttributeCode(),
'frontend_label' => $attribute->getStoreLabel(),
'value' => $value,
'attribute_options' => $attributeOptions,
];

}
return $attributesArray;
}

/**
* @param Product $product
* @return AbstractAttribute[]
*/
private function getAttributes(
Product $product
): array {
if (!isset($this->cachedAttributes[$product->getAttributeSetId()])) {
// TODO replace using deprecated getResource()
$resource = $product->getResource();
$attributeObj = $resource->loadAllAttributes($product); // @phpstan-ignore-line
/** @var AbstractAttribute[] $attributes */
$attributes = $attributeObj->getSortedAttributes($product->getAttributeSetId());
foreach ($attributes as $key => $attribute) {
if (in_array($attribute->getAttributeCode(), $this->ignoredFields->getIgnoredFields())) {
unset($attributes[$key]);
continue;
}
if (!$attribute->getIsVisibleOnFront()) {
unset($attributes[$key]);
continue;
}
}
$this->cachedAttributes[$product->getAttributeSetId()] = $attributes;
}
return $this->cachedAttributes[$product->getAttributeSetId()];
}
}
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
# magento-module-product-attributes-graph-ql
Magento 2 module - provides SFX product attributes through GraphQL
# Product Attributes GraphQl

Module for Magento 2

**Product Attributes GraphQl** - provides SFX product attributes through GraphQL.

## License

The module is licensed under the MIT license.
22 changes: 22 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "storefront-x/magento-module-product-attributes-graph-ql",
"description": "Magento 2 module - provides SFX product attributes through GraphQL",
"type": "magento2-module",
"homepage": "https://github.com/storefront-x/magento-module-product-attributes-graph-ql",
"require": {
"php": ">=7.4",
"psr/log": "*",
"magento/magento-composer-installer": "*"
},
"license": [
"MIT"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"StorefrontX\\ProductAttributesGraphQl\\": ""
}
}
}
20 changes: 20 additions & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="StorefrontX\ProductAttributesGraphQl\Model\IgnoredFields">
<arguments>
<argument name="ignoredFields" xsi:type="array">
<item name="media_gallery" xsi:type="string">media_gallery</item>
<item name="gallery" xsi:type="string">gallery</item>
</argument>
</arguments>
</type>

<type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CompositeCollectionProcessor">
<arguments>
<argument name="collectionProcessors" xsi:type="array">
<item name="sfx_attributes" xsi:type="object">StorefrontX\ProductAttributesGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor\SFXAttributesProcessor</item>
</argument>
</arguments>
</type>
</config>

10 changes: 10 additions & 0 deletions etc/module.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="StorefrontX_ProductAttributesGraphQl" >
<sequence>
<module name="Magento_GraphQl"/>
<module name="Magento_Backend"/>
</sequence>
</module>
</config>
15 changes: 15 additions & 0 deletions etc/schema.graphqls
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
interface ProductInterface {
sfx_attributes: [SFXAttributes] @resolver(class: "StorefrontX\\ProductAttributesGraphQl\\Model\\Resolver\\SFXProductAttributesGraphQl")
}

type SFXAttributes {
attribute_code: String
frontend_label: String
value: String
attribute_options: [SFXAttributeOption]
}

type SFXAttributeOption {
options_id: Int
option_value: String
}
7 changes: 7 additions & 0 deletions registration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'StorefrontX_ProductAttributesGraphQl',
__DIR__
);

0 comments on commit 8938a5b

Please sign in to comment.