Skip to content

Commit 7f58418

Browse files
authored
Merge pull request #8541 from magento-l3/PR2-L3-09132023
Pr2 l3 09132023
2 parents 086f5ef + 6dfe92e commit 7f58418

File tree

24 files changed

+807
-89
lines changed

24 files changed

+807
-89
lines changed

app/code/Magento/AwsS3/Driver/AwsS3.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -893,16 +893,24 @@ public function fileClose($resource): bool
893893
*/
894894
public function fileOpen($path, $mode)
895895
{
896+
$_mode = str_replace(['b', '+'], '', strtolower($mode));
897+
if (!in_array($_mode, ['r', 'w', 'a'], true)) {
898+
throw new FileSystemException(new Phrase('Invalid file open mode "%1".', [$mode]));
899+
}
896900
$path = $this->normalizeRelativePath($path, true);
897901

898902
if (!isset($this->streams[$path])) {
899903
$this->streams[$path] = tmpfile();
900904
try {
901905
if ($this->adapter->fileExists($path)) {
902-
//phpcs:ignore Magento2.Functions.DiscouragedFunction
903-
fwrite($this->streams[$path], $this->adapter->read($path));
904-
//phpcs:ignore Magento2.Functions.DiscouragedFunction
905-
rewind($this->streams[$path]);
906+
if ($_mode !== 'w') {
907+
//phpcs:ignore Magento2.Functions.DiscouragedFunction
908+
fwrite($this->streams[$path], $this->adapter->read($path));
909+
//phpcs:ignore Magento2.Functions.DiscouragedFunction
910+
if ($_mode !== 'a') {
911+
rewind($this->streams[$path]);
912+
}
913+
}
906914
}
907915
} catch (FlysystemFilesystemException $e) {
908916
$this->logger->error($e->getMessage());

app/code/Magento/AwsS3/Test/Unit/Driver/AwsS3Test.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,4 +537,42 @@ public function testFileCloseShouldReturnFalseIfTheArgumentIsNotAResource(): voi
537537
$this->assertEquals(false, $this->driver->fileClose(null));
538538
$this->assertEquals(false, $this->driver->fileClose(false));
539539
}
540+
541+
/**
542+
* @dataProvider fileOpenModesDataProvider
543+
*/
544+
public function testFileOppenedMode($mode, $expected): void
545+
{
546+
$this->adapterMock->method('fileExists')->willReturn(true);
547+
if ($mode !== 'w') {
548+
$this->adapterMock->expects($this->once())->method('read')->willReturn('aaa');
549+
} else {
550+
$this->adapterMock->expects($this->never())->method('read');
551+
}
552+
$resource = $this->driver->fileOpen('test/path', $mode);
553+
$this->assertEquals($expected, ftell($resource));
554+
}
555+
556+
/**
557+
* Data provider for testFileOppenedMode
558+
*
559+
* @return array[]
560+
*/
561+
public function fileOpenModesDataProvider(): array
562+
{
563+
return [
564+
[
565+
"mode" => "a",
566+
"expected" => 3
567+
],
568+
[
569+
"mode" => "r",
570+
"expected" => 0
571+
],
572+
[
573+
"mode" => "w",
574+
"expected" => 0
575+
]
576+
];
577+
}
540578
}

app/code/Magento/Catalog/Setup/Patch/Data/UpdateMultiselectAttributesBackendTypes.php

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
use Magento\Catalog\Model\Product;
1010
use Magento\Eav\Setup\EavSetup;
1111
use Magento\Eav\Setup\EavSetupFactory;
12-
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\DB\Adapter\AdapterInterface;
1313
use Magento\Framework\Setup\ModuleDataSetupInterface;
1414
use Magento\Framework\Setup\Patch\DataPatchInterface;
15+
use Magento\Framework\Setup\Patch\NonTransactionableInterface;
1516

16-
class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface
17+
class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface, NonTransactionableInterface
1718
{
1819
/**
1920
* @var ModuleDataSetupInterface
@@ -24,6 +25,11 @@ class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface
2425
*/
2526
private $eavSetupFactory;
2627

28+
/**
29+
* @var array
30+
*/
31+
private $triggersRestoreQueries = [];
32+
2733
/**
2834
* MigrateMultiselectAttributesData constructor.
2935
* @param ModuleDataSetupInterface $dataSetup
@@ -61,6 +67,7 @@ public function apply()
6167
$this->dataSetup->startSetup();
6268
$setup = $this->dataSetup;
6369
$connection = $setup->getConnection();
70+
$this->triggersRestoreQueries = [];
6471

6572
$attributeTable = $setup->getTable('eav_attribute');
6673
/** @var EavSetup $eavSetup */
@@ -74,26 +81,31 @@ public function apply()
7481
->where('backend_type = ?', 'varchar')
7582
->where('frontend_input = ?', 'multiselect')
7683
);
84+
$attributesToMigrate = array_map('intval', $attributesToMigrate);
7785

7886
$varcharTable = $setup->getTable('catalog_product_entity_varchar');
7987
$textTable = $setup->getTable('catalog_product_entity_text');
80-
$varcharTableDataSql = $connection
81-
->select()
82-
->from($varcharTable)
83-
->where('attribute_id in (?)', $attributesToMigrate);
8488

8589
$columns = $connection->describeTable($varcharTable);
8690
unset($columns['value_id']);
87-
$connection->query(
88-
$connection->insertFromSelect(
89-
$connection->select()
90-
->from($varcharTable, array_keys($columns))
91-
->where('attribute_id in (?)', $attributesToMigrate),
92-
$textTable,
93-
array_keys($columns)
94-
)
95-
);
96-
$connection->query($connection->deleteFromSelect($varcharTableDataSql, $varcharTable));
91+
$this->dropTriggers($textTable);
92+
$this->dropTriggers($varcharTable);
93+
try {
94+
$connection->query(
95+
$connection->insertFromSelect(
96+
$connection->select()
97+
->from($varcharTable, array_keys($columns))
98+
->where('attribute_id in (?)', $attributesToMigrate, \Zend_Db::INT_TYPE),
99+
$textTable,
100+
array_keys($columns),
101+
AdapterInterface::INSERT_ON_DUPLICATE
102+
)
103+
);
104+
$connection->delete($varcharTable, ['attribute_id IN (?)' => $attributesToMigrate]);
105+
} finally {
106+
$this->restoreTriggers($textTable);
107+
$this->restoreTriggers($varcharTable);
108+
}
97109

98110
foreach ($attributesToMigrate as $attributeId) {
99111
$eavSetup->updateAttribute($entityTypeId, $attributeId, 'backend_type', 'text');
@@ -103,4 +115,48 @@ public function apply()
103115

104116
return $this;
105117
}
118+
119+
/**
120+
* Drop table triggers
121+
*
122+
* @param string $tableName
123+
* @return void
124+
* @throws \Zend_Db_Statement_Exception
125+
*/
126+
private function dropTriggers(string $tableName): void
127+
{
128+
$triggers = $this->dataSetup->getConnection()
129+
->query('SHOW TRIGGERS LIKE \''. $tableName . '\'')
130+
->fetchAll();
131+
132+
if (!$triggers) {
133+
return;
134+
}
135+
136+
foreach ($triggers as $trigger) {
137+
$triggerData = $this->dataSetup->getConnection()
138+
->query('SHOW CREATE TRIGGER '. $trigger['Trigger'])
139+
->fetch();
140+
$this->triggersRestoreQueries[$tableName][] =
141+
preg_replace('/DEFINER=[^\s]*/', '', $triggerData['SQL Original Statement']);
142+
// phpcs:ignore Magento2.SQL.RawQuery.FoundRawSql
143+
$this->dataSetup->getConnection()->query('DROP TRIGGER IF EXISTS ' . $trigger['Trigger']);
144+
}
145+
}
146+
147+
/**
148+
* Restore table triggers.
149+
*
150+
* @param string $tableName
151+
* @return void
152+
* @throws \Zend_Db_Statement_Exception
153+
*/
154+
private function restoreTriggers(string $tableName): void
155+
{
156+
if (array_key_exists($tableName, $this->triggersRestoreQueries)) {
157+
foreach ($this->triggersRestoreQueries[$tableName] as $query) {
158+
$this->dataSetup->getConnection()->multiQuery($query);
159+
}
160+
}
161+
}
106162
}

