diff --git a/Model/Category/CategoryModifier.php b/Model/Category/CategoryModifier.php
new file mode 100644
index 0000000..c6d1231
--- /dev/null
+++ b/Model/Category/CategoryModifier.php
@@ -0,0 +1,153 @@
+categoryDynamicRenderer = $categoryDynamicRenderer;
+ $this->collectionFactory = $collectionFactory;
+ $this->requestedFilterArgsStorage = $requestedFilterArgsStorage;
+ $this->templateRendererAdapter = $categoryTemplateRendererAdapter;
+ $this->eventManager = $eventManager;
+ $this->attributes = $attributes;
+ }
+
+ /**
+ * @param mixed|Value $resolvedValue
+ * @param ResolveInfo $info
+ * @param array|null $args
+ * @return mixed
+ */
+ public function modify(
+ &$resolvedValue,
+ ResolveInfo $info,
+ array $args = null
+ ) {
+ $fieldSelection = $info->getFieldSelection(1);
+ $requestedAttributes = array_keys($fieldSelection['items']);
+ $attributes = array_intersect($requestedAttributes, $this->attributes);
+
+ if ($attributes) {
+ $this->requestedFilterArgsStorage->disable();
+
+ $categoryIds = array_column($resolvedValue['items'], 'id');
+ $collection = $this->getCategoryCollection($categoryIds, $attributes);
+
+ foreach ($resolvedValue['items'] as $key => $categoryData) {
+
+ foreach ($attributes as $attribute) {
+
+ if (empty($categoryData[$attribute])) {
+ continue;
+ }
+
+ $category = $collection->getItemById($categoryData['id']);
+
+ if ($category) {
+ $category->setData($categoryData);
+ $renderedValue = $this->templateRendererAdapter->getRenderedValue(
+ $attribute,
+ $category
+ );
+ $resolvedValue['items'][$key][$attribute] = $renderedValue;
+ }
+ }
+ }
+
+ $this->requestedFilterArgsStorage->enable();
+ }
+ }
+
+ /**
+ * Retrieve loaded category collection
+ *
+ * @param array $ids
+ * @param array $attributes
+ * @return \Magento\Catalog\Model\ResourceModel\Category\Collection
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ protected function getCategoryCollection(array $ids, array $attributes)
+ {
+ $collection = $this->collectionFactory->create();
+ $collection->addIdFilter($ids);
+ $collection->addAttributeToSelect($attributes);
+
+ $this->eventManager->dispatch(
+ 'mw_seoxtemplates_category_modifier_collection_load_before',
+ ['collection' => $collection]
+ );
+
+ $collection->addAttributeToSelect($this->getTemplateVariables());
+
+ $this->eventManager->dispatch(
+ 'mw_seoxtemplates_category_modifier_collection_load_after',
+ ['collection' => $collection]
+ );
+
+ return $collection;
+ }
+
+ /**
+ * @todo we need to retrieve parsed SEO-template's variables
+ * @return string[]
+ */
+ protected function getTemplateVariables(): array
+ {
+ return ['name'];
+ }
+}
diff --git a/Model/Category/CategoryTemplateRendererAdapter.php b/Model/Category/CategoryTemplateRendererAdapter.php
new file mode 100644
index 0000000..08c8890
--- /dev/null
+++ b/Model/Category/CategoryTemplateRendererAdapter.php
@@ -0,0 +1,50 @@
+categoryDynamicRenderer = $categoryDynamicRenderer;
+ }
+
+ /**
+ * @param string $attribute
+ * @param \Magento\Catalog\Model\Category $category
+ * @return string
+ */
+ public function getRenderedValue($attribute, $category)
+ {
+ $attributeValue = '';
+
+ if ('meta_title' === $attribute) {
+ $this->categoryDynamicRenderer->modifyCategoryTitle($category, $attributeValue, true);
+ } elseif ('meta_description' === $attribute) {
+ $this->categoryDynamicRenderer->modifyCategoryMetaDescription($category, $attributeValue, true);
+ } elseif ('meta_keywords' === $attribute) {
+ $this->categoryDynamicRenderer->modifyCategoryMetaKeywords($category, $attributeValue, true);
+ } elseif ('description' === $attribute) {
+ $this->categoryDynamicRenderer->modifyCategoryDescription($category, $attributeValue, true);
+ } elseif ('category_seo_name' === $attribute) {
+ $attributeValue = $this->categoryDynamicRenderer->getModifiedCategorySeoName(
+ $category,
+ $category->getCategorySeoName(),
+ true
+ );
+ }
+
+ return $attributeValue;
+ }
+}
diff --git a/Model/Category/Products/CategoryDataFiller.php b/Model/Category/Products/CategoryDataFiller.php
new file mode 100644
index 0000000..bfceb1b
--- /dev/null
+++ b/Model/Category/Products/CategoryDataFiller.php
@@ -0,0 +1,155 @@
+categoryDynamicRenderer = $categoryDynamicRenderer;
+ $this->collectionFactory = $collectionFactory;
+ $this->requestedFilterArgsStorage = $requestedFilterArgsStorage;
+ $this->categoryTemplateRendererAdapter = $categoryTemplateRendererAdapter;
+ $this->eventManager = $eventManager;
+ $this->attributes = $attributes;
+ }
+
+ /**
+ * @param mixed|Value $resolvedValue
+ * @param ResolveInfo $info
+ * @param array|null $args
+ * @return mixed
+ */
+ public function modify(
+ &$resolvedValue,
+ ResolveInfo $info,
+ array $args = null
+ ) {
+ $fieldSelection = $info->getFieldSelection(1);
+
+ if (!empty($fieldSelection['mw_seo_category_data'])
+ && !empty($resolvedValue['categories'])
+ && count($resolvedValue['categories']) === 1
+ && $resolvedValue['layer_type'] === 'category'
+ ) {
+ $requestedAttributes = array_keys($fieldSelection['mw_seo_category_data']);
+
+ $attributes = array_intersect($requestedAttributes, $this->attributes);
+
+ if ($attributes) {
+
+ $this->requestedFilterArgsStorage->set($args['filter']);
+ $collection = $this->getCategoryCollection([$resolvedValue['categories'][0]], $attributes);
+ /** @var \Magento\Catalog\Model\Category $category */
+ $category = $collection->getFirstItem();
+
+ if ($category->getId()) {
+ $resolvedValue['mw_seo_category_data'] = $fieldSelection['mw_seo_category_data'];
+
+ foreach ($attributes as $attribute) {
+ $renderedValue = $this->categoryTemplateRendererAdapter->getRenderedValue(
+ $attribute,
+ $category
+ );
+
+ $resolvedValue['mw_seo_category_data'][$attribute] = $renderedValue;
+ }
+ }
+ }
+ }
+
+ return $resolvedValue;
+ }
+
+ /**
+ * Retrieve loaded category collection
+ *
+ * @param array $ids
+ * @param array $attributes
+ * @return \Magento\Catalog\Model\ResourceModel\Category\Collection
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ protected function getCategoryCollection(array $ids, array $attributes)
+ {
+ $collection = $this->collectionFactory->create();
+ $collection->addIdFilter($ids);
+ $collection->addAttributeToSelect($attributes);
+ $collection->addAttributeToSelect($this->getTemplateVariables());
+
+ $this->eventManager->dispatch(
+ 'mw_seoxtemplates_category_data_filler_collection_load_before',
+ ['collection' => $collection]
+ );
+
+ $collection->load();
+
+ $this->eventManager->dispatch(
+ 'mw_seoxtemplates_category_data_filler_collection_load_after',
+ ['collection' => $collection]
+ );
+
+ return $collection;
+ }
+
+ /**
+ * @todo we need to retrieve parsed SEO-template's variables
+ * @return string[]
+ */
+ protected function getTemplateVariables()
+ {
+ return ['name'];
+ }
+}
diff --git a/Model/LayeredFiltersProvider/GraphQl.php b/Model/LayeredFiltersProvider/GraphQl.php
new file mode 100755
index 0000000..f9c2010
--- /dev/null
+++ b/Model/LayeredFiltersProvider/GraphQl.php
@@ -0,0 +1,134 @@
+requestedFilterArgsStorage = $requestedFilterArgsStorage;
+ $this->storeManager = $storeManager;
+ $this->attributeResource = $attributeResource;
+ $this->attributeRepository = $attributeRepository;
+ }
+
+ public function getCurrentLayeredFilters(): array
+ {
+ $attributes = $this->requestedFilterArgsStorage->get();
+
+ $filterData = [];
+
+ foreach ($attributes as $attributeCode => $rule) {
+ if ('category_id' === $attributeCode) {
+ continue;
+ }
+
+ if (!empty($rule['eq'])) {
+ $requestedOption = $rule['eq'];
+
+ try {
+ $attribute = $this->attributeRepository->get($attributeCode);
+ } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+ continue;
+ }
+
+ $attribute->setData('store_id', $this->storeManager->getStore()->getId());
+ $attributeOptions = $attribute->getOptions();
+
+ foreach ($attributeOptions as $option) {
+
+ if ($option['value'] == $requestedOption) {
+ $filterData[] = [
+ 'name' => $this->getAttributeLabel($attribute),
+ 'label' => $this->getAttributeOptionLabel($option),
+ 'code' => $attributeCode
+ ];
+ }
+ }
+ }
+ }
+
+ return $filterData;
+ }
+
+ /**
+ * @param \Magento\Eav\Api\Data\AttributeInterface $attribute
+ * @return string|null
+ */
+ protected function getAttributeLabel($attribute)
+ {
+ foreach ($attribute->getFrontendLabels() as $label) {
+ if ((int)$label->getStoreId() === (int)$this->storeManager->getStore()->getId()) {
+ return $label->getLabel();
+ }
+ }
+
+ return $attribute->getDefaultFrontendLabel();
+ }
+
+ /**
+ * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
+ * @return string|null
+ */
+ protected function getAttributeOptionLabel($option)
+ {
+ $optionStoreLabel = $this->getOptionStoreLabel($option->getId());
+ if ($optionStoreLabel) {
+ return $optionStoreLabel;
+ }
+
+ return $option->getLabel();
+ }
+
+ /**
+ * @param (int)$optionId
+ * @return mixed
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
+ */
+ protected function getOptionStoreLabel($optionId)
+ {
+ $connection = $this->attributeResource->getConnection();
+ $bind = [
+ ':attribute_id' => (int)$optionId,
+ ':store_id' => (int)$this->storeManager->getStore()->getId()
+ ];
+ $select = $connection->select()->from(
+ $this->attributeResource->getTable('eav_attribute_label'),
+ ['store_id', 'value']
+ )->where(
+ 'attribute_id = :attribute_id'
+ )->where(
+ 'store_id = :store_id'
+ );
+
+ return $connection->fetchRow($select, $bind);
+ }
+}
diff --git a/Model/Product/ProductModifier.php b/Model/Product/ProductModifier.php
new file mode 100644
index 0000000..36ef17e
--- /dev/null
+++ b/Model/Product/ProductModifier.php
@@ -0,0 +1,100 @@
+productFactory = $productFactory;
+ $this->eventManager = $eventManager;
+ $this->templateRendererAdapter = $templateRendererAdapter;
+ $this->attributes = $attributes;
+ }
+
+ /**
+ * @param mixed|Value $resolvedValue
+ * @param ResolveInfo $info
+ * @param array|null $args
+ * @return mixed
+ */
+ public function modify(
+ &$resolvedValue,
+ ResolveInfo $info,
+ array $args = null
+ ) {
+ $fieldSelection = $info->getFieldSelection(1);
+ $requestedAttributes = array_keys($fieldSelection['items']);
+ $attributes = array_intersect($requestedAttributes, $this->attributes);
+
+ if ($attributes) {
+
+ foreach ($resolvedValue['items'] as $key => $productData) {
+
+ foreach ($attributes as $attribute) {
+
+ if (empty($productData[$attribute])) {
+ continue;
+ }
+
+ $product = $this->productFactory->create();
+ $product->setData($productData);
+
+ $renderedValue = $this->templateRendererAdapter->getRenderedValue($attribute, $product);
+
+ $resolvedValue['items'][$key][$attribute] = $renderedValue;
+ }
+ }
+ }
+ }
+}
diff --git a/Model/Product/ProductTemplateRendererAdapter.php b/Model/Product/ProductTemplateRendererAdapter.php
new file mode 100644
index 0000000..0c9eb51
--- /dev/null
+++ b/Model/Product/ProductTemplateRendererAdapter.php
@@ -0,0 +1,65 @@
+metaTitleConverter = $metaTitleConverter;
+ $this->metaDescriptionConverter = $metaDescriptionConverter;
+ $this->metaKeywordsConverter = $metaKeywordsConverter;
+ $this->seoNameConverter = $seoNameConverter;
+ }
+
+ /**
+ * @param string $attribute
+ * @param \Magento\Catalog\Model\Product $product
+ * @return string
+ */
+ public function getRenderedValue($attribute, $product)
+ {
+ $attributeValue = '';
+
+ if ($attribute === 'meta_title') {
+ $attributeValue = $this->metaTitleConverter->convert($product, $product->getData($attribute), true);
+ } elseif ($attribute === 'meta_description') {
+ $attributeValue = $this->metaDescriptionConverter->convert($product, $product->getData($attribute), true);
+ } elseif ($attribute === 'meta_keyword') {
+ $attributeValue = $this->metaKeywordsConverter->convert($product, $product->getData($attribute), true);
+ } elseif ($attribute === 'product_seo_name') {
+ $attributeValue = $this->seoNameConverter->convert($product, $product->getData($attribute), true);
+ }
+
+ return $attributeValue;
+ }
+}
diff --git a/Model/RequestedFilterArgsStorage.php b/Model/RequestedFilterArgsStorage.php
new file mode 100755
index 0000000..3cd8779
--- /dev/null
+++ b/Model/RequestedFilterArgsStorage.php
@@ -0,0 +1,40 @@
+disabled = true;
+ }
+
+ public function enable(): void
+ {
+ $this->disabled = false;
+ }
+
+ public function set(array $filters)
+ {
+ $this->filters = $filters;
+ }
+
+ public function get(): ?array
+ {
+ if ($this->disabled === false) {
+ return $this->filters;
+ }
+
+ return [];
+ }
+}
diff --git a/Plugin/AddSeoNameToCategoryCollectionPlugin.php b/Plugin/AddSeoNameToCategoryCollectionPlugin.php
deleted file mode 100755
index 8cd2e2e..0000000
--- a/Plugin/AddSeoNameToCategoryCollectionPlugin.php
+++ /dev/null
@@ -1,53 +0,0 @@
-helperData = $helperData;
- }
-
- /**
- * Adds "category_seo_name" attribute to category collection if needed
- *
- * @param AttributesJoiner $subject
- * @param $result
- * @param FieldNode $fieldNode
- * @param AbstractCollection $collection
- */
- public function afterJoin(
- AttributesJoiner $subject,
- $result,
- FieldNode $fieldNode,
- AbstractCollection $collection
- ): void {
- if ($collection instanceof \Magento\Catalog\Model\ResourceModel\Category\Collection) {
- if ($this->helperData->isUseCategorySeoName()) {
- if ($collection->isAttributeAdded('name')) {
- $collection->addAttributeToSelect('category_seo_name');
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Plugin/AddSeoNameToProductCollectionPlugin.php b/Plugin/AddSeoNameToProductCollectionPlugin.php
deleted file mode 100755
index e729de0..0000000
--- a/Plugin/AddSeoNameToProductCollectionPlugin.php
+++ /dev/null
@@ -1,54 +0,0 @@
-helperData = $helperData;
- }
-
- /**
- * @param CollectionProcessorInterface $subject
- * @param Collection $result
- * @param Collection $collection
- * @param SearchCriteriaInterface $searchCriteria
- * @param array $attributeNames
- * @return Collection
- */
- public function afterProcess(
- CollectionProcessorInterface $subject,
- Collection $result,
- Collection $collection,
- SearchCriteriaInterface $searchCriteria,
- array $attributeNames
- ) {
- if ($this->helperData->isUseProductSeoName()) {
- if ($result->isAttributeAdded('name')) {
- $result->addAttributeToSelect('product_seo_name');
- }
- }
-
- return $result;
- }
-}
\ No newline at end of file
diff --git a/Plugin/ModifyCategoryDescriptionPlugin.php b/Plugin/ModifyCategoryDescriptionPlugin.php
deleted file mode 100755
index ef584a2..0000000
--- a/Plugin/ModifyCategoryDescriptionPlugin.php
+++ /dev/null
@@ -1,114 +0,0 @@
-helperData = $helperData;
- $this->dynamicRenderer = $renderer;
- }
-
- /**
- * @param \Magento\CatalogGraphQl\Model\Resolver\Category\CategoryHtmlAttribute $subject
- * @param string|null $result
- * @param Field $field
- * @param $context
- * @param ResolveInfo $info
- * @param array|null $value
- * @param array|null $args
- */
- public function afterResolve(
- $subject,
- $result,
- Field $field,
- $context,
- ResolveInfo $info,
- array $value = null,
- array $args = null
- ) {
- if (!$result) {
- return $result;
- }
-
- /** @var \Magento\Catalog\Model\Category $category */
- $category = $value['model'];
- $fieldName = $field->getName();
-
- if ($this->out($category, $fieldName)) {
- return $result;
- }
-
- if (!$this->isCurrentEntity($category, $info)) {
- return $result;
- }
-
- if ($this->dynamicRenderer->modifyCategoryDescription($category)) {
- return $category->getData('description');
- }
-
- return $result;
- }
-
- /**
- * @param \Magento\Catalog\Model\Category $category
- * @param ResolveInfo $info
- * @return bool
- */
- protected function isCurrentEntity($category, $info)
- {
- $variables = $info->variableValues;
-
- return !empty($variables['_filter_0']['category_url_path']['eq'])
- && $variables['_filter_0']['category_url_path']['eq'] === $category->getUrlPath();
- }
-
- /**
- * Check if go out
- *
- * @param \Magento\Catalog\Model\Category $category
- * @param string $fieldName
- * @return boolean
- */
- protected function out($category, $fieldName)
- {
- if (!is_object($category)) {
- return true;
- }
-
- if ($fieldName !== 'description') {
- return true;
- }
-
- return false;
- }
-}
\ No newline at end of file
diff --git a/Plugin/ModifyCategoryNamePlugin.php b/Plugin/ModifyCategoryNamePlugin.php
deleted file mode 100755
index 62eec9a..0000000
--- a/Plugin/ModifyCategoryNamePlugin.php
+++ /dev/null
@@ -1,96 +0,0 @@
-helperData = $helperData;
- }
-
- /**
- * @param \MageWorx\SeoAllGraphQl\Model\Resolver\Category\SeoRenderedElement $subject
- * @param string|null $result
- * @param Field $field
- * @param $context
- * @param ResolveInfo $info
- * @param array|null $value
- * @param array|null $args
- *
- * @return strung
- */
- public function afterResolve(
- $subject,
- $result,
- Field $field,
- $context,
- ResolveInfo $info,
- array $value = null,
- array $args = null
- ) {
- if (!$result) {
- return $result;
- }
-
- /** @var \Magento\Catalog\Model\Category $category */
- $category = $value['model'];
- $fieldName = $field->getName();
-
- if ($this->out($category, $fieldName)) {
- return $result;
- }
-
- $categorySeoName = $category->getData('category_seo_name');
- $category->setData('name', $categorySeoName);
-
- return $categorySeoName;
- }
-
- /**
- * Check if go out
- *
- * @param \Magento\Catalog\Model\Category $category
- * @param string $fieldName
- * @return boolean
- */
- protected function out($category, $fieldName)
- {
- if (!is_object($category)) {
- return true;
- }
-
- if ($fieldName !== 'name') {
- return true;
- }
-
- if (!$this->helperData->isUseCategorySeoName()) {
- return true;
- }
-
- if (empty($category->getData('category_seo_name'))) {
- return true;
- }
-
- return false;
- }
-}
\ No newline at end of file
diff --git a/Plugin/ModifyCategoryParamsPlugin.php b/Plugin/ModifyCategoryParamsPlugin.php
deleted file mode 100755
index c402869..0000000
--- a/Plugin/ModifyCategoryParamsPlugin.php
+++ /dev/null
@@ -1,127 +0,0 @@
- 'modifyCategoryTitle',
- 'meta_description' => 'modifyCategoryMetaDescription',
- 'meta_keywords' => 'modifyCategoryMetaKeywords'
- ];
-
- /**
- * ModifyCategoryDescriptionPlugin constructor.
- *
- * @param \MageWorx\SeoXTemplates\Helper\Data $helperData
- * @param Renderer $renderer
- */
- public function __construct(
- \MageWorx\SeoXTemplates\Helper\Data $helperData,
- Renderer $renderer
- ) {
- $this->helperData = $helperData;
- $this->dynamicRenderer = $renderer;
- }
-
- /**
- * @param \MageWorx\SeoAllGraphQl\Model\Resolver\Category\SeoRenderedElement $subject
- * @param string|null $result
- * @param Field $field
- * @param $context
- * @param ResolveInfo $info
- * @param array|null $value
- * @param array|null $args
- */
- public function afterResolve(
- $subject,
- $result,
- Field $field,
- $context,
- ResolveInfo $info,
- array $value = null,
- array $args = null
- ) {
- if (!$result) {
- return $result;
- }
-
- /** @var \Magento\Catalog\Model\Category $category */
- $category = $value['model'];
- $fieldName = $field->getName();
-
- if ($this->out($category, $fieldName)) {
- return $result;
- }
-
- if (!$this->isCurrentEntity($category, $info)) {
- return $result;
- }
-
- $methodName = $this->rendererMethods[$fieldName];
- $convertedResult = '';
-
-
- if ($this->dynamicRenderer->$methodName($category, $convertedResult)) {
- return $convertedResult;
- }
-
- return $result;
- }
-
- /**
- * @param \Magento\Catalog\Model\Category $category
- * @param ResolveInfo $info
- * @return bool
- */
- protected function isCurrentEntity($category, $info)
- {
- $variables = $info->variableValues;
-
- return !empty($variables['_filter_0']['category_url_path']['eq'])
- && $variables['_filter_0']['category_url_path']['eq'] === $category->getUrlPath();
- }
-
- /**
- * Check if go out
- *
- * @param \Magento\Catalog\Model\Category $category
- * @param string $fieldName
- * @return boolean
- */
- protected function out($category, $fieldName)
- {
- if (!is_object($category)) {
- return true;
- }
-
- if (empty($this->rendererMethods[$fieldName])) {
- return true;
- }
-
- return false;
- }
-}
\ No newline at end of file
diff --git a/Plugin/ModifyProductDescriptionsPlugin.php b/Plugin/ModifyProductDescriptionsPlugin.php
deleted file mode 100755
index b37a764..0000000
--- a/Plugin/ModifyProductDescriptionsPlugin.php
+++ /dev/null
@@ -1,129 +0,0 @@
-helperData = $helperData;
- $this->shortDescriptionConverter = $shortDescriptionConverter;
- $this->descriptionConverter = $descriptionConverter;
- }
-
- /**
- * @param \Magento\CatalogGraphQl\Model\Resolver\Product\ProductComplexTextAttribute $subject
- * @param string|null $result
- * @param Field $field
- * @param $context
- * @param ResolveInfo $info
- * @param array|null $value
- * @param array|null $args
- */
- public function afterResolve(
- $subject,
- $result,
- Field $field,
- $context,
- ResolveInfo $info,
- array $value = null,
- array $args = null
- ) {
- if (!$result) {
- return $result;
- }
-
- /** @var \Magento\Catalog\Model\Product $product */
- $product = $value['model'];
- $fieldName = $field->getName();
-
- if ($this->out($product, $fieldName)) {
- return $result;
- }
-
- if (empty($result['html'])) {
- return $result;
- }
-
- if (!$this->isCurrentEntity($product, $info)) {
- return $result;
- }
-
- if ($fieldName === 'short_description') {
- $result['html'] = $this->shortDescriptionConverter->convert($product, $result['html'], true);
- $product->setShortDescription($result['html']);
- }
-
- if ($fieldName === 'description') {
- $result['html'] = $this->descriptionConverter->convert($product, $result['html'], true);
- $product->setDescription($result['html']);
- }
-
- return $result;
- }
-
- /**
- * @param \Magento\Catalog\Model\Product $product
- * @param ResolveInfo $info
- * @return bool
- */
- protected function isCurrentEntity($product, $info)
- {
- $variables = $info->variableValues;
-
- return !empty($variables['_filter_0']['url_key']['eq'])
- && $variables['_filter_0']['url_key']['eq'] === $product->getUrlKey();
- }
-
- /**
- * Check if go out
- *
- * @param \Magento\Catalog\Model\Product $product
- * @param string $fieldName
- * @return boolean
- */
- protected function out($product, $fieldName)
- {
- if (!is_object($product)) {
- return true;
- }
-
- if (!in_array($fieldName, ['description', 'short_description'])) {
- return true;
- }
-
- return false;
- }
-}
\ No newline at end of file
diff --git a/Plugin/ModifyProductNamePlugin.php b/Plugin/ModifyProductNamePlugin.php
deleted file mode 100755
index e8aba7e..0000000
--- a/Plugin/ModifyProductNamePlugin.php
+++ /dev/null
@@ -1,95 +0,0 @@
-helperData = $helperData;
- }
-
- /**
- * @param \MageWorx\SeoAllGraphQl\Model\Resolver\Product\SeoRenderedElement $subject
- * @param string|null $result
- * @param Field $field
- * @param $context
- * @param ResolveInfo $info
- * @param array|null $value
- * @param array|null $args
- *
- * @return string
- */
- public function afterResolve(
- $subject,
- $result,
- Field $field,
- $context,
- ResolveInfo $info,
- array $value = null,
- array $args = null
- ) {
- if (!$result) {
- return $result;
- }
-
- /** @var \Magento\Catalog\Model\Product $product */
- $product = $value['model'];
- $fieldName = $field->getName();
-
- if ($this->out($product, $fieldName)) {
- return $result;
- }
-
- $productSeoName = $product->getData('product_seo_name');
- $product->setData('name', $productSeoName);
-
- return $productSeoName;
- }
-
- /**
- * Check if go out
- *
- * @param \Magento\Catalog\Model\Product $product
- * @param string $fieldName
- * @return boolean
- */
- protected function out($product, $fieldName)
- {
- if (!is_object($product)) {
- return true;
- }
-
- if ($fieldName !== 'name') {
- return true;
- }
-
- if (!$this->helperData->isUseProductSeoName()) {
- return true;
- }
-
- if (empty($product->getData('product_seo_name'))) {
- return true;
- }
-
- return false;
- }
-}
\ No newline at end of file
diff --git a/Plugin/ModifyProductParamsPlugin.php b/Plugin/ModifyProductParamsPlugin.php
deleted file mode 100755
index 920f6a9..0000000
--- a/Plugin/ModifyProductParamsPlugin.php
+++ /dev/null
@@ -1,138 +0,0 @@
-helperData = $helperData;
- $this->metaTitleConverter = $metaTitleConverter;
- $this->metaDescriptionConverter = $metaDescriptionConverter;
- $this->metaKeywordsConverter = $metaKeywordsConverter;
- }
-
- /**
- * @param \MageWorx\SeoAllGraphQl\Model\Resolver\Product\SeoRenderedElement $subject
- * @param string|null $result
- * @param Field $field
- * @param $context
- * @param ResolveInfo $info
- * @param array|null $value
- * @param array|null $args
- */
- public function afterResolve(
- $subject,
- $result,
- Field $field,
- $context,
- ResolveInfo $info,
- array $value = null,
- array $args = null
- ) {
- if (!$result) {
- return $result;
- }
-
- /** @var \Magento\Catalog\Model\Product $product */
- $product = $value['model'];
- $fieldName = $field->getName();
-
- if ($this->out($product, $fieldName)) {
- return $result;
- }
-
- if (!$this->isCurrentEntity($product, $info)) {
- return $result;
- }
-
- if ($fieldName === 'meta_title') {
- $result = $this->metaTitleConverter->convert($product, $result, true);
- $product->setMetaTitle($result);
- }
-
- if ($fieldName === 'meta_description') {
- $result = $this->metaDescriptionConverter->convert($product, $result, true);
- $product->setMetaDescription($result);
- }
-
- if ($fieldName === 'meta_keyword') {
- $result = $this->metaKeywordsConverter->convert($product, $result, true);
- $product->setMetaKeyword($result);
- }
-
- return $result;
- }
-
- /**
- * @param \Magento\Catalog\Model\Product $product
- * @param ResolveInfo $info
- * @return bool
- */
- protected function isCurrentEntity($product, $info)
- {
- $variables = $info->variableValues;
-
- return !empty($variables['_filter_0']['url_key']['eq'])
- && $variables['_filter_0']['url_key']['eq'] === $product->getUrlKey();
- }
-
- /**
- * Check if go out
- *
- * @param \Magento\Catalog\Model\Product $product
- * @param string $fieldName
- * @return boolean
- */
- protected function out($product, $fieldName)
- {
- if (!is_object($product)) {
- return true;
- }
-
- if (!in_array($fieldName, ['meta_title', 'meta_description', 'meta_keyword'])) {
- return true;
- }
-
- return false;
- }
-}
\ No newline at end of file
diff --git a/Plugin/Query/Resolver/RenderSeoDataPlugin.php b/Plugin/Query/Resolver/RenderSeoDataPlugin.php
new file mode 100755
index 0000000..f25c219
--- /dev/null
+++ b/Plugin/Query/Resolver/RenderSeoDataPlugin.php
@@ -0,0 +1,73 @@
+categoryDataModifier = $categoryDataModifier;
+ $this->categoryDataFiller = $categoryDataFiller;
+ $this->productsDataModifier = $productsDataModifier;
+ }
+
+ /**
+ * @param ResolverInterface $subject
+ * @param mixed|Value $resolvedValue
+ * @param Field $field
+ * @param Context $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ * @return mixed
+ */
+ public function afterResolve(
+ ResolverInterface $subject,
+ $resolvedValue,
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if ($subject instanceof \Magento\CatalogGraphQl\Model\Resolver\CategoriesQuery) {
+ $this->categoryDataModifier->modify($resolvedValue, $info, $args);
+ } elseif ($subject instanceof \Magento\CatalogGraphQl\Model\Resolver\Products) {
+ $this->categoryDataFiller->modify($resolvedValue, $info, $args);
+ $this->productsDataModifier->modify($resolvedValue, $info, $args);
+ }
+
+ return $resolvedValue;
+ }
+}
diff --git a/README.md b/README.md
index 81a23b7..a80cf6e 100755
--- a/README.md
+++ b/README.md
@@ -10,4 +10,253 @@ GraphQL API module for Mageworx [Magento 2 SEO Suite Ultimate](https://www.magew
- Execute the following command: `composer require mageworx/module-seoxtemplates-graph-ql`
## How to use
-The SeoXTemplatesGraphQl modifies the necessary attributes of the entities of Product, categories and CMS pages, when you call these entities using the standard GraphQL requests.
+
+
+ Categories query example
+All Category SEO-attributes (meta title, meta description, ...) set in "Bags[ - Filters: {filter_all}]"
+
+```graphql
+
+query GetCategories($id: String!, $pageSize: Int!, $currentPage: Int!, $filters: ProductAttributeFilterInput!, $sort: ProductAttributeSortInput) {
+ categories(filters: {ids: {in: [$id]}}) {
+ items {
+ uid
+ ...CategoryFragment
+ }
+ }
+ products(pageSize: $pageSize, currentPage: $currentPage, filter: $filters, sort: $sort) {
+ ...ProductsFragment
+ mw_seo_category_data {
+ meta_title
+ meta_description
+ meta_keywords
+ category_seo_name
+ }
+ }
+}
+
+fragment CategoryFragment on CategoryTree {
+ uid
+ meta_title
+ meta_keywords
+ meta_description
+ category_seo_name
+}
+
+fragment ProductsFragment on Products {
+ items {
+ id
+ uid
+ name
+ sku
+ url_key
+ }
+ page_info {
+ total_pages
+ }
+ total_count
+}
+```
+
+Query Variables:
+
+```json
+{
+ "currentPage": 1,
+ "id": "4",
+ "filters": {
+ "color": {
+ "eq": "49"
+ },
+ "category_id": {
+ "eq": "4"
+ }
+ },
+ "pageSize": 1,
+ "sort": {
+ "position": "ASC"
+ }
+}
+```
+
+Answer:
+
+```json
+{
+ "data": {
+ "categories": {
+ "items": [
+ {
+ "uid": "NA==",
+ "meta_title": "Bags",
+ "meta_keywords": "Bags",
+ "meta_description": "Bags",
+ "category_seo_name": "Bags"
+ }
+ ]
+ },
+ "products": {
+ "items": [
+ {
+ "id": 7,
+ "uid": "Nw==",
+ "name": "Impulse Duffle",
+ "sku": "24-UB02",
+ "url_key": "impulse-duffle"
+ }
+ ],
+ "page_info": {
+ "total_pages": 4
+ },
+ "total_count": 4,
+ "mw_seo_category_data": {
+ "meta_title": "Bags - Filters: Color: Black",
+ "meta_description": "Bags - Filters: Color: Black",
+ "meta_keywords": "Bags - Filters: Color: Black",
+ "category_seo_name": "Bags - Filters: Color: Black"
+ }
+ }
+ }
+}
+```
+
+
+
+
+
+ Products query example
+
+All Product SEO-attributes (meta title, meta description, ...) set in "Wayfarer Messenger Bag[ in {categories}]"
+
+```graphql
+query getProductDetailForProductPage($urlKey: String!) {
+ products(filter: {url_key: {eq: $urlKey}}) {
+ items {
+ id
+ uid
+ ...ProductDetailsFragment
+ }
+ }
+}
+
+fragment ProductDetailsFragment on ProductInterface {
+ categories {
+ uid
+ breadcrumbs {
+ category_uid
+ }
+ }
+ id
+ uid
+ meta_title
+ meta_description
+ meta_keyword
+ product_seo_name
+ name
+ sku
+ url_key
+ ... on ConfigurableProduct {
+ configurable_options {
+ attribute_code
+ attribute_id
+ uid
+ label
+ values {
+ uid
+ default_label
+ label
+ store_label
+ use_default_value
+ }
+ }
+ variants {
+ attributes {
+ code
+ value_index
+ }
+ product {
+ uid
+ media_gallery_entries {
+ uid
+ disabled
+ file
+ label
+ position
+ }
+ sku
+ stock_status
+ }
+ }
+ }
+}
+```
+
+Query Variables:
+
+```json
+{
+ "currentPage": 1,
+ "id": "4",
+ "filters": {
+ "color": {
+ "eq": "49"
+ },
+ "category_id": {
+ "eq": "4"
+ }
+ },
+ "pageSize": 1,
+ "sort": {
+ "position": "ASC"
+ }
+}
+```
+
+Answer:
+
+```json
+{
+ "data": {
+ "products": {
+ "items": [
+ {
+ "id": 4,
+ "uid": "NA==",
+ "categories": [
+ {
+ "uid": "Mw==",
+ "breadcrumbs": null
+ },
+ {
+ "uid": "NA==",
+ "breadcrumbs": [
+ {
+ "category_uid": "Mw=="
+ }
+ ]
+ },
+ {
+ "uid": "Nw==",
+ "breadcrumbs": null
+ },
+ {
+ "uid": "OA==",
+ "breadcrumbs": null
+ }
+ ],
+ "meta_title": "Wayfarer Messenger Bag",
+ "meta_description": "Wayfarer Messenger Bag",
+ "meta_keyword": "Wayfarer Messenger Bag",
+ "product_seo_name": "Wayfarer Messenger Bag",
+ "name": "Wayfarer Messenger Bag",
+ "sku": "24-MB05",
+ "url_key": "wayfarer-messenger-bag"
+ }
+ ]
+ }
+ }
+}
+
+```
+
+
diff --git a/composer.json b/composer.json
index a770964..3da4a08 100755
--- a/composer.json
+++ b/composer.json
@@ -3,7 +3,7 @@
"description": "N/A",
"type": "magento2-module",
"require": {
- "mageworx/module-seoxtemplates": ">= 2.8.8",
+ "mageworx/module-seoxtemplates": ">= 2.13.8",
"magento/module-cms-graph-ql": ">= 100.3.1 < 101",
"magento/module-catalog-graph-ql": ">= 100.3.1 < 101"
},
@@ -19,5 +19,5 @@
"MageWorx\\SeoXTemplatesGraphQl\\": ""
}
},
- "version": "1.0.0"
+ "version": "2.0.0"
}
diff --git a/etc/di.xml b/etc/di.xml
deleted file mode 100755
index 2db78cc..0000000
--- a/etc/di.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/etc/graphql/di.xml b/etc/graphql/di.xml
new file mode 100755
index 0000000..d92264a
--- /dev/null
+++ b/etc/graphql/di.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+ - MageWorx\SeoXTemplatesGraphQl\Model\LayeredFiltersProvider\GraphQl
+
+
+
+
+
+
+
+ - meta_title
+ - meta_description
+ - meta_keywords
+ - description
+ - category_seo_name
+
+
+
+
+
+
+
+ - meta_title
+ - meta_description
+ - meta_keywords
+ - description
+ - category_seo_name
+
+
+
+
+
+
+
+ - meta_title
+ - meta_description
+ - meta_keyword
+ - description
+ - product_seo_name
+
+
+
+
diff --git a/etc/schema.graphqls b/etc/schema.graphqls
new file mode 100755
index 0000000..a0d8654
--- /dev/null
+++ b/etc/schema.graphqls
@@ -0,0 +1,11 @@
+type Products {
+ mw_seo_category_data: MwSeoCategoryData @doc(description: "An object that includes SEO data for category from filter.")
+}
+
+type MwSeoCategoryData @doc(description: "SEO Category data for product list") {
+ meta_title: String @doc(description: "Category Meta Title")
+ meta_description: String @doc(description: "Category Meta Description")
+ meta_keywords: String @doc(description: "Category Meta Keywords")
+ description: String @doc(description: "Category Description")
+ category_seo_name: String @doc(description: "Category SEO Name")
+}