Skip to content

Commit 6e19d75

Browse files
authored
Merge pull request #9623 from magento-lynx/graphql-api-enhancements
2 parents 38501f0 + f7dba72 commit 6e19d75

File tree

59 files changed

+3747
-146
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+3747
-146
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRule\Model\Config;
9+
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
12+
class CatalogRule
13+
{
14+
private const XML_PATH_SHARE_ALL_CATALOG_RULES = 'catalog/rule/share_all_catalog_rules';
15+
private const XML_PATH_SHARE_APPLIED_CATALOG_RULES = 'catalog/rule/share_applied_catalog_rules';
16+
17+
/**
18+
* CatalogRule constructor
19+
*
20+
* @param ScopeConfigInterface $scopeConfig
21+
*/
22+
public function __construct(
23+
private readonly ScopeConfigInterface $scopeConfig
24+
) {
25+
}
26+
27+
/**
28+
* Is 'share_all_catalog_rules' config enabled
29+
*
30+
* @return bool
31+
*/
32+
public function isShareAllCatalogRulesEnabled(): bool
33+
{
34+
return $this->scopeConfig->isSetFlag(self::XML_PATH_SHARE_ALL_CATALOG_RULES);
35+
}
36+
37+
/**
38+
* Is 'share_applied_catalog_rules' config enabled
39+
*
40+
* @return bool
41+
*/
42+
public function isShareAppliedCatalogRulesEnabled(): bool
43+
{
44+
return $this->scopeConfig->isSetFlag(self::XML_PATH_SHARE_APPLIED_CATALOG_RULES);
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRule\Model\ResourceModel;
9+
10+
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Framework\EntityManager\MetadataPool;
12+
use Magento\CatalogRule\Api\Data\RuleInterface;
13+
14+
class GetAllCatalogRules
15+
{
16+
/**
17+
* GetAllCatalogRules constructor
18+
*
19+
* @param ResourceConnection $resourceConnection
20+
* @param MetadataPool $metadataPool
21+
*/
22+
public function __construct(
23+
private readonly ResourceConnection $resourceConnection,
24+
private readonly MetadataPool $metadataPool
25+
) {
26+
}
27+
28+
/**
29+
* Get all catalog rules
30+
*
31+
* @param int $websiteId
32+
* @return array
33+
*/
34+
public function execute(int $websiteId): array
35+
{
36+
$connection = $this->resourceConnection->getConnection();
37+
$linkField = $this->metadataPool->getMetadata(RuleInterface::class)->getLinkField();
38+
39+
return $connection->fetchAll(
40+
$connection->select()
41+
->from(
42+
['cr' => $this->resourceConnection->getTableName('catalogrule')],
43+
['name']
44+
)
45+
->join(
46+
['crw' => $this->resourceConnection->getTableName('catalogrule_website')],
47+
"cr.rule_id = crw.$linkField",
48+
)
49+
->reset('columns')
50+
->columns(['name'])
51+
->distinct(true)
52+
->where('cr.is_active = ?', 1)
53+
->where('crw.website_id = ?', $websiteId)
54+
) ?? [];
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRule\Model\ResourceModel;
9+
10+
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Framework\EntityManager\MetadataPool;
12+
use Magento\CatalogRule\Api\Data\RuleInterface;
13+
14+
class GetAppliedCatalogRules
15+
{
16+
/**
17+
* GetAppliedCatalogRules constructor
18+
*
19+
* @param ResourceConnection $resourceConnection
20+
* @param MetadataPool $metadataPool
21+
*/
22+
public function __construct(
23+
private readonly ResourceConnection $resourceConnection,
24+
private readonly MetadataPool $metadataPool
25+
) {
26+
}
27+
28+
/**
29+
* Get applied catalog rules
30+
*
31+
* @param int $productId
32+
* @param int $websiteId
33+
* @return array
34+
*/
35+
public function execute(int $productId, int $websiteId): array
36+
{
37+
$connection = $this->resourceConnection->getConnection();
38+
$linkField = $this->metadataPool->getMetadata(RuleInterface::class)->getLinkField();
39+
40+
return $connection->fetchAll(
41+
$connection->select()
42+
->from(
43+
['cr' => $this->resourceConnection->getTableName('catalogrule')],
44+
['name']
45+
)
46+
->join(
47+
['crp' => $this->resourceConnection->getTableName('catalogrule_product')],
48+
'crp.rule_id = cr.rule_id',
49+
)
50+
->join(
51+
['crw' => $this->resourceConnection->getTableName('catalogrule_website')],
52+
"cr.rule_id = crw.$linkField",
53+
)
54+
->reset('columns')
55+
->columns(['name'])
56+
->distinct(true)
57+
->where('cr.is_active = ?', 1)
58+
->where('crp.product_id = ?', $productId)
59+
->where('crw.website_id = ?', $websiteId)
60+
) ?? [];
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
9+
<system>
10+
<section id="catalog">
11+
<group id="rule" translate="label" showInDefault="1" sortOrder="1000">
12+
<label>GraphQl Configurations</label>
13+
<field id="share_all_catalog_rules" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="0" showInStore="0">
14+
<label>Share all Catalog Rules via GraphQl</label>
15+
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
16+
<comment>Option to disable providing Catalog Rules details via GraphQl</comment>
17+
</field>
18+
<field id="share_applied_catalog_rules" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="0" showInStore="0">
19+
<label>Share the Applied Catalog Rules via GraphQl</label>
20+
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
21+
<comment>Option to disable providing Applied Catalog Rules details via GraphQl</comment>
22+
</field>
23+
</group>
24+
</section>
25+
</system>
26+
</config>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
9+
<default>
10+
<catalog>
11+
<rule>
12+
<share_all_catalog_rules>1</share_all_catalog_rules>
13+
<share_applied_catalog_rules>1</share_applied_catalog_rules>
14+
</rule>
15+
</catalog>
16+
</default>
17+
</config>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRuleGraphQl\Model\Resolver;
9+
10+
use Magento\CatalogRule\Model\Config\CatalogRule;
11+
use Magento\CatalogRule\Model\ResourceModel\GetAllCatalogRules;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
17+
/**
18+
* Provides data for allCatalogRules.name
19+
*/
20+
class AllCatalogRules implements ResolverInterface
21+
{
22+
/**
23+
* AllCatalogRules Constructor
24+
*
25+
* @param CatalogRule $config
26+
* @param GetAllCatalogRules $getAllCatalogRules
27+
*/
28+
public function __construct(
29+
private readonly CatalogRule $config,
30+
private readonly GetAllCatalogRules $getAllCatalogRules
31+
) {
32+
}
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
public function resolve(
38+
Field $field,
39+
$context,
40+
ResolveInfo $info,
41+
?array $value = null,
42+
?array $args = null
43+
): ?array {
44+
if (!$this->config->isShareAllCatalogRulesEnabled()) {
45+
throw new GraphQlInputException(__('Sharing catalog rules information is disabled or not configured.'));
46+
}
47+
48+
return array_map(
49+
fn ($rule) => ['name' => $rule['name']],
50+
$this->getAllCatalogRules->execute(
51+
(int)$context->getExtensionAttributes()->getStore()->getWebsiteId()
52+
)
53+
);
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRuleGraphQl\Model\Resolver;
9+
10+
use Magento\CatalogRule\Model\Config\CatalogRule;
11+
use Magento\CatalogRule\Model\ResourceModel\GetAppliedCatalogRules;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
17+
/**
18+
* Provides data for product.rules.name
19+
*/
20+
class AppliedCatalogRules implements ResolverInterface
21+
{
22+
/**
23+
* AppliedCatalogRules Constructor
24+
*
25+
* @param CatalogRule $config
26+
* @param GetAppliedCatalogRules $getAppliedCatalogRules
27+
*/
28+
public function __construct(
29+
private readonly CatalogRule $config,
30+
private readonly GetAppliedCatalogRules $getAppliedCatalogRules
31+
) {
32+
}
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
public function resolve(
38+
Field $field,
39+
$context,
40+
ResolveInfo $info,
41+
?array $value = null,
42+
?array $args = null
43+
): ?array {
44+
if (!isset($value['model'])) {
45+
throw new LocalizedException(__('"model" value should be specified'));
46+
}
47+
48+
if (!$this->config->isShareAppliedCatalogRulesEnabled()) {
49+
return null; //Returning `null` to ensure that the entire product response remains intact.
50+
}
51+
52+
return array_map(
53+
fn ($rule) => ['name' => $rule['name']],
54+
$this->getAppliedCatalogRules->execute(
55+
(int)$value['model']->getId(),
56+
(int)$context->getExtensionAttributes()->getStore()->getWebsiteId()
57+
)
58+
);
59+
}
60+
}

app/code/Magento/CatalogRuleGraphQl/composer.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
"type": "magento2-module",
55
"require": {
66
"php": "~8.2.0||~8.3.0||~8.4.0",
7-
"magento/framework": "*"
8-
},
9-
"suggest": {
7+
"magento/framework": "*",
108
"magento/module-catalog-rule": "*"
119
},
1210
"license": [
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
<?xml version="1.0"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
99
<type name="Magento\CatalogRule\Pricing\Price\CatalogRulePrice">
1010
<plugin name="update_catalog_rule_price_for_logged_in_customer_group" type="Magento\CatalogRuleGraphQl\Plugin\Pricing\Price\UpdateCatalogRulePrice"/>
1111
</type>
12+
<type name="Magento\StoreGraphQl\Model\Resolver\Store\StoreConfigDataProvider">
13+
<arguments>
14+
<argument name="extendedConfigData" xsi:type="array">
15+
<item name="share_all_catalog_rules" xsi:type="string">catalog/rule/share_all_catalog_rules</item>
16+
<item name="share_applied_catalog_rules" xsi:type="string">catalog/rule/share_applied_catalog_rules</item>
17+
</argument>
18+
</arguments>
19+
</type>
1220
</config>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Copyright 2025 Adobe
2+
# All Rights Reserved.
3+
4+
type StoreConfig {
5+
share_all_catalog_rules: Boolean! @doc(description: "Configuration data from catalog/rule/share_all_catalog_rules")
6+
share_applied_catalog_rules: Boolean! @doc(description: "Configuration data from catalog/rule/share_applied_catalog_rules")
7+
}
8+
9+
type Query {
10+
allCatalogRules: [CatalogRule!] @doc(description: "Provides all active catalog rules in the store.") @resolver(class: "Magento\\CatalogRuleGraphQl\\Model\\Resolver\\AllCatalogRules")
11+
}
12+
13+
interface ProductInterface {
14+
rules: [CatalogRule!] @doc(description: "Provides applied catalog rules in the current active cart") @resolver(class: "Magento\\CatalogRuleGraphQl\\Model\\Resolver\\AppliedCatalogRules")
15+
}
16+
17+
type CatalogRule {
18+
name: String! @doc(description: "Name of the catalog rule")
19+
}

0 commit comments

Comments
 (0)