app/code/Magento/Catalog/Test/Unit/Setup/Patch/Data/UpdateMultiselectAttributesBackendTypesTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public function testApply(): void
5252
$select1 = $this->createMock(Select::class);
5353
$select2 = $this->createMock(Select::class);
5454
$select3 = $this->createMock(Select::class);
55+
$statement = $this->createMock(\Zend_Db_Statement_Interface::class);
56+
5557
$this->eavSetupFactory->method('create')
5658
->willReturn($eavSetup);
5759
$this->dataSetup->method('getConnection')
@@ -65,7 +67,7 @@ public function testApply(): void
6567
[$entityTypeId, 3, 'backend_type', 'text'],
6668
[$entityTypeId, 7, 'backend_type', 'text']
6769
);
68-
$connection->expects($this->exactly(3))
70+
$connection->expects($this->exactly(2))
6971
->method('select')
7072
->willReturnOnConsecutiveCalls($select1, $select2, $select3);
7173
$connection->method('describeTable')
@@ -78,6 +80,10 @@ public function testApply(): void
7880
'row_id' => [],
7981
]
8082
);
83+
$connection->method('query')
84+
->willReturn($statement);
85+
$connection->method('fetchAll')
86+
->willReturn([]);
8187
$connection->method('fetchCol')
8288
->with($select1)
8389
->willReturn($attributeIds);

