Skip to content

Commit 44eb871

Browse files
ENGCOM-2914: GraphQL modules delivery #166
- Merge Pull Request magento/graphql-ce#166 from magento/graphql-ce:GraphQL-165 - Merged commits: 1. a617b80 2. 94c904e 3. 9b26913 4. e17c536 5. a7f0871 6. 1f9c09e 7. 0e2a2a6 8. 85e6826 9. c776df6 10. f35af8b 11. 5074178 12. 48fa7b5 13. 5552cdc 14. 874f564 15. ad25c62 16. a182123 17. 6789fe7 18. d2b9d53 19. 98d27f3 20. a28ab2f 21. 67b4361 22. b9515e5 23. 0bdf075 24. 6847178 25. eb1ed7a 26. 3bdd690 27. 02ab4bf 28. dce6c11 29. c870ee8 30. 7a9b5bd 31. 1f2e6fa 32. 0ef53fd 33. a62af8e 34. 4a4baf2 35. 141c920 36. fcd809e 37. 348e9b8 38. 52f7069 39. 131d1e4 40. 0beed4e 41. 09ed1b8 42. dacd786 43. 3eeb28f 44. 8fe1e21 45. 4a8637f 46. 23567bc 47. c5ecc0c 48. 68fafd7 49. 48ad892 50. 6f05267 51. 51d5cea 52. 4016812 53. 01c5a3d 54. 0091c4e 55. 171d40d 56. 122fc46 57. 8ac4471 58. 3176de0 59. 7ee4000 60. 709a1f7 61. 2966ac3 62. 439df24 63. 9bff89e 64. 5c29598 65. b06aa33 66. 47d2aed 67. bf98d4f 68. 277d542 69. f8a3818 70. 6adb264 71. 32c73ce 72. 4098a38
2 parents d394949 + 4098a38 commit 44eb871

37 files changed

