Skip to content

Commit c83cfa6

Browse files
committed
Merge branch '2.4-develop' of https://github.com/magento-commerce/magento2ce into ACP2E-4031
# Conflicts: # app/code/Magento/GraphQl/Helper/Error/AggregateExceptionMessageFormatter.php # app/code/Magento/QuoteGraphQl/Model/Resolver/PlaceOrder.php
2 parents 889ca7c + fab20b0 commit c83cfa6

File tree

13 files changed

+277
-27
lines changed

13 files changed

+277
-27
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,22 @@ private function getUsedImagesSelect(): Select
184184

185185
return $select;
186186
}
187+
188+
/**
189+
* Get related website IDs for a given image file path.
190+
*
191+
* @param string $filepath
192+
* @return array
193+
*/
194+
public function getRelatedWebsiteIds(string $filepath): array
195+
{
196+
$select = $this->getUsedImagesSelect();
197+
$select->where('images.value = ?', $filepath);
198+
$result = array_map(
199+
fn ($ids) => array_map('intval', explode(',', $ids)),
200+
$this->connection->fetchPairs($select)
201+
);
202+
203+
return $result[$filepath] ?? [];
204+
}
187205
}

app/code/Magento/ConfigurableProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ConfigurablePriceTest.php

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2016 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -10,6 +10,7 @@
1010
use Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier\AbstractModifierTestCase;
1111
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
1212
use Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\ConfigurablePrice as ConfigurablePriceModifier;
13+
use Magento\Catalog\Model\Locator\LocatorInterface;
1314

1415
class ConfigurablePriceTest extends AbstractModifierTestCase
1516
{
@@ -111,4 +112,44 @@ public static function metaDataProvider()
111112
]
112113
];
113114
}
115+
116+
public function testModifyMetaRemovesScopeLabelAndServiceForConfigurable()
117+
{
118+
$locator = $this->createMock(LocatorInterface::class);
119+
$product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
120+
->disableOriginalConstructor()
121+
->getMock();
122+
$product->method('getTypeId')->willReturn(Configurable::TYPE_CODE);
123+
$locator->method('getProduct')->willReturn($product);
124+
125+
$modifier = new ConfigurablePriceModifier($locator);
126+
127+
$meta = [
128+
'product_details' => [
129+
'children' => [
130+
ConfigurablePriceModifier::CODE_GROUP_PRICE => [
131+
'children' => [
132+
'price' => [
133+
'arguments' => [
134+
'data' => [
135+
'config' => [
136+
'scopeLabel' => 'Some Label',
137+
'service' => 'Some Service'
138+
]
139+
]
140+
]
141+
]
142+
]
143+
]
144+
]
145+
]
146+
];
147+
148+
$result = $modifier->modifyMeta($meta);
149+
150+
$config = $result['group']['children'][ConfigurablePriceModifier::CODE_GROUP_PRICE]
151+
['children']['price']['arguments']['data']['config'] ?? [];
152+
$this->assertArrayNotHasKey('scopeLabel', $config);
153+
$this->assertArrayNotHasKey('service', $config);
154+
}
114155
}

app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2016 Adobe
4+
* All Rights Reserved.
55
*/
66
namespace Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier;
77

