Skip to content

Commit 2271bc2

Browse files
committed
Merge remote-tracking branch 'origin/MC-20318-category-cms-block' into MC-21691
# Conflicts: # composer.lock
2 parents 9b84004 + f740d4f commit 2271bc2

File tree

11 files changed

+253
-5
lines changed

11 files changed

+253
-5
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogCmsGraphQl\Model\Resolver\Category;
9+
10+
use Magento\Catalog\Model\Category;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\Exception\NoSuchEntityException;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
use Magento\CmsGraphQl\Model\Resolver\DataProvider\Block as BlockProvider;
17+
18+
/**
19+
* Resolver category cms content
20+
*/
21+
class Block implements ResolverInterface
22+
{
23+
/**
24+
* @var BlockProvider
25+
*/
26+
private $blockProvider;
27+
28+
/**
29+
* @param BlockProvider $blockProvider
30+
*/
31+
public function __construct(BlockProvider $blockProvider)
32+
{
33+
$this->blockProvider = $blockProvider;
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function resolve(
40+
Field $field,
41+
$context,
42+
ResolveInfo $info,
43+
array $value = null,
44+
array $args = null
45+
) {
46+
if (!isset($value['model'])) {
47+
throw new LocalizedException(__('"model" value should be specified'));
48+
}
49+
/** @var Category $category */
50+
$category = $value['model'];
51+
$blockId = $category->getLandingPage();
52+
53+
if (empty($blockId)) {
54+
return null;
55+
}
56+
57+
try {
58+
$block = $this->blockProvider->getData($blockId);
59+
} catch (NoSuchEntityException $e) {
60+
return null;
61+
}
62+
63+
return $block;
64+
}
65+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# CatalogCmsGraphQl
2+
3+
**CatalogCmsGraphQl** provides type and resolver information for GraphQL attributes that have dependencies on the Catalog and Cms modules.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "magento/module-catalog-cms-graph-ql",
3+
"description": "N/A",
4+
"type": "magento2-module",
5+
"require": {
6+
"php": "~7.1.3||~7.2.0||~7.3.0",
7+
"magento/framework": "*",
8+
"magento/module-catalog": "*",
9+
"magento/module-cms-graph-ql": "*"
10+
},
11+
"suggest": {
12+
"magento/module-graph-ql": "*",
13+
"magento/module-cms": "*",
14+
"magento/module-catalog-graph-ql": "*"
15+
},
16+
"license": [
17+
"OSL-3.0",
18+
"AFL-3.0"
19+
],
20+
"autoload": {
21+
"files": [
22+
"registration.php"
23+
],
24+
"psr-4": {
25+
"Magento\\CatalogCmsGraphQl\\": ""
26+
}
27+
}
28+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<type name="Magento\CatalogGraphQl\Model\AttributesJoiner">
10+
<arguments>
11+
<argument name="fieldToAttributeMap" xsi:type="array">
12+
<item name="cms_block" xsi:type="array">
13+
<item name="landing_page" xsi:type="string">landing_page</item>
14+
</item>
15+
</argument>
16+
</arguments>
17+
</type>
18+
</config>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
9+
<module name="Magento_CatalogCmsGraphQl" >
10+
<sequence>
11+
<module name="Magento_CmsGraphQl"/>
12+
<module name="Magento_CatalogGraphQl"/>
13+
</sequence>
14+
</module>
15+
</config>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
interface CategoryInterface {
5+
cms_block: CmsBlock @doc(description: "Category CMS Block.") @resolver(class: "Magento\\CatalogCmsGraphQl\\Model\\Resolver\\Category\\Block")
6+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Framework\Component\ComponentRegistrar;
8+
9+
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_CatalogCmsGraphQl', __DIR__);

app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,24 @@ class AttributesJoiner
2020
*/
2121
private $queryFields = [];
2222

23+
/**
24+
* Field to attribute mapping
25+
*
26+
* For fields that are not named the same as their attribute, or require extra attributes to resolve
27+
* e.g. ['field' => ['attr1', 'attr2'], 'other_field' => ['other_attr']]
28+
*
29+
* @var array
30+
*/
31+
private $fieldToAttributeMap = [];
32+
33+
/**
34+
* @param array $fieldToAttributeMap
35+
*/
36+
public function __construct(array $fieldToAttributeMap = [])
37+
{
38+
$this->fieldToAttributeMap = $fieldToAttributeMap;
39+
}
40+
2341
/**
2442
* Join fields attached to field node to collection's select.
2543
*
@@ -30,9 +48,7 @@ class AttributesJoiner
3048
public function join(FieldNode $fieldNode, AbstractCollection $collection) : void
3149
{
3250
foreach ($this->getQueryFields($fieldNode) as $field) {
33-
if (!$collection->isAttributeAdded($field)) {
34-
$collection->addAttributeToSelect($field);
35-
}
51+
$this->addFieldToCollection($collection, $field);
3652
}
3753
}
3854

@@ -42,7 +58,7 @@ public function join(FieldNode $fieldNode, AbstractCollection $collection) : voi
4258
* @param FieldNode $fieldNode
4359
* @return string[]
4460
*/
45-
public function getQueryFields(FieldNode $fieldNode)
61+
public function getQueryFields(FieldNode $fieldNode): array
4662
{
4763
if (!isset($this->queryFields[$fieldNode->name->value])) {
4864
$this->queryFields[$fieldNode->name->value] = [];
@@ -58,4 +74,29 @@ public function getQueryFields(FieldNode $fieldNode)
5874

5975
return $this->queryFields[$fieldNode->name->value];
6076
}
77+
78+
/**
79+
* Add field to collection select
80+
*
81+
* Add a query field to the collection, using mapped attribute names if they are set
82+
*
83+
* @param AbstractCollection $collection
84+
* @param string $field
85+
*/
86+
private function addFieldToCollection(AbstractCollection $collection, string $field)
87+
{
88+
$attribute = isset($this->fieldToAttributeMap[$field]) ? $this->fieldToAttributeMap[$field] : $field;
89+
90+
if (is_array($attribute)) {
91+
foreach ($attribute as $attributeName) {
92+
if (!$collection->isAttributeAdded($attributeName)) {
93+
$collection->addAttributeToSelect($attributeName);
94+
}
95+
}
96+
} else {
97+
if (!$collection->isAttributeAdded($attribute)) {
98+
$collection->addAttributeToSelect($attribute);
99+
}
100+
}
101+
}
61102
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@
170170
"magento/module-graph-ql": "*",
171171
"magento/module-graph-ql-cache": "*",
172172
"magento/module-catalog-graph-ql": "*",
173+
"magento/module-catalog-cms-graph-ql": "*",
173174
"magento/module-catalog-url-rewrite-graph-ql": "*",
174175
"magento/module-configurable-product-graph-ql": "*",
175176
"magento/module-customer-graph-ql": "*",

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl\CatalogCms;
9+
10+
use Magento\Catalog\Api\CategoryRepositoryInterface;
11+
use Magento\Cms\Api\BlockRepositoryInterface;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use Magento\TestFramework\TestCase\GraphQlAbstract;
14+
use Magento\Widget\Model\Template\FilterEmulate;
15+
16+
/**
17+
* Test category cms fields are resolved correctly
18+
*/
19+
class CategoryBlockTest extends GraphQlAbstract
20+
{
21+
/**
22+
* @magentoApiDataFixture Magento/Catalog/_files/category_tree.php
23+
* @magentoApiDataFixture Magento/Cms/_files/block.php
24+
*/
25+
public function testCategoryCmsBlock()
26+
{
27+
$blockId = 'fixture_block';
28+
/** @var BlockRepositoryInterface $blockRepository */
29+
$blockRepository = Bootstrap::getObjectManager()->get(BlockRepositoryInterface::class);
30+
$block = $blockRepository->getById($blockId);
31+
$filter = Bootstrap::getObjectManager()->get(FilterEmulate::class);
32+
$renderedContent = $filter->setUseSessionInUrl(false)->filter($block->getContent());
33+
34+
/** @var CategoryRepositoryInterface $categoryRepository */
35+
$categoryRepository = Bootstrap::getObjectManager()->get(CategoryRepositoryInterface::class);
36+
$category = $categoryRepository->get(401);
37+
$category->setLandingPage($block->getId());
38+
$categoryRepository->save($category);
39+
40+
$query = <<<QUERY
41+
{
42+
category(id: 401){
43+
name
44+
cms_block{
45+
identifier
46+
title
47+
content
48+
}
49+
}
50+
}
51+
QUERY;
52+
53+
$response = $this->graphQlQuery($query);
54+
$this->assertArrayNotHasKey('errors', $response);
55+
$this->assertNotEmpty($response['category']);
56+
$actualBlock = $response['category']['cms_block'];
57+
58+
$this->assertEquals($block->getTitle(), $actualBlock['title']);
59+
$this->assertEquals($block->getIdentifier(), $actualBlock['identifier']);
60+
$this->assertEquals($renderedContent, $actualBlock['content']);
61+
}
62+
}

0 commit comments

Comments
 (0)