Skip to content

Commit c7d0490

Browse files
committed
Merge remote-tracking branch 'origin/2.0' into MDVA-126
2 parents 61f8ed6 + 75dbc95 commit c7d0490

File tree

52 files changed

+1745
-148
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

+1745
-148
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
2.0.8
2+
=============
3+
* Fixed bugs:
4+
* Fixed exception when merchant resets "Product Attributes mass update" Admin form.
5+
* Fixed fatal error in CLI command after compilation on some environments.
6+
* Fixed duplicate URL keys on creating configurable product.
7+
* Fixed issue with Magento sending emails from Admin using default configuration instead of a store-specific email address.
8+
* Fixed issue with delayed session messages.
9+
* GitHub requests:
10+
* [#3490](https://github.com/magento/magento2/pull/3490) -- Fix support for GLOB_BRACE on non-GNU Linux systems
11+
* [#3018](https://github.com/magento/magento2/issues/3018) -- Magento\Sales\Model\OrderRepository::getList() is incomplete
12+
113
2.0.7
214
=============
315
* GitHub requests:

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]);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,12 @@ public function execute()
4646
);
4747
return $resultJson;
4848
}
49+
50+
/**
51+
* @return bool
52+
*/
53+
protected function _isAllowed()
54+
{
55+
return $this->_authorization->isAllowed('Magento_Catalog::products');
56+
}
4957
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,12 @@ public function execute()
5050
);
5151
return $resultJson;
5252
}
53+
54+
/**
55+
* @return bool
56+
*/
57+
protected function _isAllowed()
58+
{
59+
return $this->_authorization->isAllowed('Magento_Catalog::products');
60+
}
5361
}

app/code/Magento/Catalog/Setup/CategorySetup.php

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

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Magento\ImportExport\Model\Import;
1717
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingError;
1818
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
19+
use Magento\Catalog\Model\Product\Visibility;
1920

2021
/**
2122
* Import entity product model
@@ -2237,7 +2238,8 @@ public function validateRow(array $rowData, $rowNum)
22372238
}
22382239
// validate custom options
22392240
$this->getOptionEntity()->validateRow($rowData, $rowNum);
2240-
if (!empty($rowData[self::URL_KEY]) || !empty($rowData[self::COL_NAME])) {
2241+
2242+
if ($this->isNeedToValidateUrlKey($rowData)) {
22412243
$urlKey = $this->getUrlKey($rowData);
22422244
$storeCodes = empty($rowData[self::COL_STORE_VIEW_CODE])
22432245
? array_flip($this->storeResolver->getStoreCodeToId())
@@ -2259,6 +2261,18 @@ public function validateRow(array $rowData, $rowNum)
22592261
return !$this->getErrorAggregator()->isRowInvalid($rowNum);
22602262
}
22612263

2264+
/**
2265+
* @param array $rowData
2266+
* @return bool
2267+
*/
2268+
private function isNeedToValidateUrlKey($rowData)
2269+
{
2270+
return (!empty($rowData[self::URL_KEY]) || !empty($rowData[self::COL_NAME]))
2271+
&& (empty($rowData['visibility'])
2272+
|| $rowData['visibility']
2273+
!== (string)Visibility::getOptionArray()[Visibility::VISIBILITY_NOT_VISIBLE]);
2274+
}
2275+
22622276
/**
22632277
* Parse attributes names and values string to array.
22642278
*

app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ protected function generateProductUrls($websiteId, $originWebsiteId)
113113
$collection = $this->productFactory->create()
114114
->getCollection()
115115
->addCategoryIds()
116-
->addAttributeToSelect(['name', 'url_path', 'url_key'])
116+
->addAttributeToSelect(['name', 'url_path', 'url_key', 'visibility'])
117117
->addWebsiteFilter($websiteIds);
118118
foreach ($collection as $product) {
119119
/** @var \Magento\Catalog\Model\Product $product */

app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
use Magento\UrlRewrite\Model\UrlPersistInterface;
1515
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
1616

17+
/**
18+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
19+
*/
1720
class View
1821
{
1922
/** @var UrlPersistInterface */
@@ -100,7 +103,7 @@ protected function generateProductUrls($websiteId, $originWebsiteId, $storeId)
100103
$collection = $this->productFactory->create()
101104
->getCollection()
102105
->addCategoryIds()
103-
->addAttributeToSelect(['name', 'url_path', 'url_key'])
106+
->addAttributeToSelect(['name', 'url_path', 'url_key', 'visibility'])
104107
->addWebsiteFilter($websiteIds);
105108
foreach ($collection as $product) {
106109
$product->setStoreId($storeId);

app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator;
1212
use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
1313
use Magento\Store\Model\Store;
14+
use Magento\Catalog\Model\Product\Visibility;
1415

1516
class ProductUrlRewriteGenerator
1617
{
@@ -75,6 +76,10 @@ public function __construct(
7576
*/
7677
public function generate(Product $product)
7778
{
79+
if ($product->getVisibility() == Visibility::VISIBILITY_NOT_VISIBLE) {
80+
return [];
81+
}
82+
7883
$this->product = $product;
7984
$storeId = $this->product->getStoreId();
8085

0 commit comments

Comments
 (0)