@@ -15,7 +15,7 @@
1515
*/
1616
class ConfigurablePrice extends AbstractModifier
1717
{
18-
const CODE_GROUP_PRICE = 'container_price';
18+
public const CODE_GROUP_PRICE = 'container_price';
1919

2020
/**
2121
* @var string
@@ -87,6 +87,14 @@ public function modifyMeta(array $meta)
8787
];
8888
$config = $visibilityConfig;
8989
$config['componentType'] = 'container';
90+
if ($productTypeId === ConfigurableType::TYPE_CODE &&
91+
isset($meta[$groupCode]['children'][self::CODE_GROUP_PRICE]
92+
['children']['price']['arguments']['data']['config']['scopeLabel'])) {
93+
unset($meta[$groupCode]['children'][self::CODE_GROUP_PRICE]
94+
['children']['price']['arguments']['data']['config']['scopeLabel']);
95+
unset($meta[$groupCode]['children'][self::CODE_GROUP_PRICE]
96+
['children']['price']['arguments']['data']['config']['service']);
97+
}
9098
$meta[$groupCode]['children'][self::CODE_GROUP_PRICE] = array_replace_recursive(
9199
$meta[$groupCode]['children'][self::CODE_GROUP_PRICE],
92100
[

app/code/Magento/GraphQl/Helper/Error/AggregateExceptionMessageFormatter.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public function getFormatted(
6363
$messageWithPrefix = empty($messagePrefix)
6464
? $messageText
6565
: __("$messagePrefix: %message", ['message' => $messageText]);
66+
6667
return new GraphQlInputException($messageWithPrefix, $e, $e->getCode());
6768
}
6869
}

app/code/Magento/MediaStorage/App/Media.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2011 Adobe
4+
* All Rights Reserved.
55
*/
66

77
namespace Magento\MediaStorage\App;
@@ -24,7 +24,6 @@
2424
use Magento\MediaStorage\Model\File\Storage\Config;
2525
use Magento\MediaStorage\Model\File\Storage\ConfigFactory;
2626
use Magento\MediaStorage\Model\File\Storage\Response;
27-
use Magento\MediaStorage\Model\File\Storage\Synchronization;
2827
use Magento\MediaStorage\Model\File\Storage\SynchronizationFactory;
2928
use Magento\MediaStorage\Service\ImageResize;
3029

@@ -220,7 +219,7 @@ private function createLocalCopy(): void
220219
}
221220

