Skip to content

Commit ccffe33

Browse files
committed
Merge branch '2.3-develop' of github.com:magento/magento2ce into MFTF2.0.2-2.3-develop
2 parents 36f6791 + b7dc2b3 commit ccffe33

File tree

40 files changed

+600
-112
lines changed

40 files changed

+600
-112
lines changed

.htaccess.sample

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@
111111
############################################
112112
## enable rewrites
113113

114-
Options +FollowSymLinks
114+
# The following line has better security but add some performance overhead - see https://httpd.apache.org/docs/2.4/en/misc/perf-tuning.html
115+
Options -FollowSymLinks +SymLinksIfOwnerMatch
115116
RewriteEngine on
116117

117118
############################################

app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function execute()
3434
{
3535
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
3636
$resultPage = $this->resultPageFactory->create();
37-
$resultPage->setStatusHeader(404, '1.1', 'Forbidden');
37+
$resultPage->setStatusHeader(404, '1.1', 'Not Found');
3838
$resultPage->setHeader('Status', '404 File not found');
3939
$resultPage->addHandle('adminhtml_noroute');
4040
return $resultPage;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
<div class="messages">
8686
<div class="message message-notice notice">
8787
<span
88-
translate="'Search strings are either normal strings or regular exceptions (PCRE). They are matched in the same order as entered.'"></span>
88+
translate="'Search strings are either normal strings or regular expressions (PCRE). They are matched in the same order as entered.'"></span>
8989
<br>
9090
<span
9191
translate="'Examples'"></span>:

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

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@
55
*/
66
namespace Magento\CatalogImportExport\Model\Import;
77

8+
use Magento\Catalog\Model\Config as CatalogConfig;
89
use Magento\Catalog\Model\Product\Visibility;
10+
use Magento\CatalogImportExport\Model\Import\Product\ImageTypeProcessor;
911
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface as ValidatorInterface;
1012
use Magento\Framework\App\Filesystem\DirectoryList;
11-
use Magento\Framework\App\ObjectManager;
13+
use Magento\Framework\Filesystem;
1214
use Magento\Framework\Model\ResourceModel\Db\ObjectRelationProcessor;
1315
use Magento\Framework\Model\ResourceModel\Db\TransactionManagerInterface;
1416
use Magento\Framework\Stdlib\DateTime;
15-
use Magento\Framework\Filesystem;
1617
use Magento\ImportExport\Model\Import;
1718
use Magento\ImportExport\Model\Import\Entity\AbstractEntity;
1819
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingError;
1920
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
20-
use Magento\Catalog\Model\Config as CatalogConfig;
2121

2222
/**
2323
* Import entity product model
@@ -425,7 +425,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
425425
*
426426
* @var string[]
427427
*/
428-
protected $_imagesArrayKeys = ['image', 'small_image', 'thumbnail', 'swatch_image', '_media_image'];
428+
protected $_imagesArrayKeys = [];
429429

430430
/**
431431
* Permanent entity columns.
@@ -699,6 +699,11 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
699699
*/
700700
private $catalogConfig;
701701

702+
/**
703+
* @var ImageTypeProcessor
704+
*/
705+
private $imageTypeProcessor;
706+
702707
/**
703708
* @param \Magento\Framework\Json\Helper\Data $jsonHelper
704709
* @param \Magento\ImportExport\Helper\Data $importExportData
@@ -738,6 +743,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
738743
* @param array $data
739744
* @param array $dateAttrCodes
740745
* @param CatalogConfig $catalogConfig
746+
* @param ImageTypeProcessor $imageTypeProcessor
741747
* @throws \Magento\Framework\Exception\LocalizedException
742748
*
743749
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -781,7 +787,8 @@ public function __construct(
781787
\Magento\Catalog\Model\Product\Url $productUrl,
782788
array $data = [],
783789
array $dateAttrCodes = [],
784-
CatalogConfig $catalogConfig = null
790+
CatalogConfig $catalogConfig = null,
791+
ImageTypeProcessor $imageTypeProcessor = null
785792
) {
786793
$this->_eventManager = $eventManager;
787794
$this->stockRegistry = $stockRegistry;
@@ -814,6 +821,8 @@ public function __construct(
814821
$this->dateAttrCodes = array_merge($this->dateAttrCodes, $dateAttrCodes);
815822
$this->catalogConfig = $catalogConfig ?: \Magento\Framework\App\ObjectManager::getInstance()
816823
->get(CatalogConfig::class);
824+
$this->imageTypeProcessor = $imageTypeProcessor ?: \Magento\Framework\App\ObjectManager::getInstance()
825+
->get(ImageTypeProcessor::class);
817826

818827
parent::__construct(
819828
$jsonHelper,
@@ -833,7 +842,8 @@ public function __construct(
833842

834843
$this->_initAttributeSets()
835844
->_initTypeModels()
836-
->_initSkus();
845+
->_initSkus()
846+
->initImagesArrayKeys();
837847
$this->validator->init($this);
838848
}
839849

@@ -1076,6 +1086,17 @@ protected function _initSkus()
10761086
return $this;
10771087
}
10781088

1089+
/**
1090+
* Initialize image array keys.
1091+
*
1092+
* @return $this
1093+
*/
1094+
private function initImagesArrayKeys()
1095+
{
1096+
$this->_imagesArrayKeys = $this->imageTypeProcessor->getImageTypes();
1097+
return $this;
1098+
}
1099+
10791100
/**
10801101
* Initialize product type models.
10811102
*
@@ -1298,20 +1319,15 @@ protected function _saveLinks()
12981319
*/
12991320
protected function _saveProductAttributes(array $attributesData)
13001321
{
1322+
$linkField = $this->getProductEntityLinkField();
13011323
foreach ($attributesData as $tableName => $skuData) {
13021324
$tableData = [];
13031325
foreach ($skuData as $sku => $attributes) {
1304-
$linkId = $this->_connection->fetchOne(
1305-
$this->_connection->select()
1306-
->from($this->getResource()->getTable('catalog_product_entity'))
1307-
->where('sku = ?', (string)$sku)
1308-
->columns($this->getProductEntityLinkField())
1309-
);
1310-
1326+
$linkId = $this->_oldSku[strtolower($sku)][$linkField];
13111327
foreach ($attributes as $attributeId => $storeValues) {
13121328
foreach ($storeValues as $storeId => $storeValue) {
13131329
$tableData[] = [
1314-
$this->getProductEntityLinkField() => $linkId,
1330+
$linkField => $linkId,
13151331
'attribute_id' => $attributeId,
13161332
'store_id' => $storeId,
13171333
'value' => $storeValue,
@@ -1321,6 +1337,7 @@ protected function _saveProductAttributes(array $attributesData)
13211337
}
13221338
$this->_connection->insertOnDuplicate($tableName, $tableData, ['value']);
13231339
}
1340+
13241341
return $this;
13251342
}
13261343

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CatalogImportExport\Model\Import\Product;
7+
8+
use Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModel;
9+
10+
class ImageTypeProcessor
11+
{
12+
/**
13+
* @var \Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModelFactory
14+
*/
15+
private $resourceFactory;
16+
17+
/**
18+
* @param \Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModelFactory $resourceFactory
19+
*/
20+
public function __construct(
21+
\Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModelFactory $resourceFactory
22+
) {
23+
$this->resourceFactory = $resourceFactory;
24+
}
25+
26+
/**
27+
* @return array
28+
*/
29+
public function getImageTypes()
30+
{
31+
$imageKeys = [];
32+
/** @var ResourceModel $resource */
33+
$resource = $this->resourceFactory->create();
34+
$connection = $resource->getConnection();
35+
$select = $connection->select();
36+
$select->from(
37+
$resource->getTable('eav_attribute'),
38+
['code' => 'attribute_code']
39+
);
40+
$select->where(
41+
'frontend_input = :frontend_input'
42+
);
43+
$bind = [':frontend_input' => 'media_image'];
44+
45+
$imageKeys = $connection->fetchCol($select, $bind);
46+
$imageKeys[] = '_media_image';
47+
48+
return $imageKeys;
49+
}
50+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CatalogImportExport\Test\Unit\Model\Import\Product;
7+
8+
use Magento\CatalogImportExport\Model\Import\Product\ImageTypeProcessor;
9+
10+
class ImageTypeProcessorTest extends \PHPUnit\Framework\TestCase
11+
{
12+
public function testGetImageTypes()
13+
{
14+
$resourceFactory = $this->createPartialMock(
15+
\Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModelFactory::class,
16+
['create']
17+
);
18+
19+
$resource = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModel::class)
20+
->disableOriginalConstructor()
21+
->setMethods(['getTable', 'getConnection'])
22+
->getMock();
23+
$resource->expects($this->once())
24+
->method('getTable')
25+
->with('eav_attribute')
26+
->willReturnArgument(0);
27+
$connection = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
28+
$resource->expects($this->any())
29+
->method('getConnection')
30+
->willReturn($connection);
31+
$resourceFactory->expects($this->once())
32+
->method('create')
33+
->willReturn($resource);
34+
35+
$selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
36+
->disableOriginalConstructor()
37+
->getMock();
38+
$selectMock->expects($this->once())
39+
->method('from')
40+
->with('eav_attribute', ['code' => 'attribute_code'], null)
41+
->willReturnSelf();
42+
$selectMock->expects($this->once())
43+
->method('where')
44+
->with('frontend_input = :frontend_input')
45+
->willReturnSelf();
46+
$connection->expects($this->any())
47+
->method('fetchCol')
48+
->willReturn(['image', 'small_image', 'thumbnail', 'swatch_image']);
49+
$connection->expects($this->any())
50+
->method('select')
51+
->willReturn($selectMock);
52+
53+
$typeProcessor = new ImageTypeProcessor($resourceFactory);
54+
$this->assertEquals(
55+
['image', 'small_image', 'thumbnail', 'swatch_image', '_media_image'],
56+
$typeProcessor->getImageTypes()
57+
);
58+
}
59+
}

app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
*/
66
namespace Magento\CatalogImportExport\Test\Unit\Model\Import;
77

8+
use Magento\CatalogImportExport\Model\Import\Product\ImageTypeProcessor;
89
use Magento\Framework\App\Filesystem\DirectoryList;
9-
use Magento\Framework\Stdlib\DateTime;
1010
use Magento\ImportExport\Model\Import;
1111

1212
/**
@@ -159,6 +159,9 @@ class ProductTest extends \Magento\ImportExport\Test\Unit\Model\Import\AbstractI
159159
/** @var \Magento\Catalog\Model\Product\Url|\PHPUnit_Framework_MockObject_MockObject*/
160160
protected $productUrl;
161161

162+
/** @var ImageTypeProcessor|\PHPUnit_Framework_MockObject_MockObject */
163+
protected $imageTypeProcessor;
164+
162165
/**
163166
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
164167
*/
@@ -326,11 +329,16 @@ protected function setUp()
326329

327330
$this->data = [];
328331

332+
$this->imageTypeProcessor = $this->getMockBuilder(ImageTypeProcessor::class)
333+
->disableOriginalConstructor()
334+
->getMock();
335+
329336
$this->_objectConstructor()
330337
->_parentObjectConstructor()
331338
->_initAttributeSets()
332339
->_initTypeModels()
333-
->_initSkus();
340+
->_initSkus()
341+
->_initImagesArrayKeys();
334342

335343
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
336344

@@ -373,7 +381,8 @@ protected function setUp()
373381
'taxClassProcessor' => $this->taxClassProcessor,
374382
'scopeConfig' => $this->scopeConfig,
375383
'productUrl' => $this->productUrl,
376-
'data' => $this->data
384+
'data' => $this->data,
385+
'imageTypeProcessor' => $this->imageTypeProcessor
377386
]
378387
);
379388
$reflection = new \ReflectionClass(\Magento\CatalogImportExport\Model\Import\Product::class);
@@ -496,6 +505,14 @@ protected function _initSkus()
496505
return $this;
497506
}
498507

508+
protected function _initImagesArrayKeys()
509+
{
510+
$this->imageTypeProcessor->expects($this->once())->method('getImageTypes')->willReturn(
511+
['image', 'small_image', 'thumbnail', 'swatch_image', '_media_image']
512+
);
513+
return $this;
514+
}
515+
499516
public function testSaveProductAttributes()
500517
{
501518
$testTable = 'test_table';
@@ -513,25 +530,6 @@ public function testSaveProductAttributes()
513530
]
514531
]
515532
];
516-
$entityTable = 'catalog_product_entity';
517-
$resource = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModel::class)
518-
->disableOriginalConstructor()
519-
->setMethods(['getTable'])
520-
->getMock();
521-
$resource->expects($this->once())->method('getTable')->with($entityTable)->willReturnArgument(0);
522-
$this->_resourceFactory->expects($this->once())->method('create')->willReturn($resource);
523-
$selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
524-
->disableOriginalConstructor()
525-
->getMock();
526-
$selectMock->expects($this->once())->method('from')->with($entityTable, '*', null)->willReturnSelf();
527-
$selectMock->expects($this->once())->method('where')->with('sku = ?', $testSku)->willReturnSelf();
528-
$selectMock->expects($this->once())->method('columns')->with('entity_id')->willReturnSelf();
529-
$this->_connection->expects($this->any())->method('fetchOne')->willReturn(self::ENTITY_ID);
530-
$this->_connection->expects($this->any())->method('select')->willReturn($selectMock);
531-
$this->_connection->expects($this->any())
532-
->method('quoteInto')
533-
->willReturnCallback([$this, 'returnQuoteCallback']);
534-
535533
$tableData[] = [
536534
'entity_id' => self::ENTITY_ID,
537535
'attribute_id' => $attributeId,
@@ -541,6 +539,7 @@ public function testSaveProductAttributes()
541539
$this->_connection->expects($this->once())
542540
->method('insertOnDuplicate')
543541
->with($testTable, $tableData, ['value']);
542+
$this->setPropertyValue($this->importProduct, '_oldSku', [$testSku => ['entity_id' => self::ENTITY_ID]]);
544543
$object = $this->invokeMethod($this->importProduct, '_saveProductAttributes', [$attributesData]);
545544
$this->assertEquals($this->importProduct, $object);
546545
}

app/code/Magento/Checkout/view/frontend/web/js/region-updater.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ define([
195195
regionInput.hide();
196196
label.attr('for', regionList.attr('id'));
197197
} else {
198+
this._removeSelectOptions(regionList);
199+
198200
if (this.options.isRegionRequired) {
199201
regionInput.addClass('required-entry').removeAttr('disabled');
200202
requiredLabel.addClass('required');
@@ -206,7 +208,7 @@ define([
206208
regionInput.removeClass('required-entry');
207209
}
208210

209-
regionList.removeClass('required-entry').hide();
211+
regionList.removeClass('required-entry').prop('disabled', 'disabled').hide();
210212
regionInput.show();
211213
label.attr('for', regionInput.attr('id'));
212214
}

app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,7 @@ private function loadUsedProducts(\Magento\Catalog\Model\Product $product, $cach
12961296
if ($salableOnly) {
12971297
$collection = $this->salableProcessor->process($collection);
12981298
}
1299-
$usedProducts = $collection->getItems();
1299+
$usedProducts = array_values($collection->getItems());
13001300
$this->saveUsedProductsCacheData($product, $usedProducts, $cacheKey);
13011301
}
13021302
$product->setData($dataFieldName, $usedProducts);

0 commit comments

Comments
 (0)