Skip to content

Commit de3ce5c

Browse files
author
Bohdan Korablov
committed
Merge remote-tracking branch 'mainline/develop' into MAGETWO-51859
2 parents 1f2a854 + 072a1ae commit de3ce5c

File tree

52 files changed

+1484
-322
lines changed

Some content is hidden

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

52 files changed

+1484
-322
lines changed

app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/cells/action-delete.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
-->
77
<button class="action-delete"
88
data-bind="
9-
click: function(){ $parents[1].deleteRecord($parent.index, $parent.recordId); },
9+
click: function(){ $parent.processingDeleteRecord($record().index, $record().recordId); },
1010
attr: {
11-
title: $parents[1].deleteButtonLabel
11+
title: $parent.deleteButtonLabel
1212
}
1313
">
14-
<span data-bind="text: $parents[1].deleteButtonLabel"></span>
14+
<span data-bind="text: $parent.deleteButtonLabel"></span>
1515
</button>

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

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,44 @@
3434
</label>
3535

3636
<div class="admin__field-control" data-role="grid-wrapper">
37+
<div class="admin__control-table-pagination" visible="!!$data.recordData().length">
38+
<div class="admin__data-grid-pager">
39+
<button class="action-previous" type="button" data-bind="attr: {title: $t('Previous Page')}, click: previousPage, disable: isFirst()"></button>
40+
<input class="admin__control-text" type="number" data-bind="attr: {id: ++ko.uid}, value: currentPage">
41+
<label class="admin__control-support-text" data-bind="attr: {for: ko.uid}, text: 'of ' + pages()"></label>
42+
<button class="action-next" type="button" data-bind="attr: {title: $t('Next Page')}, click: nextPage, disable: isLast()"></button>
43+
</div>
44+
</div>
3745
<div class="admin__control-table-wrapper">
3846
<table class="admin__dynamic-rows data-grid" data-role="grid">
3947
<thead if="element.columnsHeader">
4048
<tr>
4149
<th if="dndConfig.enabled"
4250
class="data-grid-draggable-row-cell"/>
4351

44-
<!-- ko foreach: {data: labels, as: 'item'} -->
45-
<th class="data-grid-th"
46-
text="item.label"
47-
visible="item.visible"
48-
disabled="item.disabled"
49-
css="$parent.setClasses(item)">
52+
<th repeat="foreach: labels, item: '$label'"
53+
class="data-grid-th"
54+
text="$label().label"
55+
visible="$label().visible"
56+
disable="$label().disabled"
57+
css="setClasses($label())">
5058
</th>
51-
<!-- /ko -->
5259
</tr>
5360
</thead>
5461

5562
<tbody data-bind="foreach: elems">
56-
<tr class="data-row"
57-
css="'_odd-row': $index() % 2">
58-
<td if="$parent.dndConfig.enabled"
63+
<tr repeat="foreach: elems, item: '$record'"
64+
class="data-row"
65+
css="'_odd-row': $index % 2">
66+
<td if="dndConfig.enabled"
5967
class="data-grid-draggable-row-cell"
60-
template="name: $parent.dndConfig.template, data: $parent.dnd"/>
68+
template="name: dndConfig.template, data: dnd"/>
6169

