Skip to content

Commit 3621898

Browse files
author
Bohdan Korablov
committed
Merge remote-tracking branch 'mainline/2.3-develop' into PR-bugfixes
2 parents 5a54255 + a29b455 commit 3621898

File tree

104 files changed

+3007
-1106
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+3007
-1106
lines changed

COPYING.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright © 2013-2017 Magento, Inc.
1+
Copyright © 2013-2018 Magento, Inc.
22

33
Each Magento source file included in this distribution is licensed under OSL 3.0 or the Magento Enterprise Edition (MEE) license
44

app/bootstrap.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,13 @@
4949
unset($_SERVER['ORIG_PATH_INFO']);
5050
}
5151

52-
if (!empty($_SERVER['MAGE_PROFILER'])
52+
if (
53+
(!empty($_SERVER['MAGE_PROFILER']) || file_exists(BP . '/var/profiler.flag'))
5354
&& isset($_SERVER['HTTP_ACCEPT'])
5455
&& strpos($_SERVER['HTTP_ACCEPT'], 'text/html') !== false
5556
) {
5657
\Magento\Framework\Profiler::applyConfig(
57-
$_SERVER['MAGE_PROFILER'],
58+
(isset($_SERVER['MAGE_PROFILER']) && strlen($_SERVER['MAGE_PROFILER'])) ? $_SERVER['MAGE_PROFILER'] : trim(file_get_contents(BP . '/var/profiler.flag')),
5859
BP,
5960
!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
6061
);

app/code/Magento/Backup/Model/Db.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ public function createBackup(\Magento\Framework\Backup\Db\BackupInterface $backu
173173
}
174174
}
175175
$backup->write($this->getResource()->getTableForeignKeysSql());
176+
$backup->write($this->getResource()->getTableTriggersSql());
176177
$backup->write($this->getResource()->getFooter());
177178

178179
$this->getResource()->commitTransaction();

app/code/Magento/Backup/Model/ResourceModel/Db.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,31 @@ public function getTableForeignKeysSql($tableName = null)
114114
return $fkScript;
115115
}
116116

117+
/**
118+
* Return triggers for table(s).
119+
*
120+
* @param string|null $tableName
121+
* @param bool $addDropIfExists
122+
* @return string
123+
*/
124+
public function getTableTriggersSql($tableName = null, $addDropIfExists = true)
125+
{
126+
$triggerScript = '';
127+
if (!$tableName) {
128+
$tables = $this->getTables();
129+
foreach ($tables as $table) {
130+
$tableTriggerScript = $this->_resourceHelper->getTableTriggersSql($table, $addDropIfExists);
131+
if (!empty($tableTriggerScript)) {
132+
$triggerScript .= "\n" . $tableTriggerScript;
133+
}
134+
}
135+
} else {
136+
$triggerScript = $this->getTableTriggersSql($tableName, $addDropIfExists);
137+
}
138+
139+
return $triggerScript;
140+
}
141+
117142
/**
118143
* Retrieve table status
119144
*

app/code/Magento/Backup/Model/ResourceModel/Helper.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,4 +337,40 @@ public function restoreTransactionIsolationLevel()
337337
{
338338
$this->getConnection()->query('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ');
339339
}
340+
341+
/**
342+
* Get create script for triggers.
343+
*
344+
* @param string $tableName
345+
* @param boolean $addDropIfExists
346+
* @param boolean $stripDefiner
347+
* @return string
348+
*/
349+
public function getTableTriggersSql($tableName, $addDropIfExists = false, $stripDefiner = true)
350+
{
351+
$script = "--\n-- Triggers structure for table `{$tableName}`\n--\n";
352+
$triggers = $this->getConnection()->query('SHOW TRIGGERS LIKE \''. $tableName . '\'')->fetchAll();
353+
354+
if (!$triggers) {
355+
return '';
356+
}
357+
foreach ($triggers as $trigger) {
358+
if ($addDropIfExists) {
359+
$script .= 'DROP TRIGGER IF EXISTS ' . $trigger['Trigger'] . ";\n";
360+
}
361+
$script .= "delimiter ;;\n";
362+
363+
$triggerData = $this->getConnection()->query('SHOW CREATE TRIGGER '. $trigger['Trigger'])->fetch();
364+
if ($stripDefiner) {
365+
$cleanedScript = preg_replace('/DEFINER=[^\s]*/', '', $triggerData['SQL Original Statement']);
366+
$script .= $cleanedScript . "\n";
367+
} else {
368+
$script .= $triggerData['SQL Original Statement'] . "\n";
369+
}
370+
$script .= ";;\n";
371+
$script .= "delimiter ;\n";
372+
}
373+
374+
return $script;
375+
}
340376
}

