Skip to content

Commit 4f7b4f0

Browse files
authored
Merge branch 'magento-commerce:2.4-develop' into ACP2E-1338
2 parents a12b85c + 39f0be8 commit 4f7b4f0

File tree

15 files changed

+430
-251
lines changed

15 files changed

+430
-251
lines changed

app/code/Magento/Catalog/Model/Category/AttributeRepository.php

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ class AttributeRepository implements CategoryAttributeRepositoryInterface
2929
*/
3030
private $eavConfig;
3131

32+
/**
33+
* @var array
34+
*/
35+
private $metadataCache;
36+
3237
/**
3338
* @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
3439
* @param \Magento\Framework\Api\FilterBuilder $filterBuilder
@@ -48,7 +53,7 @@ public function __construct(
4853
}
4954

5055
/**
51-
* {@inheritdoc}
56+
* @inheritdoc
5257
*/
5358
public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
5459
{
@@ -59,7 +64,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
5964
}
6065

6166
/**
62-
* {@inheritdoc}
67+
* @inheritdoc
6368
*/
6469
public function get($attributeCode)
6570
{
@@ -70,23 +75,27 @@ public function get($attributeCode)
7075
}
7176

7277
/**
73-
* {@inheritdoc}
78+
* @inheritdoc
79+
*
7480
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
7581
*/
7682
public function getCustomAttributesMetadata($dataObjectClassName = null)
7783
{
78-
$defaultAttributeSetId = $this->eavConfig
79-
->getEntityType(\Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE)
80-
->getDefaultAttributeSetId();
81-
$searchCriteria = $this->searchCriteriaBuilder->addFilters(
82-
[
83-
$this->filterBuilder
84-
->setField('attribute_set_id')
85-
->setValue($defaultAttributeSetId)
86-
->create(),
87-
]
88-
);
89-
90-
return $this->getList($searchCriteria->create())->getItems();
84+
if (!isset($this->metadataCache[$dataObjectClassName])) {
85+
$defaultAttributeSetId = $this->eavConfig
86+
->getEntityType(\Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE)
87+
->getDefaultAttributeSetId();
88+
$searchCriteria = $this->searchCriteriaBuilder->addFilters(
89+
[
90+
$this->filterBuilder
91+
->setField('attribute_set_id')
92+
->setValue($defaultAttributeSetId)
93+
->create(),
94+
]
95+
);
96+
$this->metadataCache[$dataObjectClassName] = $this->getList($searchCriteria->create())
97+
->getItems();
98+
}
99+
return $this->metadataCache[$dataObjectClassName];
91100
}
92101
}

app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77

88
namespace Magento\CatalogGraphQl\Model\Category;
99

10-
use Magento\Catalog\Api\CategoryRepositoryInterface;
11-
use Magento\Catalog\Api\Data\CategorySearchResultsInterface;
12-
use Magento\Catalog\Api\Data\CategorySearchResultsInterfaceFactory;
1310
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
1411
use Magento\CatalogGraphQl\Model\Resolver\Categories\DataProvider\Category\CollectionProcessorInterface;
1512
use Magento\CatalogGraphQl\Model\Category\Filter\SearchCriteria;
1613
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
14+
use Magento\Framework\DB\Select;
1715
use Magento\Framework\Exception\InputException;
1816
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
1917
use Magento\GraphQl\Model\Query\ContextInterface;
@@ -39,16 +37,6 @@ class CategoryFilter
3937
*/
4038
private $extensionAttributesJoinProcessor;
4139