app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2424
* @api
2525
*
26-
* @deprecated 100.3.0 Replaced with Multi Source Inventory
26+
* @deprecated 100.3.0
27+
* @see Replaced with Multi Source Inventory
2728
* @link https://developer.adobe.com/commerce/webapi/rest/inventory/index.html
2829
* @link https://developer.adobe.com/commerce/webapi/rest/inventory/inventory-api-reference.html
2930
* @since 100.0.2
@@ -35,6 +36,7 @@ class Status extends AbstractDb
3536
*
3637
* @var StoreManagerInterface
3738
* @deprecated 100.1.0
39+
* @see Not used anymore
3840
*/
3941
protected $_storeManager;
4042

@@ -227,7 +229,7 @@ public function getProductCollection($lastEntityId = 0, $limit = 1000)
227229
*/
228230
public function addStockStatusToSelect(Select $select, Website $website)
229231
{
230-
$websiteId = $this->getWebsiteId($website->getId());
232+
$websiteId = $this->getWebsiteId();
231233
$select->joinLeft(
232234
['stock_status' => $this->getMainTable()],
233235
'e.entity_id = stock_status.product_id AND stock_status.website_id=' . $websiteId,

app/code/Magento/Checkout/Controller/Cart/UpdatePost.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ protected function _updateShoppingCart()
8383
$this->cart->updateItems($cartData)->save();
8484
}
8585
} catch (\Magento\Framework\Exception\LocalizedException $e) {
86+
$this->cart->save();
8687
$this->messageManager->addErrorMessage(
8788
$this->_objectManager->get(\Magento\Framework\Escaper::class)->escapeHtml($e->getMessage())
8889
);

app/code/Magento/Checkout/Model/Cart.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
2020
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2121
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
22+
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
2223
* @deprecated 100.1.0 Use \Magento\Quote\Model\Quote instead
2324
* @see \Magento\Quote\Api\Data\CartInterface
2425
* @since 100.0.2
@@ -522,6 +523,7 @@ public function updateItems($data)
522523
);
523524