62-
<!-- ko foreach: { data: elems, as: 'elem'} -->
70+
<!-- ko fastForEach: { data: $record().elems, as: 'elem'} -->
6371
<td if="elem.template"
6472
visible="elem.visible"
65-
disabled="elem.disabled"
66-
css="$parents[1].setClasses(elem)"
73+
disable="elem.disabled"
74+
css="$parent.setClasses(elem)"
6775
template="elem.template"
6876
attr="'data-index': index"/>
6977
<!-- /ko -->

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ public function __construct(
5353
*/
5454
public function execute()
5555
{
56-
$collection = $this->filter->getCollection($this->collectionFactory->create());
57-
$this->attributeHelper->setProductIds($collection->getAllIds());
56+
if ($this->getRequest()->getParam('filters')) {
57+
$collection = $this->filter->getCollection($this->collectionFactory->create());
58+
$this->attributeHelper->setProductIds($collection->getAllIds());
59+
}
5860

5961
if (!$this->_validateProducts()) {
6062
return $this->resultRedirectFactory->create()->setPath('catalog/product/', ['_current' => true]);
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?php
2+
/**
3+
*
4+
* Copyright © 2016 Magento. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Action\Attribute;
8+
9+
class EditTest extends \PHPUnit_Framework_TestCase
10+
{
11+
/** @var \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Save */
12+
private $object;
13+
14+
/** @var \Magento\Catalog\Helper\Product\Edit\Action\Attribute|\PHPUnit_Framework_MockObject_MockObject */
15+
private $attributeHelper;
16+
17+
/** @var \Magento\Backend\Model\View\Result\RedirectFactory|\PHPUnit_Framework_MockObject_MockObject */
18+
private $resultRedirectFactory;
19+
20+
/** @var \Magento\Ui\Component\MassAction\Filter|\PHPUnit_Framework_MockObject_MockObject */
21+
private $filter;
22+
23+
/** @var \Magento\Backend\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject */
24+
private $context;
25+
26+
/** @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject */
27+
private $collectionFactory;
28+
29+
/** @var \Magento\Framework\View\Result\Page|\PHPUnit_Framework_MockObject_MockObject */
30+
private $resultPage;
31+
32+
/** @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject */
33+
private $request;
34+
35+
protected function setUp()
36+
{
37+
$this->attributeHelper = $this->getMockBuilder('Magento\Catalog\Helper\Product\Edit\Action\Attribute')
38+
->setMethods(['getProductIds', 'setProductIds'])
39+
->disableOriginalConstructor()->getMock();
40+
41+
$this->resultRedirectFactory = $this->getMockBuilder('Magento\Backend\Model\View\Result\RedirectFactory')
42+
->disableOriginalConstructor()
43+
->setMethods(['create'])
44+
->getMock();
45+
46+
$this->filter = $this->getMockBuilder('Magento\Ui\Component\MassAction\Filter')
47+
->setMethods(['getCollection'])->disableOriginalConstructor()->getMock();
48+
49+
$this->collectionFactory = $this->getMockBuilder(
50+
'Magento\Catalog\Model\ResourceModel\Product\CollectionFactory'
51+
)->setMethods(['create'])->disableOriginalConstructor()->getMock();
52+
53+
$this->resultPage = $this->getMockBuilder('Magento\Framework\View\Result\Page')
54+
->setMethods(['getConfig'])->disableOriginalConstructor()->getMock();
55+
56+
$resultPageFactory = $this->getMockBuilder('Magento\Framework\View\Result\PageFactory')
57+
->setMethods(['create'])->disableOriginalConstructor()->getMock();
58+
$resultPageFactory->expects($this->any())->method('create')->willReturn($this->resultPage);
59+
60+
$this->prepareContext();
61+
62+
$this->object = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject(
63+
'Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Edit',
64+
[
65+
'context' => $this->context,
66+
'attributeHelper' => $this->attributeHelper,
67+
'filter' => $this->filter,
68+
'resultPageFactory' => $resultPageFactory,
69+
'collectionFactory' => $this->collectionFactory
70+
]
71+
);
72+
}
73+
74+
private function prepareContext()
75+
{
76+
$this->request = $this->getMockBuilder('Magento\Framework\App\Request\Http')
77+
->setMethods(['getParam', 'getParams', 'setParams'])
78+
->disableOriginalConstructor()->getMock();
79+
80+
$objectManager = $this->getMock('Magento\Framework\ObjectManagerInterface');
81+
$product = $this->getMockBuilder('Magento\Catalog\Model\Product')
82+
->setMethods(['isProductsHasSku'])
83+
->disableOriginalConstructor()->getMock();
84+
$product->expects($this->any())->method('isProductsHasSku')
85+
->with([1, 2, 3])
86+
->willReturn(true);
87+
$objectManager->expects($this->any())->method('create')
88+
->with('Magento\Catalog\Model\Product')
89+
->willReturn($product);
90+
$messageManager = $this->getMockBuilder('\Magento\Framework\Message\ManagerInterface')
91+
->setMethods([])
92+
->disableOriginalConstructor()->getMock();
93+
$messageManager->expects($this->any())->method('addError')->willReturn(true);
94+
$this->context = $this->getMockBuilder('Magento\Backend\App\Action\Context')
95+
->setMethods(['getRequest', 'getObjectManager', 'getMessageManager', 'getResultRedirectFactory'])
96+
->disableOriginalConstructor()->getMock();
97+
$this->context->expects($this->any())->method('getRequest')->willReturn($this->request);
98+
$this->context->expects($this->any())->method('getObjectManager')->willReturn($objectManager);
99+
$this->context->expects($this->any())->method('getMessageManager')->willReturn($messageManager);
100+
$this->context->expects($this->any())->method('getResultRedirectFactory')
101+
->willReturn($this->resultRedirectFactory);
102+
}
103+
104+
public function testExecutePageRequested()
105+
{
106+
$this->request->expects($this->any())->method('getParam')->with('filters')->willReturn(['placeholder' => true]);
107+
$this->request->expects($this->any())->method('getParams')->willReturn(
108+
[
109+
'namespace' => 'product_listing',
110+
'exclude' => true,
111+
'filters' => ['placeholder' => true]
112+
]
113+
);
114+
115+
$this->attributeHelper->expects($this->any())->method('getProductIds')->willReturn([1, 2, 3]);
116+
$this->attributeHelper->expects($this->any())->method('setProductIds')->with([1, 2, 3]);
117+
118+
$collection = $this->getMockBuilder('Magento\Catalog\Model\ResourceModel\Product\Collection')
119+
->setMethods(['getAllIds'])
120+
->disableOriginalConstructor()->getMock();
121+
$collection->expects($this->any())->method('getAllIds')->willReturn([1, 2, 3]);
122+
$this->filter->expects($this->any())->method('getCollection')->with($collection)->willReturn($collection);
123+
$this->collectionFactory->expects($this->any())->method('create')->willReturn($collection);
124+
125+
$title = $this->getMockBuilder('Magento\Framework\View\Page\Title')
126+
->setMethods(['prepend'])
127+
->disableOriginalConstructor()->getMock();
128+
$config = $this->getMockBuilder('Magento\Framework\View\Page\Config')
129+
->setMethods(['getTitle'])
130+
->disableOriginalConstructor()->getMock();
131+
$config->expects($this->any())->method('getTitle')->willReturn($title);
132+
$this->resultPage->expects($this->any())->method('getConfig')->willReturn($config);
133+
134+
$this->assertSame($this->resultPage, $this->object->execute());
135+
}
136+
137+
public function testExecutePageReload()
138+
{
139+
$this->request->expects($this->any())->method('getParam')->with('filters')->willReturn(null);
140+
$this->request->expects($this->any())->method('getParams')->willReturn([]);
141+
142+
$this->attributeHelper->expects($this->any())->method('getProductIds')->willReturn([1, 2, 3]);
143+
$this->attributeHelper->expects($this->any())->method('setProductIds')->with([1, 2, 3]);
144+
145+
$title = $this->getMockBuilder('Magento\Framework\View\Page\Title')
146+
->setMethods(['prepend'])
147+
->disableOriginalConstructor()->getMock();
148+
$config = $this->getMockBuilder('Magento\Framework\View\Page\Config')
149+
->setMethods(['getTitle'])
150+
->disableOriginalConstructor()->getMock();
151+
$config->expects($this->any())->method('getTitle')->willReturn($title);
152+
$this->resultPage->expects($this->any())->method('getConfig')->willReturn($config);
153+
154+
$this->assertSame($this->resultPage, $this->object->execute());
155+
}
156+
157+
public function testExecutePageDirectAccess()
158+
{
159+
$this->request->expects($this->any())->method('getParam')->with('filters')->willReturn(null);
160+
$this->request->expects($this->any())->method('getParams')->willReturn([]);
161+
$this->attributeHelper->expects($this->any())->method('getProductIds')->willReturn(null);
162+
163+
$resultRedirect = $this->getMockBuilder('Magento\Backend\Model\View\Result\Redirect')
164+
->setMethods(['setPath'])
165+
->disableOriginalConstructor()
166+
->getMock();
167+
$resultRedirect->expects($this->any())->method('setPath')
168+
->with('catalog/product/', ['_current' => true])
169+
->willReturnSelf();
170+
$this->resultRedirectFactory->expects($this->any())
171+
->method('create')
172+
->willReturn($resultRedirect);
173+
174+
$this->assertSame($resultRedirect, $this->object->execute());
175+
}
176+
}

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ protected function getTextColumn($dataScope, $fit, Phrase $label, $sortOrder)
627627
'componentType' => Field::NAME,
628628
'formElement' => Input::NAME,
629629
'elementTmpl' => 'ui/dynamic-rows/cells/text',
630+
'component' => 'Magento_Ui/js/form/element/text',
630631
'dataType' => Text::NAME,
631632
'dataScope' => $dataScope,
632633
'fit' => $fit,

app/code/Magento/Catalog/view/adminhtml/templates/catalog/form/renderer/fieldset/element.phtml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
<?php
1616
/* @var $block \Magento\Backend\Block\Widget\Form\Renderer\Fieldset\Element */
1717
$element = $block->getElement();
18-
$note = $element->getNote() ? '<div class="note">' . $element->getNote() . '</div>' : '';
18+
$note = $element->getNote() ? '<div class="note admin__field-note">' . $element->getNote() . '</div>' : '';
1919
$elementBeforeLabel = $element->getExtType() == 'checkbox' || $element->getExtType() == 'radio';
2020
$addOn = $element->getBeforeElementHtml() || $element->getAfterElementHtml();
2121
$fieldId = ($element->getHtmlId()) ? ' id="attribute-' . $element->getHtmlId() . '-container"' : '';
2222
$entity = $element->getEntityAttribute();
23-
$fieldClass = "field field-{$element->getId()} {$element->getCssClass()}";
23+
$fieldClass = "admin__field field field-{$element->getId()} {$element->getCssClass()}";
2424
$fieldClass .= ($elementBeforeLabel) ? ' choice' : '';
2525
$fieldClass .= ($addOn) ? ' with-addon' : '';
2626
$fieldClass .= ($element->getRequired()) ? ' required' : '';
@@ -51,7 +51,7 @@ $fieldAttributes = $fieldId . ' class="' . $fieldClass . '" '
5151
<?php /* @escapeNotVerified */ echo $note ?>
5252
<?php else: ?>
5353
<?php echo $element->getLabelHtml('', $block->getScopeLabel()) ?>
54-
<div class="control">
54+
<div class="admin__field-control control">
5555
<?php /* @escapeNotVerified */ echo($addOn) ? '<div class="addon">' . $block->getElementHtml() . '</div>' : $block->getElementHtml(); ?>
5656
<?php /* @escapeNotVerified */ echo $note ?>
5757
</div>

app/code/Magento/Catalog/view/adminhtml/web/template/form/element/action-delete.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
<button class="action-delete"
88
attr="{'data-action': 'remove_row'}"
99
data-bind="
10-
click: function(){ $data.deleteRecord($parents); },
10+
click: function(){ $data.processingDeleteRecord($parents); },
1111
attr: {
12-
title: $parents[1].deleteButtonLabel
12+
title: $parent.deleteButtonLabel
1313
}
1414
">
15-
<span data-bind="text: $parents[1].deleteButtonLabel"></span>
15+
<span data-bind="text: $parent.deleteButtonLabel"></span>
1616
</button>

app/code/Magento/CatalogImportExport/Model/Export/Product.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -762,13 +762,18 @@ protected function getItemsPerPage()
762762
$memoryUsagePercent = 0.8;
763763
// Minimum Products limit
764764
$minProductsLimit = 500;
765+
// Maximal Products limit
766+
$maxProductsLimit = 5000;
765767

766768
$this->_itemsPerPage = intval(
767769
($memoryLimit * $memoryUsagePercent - memory_get_usage(true)) / $memoryPerProduct
768770
);
769771
if ($this->_itemsPerPage < $minProductsLimit) {
770772
$this->_itemsPerPage = $minProductsLimit;
771773
}
774+
if ($this->_itemsPerPage > $maxProductsLimit) {
775+
$this->_itemsPerPage = $maxProductsLimit;
776+
}
772777
}
773778
return $this->_itemsPerPage;
774779
}
@@ -850,8 +855,10 @@ protected function getExportData()
850855
if ($storeId == Store::DEFAULT_STORE_ID && isset($stockItemRows[$productId])) {
851856
$dataRow = array_merge($dataRow, $stockItemRows[$productId]);
852857
}
853-
854-
$exportData = array_merge($exportData, $this->addMultirowData($dataRow, $multirawData));
858+
$this->appendMultirowData($dataRow, $multirawData);
859+
if ($dataRow) {
860+
$exportData[] = $dataRow;
861+
}
855862
}
856863
}
857864
} catch (\Exception $e) {
@@ -1053,9 +1060,8 @@ protected function isValidAttributeValue($code, $value)
10531060
* @SuppressWarnings(PHPMD.NPathComplexity)
10541061
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
10551062
*/
1056-
protected function addMultirowData($dataRow, $multiRawData)
1063+
private function appendMultirowData(&$dataRow, &$multiRawData)
10571064
{
1058-
$result = [];
10591065
$productId = $dataRow['product_id'];
10601066
$productLinkId = $dataRow['product_link_id'];
10611067
$storeId = $dataRow['store_id'];
@@ -1121,7 +1127,6 @@ protected function addMultirowData($dataRow, $multiRawData)
11211127
}
11221128
}
11231129
$dataRow = $this->rowCustomizer->addData($dataRow, $productId);
1124-
11251130
}
11261131