42-
/**
43-
* @var CategorySearchResultsInterfaceFactory
44-
*/
45-
private $categorySearchResultsFactory;
46-
47-
/**
48-
* @var CategoryRepositoryInterface
49-
*/
50-
private $categoryRepository;
51-
5240
/**
5341
* @var SearchCriteria
5442
*/
@@ -58,23 +46,17 @@ class CategoryFilter
5846
* @param CollectionFactory $categoryCollectionFactory
5947
* @param CollectionProcessorInterface $collectionProcessor
6048
* @param JoinProcessorInterface $extensionAttributesJoinProcessor
61-
* @param CategorySearchResultsInterfaceFactory $categorySearchResultsFactory
62-
* @param CategoryRepositoryInterface $categoryRepository
6349
* @param SearchCriteria $searchCriteria
6450
*/
6551
public function __construct(
6652
CollectionFactory $categoryCollectionFactory,
6753
CollectionProcessorInterface $collectionProcessor,
6854
JoinProcessorInterface $extensionAttributesJoinProcessor,
69-
CategorySearchResultsInterfaceFactory $categorySearchResultsFactory,
70-
CategoryRepositoryInterface $categoryRepository,
7155
SearchCriteria $searchCriteria
7256
) {
7357
$this->categoryCollectionFactory = $categoryCollectionFactory;
7458
$this->collectionProcessor = $collectionProcessor;
7559
$this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
76-
$this->categorySearchResultsFactory = $categorySearchResultsFactory;
77-
$this->categoryRepository = $categoryRepository;
7860
$this->searchCriteria = $searchCriteria;
7961
}
8062