222221
if ($this->mediaUrlFormat === CatalogMediaConfig::HASH) {
223-
$this->imageResize->resizeFromImageName($this->getOriginalImage($this->relativeFileName));
222+
$this->imageResize->resizeFromImageName($this->getOriginalImage($this->relativeFileName), true);
224223
if (!$this->directoryPub->isReadable($this->relativeFileName)) {
225224
$synchronizer->synchronize($this->relativeFileName);
226225
}

app/code/Magento/MediaStorage/Service/ImageResize.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,10 @@ public function __construct(
151151
* Create resized images of different sizes from an original image.
152152
*
153153
* @param string $originalImageName
154+
* @param bool $skipHiddenImages
154155
* @throws NotFoundException
155156
*/
156-
public function resizeFromImageName(string $originalImageName)
157+
public function resizeFromImageName(string $originalImageName, bool $skipHiddenImages = false)
157158
{
158159
$mediastoragefilename = $this->imageConfig->getMediaPath($originalImageName);
159160
$originalImagePath = $this->mediaDirectory->getAbsolutePath($mediastoragefilename);
@@ -167,7 +168,17 @@ public function resizeFromImageName(string $originalImageName)
167168
if (!$this->mediaDirectory->isFile($originalImagePath)) {
168169
throw new NotFoundException(__('Cannot resize image "%1" - original image not found', $originalImagePath));
169170
}
170-
foreach ($this->getViewImages($this->getThemesInUse()) as $viewImage) {
171+
172+
$viewImages = $this->getViewImages($this->getThemesInUse());
173+
if ($skipHiddenImages) {
174+
$websiteIds = $this->productImage->getRelatedWebsiteIds($originalImageName);
175+
$viewImages = array_filter(
176+
$viewImages,
177+
fn (string $index) => array_intersect($websiteIds, $this->paramsWebsitesMap[$index]),
178+
ARRAY_FILTER_USE_KEY
179+
);
180+
}
181+
foreach ($viewImages as $viewImage) {
171182
$this->resize($viewImage, $originalImagePath, $originalImageName);
172183
}
173184
}

app/code/Magento/MediaStorage/Test/Unit/Service/ImageResizeTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,60 @@ public function testResizeFromImageNameMediaStorageDatabase()
444444
$this->service->resizeFromImageName($this->testfilename);
445445
}
446446

447+
public function testResizeFromImageNameWithAssignedWebsite()
448+
{
449+
$this->databaseMock->expects($this->atLeastOnce())
450+
->method('checkDbUsage')
451+
->willReturn(false);
452+
$this->mediaDirectoryMock->expects($this->exactly(2))
453+
->method('isFile')
454+
->with($this->testfilepath)
455+
->willReturnOnConsecutiveCalls(true, false);
456+
$this->themeCollectionMock->expects($this->once())
457+
->method('loadRegisteredThemes')
458+
->willReturn(
459+
[ new DataObject(['id' => '0']) ]
460+
);
461+
$this->themeCustomizationConfigMock->expects($this->once())
462+
->method('getStoresByThemes')
463+
->willReturn(
464+
['0' => []]
465+
);
466+
$this->productImageMock->expects($this->once())->method('getRelatedWebsiteIds')->willReturn([2]);
467+
$imageMock = $this->createMock(Image::class);
468+
$this->imageFactoryMock->expects($this->once())
469+
->method('create')
470+
->willReturn($imageMock);
471+
472+
$this->service->resizeFromImageName($this->testfilename, true);
473+
}
474+
475+
public function testResizeFromImageNameWithNotAssignedWebsite()
476+
{
477+
$this->databaseMock->expects($this->atLeastOnce())
478+
->method('checkDbUsage')
479+
->willReturn(false);
480+
$this->mediaDirectoryMock->expects($this->once())
481+
->method('isFile')
482+
->with($this->testfilepath)
483+
->willReturn(true);
484+
$this->themeCollectionMock->expects($this->once())
485+
->method('loadRegisteredThemes')
486+
->willReturn(
487+
[ new DataObject(['id' => '0']) ]
488+
);
489+
$this->themeCustomizationConfigMock->expects($this->once())
490+
->method('getStoresByThemes')
491+
->willReturn(
492+
['0' => []]
493+
);
494+
$this->productImageMock->expects($this->once())->method('getRelatedWebsiteIds')->willReturn([3]);
495+
$this->imageFactoryMock->expects($this->never())
496+
->method('create');
497+
498+
$this->service->resizeFromImageName($this->testfilename, true);
499+
}
500+
447501
public function testSkipResizingAlreadyResizedImageOnDisk()
448502
{
449503
$this->databaseMock->expects($this->atLeastOnce())

app/code/Magento/QuoteGraphQl/Model/Resolver/PlaceOrder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, ?array $value
7070
// @deprecated The order_id field is deprecated, use order_number instead
7171
'order_id' => $order?->getIncrementId(),
7272
],
73-
'orderV2' => $order ? $this->orderFormatter->format($order) : null,
73+
'orderV2' => $order ? $this->orderFormatter->format($order) : null
7474
];
7575
}
7676
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Test\Unit\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Config\Element\Field;
11+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
12+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13+
use Magento\GraphQl\Helper\Error\AggregateExceptionMessageFormatter;
14+
use Magento\GraphQl\Model\Query\Context;
15+
use Magento\GraphQl\Model\Query\ContextExtensionInterface;
16+
use Magento\Quote\Model\Quote;
17+
use Magento\QuoteGraphQl\Model\Cart\GetCartForCheckout;
18+
use Magento\QuoteGraphQl\Model\Cart\PlaceOrder as PlaceOrderModel;
19+
use Magento\QuoteGraphQl\Model\ErrorMapper;
20+
use Magento\QuoteGraphQl\Model\QuoteException;
21+
use Magento\QuoteGraphQl\Model\Resolver\PlaceOrder;
22+
use Magento\Sales\Api\OrderRepositoryInterface;
23+
use Magento\SalesGraphQl\Model\Formatter\Order as OrderFormatter;
24+
use Magento\Store\Api\Data\StoreInterface;
25+
use PHPUnit\Framework\MockObject\MockObject;
26+
use PHPUnit\Framework\TestCase;
27+
28+
/**
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30+
*/
31+
class PlaceOrderTranslationTest extends TestCase
32+
{
33+
/**
34+
* @var GetCartForCheckout|MockObject
35+
*/
36+
private $getCartForCheckoutMock;
37+
38+
/**
39+
* @var PlaceOrderModel|MockObject
40+
*/
41+
private $placeOrderModelMock;
42+
43+
/**
44+
* @var AggregateExceptionMessageFormatter|MockObject
45+
*/
46+
private $errorMessageFormatterMock;
47+
48+
/**
49+
* @var ErrorMapper|MockObject
50+
*/
51+
private $errorMapperMock;
52+
53+
/**
54+
* @var PlaceOrder
55+
*/
56+
private $placeOrderResolver;
57+
58+
protected function setUp(): void
59+
{
60+
$this->getCartForCheckoutMock = $this->createMock(GetCartForCheckout::class);
61+
$this->placeOrderModelMock = $this->createMock(PlaceOrderModel::class);
62+
$this->errorMessageFormatterMock = $this->createMock(AggregateExceptionMessageFormatter::class);
63+
$this->errorMapperMock = $this->createMock(ErrorMapper::class);
64+
65+
$this->placeOrderResolver = new PlaceOrder(
66+
$this->getCartForCheckoutMock,
67+
$this->placeOrderModelMock,
68+
$this->createMock(OrderRepositoryInterface::class),
69+
$this->createMock(OrderFormatter::class),
70+
$this->errorMessageFormatterMock,
71+
$this->errorMapperMock
72+
);
73+
}
74+
75+
/**
76+
* Test that getRawMessage() is called on GraphQlInputException to map the error message properly.
77+
*/
78+
public function testGetRawMessageIsCalledForErrorMapping(): void
79+
{
80+
$exception = $this->getMockBuilder(GraphQlInputException::class)
81+
->disableOriginalConstructor()
82+
->onlyMethods(['getRawMessage'])
83+
->getMock();
84+
$exception->method('getRawMessage')->willReturn('Raw error message');
85+
$exception->expects($this->once())->method('getRawMessage');
86+
87+
$this->errorMapperMock->expects($this->once())
88+
->method('getErrorMessageId')
89+
->with('Raw error message')
90+
->willReturn(1);
91+
92+
$this->getCartForCheckoutMock->method('execute')->willReturn($this->createMock(Quote::class));
93+
$this->placeOrderModelMock->method('execute')->willThrowException($exception);
94+
$this->errorMessageFormatterMock->method('getFormatted')->willReturn($exception);
95+
96+
$contextMock = $this->createMock(Context::class);
97+
98+
$extensionAttributesMock = $this->getMockBuilder(ContextExtensionInterface::class)
99+
->disableOriginalConstructor()
100+
->addMethods(
101+
[
102+
'getStore',
103+
]
104+
)
105+
->getMock();
106+
$extensionAttributesMock->method('getStore')->willReturn($this->createMock(StoreInterface::class));
107+
$contextMock->method('getExtensionAttributes')->willReturn($extensionAttributesMock);
108+
109+
$this->expectException(QuoteException::class);
110+
$this->placeOrderResolver->resolve(
111+
$this->createMock(Field::class),
112+
$contextMock,
113+
$this->createMock(ResolveInfo::class),
114+
null,
115+
['input' => ['cart_id' => 'masked_cart_id']]
116+
);
117+
}
118+
}

app/design/adminhtml/Magento/backend/etc/view.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2015 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88
<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
@@ -62,6 +62,6 @@
6262
<item type="directory">Lib::less</item>
6363
<item type="directory">Lib::fotorama</item>
6464
<item type="directory">Lib::magnifier</item>
65-
<item type="directory">Lib::tiny_mce</item>
65+
<item type="directory">Lib::hugerte</item>
6666
</exclude>
6767
</view>

0 commit comments

Comments
 (0)