11271132
if (!empty($this->collectedMultiselectsData[$storeId][$productId])) {
@@ -1144,17 +1149,27 @@ protected function addMultirowData($dataRow, $multiRawData)
11441149
}
11451150

11461151
if (empty($dataRow)) {
1147-
return $result;
1152+
return null;
11481153
} elseif ($storeId != Store::DEFAULT_STORE_ID) {
11491154
$dataRow[self::COL_STORE] = $this->_storeIdToCode[$storeId];
11501155
if (isset($productData[Store::DEFAULT_STORE_ID][self::COL_VISIBILITY])) {
11511156
$dataRow[self::COL_VISIBILITY] = $productData[Store::DEFAULT_STORE_ID][self::COL_VISIBILITY];
11521157
}
11531158
}
11541159
$dataRow[self::COL_SKU] = $sku;
1155-
$result[] = $dataRow;
1160+
return $dataRow;
1161+
}
11561162

1157-
return $result;
1163+
/**
1164+
* @deprecated
1165+
* @param array $dataRow
1166+
* @param array $multiRawData
1167+
* @return array
1168+
*/
1169+
protected function addMultirowData($dataRow, $multiRawData)
1170+
{
1171+
$data = $this->appendMultirowData($dataRow, $multiRawData);
1172+
return $data ? [$data] : [];
11581173
}
11591174

11601175
/**

0 commit comments

Comments
 (0)