app/code/Magento/Bundle/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Bundle.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ protected function processBundleOptionsData(\Magento\Catalog\Model\Product $prod
127127
}
128128
$options = [];
129129
foreach ($bundleOptionsData as $key => $optionData) {
130-
if ((bool)$optionData['delete']) {
130+
if (!empty($optionData['delete'])) {
131131
continue;
132132
}
133133

app/code/Magento/Bundle/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/BundleTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ protected function setUp()
5757
'setOptions',
5858
'setCanSaveBundleSelections',
5959
'__wakeup',
60-
'getOptionsReadonly'
60+
'getOptionsReadonly',
61+
'getBundleOptionsData',
62+
'getExtensionAttributes',
63+
'setExtensionAttributes',
6164
];
6265
$this->productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, $methods);
6366
$optionInterfaceFactory = $this->getMockBuilder(\Magento\Bundle\Api\Data\OptionInterfaceFactory::class)
@@ -127,6 +130,17 @@ public function testAfterInitializeIfBundleAnsCustomOptionsAndBundleSelectionsEx
127130
);
128131
$this->productMock->expects($this->once())->method('setOptions')->with(null);
129132
$this->productMock->expects($this->once())->method('setCanSaveBundleSelections')->with(true);
133+
$this->productMock->expects($this->once())
134+
->method('getBundleOptionsData')
135+
->willReturn(['option_1' => ['delete' => 1]]);
136+
$extentionAttribute = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductExtensionInterface::class)
137+
->disableOriginalConstructor()
138+
->setMethods(['setBundleProductOptions'])
139+
->getMockForAbstractClass();
140+
$extentionAttribute->expects($this->once())->method('setBundleProductOptions')->with([]);
141+
$this->productMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extentionAttribute);
142+
$this->productMock->expects($this->once())->method('setExtensionAttributes')->with($extentionAttribute);
143+
130144
$this->model->afterInitialize($this->subjectMock, $this->productMock);
131145
}
132146

app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class SaveHandler
3131
private $linkResource;
3232

3333
/**
34+
* SaveHandler constructor.
3435
* @param MetadataPool $metadataPool
3536
* @param Link $linkResource
3637
* @param ProductLinkRepositoryInterface $productLinkRepository
@@ -55,17 +56,50 @@ public function execute($entityType, $entity)
5556
{
5657
$link = $entity->getData($this->metadataPool->getMetadata($entityType)->getLinkField());
5758
if ($this->linkResource->hasProductLinks($link)) {
58-
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
59+
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
5960
foreach ($this->productLinkRepository->getList($entity) as $link) {
6061
$this->productLinkRepository->delete($link);
6162
}
6263
}
63-
$productLinks = $entity->getProductLinks();
64+
65+
// Build links per type
66+
$linksByType = [];
67+
foreach ($entity->getProductLinks() as $link) {
68+
$linksByType[$link->getLinkType()][] = $link;
69+
}
70+
71+
// Set array position as a fallback position if necessary
72+
foreach ($linksByType as $linkType => $links) {
73+
if (!$this->hasPosition($links)) {
74+
array_walk($linksByType[$linkType], function ($productLink, $position) {
75+
$productLink->setPosition(++$position);
76+
});
77+
}
78+
}
79+
80+
// Flatten multi-dimensional linksByType in ProductLinks
81+
$productLinks = array_reduce($linksByType, 'array_merge', []);
82+
6483
if (count($productLinks) > 0) {
6584
foreach ($entity->getProductLinks() as $link) {
6685
$this->productLinkRepository->save($link);
6786
}
6887
}
6988
return $entity;
7089
}
90+
91+
/**
92+
* Check if at least one link without position
93+
* @param array $links
94+
* @return bool
95+
*/
96+
private function hasPosition(array $links)
97+
{
98+
foreach ($links as $link) {
99+
if (!array_key_exists('position', $link->getData())) {
100+
return false;
101+
}
102+
}
103+
return true;
104+
}
71105
}

app/code/Magento/Catalog/Model/Product/Option/Value.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use Magento\Catalog\Model\Product;
1010
use Magento\Catalog\Model\Product\Option;
11+
use Magento\Catalog\Pricing\Price\BasePrice;
1112
use Magento\Framework\Model\AbstractModel;
1213

1314
/**
@@ -222,7 +223,7 @@ public function saveValues()
222223
public function getPrice($flag = false)
223224
{
224225
if ($flag && $this->getPriceType() == self::TYPE_PERCENT) {
225-
$basePrice = $this->getOption()->getProduct()->getFinalPrice();
226+
$basePrice = $this->getOption()->getProduct()->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getValue();
226227
$price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100);
227228
return $price;
228229
}

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ private function getMockedValueCollectionFactory()
104104

105105
$mockBuilder =
106106
$this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Option\Value\CollectionFactory::class)
107-
->setMethods(['create'])
108-
->disableOriginalConstructor();
107+
->setMethods(['create'])
108+
->disableOriginalConstructor();
109109
$mock = $mockBuilder->getMock();
110110

111111
$mock->expects($this->any())
@@ -164,13 +164,27 @@ private function getMockedOption()
164164
private function getMockedProduct()
165165
{
166166
$mockBuilder = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
167-
->setMethods(['getFinalPrice', '__wakeup'])
167+
->setMethods(['getPriceInfo', '__wakeup'])
168168
->disableOriginalConstructor();
169169
$mock = $mockBuilder->getMock();
170170

171-
$mock->expects($this->any())
172-
->method('getFinalPrice')
173-
->will($this->returnValue(10));
171+
$priceInfoMock = $this->getMockForAbstractClass(
172+
\Magento\Framework\Pricing\PriceInfoInterface::class,
173+
[],
174+
'',
175+
false,
176+
false,
177+
true,
178+
['getPrice']
179+
);
180+
181+
$priceMock = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Price\PriceInterface::class);
182+
183+
$priceInfoMock->expects($this->any())->method('getPrice')->willReturn($priceMock);
184+
185+
$mock->expects($this->any())->method('getPriceInfo')->willReturn($priceInfoMock);
186+
187+
$priceMock->expects($this->any())->method('getValue')->willReturn(10);
174188

175189
return $mock;
176190
}

0 commit comments

Comments
 (0)