diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index 4326a51f309b..e2998438bd74 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -79,7 +79,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) @@ -114,6 +114,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $categories[$item->getId()] = $this->customAttributesFlattener ->flatten($categories[$item->getId()]); $categories[$item->getId()]['product_count'] = $item->getProductCount(); + $categories[$item->getId()]['model'] = $item; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryHtmlAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryHtmlAttribute.php new file mode 100644 index 000000000000..7ccb46c3a293 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/CategoryHtmlAttribute.php @@ -0,0 +1,57 @@ +outputHelper = $outputHelper; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + /* @var $category Category */ + $category = $value['model']; + $fieldName = $field->getName(); + $renderedValue = $this->outputHelper->categoryAttribute($category, $category->getData($fieldName), $fieldName); + + return $renderedValue; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php index 49617c442eeb..6830aecb78f1 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php @@ -9,6 +9,7 @@ use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\ImageFactory; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -45,7 +46,7 @@ public function resolve( array $args = null ): array { if (!isset($value['model'])) { - throw new \LogicException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ $product = $value['model']; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php index bae9def4ee6e..07d8996838e9 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php @@ -83,6 +83,8 @@ public function __construct( } /** + * Returns categories tree starting from parent $rootCategoryId + * * @param ResolveInfo $resolveInfo * @param int $rootCategoryId * @return array @@ -107,6 +109,8 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId) : array } /** + * Iterates through category tree + * * @param \Iterator $iterator * @return array */ @@ -119,6 +123,7 @@ private function processTree(\Iterator $iterator) : array $iterator->next(); $nextCategory = $iterator->current(); $tree[$category->getId()] = $this->hydrator->hydrateCategory($category); + $tree[$category->getId()]['model'] = $category; if ($nextCategory && (int) $nextCategory->getLevel() !== (int) $category->getLevel()) { $tree[$category->getId()]['children'] = $this->processTree($iterator); } @@ -128,6 +133,8 @@ private function processTree(\Iterator $iterator) : array } /** + * Joins EAV attributes recursively + * * @param Collection $collection * @param FieldNode $fieldNode * @return void diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index d90af0e1d9a3..a1a587f3f37b 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -369,7 +369,7 @@ interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGra interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CategoryInterfaceTypeResolver") @doc(description: "CategoryInterface contains the full set of attributes that can be returned in a category search") { id: Int @doc(description: "An ID that uniquely identifies the category") - description: String @doc(description: "An optional description of the category") + description: String @doc(description: "An optional description of the category") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryHtmlAttribute") name: String @doc(description: "The display name of the category") path: String @doc(description: "Category Path") path_in_store: String @doc(description: "Category path in store") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryWithDescriptionDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryWithDescriptionDirectivesTest.php new file mode 100644 index 000000000000..c115f7124c9f --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryWithDescriptionDirectivesTest.php @@ -0,0 +1,68 @@ +objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category.php + */ + public function testHtmlDirectivesRendered() + { + $categoryId = 333; + $mediaFilePath = '/path/to/mediafile'; + /** @var StoreManagerInterface $storeManager */ + $storeManager = ObjectManager::getInstance()->get(StoreManagerInterface::class); + $storeBaseUrl = $storeManager->getStore()->getBaseUrl(); + + /* Remove index.php from base URL */ + $storeBaseUrlParts = explode('/index.php', $storeBaseUrl); + $storeBaseUrl = $storeBaseUrlParts[0]; + + /** @var CategoryRepositoryInterface $categoryRepository */ + $categoryRepository = ObjectManager::getInstance()->get(CategoryRepositoryInterface::class); + /** @var CategoryInterface $category */ + $category = $categoryRepository->get($categoryId); + $category->setDescription('Test: {{media url="' . $mediaFilePath . '"}}'); + $categoryRepository->save($category); + + $query = <<graphQlQuery($query); + + self::assertNotContains('media url', $response['category']['description']); + self::assertContains($storeBaseUrl, $response['category']['description']); + } +}