Skip to content

Commit aacf9a2

Browse files
committed
Merge branch '2.4-develop' into refactoring-AdminCreateSimpleProductNegativePriceTest
2 parents ea063e0 + 592c792 commit aacf9a2

File tree

28 files changed

+1002
-81
lines changed

28 files changed

+1002
-81
lines changed

app/code/Magento/AwsS3/Test/Mftf/Helper/S3FileAssertions.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,21 @@ public function assertFileExists($filePath, $message = ''): void
149149
$this->assertTrue($this->driver->isExists($filePath), $message);
150150
}
151151

152+
/**
153+
* Asserts that a file with the given glob pattern exists in the given path on the remote storage system
154+
*
155+
* @param string $path
156+
* @param string $pattern
157+
* @param string $message
158+
*
159+
* @throws \Magento\Framework\Exception\FileSystemException
160+
*/
161+
public function assertGlobbedFileExists($path, $pattern, $message = ""): void
162+
{
163+
$files = $this->driver->search($pattern, $path);
164+
$this->assertNotEmpty($files, $message);
165+
}
166+
152167
/**
153168
* Assert a file does not exist on the remote storage system
154169
*
@@ -206,6 +221,24 @@ public function assertFileContainsString($filePath, $text, $message = ""): void
206221
$this->assertStringContainsString($text, $this->driver->fileGetContents($filePath), $message);
207222
}
208223

224+
/**
225+
* Asserts that a file with the given glob pattern at the given path on the remote storage system contains a given string
226+
*
227+
* @param string $path
228+
* @param string $pattern
229+
* @param string $text
230+
* @param int $fileIndex
231+
* @param string $message
232+
* @return void
233+
*
234+
* @throws \Magento\Framework\Exception\FileSystemException
235+
*/
236+
public function assertGlobbedFileContainsString($path, $pattern, $text, $fileIndex = 0, $message = ""): void
237+
{
238+
$files = $this->driver->search($pattern, $path);
239+
$this->assertStringContainsString($text, $this->driver->fileGetContents($files[$fileIndex] ?? ''), $message);
240+
}
241+
209242
/**
210243
* Assert a file on the remote storage system does not contain a given string
211244
*

app/code/Magento/Catalog/Test/Mftf/Helper/LocalFileAssertions.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,22 @@ public function assertFileExists($filePath, $message = ''): void
134134
$this->assertTrue($this->driver->isExists($realPath), $message);
135135
}
136136

137+
/**
138+
* Asserts that a file with the given glob pattern exists in the given path
139+
*
140+
* @param string $path
141+
* @param string $pattern
142+
* @param string $message
143+
*
144+
* @throws \Magento\Framework\Exception\FileSystemException
145+
*/
146+
public function assertGlobbedFileExists($path, $pattern, $message = ""): void
147+
{
148+
$realPath = $this->expandPath($path);
149+
$files = $this->driver->search($pattern, $realPath);
150+
$this->assertNotEmpty($files, $message);
151+
}
152+
137153
/**
138154
* Assert a file does not exist
139155
*
@@ -195,6 +211,25 @@ public function assertFileContainsString($filePath, $text, $message = ""): void
195211
$this->assertStringContainsString($text, $this->driver->fileGetContents($realPath), $message);
196212
}
197213

214+
/**
215+
* Asserts that a file with the given glob pattern at the given path contains a given string
216+
*
217+
* @param string $path
218+
* @param string $pattern
219+
* @param string $text
220+
* @param int $fileIndex
221+
* @param string $message
222+
* @return void
223+
*
224+
* @throws \Magento\Framework\Exception\FileSystemException
225+
*/
226+
public function assertGlobbedFileContainsString($path, $pattern, $text, $fileIndex = 0, $message = ""): void
227+
{
228+
$realPath = $this->expandPath($path);
229+
$files = $this->driver->search($pattern, $realPath);
230+
$this->assertStringContainsString($text, $this->driver->fileGetContents($files[$fileIndex] ?? ''), $message);
231+
}
232+
198233
/**
199234
* Assert a file does not contain a given string
200235
*
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\ConfigurableProductGraphQl\Model\Formatter;
10+
11+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute;
12+
use Magento\Framework\GraphQl\Query\Uid;
13+
14+
/**
15+
* Formatter for configurable product options
16+
*/
17+
class Option
18+
{
19+
/**
20+
* @var Uid
21+
*/
22+
private $idEncoder;
23+
24+
/**
25+
* @var OptionValue
26+
*/
27+
private $valueFormatter;
28+
29+
/**
30+
* @param Uid $idEncoder
31+
* @param OptionValue $valueFormatter
32+
*/
33+
public function __construct(
34+
Uid $idEncoder,
35+
OptionValue $valueFormatter
36+
) {
37+
$this->idEncoder = $idEncoder;
38+
$this->valueFormatter = $valueFormatter;
39+
}
40+
41+
/**
42+
* Format configurable product options according to the GraphQL schema
43+
*
44+
* @param Attribute $attribute
45+
* @param array $optionIds
46+
* @return array|null
47+
*/
48+
public function format(Attribute $attribute, array $optionIds): ?array
49+
{
50+
$optionValues = [];
51+
52+
foreach ($attribute->getOptions() as $option) {
53+
$optionValues[] = $this->valueFormatter->format($option, $attribute, $optionIds);
54+
}
55+
56+
return [
57+
'uid' => $this->idEncoder->encode($attribute->getProductSuperAttributeId()),
58+
'attribute_code' => $attribute->getProductAttribute()->getAttributeCode(),
59+
'label' => $attribute->getLabel(),
60+
'values' => $optionValues,
61+
];
62+
}
63+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\ConfigurableProductGraphQl\Model\Formatter;
10+
11+
use Magento\CatalogInventory\Model\StockRegistry;
12+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute;
13+
use Magento\ConfigurableProductGraphQl\Model\Options\SelectionUidFormatter;
14+
15+
/**
16+
* Formatter for configurable product option values
17+
*/
18+
class OptionValue
19+
{
20+
/**
21+
* @var SelectionUidFormatter
22+
*/
23+
private $selectionUidFormatter;
24+
25+
/**
26+
* @var StockRegistry
27+
*/
28+
private $stockRegistry;
29+
30+
/**
31+
* @param SelectionUidFormatter $selectionUidFormatter
32+
* @param StockRegistry $stockRegistry
33+
*/
34+
public function __construct(
35+
SelectionUidFormatter $selectionUidFormatter,
36+
StockRegistry $stockRegistry
37+
) {
38+
$this->selectionUidFormatter = $selectionUidFormatter;
39+
$this->stockRegistry = $stockRegistry;
40+
}
41+
42+
/**
43+
* Format configurable product option values according to the GraphQL schema
44+
*
45+
* @param array $optionValue
46+
* @param Attribute $attribute
47+
* @param array $optionIds
48+
* @return array
49+
*/
50+
public function format(array $optionValue, Attribute $attribute, array $optionIds): array
51+
{
52+
$valueIndex = (int)$optionValue['value_index'];
53+
$attributeId = (int)$attribute->getAttributeId();
54+
55+
return [
56+
'uid' => $this->selectionUidFormatter->encode(
57+
$attributeId,
58+
$valueIndex
59+
),
60+
'is_available' => $this->getIsAvailable($optionIds[$valueIndex] ?? []),
61+
'is_use_default' => (bool)$attribute->getIsUseDefault(),
62+
'label' => $optionValue['label'],
63+
'value_index' => $optionValue['value_index']
64+
];
65+
}
66+
67+
/**
68+
* Get is variants available
69+
*
70+
* @param array $variantIds
71+
* @return bool
72+
*/
73+
private function getIsAvailable(array $variantIds): bool
74+
{
75+
foreach ($variantIds as $variantId) {
76+
if ($this->stockRegistry->getProductStockStatus($variantId)) {
77+
return true;
78+
}
79+
}
80+
81+
return false;
82+
}
83+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\ConfigurableProductGraphQl\Model\Formatter;
10+
11+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
12+
13+
/**
14+
* Formatter for configurable product variant
15+
*/
16+
class Variant
17+
{
18+
/**
19+
* Format selected variant of configurable product based on selected options
20+
*
21+
* @param array $options
22+
* @param array $selectedOptions
23+
* @param array $variants
24+
* @return array|null
25+
* @throws GraphQlInputException
26+
*/
27+
public function format(array $options, array $selectedOptions, array $variants): ?array
28+
{
29+
$variant = null;
30+
$productIds = array_keys($variants);
31+
32+
foreach ($selectedOptions as $attributeId => $selectedValue) {
33+
if (!isset($options[$attributeId][$selectedValue])) {
34+
throw new GraphQlInputException(__('configurableOptionValueUids values are incorrect'));
35+
}
36+
37+
$productIds = array_intersect($productIds, $options[$attributeId][$selectedValue]);
38+
}
39+
40+
if (count($productIds) === 1) {
41+
$variantProduct = $variants[array_pop($productIds)];
42+
$variant = $variantProduct->getData();
43+
$variant['url_path'] = $variantProduct->getProductUrl();
44+
$variant['model'] = $variantProduct;
45+
}
46+
47+
return $variant;
48+
}
49+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\ConfigurableProductGraphQl\Model\Options;
10+
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\ConfigurableProduct\Helper\Data;
13+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute;
14+
use Magento\ConfigurableProductGraphQl\Model\Formatter\Option;
15+
16+
/**
17+
* Retrieve metadata for configurable option selection.
18+
*/
19+
class ConfigurableOptionsMetadata
20+
{
21+
/**
22+
* @var Data
23+
*/
24+
private $configurableProductHelper;
25+
26+
/**
27+
* @var Option
28+
*/
29+
private $configurableOptionsFormatter;
30+
31+
/**
32+
* @param Data $configurableProductHelper
33+
* @param Option $configurableOptionsFormatter
34+
*/
35+
public function __construct(
36+
Data $configurableProductHelper,
37+
Option $configurableOptionsFormatter
38+
) {
39+
$this->configurableProductHelper = $configurableProductHelper;
40+
$this->configurableOptionsFormatter = $configurableOptionsFormatter;
41+
}
42+
43+
/**
44+
* Load available selections from configurable options and variant.
45+
*
46+
* @param ProductInterface $product
47+
* @param array $options
48+
* @param array $selectedOptions
49+
* @return array
50+
*/
51+
public function getAvailableSelections(ProductInterface $product, array $options, array $selectedOptions): array
52+
{
53+
$attributes = $this->getAttributes($product);
54+
$availableSelections = [];
55+
56+
foreach ($options as $attributeId => $option) {
57+
if ($attributeId === 'index' || isset($selectedOptions[$attributeId])) {
58+
continue;
59+
}
60+
61+
$availableSelections[] = $this->configurableOptionsFormatter->format(
62+
$attributes[$attributeId],
63+
$options[$attributeId] ?? []
64+
);
65+
}
66+
67+
return $availableSelections;
68+
}
69+
70+
/**
71+
* Retrieve configurable attributes for the product
72+
*
73+
* @param ProductInterface $product
74+
* @return Attribute[]
75+
*/
76+
private function getAttributes(ProductInterface $product): array
77+
{
78+
$allowedAttributes = $this->configurableProductHelper->getAllowAttributes($product);
79+
$attributes = [];
80+
foreach ($allowedAttributes as $attribute) {
81+
$attributes[$attribute->getAttributeId()] = $attribute;
82+
}
83+
84+
return $attributes;
85+
}
86+
}

0 commit comments

Comments
 (0)