Skip to content

Commit 12e071c

Browse files
Merge pull request #8844 from adobe-commerce-tier-4/Tier4-Kings-PR-03-19-2024
[Support Tier-4-Kings glo16746] 03.19.2024 Regular delivery of bugfixes and improvements
2 parents c971859 + e269ed7 commit 12e071c

File tree

6 files changed

+278
-33
lines changed

6 files changed

+278
-33
lines changed

app/code/Magento/CatalogGraphQl/DataProvider/Product/LayeredNavigation/Builder/Aggregations/Category/IncludeDirectChildrenOnly.php

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
namespace Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Builder\Aggregations\Category;
99

1010
use Magento\Catalog\Api\CategoryListInterface;
11+
use Magento\Catalog\Model\Config\LayerCategoryConfig;
1112
use Magento\Framework\Api\SearchCriteriaBuilder;
13+
use Magento\Framework\App\ObjectManager;
1214
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
1315
use Magento\Framework\Search\Response\Aggregation;
1416
use Magento\Framework\Search\Response\AggregationFactory;
@@ -61,25 +63,34 @@ class IncludeDirectChildrenOnly implements ResetAfterRequestInterface
6163
*/
6264
private $searchCriteriaBuilder;
6365

66+
/**
67+
* @var LayerCategoryConfig|null
68+
*/
69+
private $layerCategoryConfig;
70+
6471
/**
6572
* @param AggregationFactory $aggregationFactory
6673
* @param BucketFactory $bucketFactory
6774
* @param StoreManagerInterface $storeManager
6875
* @param CategoryListInterface $categoryList
6976
* @param SearchCriteriaBuilder $searchCriteriaBuilder
77+
* @param LayerCategoryConfig|null $layerCategoryConfig
7078
*/
7179
public function __construct(
7280
AggregationFactory $aggregationFactory,
7381
BucketFactory $bucketFactory,
7482
StoreManagerInterface $storeManager,
7583
CategoryListInterface $categoryList,
76-
SearchCriteriaBuilder $searchCriteriaBuilder
84+
SearchCriteriaBuilder $searchCriteriaBuilder,
85+
?LayerCategoryConfig $layerCategoryConfig = null
7786
) {
7887
$this->aggregationFactory = $aggregationFactory;
7988
$this->bucketFactory = $bucketFactory;
8089
$this->storeManager = $storeManager;
8190
$this->categoryList = $categoryList;
8291
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
92+
$this->layerCategoryConfig = $layerCategoryConfig ?? ObjectManager::getInstance()
93+
->get(LayerCategoryConfig::class);
8394
}
8495