524525
$qtyRecalculatedFlag = false;
526+
$itemErrors = [];
525527
foreach ($data as $itemId => $itemInfo) {
526528
$item = $this->getQuote()->getItemById($itemId);
527529
if (!$item) {
@@ -540,7 +542,7 @@ public function updateItems($data)
540542
$item->setQty($qty);
541543

542544
if ($item->getHasError()) {
543-
throw new \Magento\Framework\Exception\LocalizedException(__($item->getMessage()));
545+
$itemErrors[$item->getId()] = __($item->getMessage());
544546
}
545547

546548
if (isset($itemInfo['before_suggest_qty']) && $itemInfo['before_suggest_qty'] != $qty) {
@@ -564,6 +566,10 @@ public function updateItems($data)
564566
['cart' => $this, 'info' => $infoDataObject]
565567
);
566568

569+
if (count($itemErrors)) {
570+
throw new \Magento\Framework\Exception\LocalizedException(current($itemErrors));
571+
}
572+
567573
return $this;
568574
}
569575

app/code/Magento/ConfigurableProduct/Model/Plugin/ProductIdentitiesExtender.php

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
namespace Magento\ConfigurableProduct\Model\Plugin;
99

1010
use Magento\Catalog\Model\Product\Type as ProductTypes;
11+
use Magento\Catalog\Model\ResourceModel\Product\Website\Link as ProductWebsiteLink;
1112
use Magento\ConfigurableProduct\Model\Product\Type\Configurable as ConfigurableType;
1213
use Magento\Catalog\Api\ProductRepositoryInterface;
1314
use Magento\Catalog\Model\Product;
1415
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
16+
use Magento\Store\Model\Store;
1517

1618
/**
1719
* Extender of product identities for child of configurable products
@@ -28,6 +30,11 @@ class ProductIdentitiesExtender implements ResetAfterRequestInterface
2830
*/
2931
private $productRepository;
3032

33+
/**
34+
* @var ProductWebsiteLink
35+
*/
36+
private $productWebsiteLink;
37+
3138
/**
3239
* @var array
3340
*/
@@ -36,11 +43,16 @@ class ProductIdentitiesExtender implements ResetAfterRequestInterface
3643
/**
3744
* @param ConfigurableType $configurableType
3845
* @param ProductRepositoryInterface $productRepository
46+
* @param ProductWebsiteLink $productWebsiteLink
3947
*/
40-
public function __construct(ConfigurableType $configurableType, ProductRepositoryInterface $productRepository)
41-
{
48+
public function __construct(
49+
ConfigurableType $configurableType,
50+
ProductRepositoryInterface $productRepository,
51+
ProductWebsiteLink $productWebsiteLink
52+
) {
4253
$this->configurableType = $configurableType;
4354
$this->productRepository = $productRepository;
55+
$this->productWebsiteLink = $productWebsiteLink;
4456
}
4557

4658
/**
@@ -56,10 +68,19 @@ public function afterGetIdentities(Product $subject, array $identities): array
5668
if ($subject->getTypeId() !== ProductTypes::TYPE_SIMPLE) {
5769
return $identities;
5870
}
71+
72+
$store = $subject->getStore();
5973
$parentProductsIdentities = [];
6074
foreach ($this->getParentIdsByChild($subject->getId()) as $parentId) {
61-
$parentProduct = $this->productRepository->getById($parentId);
62-
$parentProductsIdentities[] = $parentProduct->getIdentities();
75+
$addParentIdentities = true;
76+
if (Store::DEFAULT_STORE_ID !== (int) $store->getId()) {
77+
$parentWebsiteIds = $this->productWebsiteLink->getWebsiteIdsByProductId($parentId);
78+
$addParentIdentities = in_array($store->getWebsiteId(), $parentWebsiteIds);
79+
}
80+
if ($addParentIdentities) {
81+
$parentProduct = $this->productRepository->getById($parentId);
82+
$parentProductsIdentities[] = $parentProduct->getIdentities();
83+
}
6384
}
6485
$identities = array_merge($identities, ...$parentProductsIdentities);
6586

0 commit comments

Comments
 (0)