+1353
-2
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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\CatalogInventoryGraphQl\Model\Resolver;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\CatalogInventory\Api\StockRegistryInterface;
12+
use Magento\CatalogInventory\Model\Configuration;
13+
use Magento\Framework\App\Config\ScopeConfigInterface;
14+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
15+
use Magento\Framework\GraphQl\Config\Element\Field;
16+
use Magento\Framework\GraphQl\Query\Resolver\Value;
17+
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
18+
use Magento\Framework\GraphQl\Query\ResolverInterface;
19+
use Magento\Store\Model\ScopeInterface;
20+
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
class OnlyXLeftInStockResolver implements ResolverInterface
25+
{
26+
/**
27+
* @var ValueFactory
28+
*/
29+
private $valueFactory;
30+
31+
/**
32+
* @var ScopeConfigInterface
33+
*/
34+
private $scopeConfig;
35+
36+
/**
37+
* @var StockRegistryInterface
38+
*/
39+
private $stockRegistry;
40+
41+
/**
42+
* @param ValueFactory $valueFactory
43+
* @param ScopeConfigInterface $scopeConfig
44+
* @param StockRegistryInterface $stockRegistry
45+
*/
46+
public function __construct(
47+
ValueFactory $valueFactory,
48+
ScopeConfigInterface $scopeConfig,
49+
StockRegistryInterface $stockRegistry
50+
) {
51+
$this->valueFactory = $valueFactory;
52+
$this->scopeConfig = $scopeConfig;
53+
$this->stockRegistry = $stockRegistry;
54+
}
55+
56+
/**
57+
* {@inheritdoc}
58+
*/
59+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null): Value
60+
{
61+
if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) {
62+
$result = function () {
63+
return null;
64+
};
65+
66+
return $this->valueFactory->create($result);
67+
}
68+
69+
/* @var $product ProductInterface */
70+
$product = $value['model'];
71+
$onlyXLeftQty = $this->getOnlyXLeftQty($product);
72+
73+
$result = function () use ($onlyXLeftQty) {
74+
return $onlyXLeftQty;
75+
};
76+
77+
return $this->valueFactory->create($result);
78+
}
79+
80+
/**
81+
* Get product qty left when "Catalog > Inventory > Stock Options > Only X left Threshold" is greater than 0
82+
*
83+
* @param ProductInterface $product
84+
*
85+
* @return null|float
86+
*/
87+
private function getOnlyXLeftQty(ProductInterface $product): ?float
88+
{
89+
$thresholdQty = (float)$this->scopeConfig->getValue(
90+
Configuration::XML_PATH_STOCK_THRESHOLD_QTY,
91+
ScopeInterface::SCOPE_STORE
92+
);
93+
if ($thresholdQty === 0) {
94+
return null;
95+
}
96+
97+
$stockItem = $this->stockRegistry->getStockItem($product->getId());
98+
99+
$stockCurrentQty = $this->stockRegistry->getStockStatus(
100+
$product->getId(),
101+
$product->getStore()->getWebsiteId()
102+
)->getQty();
103+
104+
$stockLeft = $stockCurrentQty - $stockItem->getMinQty();
105+
106+
$thresholdQty = (float)$this->scopeConfig->getValue(
107+
Configuration::XML_PATH_STOCK_THRESHOLD_QTY,
108+
ScopeInterface::SCOPE_STORE
109+
);
110+
111+
if ($stockCurrentQty > 0 && $stockLeft <= $thresholdQty) {
112+
return $stockLeft;
113+
}
114+
115+
return null;
116+
}
117+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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\CatalogInventoryGraphQl\Model\Resolver;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\CatalogInventory\Api\Data\StockStatusInterface;
12+
use Magento\CatalogInventory\Api\StockStatusRepositoryInterface;
13+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
14+
use Magento\Framework\GraphQl\Config\Element\Field;
15+
use Magento\Framework\GraphQl\Query\Resolver\Value;
16+
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
17+
use Magento\Framework\GraphQl\Query\ResolverInterface;
18+
19+
/**
20+
* {@inheritdoc}
21+
*/
22+
class StockStatusProvider implements ResolverInterface
23+
{
24+
/**
25+
* @var ValueFactory
26+
*/
27+
private $valueFactory;
28+
29+
/**
30+
* @var StockStatusRepositoryInterface
31+
*/
32+
private $stockStatusRepository;
33+
34+
/**
35+
* @param ValueFactory $valueFactory
36+
* @param StockStatusRepositoryInterface $stockStatusRepository
37+
*/
38+
public function __construct(ValueFactory $valueFactory, StockStatusRepositoryInterface $stockStatusRepository)
39+
{
40+
$this->valueFactory = $valueFactory;
41+
$this->stockStatusRepository = $stockStatusRepository;
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null): Value
48+
{
49+
if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) {
50+
$result = function () {
51+
return null;
52+
};
53+
54+
return $this->valueFactory->create($result);
55+
}
56+
57+
/* @var $product ProductInterface */
58+
$product = $value['model'];
59+
60+
$stockStatus = $this->stockStatusRepository->get($product->getId());
61+
$productStockStatus = (int)$stockStatus->getStockStatus();
62+
63+
$result = function () use ($productStockStatus) {
64+
return $productStockStatus === StockStatusInterface::STATUS_IN_STOCK ? 'IN_STOCK' : 'OUT_OF_STOCK';
65+
};
66+
67+
return $this->valueFactory->create($result);
68+
}
69+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# CatalogInventoryGraphQl
2+
3+
**CatalogInventoryGraphQl** provides type information for the GraphQl module
4+
to generate inventory stock fields for product information endpoints.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "magento/module-catalog-inventory-graph-ql",
3+
"description": "N/A",
4+
"type": "magento2-module",
5+
"require": {
6+
"php": "~7.1.3||~7.2.0",
7+
"magento/framework": "*",
8+
"magento/module-store": "*",
9+
"magento/module-catalog": "*",
10+
"magento/module-catalog-inventory": "*"
11+
},
12+
"license": [
13+
"OSL-3.0",
14+
"AFL-3.0"
15+
],
16+
"autoload": {
17+
"files": [
18+
"registration.php"
19+
],
20+
"psr-4": {
21+
"Magento\\CatalogInventoryGraphQl\\": ""
22+
}
23+
}
24+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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_CatalogInventoryGraphQl">
10+
<sequence>
11+
<module name="Magento_Store"/>
12+
<module name="Magento_Catalog"/>
13+
<module name="Magento_CatalogInventory"/>
14+
</sequence>
15+
</module>
16+
</config>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
interface ProductInterface {
5+
only_x_left_in_stock: Float @doc(description: "Product stock only x left count") @resolver(class: "Magento\\CatalogInventoryGraphQl\\Model\\Resolver\\OnlyXLeftInStockResolver")
6+
stock_status: ProductStockStatus @doc(description: "Stock status of the product") @resolver(class: "Magento\\CatalogInventoryGraphQl\\Model\\Resolver\\StockStatusProvider")
7+
}
8+
9+
enum ProductStockStatus @doc(description: "This enumeration states whether a product stock status is in stock or out of stock") {
10+
IN_STOCK
11+
OUT_OF_STOCK
12+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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+
use Magento\Framework\Component\ComponentRegistrar;
9+
10+
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_CatalogInventoryGraphQl', __DIR__);
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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\CmsGraphQl\Model\Resolver;
9+
10+
use Magento\CmsGraphQl\Model\Resolver\DataProvider\Block as BlockDataProvider;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
14+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
15+
use Magento\Framework\GraphQl\Query\Resolver\Value;
16+
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
17+
use Magento\Framework\GraphQl\Query\ResolverInterface;
18+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
19+
20+
/**
21+
* CMS blocks field resolver, used for GraphQL request processing
22+
*/
23+
class Blocks implements ResolverInterface
24+
{
25+
/**
26+
* @var BlockDataProvider
27+
*/
28+
private $blockDataProvider;
29+
30+
/**
31+
* @var ValueFactory
32+
*/
33+
private $valueFactory;
34+
35+
/**
36+
* @param BlockDataProvider $blockDataProvider
37+
* @param ValueFactory $valueFactory
38+
*/
39+
public function __construct(
40+
BlockDataProvider $blockDataProvider,
41+
ValueFactory $valueFactory
42+
) {
43+
$this->blockDataProvider = $blockDataProvider;
44+
$this->valueFactory = $valueFactory;
45+
}
46+
47+
/**
48+
* @inheritdoc
49+
*/
50+
public function resolve(
51+
Field $field,
52+
$context,
53+
ResolveInfo $info,
54+
array $value = null,
55+
array $args = null
56+
) : Value {
57+
58+
$result = function () use ($args) {
59+
$blockIdentifiers = $this->getBlockIdentifiers($args);
60+
$blocksData = $this->getBlocksData($blockIdentifiers);
61+
62+
$resultData = [
63+
'items' => $blocksData,
64+
];
65+
return $resultData;
66+
};
67+
return $this->valueFactory->create($result);
68+
}
69+
70+
/**
71+
* @param array $args
72+
* @return string[]
73+
* @throws GraphQlInputException
74+
*/
75+
private function getBlockIdentifiers(array $args): array
76+
{
77+
if (!isset($args['identifiers']) || !is_array($args['identifiers']) || count($args['identifiers']) === 0) {
78+
throw new GraphQlInputException(__('"identifiers" of CMS blocks should be specified'));
79+
}
80+
81+
return $args['identifiers'];
82+
}
83+
84+
/**
85+
* @param array $blockIdentifiers
86+
* @return array
87+
* @throws GraphQlNoSuchEntityException
88+
*/
89+
private function getBlocksData(array $blockIdentifiers): array
90+
{
91+
$blocksData = [];
92+
try {
93+
foreach ($blockIdentifiers as $blockIdentifier) {
94+
$blocksData[$blockIdentifier] = $this->blockDataProvider->getData($blockIdentifier);
95+
}
96+
} catch (NoSuchEntityException $e) {
97+
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
98+
}
99+
return $blocksData;
100+
}
101+
}

0 commit comments

Comments
 (0)