@@ -95,22 +77,21 @@ public function getResult(array $criteria, StoreInterface $store, array $attribu
9577
$this->extensionAttributesJoinProcessor->process($collection);
9678
$this->collectionProcessor->process($collection, $searchCriteria, $attributeNames, $context);
9779

98-
/** @var CategorySearchResultsInterface $searchResult */
99-
$categories = $this->categorySearchResultsFactory->create();
100-
$categories->setSearchCriteria($searchCriteria);
101-
$categories->setItems($collection->getItems());
102-
$categories->setTotalCount($collection->getSize());
80+
// only fetch necessary category entity id
81+
$collection
82+
->getSelect()
83+
->reset(Select::COLUMNS)
84+
->columns(
85+
'e.entity_id'
86+
);
10387

104-
$categoryIds = [];
105-
foreach ($categories->getItems() as $category) {
106-
$categoryIds[] = (int)$category->getId();
107-
}
88+
$categoryIds = $collection->load()->getLoadedIds();
10889

10990
$totalPages = 0;
110-
if ($categories->getTotalCount() > 0 && $searchCriteria->getPageSize() > 0) {
111-
$totalPages = ceil($categories->getTotalCount() / $searchCriteria->getPageSize());
91+
if ($collection->getSize() > 0 && $searchCriteria->getPageSize() > 0) {
92+
$totalPages = ceil($collection->getSize() / $searchCriteria->getPageSize());
11293
}
113-
if ($searchCriteria->getCurrentPage() > $totalPages && $categories->getTotalCount() > 0) {
94+
if ($searchCriteria->getCurrentPage() > $totalPages && $collection->getSize() > 0) {
11495
throw new GraphQlInputException(
11596
__(
11697
'currentPage value %1 specified is greater than the %2 page(s) available.',
@@ -121,7 +102,7 @@ public function getResult(array $criteria, StoreInterface $store, array $attribu
121102

122103
return [
123104
'category_ids' => $categoryIds,
124-
'total_count' => $categories->getTotalCount(),
105+
'total_count' => $collection->getSize(),
125106
'page_info' => [
126107
'total_pages' => $totalPages,
127108
'page_size' => $searchCriteria->getPageSize(),

app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,12 @@ public function hydrateCategory(Category $category, $basicFieldsOnly = false) :
6060
if ($basicFieldsOnly) {
6161
$categoryData = $category->getData();
6262
} else {
63-
$categoryData = $this->dataObjectProcessor->buildOutputDataArray($category, CategoryInterface::class);
63+
$categoryData = $this->dataObjectProcessor->buildOutputDataArray(
64+
$category,
65+
CategoryInterface::class
66+
);
6467
}
68+
6569
$categoryData['id'] = $category->getId();
6670
$categoryData['uid'] = $this->uidEncoder->encode((string) $category->getId());
6771
$categoryData['children'] = [];

app/code/Magento/CatalogGraphQl/etc/graphql/di.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@
191191
<type name="Magento\Catalog\Api\ProductRepositoryInterface">
192192
<plugin name="availableProductsFilter" type="Magento\CatalogGraphQl\Plugin\AvailableProductsFilter" />
193193
</type>
194+
<type name="Magento\CatalogGraphQl\Model\Category\Hydrator">
195+
<arguments>
196+
<argument name="dataObjectProcessor" xsi:type="object">Magento\CatalogGraphQl\Category\DataObjectProcessor</argument>
197+
</arguments>
198+
</type>
194199
<virtualType name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ChildProduct"
195200
type="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product">
196201
<arguments>
@@ -207,4 +212,16 @@
207212
</argument>
208213
</arguments>
209214
</virtualType>
215+
<virtualType
216+
name="Magento\CatalogGraphQl\Category\DataObjectProcessor"
217+
type="Magento\Framework\Reflection\DataObjectProcessor"
218+
>
219+
<arguments>
220+
<argument name="excludedMethodsClassMap" xsi:type="array">
221+
<item name="Magento\Catalog\Api\Data\CategoryInterface" xsi:type="array">
222+
<item name="getChildren" xsi:type="string">getChildren</item>
223+
</item>
224+
</argument>
225+
</arguments>
226+
</virtualType>
210227
</config>

app/code/Magento/Quote/Model/Cart/AddProductsToCart.php

Lines changed: 16 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
namespace Magento\Quote\Model\Cart;
99

10-
use Magento\Catalog\Api\ProductRepositoryInterface;
11-
use Magento\Framework\App\ObjectManager;
1210
use Magento\Framework\Exception\NoSuchEntityException;
1311
use Magento\Quote\Api\CartRepositoryInterface;
1412
use Magento\Quote\Model\Cart\BuyRequest\BuyRequestBuilder;
@@ -23,29 +21,6 @@
2321
*/
2422
class AddProductsToCart
2523
{
26-
/**#@+
27-
* Error message codes
28-
*/
29-
private const ERROR_PRODUCT_NOT_FOUND = 'PRODUCT_NOT_FOUND';
30-
private const ERROR_INSUFFICIENT_STOCK = 'INSUFFICIENT_STOCK';
31-
private const ERROR_NOT_SALABLE = 'NOT_SALABLE';
32-
private const ERROR_UNDEFINED = 'UNDEFINED';
33-
/**#@-*/
34-
35-
/**
36-
* List of error messages and codes.
37-
*/
38-
private const MESSAGE_CODES = [
39-
'Could not find a product with SKU' => self::ERROR_PRODUCT_NOT_FOUND,
40-
'The required options you selected are not available' => self::ERROR_NOT_SALABLE,
41-
'Product that you are trying to add is not available.' => self::ERROR_NOT_SALABLE,
42-
'This product is out of stock' => self::ERROR_INSUFFICIENT_STOCK,
43-
'There are no source items' => self::ERROR_NOT_SALABLE,
44-
'The fewest you may purchase is' => self::ERROR_INSUFFICIENT_STOCK,
45-
'The most you may purchase is' => self::ERROR_INSUFFICIENT_STOCK,
46-
'The requested qty is not available' => self::ERROR_INSUFFICIENT_STOCK,
47-
];
48-
4924
/**
5025
* @var CartRepositoryInterface
5126
*/
@@ -67,25 +42,29 @@ class AddProductsToCart
6742
private $productReader;
6843

6944
/**
70-
* @param ProductRepositoryInterface $productRepository
45+
* @var AddProductsToCartError
46+
*/
47+
private $error;
48+
49+
/**
7150
* @param CartRepositoryInterface $cartRepository
7251
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
7352
* @param BuyRequestBuilder $requestBuilder
74-
* @param ProductReaderInterface|null $productReader
75-
*
76-
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
53+
* @param ProductReaderInterface $productReader
54+
* @param AddProductsToCartError $addProductsToCartError
7755
*/
7856
public function __construct(
79-
ProductRepositoryInterface $productRepository,
8057
CartRepositoryInterface $cartRepository,
8158
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
8259
BuyRequestBuilder $requestBuilder,
83-
ProductReaderInterface $productReader = null
60+
ProductReaderInterface $productReader,
61+
AddProductsToCartError $addProductsToCartError
8462
) {
8563
$this->cartRepository = $cartRepository;
8664
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
8765
$this->requestBuilder = $requestBuilder;
88-
$this->productReader = $productReader ?: ObjectManager::getInstance()->get(ProductReaderInterface::class);
66+
$this->productReader = $productReader;
67+
$this->error = $addProductsToCartError;
8968
}
9069

9170
/**
@@ -106,7 +85,7 @@ public function execute(string $maskedCartId, array $cartItems): AddProductsToCa
10685

10786
/** @var MessageInterface $error */
10887
foreach ($errors as $error) {
109-
$allErrors[] = $this->createError($error->getText());
88+
$allErrors[] = $this->error->create($error->getText());
11089
}
11190
}
11291

@@ -181,22 +160,22 @@ private function addItemToCart(Quote $cart, Data\CartItem $cartItem, int $cartIt
181160
$result = null;
182161

183162
if ($cartItem->getQuantity() <= 0) {
184-
$errors[] = $this->createError(
163+
$errors[] = $this->error->create(
185164
__('The product quantity should be greater than 0')->render(),
186165
$cartItemPosition
187166
);
188167
} else {
189168
$product = $this->productReader->getProductBySku($sku);
190169
if (!$product || !$product->isSaleable() || !$product->isAvailable()) {
191-
$errors[] = $this->createError(
170+
$errors[] = $this->error->create(
192171
__('Could not find a product with SKU "%sku"', ['sku' => $sku])->render(),
193172
$cartItemPosition
194173
);
195174
} else {
196175
try {
197176
$result = $cart->addProduct($product, $this->requestBuilder->build($cartItem));
198177
} catch (\Throwable $e) {
199-
$errors[] = $this->createError(
178+
$errors[] = $this->error->create(
200179
__($e->getMessage())->render(),
201180
$cartItemPosition
202181
);
@@ -205,50 +184,14 @@ private function addItemToCart(Quote $cart, Data\CartItem $cartItem, int $cartIt
205184

206185
if (is_string($result)) {
207186
foreach (array_unique(explode("\n", $result)) as $error) {
208-
$errors[] = $this->createError(__($error)->render(), $cartItemPosition);
187+
$errors[] = $this->error->create(__($error)->render(), $cartItemPosition);
209188
}
210189
}
211190
}
212191

213192
return $errors;
214193
}
215194

216-
/**
217-
* Returns an error object
218-
*
219-
* @param string $message
220-
* @param int $cartItemPosition
221-
* @return Data\Error
222-
*/
223-
private function createError(string $message, int $cartItemPosition = 0): Data\Error
224-
{
225-
return new Data\Error(
226-
$message,
227-
$this->getErrorCode($message),
228-
$cartItemPosition
229-
);
230-
}
231-
232-
/**
233-
* Get message error code.
234-
*
235-
* TODO: introduce a separate class for getting error code from a message
236-
*
237-
* @param string $message
238-
* @return string
239-
*/
240-
private function getErrorCode(string $message): string
241-
{
242-
foreach (self::MESSAGE_CODES as $codeMessage => $code) {
243-
if (false !== stripos($message, $codeMessage)) {
244-
return $code;
245-
}
246-
}
247-
248-
/* If no code was matched, return the default one */
249-
return self::ERROR_UNDEFINED;
250-
}
251-
252195
/**
253196
* Creates a new output from existing errors
254197
*

0 commit comments

Comments
 (0)