Skip to content

Commit 211c549

Browse files
committed
Merge remote-tracking branch 'mainline/develop' into PR-4
2 parents 01ec09a + 32e7ab6 commit 211c549

File tree

304 files changed

+5914
-4340
lines changed

Some content is hidden

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

304 files changed

+5914
-4340
lines changed

app/code/Magento/Backend/Block/Dashboard/Tab/Customers/Most.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,14 @@ protected function _prepareColumns()
8080

8181
$this->addColumn(
8282
'orders_count',
83-
['header' => __('Orders'), 'sortable' => false, 'index' => 'orders_count', 'type' => 'number']
83+
[
84+
'header' => __('Orders'),
85+
'sortable' => false,
86+
'index' => 'orders_count',
87+
'type' => 'number',
88+
'header_css_class' => 'col-orders',
89+
'column_css_class' => 'col-orders'
90+
]
8491
);
8592

8693
$baseCurrencyCode = (string)$this->_storeManager->getStore(

app/code/Magento/Backend/Block/Dashboard/Tab/Customers/Newest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,14 @@ protected function _prepareColumns()
7878

7979
$this->addColumn(
8080
'orders_count',
81-
['header' => __('Orders'), 'sortable' => false, 'index' => 'orders_count', 'type' => 'number']
81+
[
82+
'header' => __('Orders'),
83+
'sortable' => false,
84+
'index' => 'orders_count',
85+
'type' => 'number',
86+
'header_css_class' => 'col-orders',
87+
'column_css_class' => 'col-orders'
88+
]
8289
);
8390

8491
$baseCurrencyCode = (string)$this->_storeManager->getStore(

app/code/Magento/Backend/view/adminhtml/templates/page/copyright.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88

99
?>
1010
<a class="link-copyright" href="http://magento.com" target="_blank" title="<?php /* @escapeNotVerified */ echo __('Magento') ?>"></a>
11-
<?php /* @escapeNotVerified */ echo __('Copyright&copy; %1 Magento Commerce Inc. All rights reserved.', date('Y')) ?>
11+
<?php /* @escapeNotVerified */ echo __('Copyright &copy; %1 Magento Commerce Inc. All rights reserved.', date('Y')) ?>

app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
*/
66
-->
77

8-
<div class="admin_field-complex" if="element.addButton">
9-
<div class="admin_field-complex-title">
8+
<div class="admin__field-complex" if="element.addButton">
9+
<div class="admin__field-complex-title">
1010
<span class="label" translate="'User Agent Rules'"></span>
1111
</div>
1212

13-
<div class="admin_field-complex-elements">
13+
<div class="admin__field-complex-elements">
1414
<render args="fallbackResetTpl" if="$data.showFallbackReset && $data.isDifferedFromDefault"/>
1515
<button attr="{disabled: disabled}"
1616
class="action-secondary"
@@ -20,7 +20,7 @@
2020
</button>
2121
</div>
2222

23-
<div class="admin_field-complex-content"
23+
<div class="admin__field-complex-content"
2424
translate="'User agent exceptions override product and CMS pages rules.'"></div>
2525
</div>
2626

app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,15 @@ public function execute()
4949
$productId = (int) $this->getRequest()->getParam('id');
5050
$product = $this->productBuilder->build($this->getRequest());
5151

52-
if ($productId && !$product->getEntityId()) {
53-
$this->messageManager->addError(__('This product no longer exists.'));
52+
if (($productId && !$product->getEntityId())) {
5453
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
5554
$resultRedirect = $this->resultRedirectFactory->create();
55+
$this->messageManager->addError(__('This product doesn\'t exist.'));
56+
return $resultRedirect->setPath('catalog/*/');
57+
} else if ($productId === 0) {
58+
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
59+
$resultRedirect = $this->resultRedirectFactory->create();
60+
$this->messageManager->addError(__('Invalid product id. Should be numeric value greater than 0'));
5661
return $resultRedirect->setPath('catalog/*/');
5762
}
5863

app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ public function initializeFromData(\Magento\Catalog\Model\Product $product, arra
163163
} else {
164164
$productOptions = [];
165165
}
166+
166167
$product->addData($productData);
167168

168169
if ($wasLockedMedia) {
@@ -307,20 +308,28 @@ protected function normalize(array $productData)
307308
public function mergeProductOptions($productOptions, $overwriteOptions)
308309
{
309310
if (!is_array($productOptions)) {
310-
$productOptions = [];
311+
return [];
311312
}
312-
if (is_array($overwriteOptions)) {
313-
$options = array_replace_recursive($productOptions, $overwriteOptions);
314-
array_walk_recursive($options, function (&$item) {
315-
if ($item === "") {
316-
$item = null;
313+
314+
if (!is_array($overwriteOptions)) {
315+
return $productOptions;
316+
}
317+
318+
foreach ($productOptions as $index => $option) {
319+
$optionId = $option['option_id'];
320+
321+
if (!isset($overwriteOptions[$optionId])) {
322+
continue;
323+
}
324+
325+
foreach ($overwriteOptions[$optionId] as $fieldName => $overwrite) {
326+
if ($overwrite && isset($option[$fieldName]) && isset($option['default_' . $fieldName])) {
327+
$productOptions[$index][$fieldName] = $option['default_' . $fieldName];
317328
}
318-
});
319-
} else {
320-
$options = $productOptions;
329+
}
321330
}
322331

323-
return $options;
332+
return $productOptions;
324333
}
325334

326335
/**

app/code/Magento/Catalog/Cron/RefreshSpecialPrices.php

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
namespace Magento\Catalog\Cron;
77

88
use Magento\Framework\App\ResourceConnection;
9+
use Magento\Catalog\Api\Data\CategoryInterface;
10+
use Magento\Framework\EntityManager\MetadataPool;
11+
use Magento\Framework\App\ObjectManager;
912

1013
class RefreshSpecialPrices
1114
{
@@ -44,6 +47,11 @@ class RefreshSpecialPrices
4447
*/
4548
protected $_connection;
4649

50+
/**
51+
* @var MetadataPool
52+
*/
53+
private $metadataPool;
54+
4755
/**
4856
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
4957
* @param ResourceConnection $resource
@@ -131,22 +139,50 @@ protected function _refreshSpecialPriceByStore($storeId, $attrCode, $attrConditi
131139
$attribute = $this->_eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attrCode);
132140
$attributeId = $attribute->getAttributeId();
133141

142+
$linkField = $this->getMetadataPool()->getMetadata(CategoryInterface::class)->getLinkField();
143+
$identifierField = $this->getMetadataPool()->getMetadata(CategoryInterface::class)->getIdentifierField();
144+
134145
$connection = $this->_getConnection();
135146

136147
$select = $connection->select()->from(
137-
$this->_resource->getTableName(['catalog_product_entity', 'datetime']),
138-
['entity_id']
148+
['attr' => $this->_resource->getTableName(['catalog_product_entity', 'datetime'])],
149+
[
150+
$identifierField => 'cat.' . $identifierField,
151+
]
152+
)->joinLeft(
153+
['cat' => $this->_resource->getTableName('catalog_product_entity')],
154+
'cat.' . $linkField . '= attr.' . $linkField,
155+
''
139156
)->where(
140-
'attribute_id = ?',
157+
'attr.attribute_id = ?',
141158
$attributeId
142159
)->where(
143-
'store_id = ?',
160+
'attr.store_id = ?',
144161
$storeId
145162
)->where(
146-
'value = ?',
163+
'attr.value = ?',
147164
$attrConditionValue
148165
);
149166

150-
$this->_processor->getIndexer()->reindexList($connection->fetchCol($select, ['entity_id']));
167+
$selectData = $connection->fetchCol($select, $identifierField);
168+
169+
if (!empty($selectData)) {
170+
$this->_processor->getIndexer()->reindexList($selectData);
171+
}
172+
173+
}
174+
175+
/**
176+
* Get MetadataPool instance
177+
* @return MetadataPool
178+
*
179+
* @deprecated
180+
*/
181+
private function getMetadataPool()
182+
{
183+
if (null === $this->metadataPool) {
184+
$this->metadataPool = ObjectManager::getInstance()->get(MetadataPool::class);
185+
}
186+
return $this->metadataPool;
151187
}
152188
}

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -326,25 +326,72 @@ public function testInitialize()
326326
public function mergeProductOptionsDataProvider()
327327
{
328328
return [
329-
[
329+
'options are not array, empty array is returned' => [
330330
null,
331331
[],
332332
[],
333333
],
334-
[
335-
['key' => 'val'],
334+
'replacement is not array, original options are returned' => [
335+
['val'],
336336
null,
337-
['key' => 'val'],
337+
['val'],
338338
],
339-
[
340-
['key' => ['key' => 'val']],
341-
['key' => ['key' => 'val2', 'key2' => 'val2']],
342-
['key' => ['key' => 'val2', 'key2' => 'val2']],
339+
'ids do not match, no replacement occurs' => [
340+
[
341+
[
342+
'option_id' => '3',
343+
'key1' => 'val1',
344+
'default_key1' => 'val2'
345+
]
346+
],
347+
[4 => ['key1' => '1']],
348+
[
349+
[
350+
'option_id' => '3',
351+
'key1' => 'val1',
352+
'default_key1' => 'val2'
353+
]
354+
]
343355
],
344-
[
345-
['key' => ['key' => 'val', 'another_key' => 'another_value']],
346-
['key' => ['key' => 'val2', 'key2' => 'val2']],
347-
['key' => ['key' => 'val2', 'another_key' => 'another_value', 'key2' => 'val2',]],
356+
'key2 is replaced, key1 is not (checkbox is not checked)' => [
357+
[
358+
[
359+
'option_id' => '5',
360+
'key1' => 'val1',
361+
'key2' => 'val2',
362+
'default_key1' => 'val3',
363+
'default_key2' => 'val4'
364+
]
365+
],
366+
[5 => ['key1' => '0', 'key2' => '1']],
367+
[
368+
[
369+
'option_id' => '5',
370+
'key1' => 'val1',
371+
'key2' => 'val4',
372+
'default_key1' => 'val3',
373+
'default_key2' => 'val4'
374+
]
375+
]
376+
],
377+
'key1 is replaced, key2 has no default value' => [
378+
[
379+
[
380+
'option_id' => '7',
381+
'key1' => 'val1',
382+
'key2' => 'val2',
383+
'default_key1' => 'val3'
384+
]
385+
],
386+
[7 => ['key1' => '1', 'key2' => '1']],
387+
[
388+
[
389+
'option_id' => '7',
390+
'key1' => 'val3',
391+
'key2' => 'val2',
392+
'default_key1' => 'val3'
393+
]
394+
],
348395
],
349396
];
350397
}

app/code/Magento/Catalog/Test/Unit/Cron/RefreshSpecialPricesTest.php

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\Catalog\Test\Unit\Cron;
77

88
use Magento\Framework\App\ResourceConnection;
9+
use Magento\Framework\EntityManager\MetadataPool;
910

1011
class RefreshSpecialPricesTest extends \PHPUnit_Framework_TestCase
1112
{
@@ -49,6 +50,16 @@ class RefreshSpecialPricesTest extends \PHPUnit_Framework_TestCase
4950
*/
5051
protected $_priceProcessorMock;
5152

53+
/**
54+
* @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject
55+
*/
56+
protected $metadataPool;
57+
58+
/**
59+
* @var \Magento\Framework\EntityManager\EntityMetadata|\PHPUnit_Framework_MockObject_MockObject
60+
*/
61+
protected $metadataMock;
62+
5263
protected function setUp()
5364
{
5465
$this->_objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -72,6 +83,8 @@ protected function setUp()
7283
false
7384
);
7485

86+
$this->metadataMock = $this->getMock(\Magento\Framework\EntityManager\EntityMetadata::class, [], [], '', false);
87+
7588
$this->_model = $this->_objectManager->getObject(
7689
'Magento\Catalog\Cron\RefreshSpecialPrices',
7790
[
@@ -83,14 +96,30 @@ protected function setUp()
8396
'processor' => $this->_priceProcessorMock
8497
]
8598
);
99+
100+
$this->metadataPool = $this->getMock(MetadataPool::class, [], [], '', false);
101+
102+
$reflection = new \ReflectionClass(get_class($this->_model));
103+
$reflectionProperty = $reflection->getProperty('metadataPool');
104+
$reflectionProperty->setAccessible(true);
105+
$reflectionProperty->setValue($this->_model, $this->metadataPool);
86106
}
87107

88108
public function testRefreshSpecialPrices()
89109
{
90110
$idsToProcess = [1, 2, 3];
91111

112+
$this->metadataPool->expects($this->atLeastOnce())
113+
->method('getMetadata')
114+
->willReturn($this->metadataMock);
115+
116+
$this->metadataMock->expects($this->atLeastOnce())->method('getLinkField')->willReturn('row_id');
117+
118+
$this->metadataMock->expects($this->atLeastOnce())->method('getIdentifierField')->willReturn('entity_id');
119+
92120
$selectMock = $this->getMock('Magento\Framework\DB\Select', [], [], '', false);
93121
$selectMock->expects($this->any())->method('from')->will($this->returnSelf());
122+
$selectMock->expects($this->any())->method('joinLeft')->will($this->returnSelf());
94123
$selectMock->expects($this->any())->method('where')->will($this->returnSelf());
95124

96125
$connectionMock = $this->getMock('Magento\Framework\DB\Adapter\AdapterInterface', [], [], '', false);
@@ -99,12 +128,10 @@ public function testRefreshSpecialPrices()
99128
$this->any()
100129
)->method(
101130
'fetchCol'
102-
)->with(
103-
$selectMock,
104-
['entity_id']
105131
)->will(
106132
$this->returnValue($idsToProcess)
107133
);
134+
108135
$this->_resourceMock->expects(
109136
$this->once()
110137
)->method(
@@ -113,6 +140,14 @@ public function testRefreshSpecialPrices()
113140
$this->returnValue($connectionMock)
114141
);
115142

143+
$this->_resourceMock->expects(
144+
$this->any()
145+
)->method(
146+
'getTableName'
147+
)->will(
148+
$this->returnValue('category')
149+
);
150+
116151
$storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
117152
$storeMock->expects($this->any())->method('getId')->will($this->returnValue(1));
118153

0 commit comments

Comments
 (0)