8596
/**
@@ -91,28 +102,34 @@ public function __construct(
91102
*/
92103
public function filter(AggregationInterface $aggregation, ?int $storeId): Aggregation
93104
{
94-
$categoryIdsRequested = $this->filter['category'] ?? null;
95-
if ($categoryIdsRequested === null) {
96-
return $aggregation;
97-
}
98-
$buckets = $aggregation->getBuckets();
99-
$categoryBucket = $buckets[self::CATEGORY_BUCKET] ?? null;
100-
if ($categoryBucket === null || empty($categoryBucket->getValues())) {
101-
return $aggregation;
105+
if (!$this->layerCategoryConfig->isCategoryFilterVisibleInLayerNavigation()) {
106+
$buckets = $aggregation->getBuckets();
107+
unset($buckets[self::CATEGORY_BUCKET]);
108+
} else {
109+
$categoryIdsRequested = $this->filter['category'] ?? null;
110+
if ($categoryIdsRequested === null) {
111+
return $aggregation;
112+
}
113+
$buckets = $aggregation->getBuckets();
114+
$categoryBucket = $buckets[self::CATEGORY_BUCKET] ?? null;
115+
if ($categoryBucket === null || empty($categoryBucket->getValues())) {
116+
return $aggregation;
117+
}
118+
$categoryIdsRequested = is_array($categoryIdsRequested) ? $categoryIdsRequested : [$categoryIdsRequested];
119+
$bucketValuesFiltered = $this->filterBucketValues(
120+
$categoryBucket->getValues(),
121+
$categoryIdsRequested,
122+
$storeId
123+
);
124+
$categoryBucketResolved = $this->bucketFactory->create(
125+
[
126+
'name' => self::CATEGORY_BUCKET,
127+
'values' => $bucketValuesFiltered
128+
]
129+
);
130+
$buckets[self::CATEGORY_BUCKET] = $categoryBucketResolved;
102131
}
103-
$categoryIdsRequested = is_array($categoryIdsRequested) ? $categoryIdsRequested : [$categoryIdsRequested];
104-
$bucketValuesFiltered = $this->filterBucketValues(
105-
$categoryBucket->getValues(),
106-
$categoryIdsRequested,
107-
$storeId
108-
);
109-
$categoryBucketResolved = $this->bucketFactory->create(
110-
[
111-
'name' => self::CATEGORY_BUCKET,
112-
'values' => $bucketValuesFiltered
113-
]
114-
);
115-
$buckets[self::CATEGORY_BUCKET] = $categoryBucketResolved;
132+
116133
return $this->aggregationFactory->create([self::BUCKETS_NAME => $buckets]);
117134
}
118135

app/code/Magento/Sales/Model/ResourceModel/Order/Address.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\Sales\Model\ResourceModel\Order;
77

8+
use Magento\Framework\Model\AbstractModel;
89
use Magento\Sales\Model\ResourceModel\EntityAbstract as SalesResource;
910
use Magento\Sales\Model\Spi\OrderAddressResourceInterface;
1011
use Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot;
@@ -15,7 +16,7 @@
1516
class Address extends SalesResource implements OrderAddressResourceInterface
1617
{
1718
/**
18-
* Event prefix
19+
* Sales order address event prefix
1920
*
2021
* @var string
2122
*/
@@ -33,10 +34,10 @@ class Address extends SalesResource implements OrderAddressResourceInterface
3334

3435
/**
3536
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
36-
* @param \Magento\Sales\Model\ResourceModel\Attribute $attribute
37-
* @param \Magento\SalesSequence\Model\Manager $sequenceManager
3837
* @param Snapshot $entitySnapshot
3938
* @param \Magento\Framework\Model\ResourceModel\Db\VersionControl\RelationComposite $entityRelationComposite
39+
* @param \Magento\Sales\Model\ResourceModel\Attribute $attribute
40+
* @param \Magento\SalesSequence\Model\Manager $sequenceManager
4041
* @param \Magento\Sales\Model\Order\Address\Validator $validator
4142
* @param \Magento\Sales\Model\ResourceModel\GridPool $gridPool
4243
* @param string $connectionName
@@ -122,4 +123,24 @@ protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object)
122123
}
123124
return $this;
124125
}
126+
127+
/**
128+
* @inheritdoc
129+
*/
130+
protected function isModified(AbstractModel $entity): bool
131+
{
132+
if (!$entity->getId()) {
133+
return true;
134+
}
135+
$snapShotData = $this->entitySnapshot->getSnapshotData($entity);
136+
foreach ($snapShotData as $field => $value) {
137+
$fieldValue = $entity->getDataByKey($field);
138+
if (is_numeric($fieldValue) && is_numeric($value)) {
139+
if ($fieldValue !== $value) {
140+
return true;
141+
}
142+
}
143+
}
144+
return parent::isModified($entity);
145+
}
125146
}

app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/AddressTest.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,6 @@ public function testSave()
9898
->method('validate')
9999
->with($this->addressMock)
100100
->willReturn([]);
101-
$this->entitySnapshotMock->expects($this->once())
102-
->method('isModified')
103-
->with($this->addressMock)
104-
->willReturn(true);
105101
$this->addressMock->expects($this->once())
106102
->method('getParentId')
107103
->willReturn(1);
@@ -116,10 +112,6 @@ public function testSaveValidationFailed()
116112
{
117113
$this->expectException('Magento\Framework\Exception\LocalizedException');
118114
$this->expectExceptionMessage('We can\'t save the address:');
119-
$this->entitySnapshotMock->expects($this->once())
120-
->method('isModified')
121-
->with($this->addressMock)
122-
->willReturn(true);
123115
$this->addressMock->expects($this->any())
124116
->method('hasDataChanges')
125117
->willReturn(true);

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchCategoryAggregationsTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,92 @@ private function getGraphQlQuery(string $categoryList, string $includeDirectChil
225225
}
226226
}
227227
}
228+
QUERY;
229+
}
230+
231+
/**
232+
* Test the categories that appear in aggregation Layered Navigation > Display Category Filter => Yes (default).
233+
*
234+
* @magentoApiDataFixture Magento/Catalog/_files/categories.php
235+
* @throws \Exception
236+
*/
237+
public function testFetchCategoriesWhenDisplayCategoryEnabled(): void
238+
{
239+
$result = $this->aggregationWithDisplayCategorySetting();
240+
$aggregationAttributeCode = [];
241+
foreach ($result['products']['aggregations'] as $aggregation) {
242+
$this->assertArrayHasKey('attribute_code', $aggregation);
243+
$aggregationAttributeCode[] = $aggregation['attribute_code'];
244+
}
245+
$this->assertTrue(in_array('category_uid', $aggregationAttributeCode));
246+
}
247+
248+
/**
249+
* Test the categories not in aggregation when Layered Navigation > Display Category Filter => No.
250+
*
251+
* @magentoConfigFixture catalog/layered_navigation/display_category 0
252+
* @magentoApiDataFixture Magento/Catalog/_files/categories.php
253+
* @throws \Exception
254+
*/
255+
public function testDontFetchCategoriesWhenDisplayCategoryDisabled(): void
256+
{
257+
$result = $this->aggregationWithDisplayCategorySetting();
258+
$aggregationAttributeCode = [];
259+
foreach ($result['products']['aggregations'] as $aggregation) {
260+
$this->assertArrayHasKey('attribute_code', $aggregation);
261+
$aggregationAttributeCode[] = $aggregation['attribute_code'];
262+
}
263+
$this->assertFalse(in_array('category_uid', $aggregationAttributeCode));
264+
}
265+
266+
/**
267+
* @return array
268+
* @throws \Exception
269+
*/
270+
private function aggregationWithDisplayCategorySetting(): array
271+
{
272+
$query = $this->getGraphQlQueryProductSearch();
273+
$result = $this->graphQlQuery($query);
274+
275+
$this->assertArrayNotHasKey('errors', $result);
276+
$this->assertArrayHasKey('aggregations', $result['products']);
277+
return $result;
278+
}
279+
280+
/**
281+
* Get graphQl query.
282+
*
283+
* @return string
284+
*/
285+
private function getGraphQlQueryProductSearch(): string
286+
{
287+
return <<<QUERY
288+
{
289+
products(
290+
search: "simple"
291+
pageSize: 20
292+
currentPage: 1
293+
sort: { }
294+
) {
295+
items {
296+
sku
297+
canonical_url
298+
categories{
299+
name
300+
path
301+
}
302+
}
303+
aggregations (filter: {category: {includeDirectChildrenOnly: true}}) {
304+
attribute_code
305+
count
306+
label
307+
options {
308+
label
309+
value
310+
}
311+
}
312+
}
313+
}
228314
QUERY;
229315
}
230316
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
* Copyright 2023 Adobe
4+
* All Rights Reserved.
5+
*
6+
* NOTICE: All information contained herein is, and remains
7+
* the property of Adobe and its suppliers, if any. The intellectual
8+
* and technical concepts contained herein are proprietary to Adobe
9+
* and its suppliers and are protected by all applicable intellectual
10+
* property laws, including trade secret and copyright laws.
11+
* Dissemination of this information or reproduction of this material
12+
* is strictly forbidden unless prior written permission is obtained
13+
* from Adobe.
14+
*/
15+
declare(strict_types=1);
16+
17+
namespace Magento\Sales\Model\ResourceModel\Order;
18+
19+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
20+
use Magento\Checkout\Test\Fixture\PlaceOrder as PlaceOrderFixture;
21+
use Magento\Checkout\Test\Fixture\SetBillingAddress;
22+
use Magento\Checkout\Test\Fixture\SetDeliveryMethod as SetDeliveryMethodFixture;
23+
use Magento\Checkout\Test\Fixture\SetPaymentMethod as SetPaymentMethodFixture;
24+
use Magento\Checkout\Test\Fixture\SetShippingAddress;
25+
use Magento\Customer\Test\Fixture\Customer;
26+
use Magento\Framework\Exception\LocalizedException;
27+
use Magento\Quote\Test\Fixture\AddProductToCart;
28+
use Magento\Quote\Test\Fixture\CustomerCart;
29+
use Magento\Sales\Api\OrderAddressRepositoryInterface;
30+
use Magento\Sales\Api\OrderRepositoryInterface;
31+
use Magento\TestFramework\Fixture\DataFixture;
32+
use Magento\TestFramework\Fixture\DataFixtureStorage;
33+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
34+
use Magento\TestFramework\Fixture\DbIsolation;
35+
use Magento\TestFramework\Helper\Bootstrap;
36+
use Magento\TestFramework\ObjectManager;
37+
use PHPUnit\Framework\TestCase;
38+
39+
/**
40+
* Test for order address
41+
*
42+
* @magentoAppArea adminhtml
43+
*/
44+
class AddressTest extends TestCase
45+
{
46+
/**
47+
* @var ObjectManager
48+
*/
49+
private $objectManager;
50+
51+
/**
52+
* @var DataFixtureStorage
53+
*/
54+
private $fixtures;
55+
56+
/**
57+
* @var OrderAddressRepositoryInterface
58+
*/
59+
private $orderAddressRepository;
60+
61+
/**
62+
* @var OrderRepositoryInterface
63+
*/
64+
private $orderRepository;
65+
66+
protected function setUp(): void
67+
{
68+
$this->objectManager = Bootstrap::getObjectManager();
69+
$this->fixtures = $this->objectManager->get(DataFixtureStorageManager::class)->getStorage();
70+
$this->orderAddressRepository = $this->objectManager->get(OrderAddressRepositoryInterface::class);
71+
$this->orderRepository = $this->objectManager->get(OrderRepositoryInterface::class);
72+
}
73+
74+
/**
75+
* Check to see if leading zeros have been added to the number strings
76+
* in the order address's phone field.
77+
*
78+
* @return void
79+
* @throws LocalizedException
80+
*/
81+
#[
82+
DataFixture(ProductFixture::class, as: 'product'),
83+
DataFixture(Customer::class, as: 'customer'),
84+
DataFixture(CustomerCart::class, ['customer_id' => '$customer.id$'], as: 'quote'),
85+
DataFixture(AddProductToCart::class, ['cart_id' => '$quote.id$', 'product_id' => '$product.id$', 'qty' => 1]),
86+
DataFixture(SetBillingAddress::class, [
87+
'cart_id' => '$quote.id$',
88+
'address' => [
89+
'customer_id' => '$customer.id$',
90+
'telephone' => '009999999999'
91+
]
92+
]),
93+
DataFixture(SetShippingAddress::class, ['cart_id' => '$quote.id$']),
94+
DataFixture(SetDeliveryMethodFixture::class, ['cart_id' => '$quote.id$']),
95+
DataFixture(SetPaymentMethodFixture::class, ['cart_id' => '$quote.id$']),
96+
DataFixture(PlaceOrderFixture::class, ['cart_id' => '$quote.id$'], 'order')
97+
]
98+
public function testOrderAddressUpdateWithTelephone(): void
99+
{
100+
$telephoneValue = '9999999999';
101+
$order = $this->fixtures->get('order');
102+
$address = $this->orderAddressRepository->get($order->getBillingAddressId());
103+
$address->setTelephone($telephoneValue);
104+
$this->orderAddressRepository->save($address);
105+
$updatedOrder = $this->orderRepository->get($order->getId());
106+
$billingAddress = $updatedOrder->getBillingAddress();
107+
$updatedTelephoneValue = $billingAddress->getTelephone();
108+
$this->assertEquals($telephoneValue, $updatedTelephoneValue);
109+
}
110+
}

0 commit comments

Comments
 (0)