Skip to content

Commit 1a17980

Browse files
merge magento/2.3-develop into magento-epam/EPAM-PR-71
2 parents e6c0c83 + 7725283 commit 1a17980

File tree

26 files changed

+801
-50
lines changed

26 files changed

+801
-50
lines changed

.github/CODEOWNERS

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/app/code/Magento/AdminNotification/ @paliarush
2+
/app/code/Magento/Backend/ @paliarush
3+
/app/code/Magento/User/ @paliarush
4+
/lib/internal/Magento/Framework/App/ @buskamuza
5+
/lib/internal/Magento/Framework/Controller/ @buskamuza
6+
/lib/internal/Magento/Framework/Flag/ @buskamuza
7+
/lib/internal/Magento/Framework/HTTP/ @buskamuza
8+
/lib/internal/Magento/Framework/Logger/ @buskamuza
9+
/lib/internal/Magento/Framework/Message/ @buskamuza
10+
/lib/internal/Magento/Framework/Notification/ @buskamuza
11+
/lib/internal/Magento/Framework/Session/ @buskamuza
12+
/lib/internal/Magento/Framework/Url/ @buskamuza
13+
/app/code/Magento/Cms/ @melnikovi
14+
/app/code/Magento/CmsUrlRewrite/ @melnikovi
15+
/app/code/Magento/Contact/ @melnikovi
16+
/app/code/Magento/Email/ @melnikovi
17+
/app/code/Magento/Variable/ @melnikovi
18+
/app/code/Magento/Widget/ @melnikovi
19+
/lib/internal/Magento/Framework/Cache/ @kokoc
20+
/app/code/Magento/CacheInvalidate/ @kokoc
21+
/app/code/Magento/CatalogInventory/ @tariqjawed83 @maghamed
22+
/app/code/Magento/Bundle/ @akaplya
23+
/app/code/Magento/BundleImportExport/ @akaplya
24+
/app/code/Magento/Catalog/ @akaplya
25+
/app/code/Magento/CatalogAnalytics/ @akaplya
26+
/app/code/Magento/CatalogImportExport/ @akaplya
27+
/app/code/Magento/CatalogSearch/ @kokoc
28+
/app/code/Magento/CatalogUrlRewrite/ @akaplya
29+
/app/code/Magento/ConfigurableImportExport/ @akaplya
30+
/app/code/Magento/ConfigurableProduct/ @akaplya
31+
/app/code/Magento/Downloadable/ @akaplya
32+
/app/code/Magento/DownloadableImportExport/ @akaplya
33+
/app/code/Magento/GroupedImportExport/ @akaplya
34+
/app/code/Magento/GroupedProduct/ @akaplya
35+
/app/code/Magento/LayeredNavigation/ @kokoc
36+
/app/code/Magento/ProductVideo/ @akaplya
37+
/app/code/Magento/Review/ @akaplya
38+
/app/code/Magento/Swatches/ @akaplya
39+
/app/code/Magento/SwatchesLayeredNavigation/ @kokoc
40+
/app/code/Magento/Checkout/ @paliarush
41+
/app/code/Magento/CheckoutAgreements/ @paliarush
42+
/app/code/Magento/GiftMessage/ @paliarush
43+
/app/code/Magento/InstantPurchase/ @paliarush
44+
/app/code/Magento/Multishipping/ @joni-jones
45+
/app/code/Magento/Quote/ @paliarush
46+
/app/code/Magento/QuoteAnalytics/ @paliarush
47+
/lib/internal/Magento/Framework/Code/ @joni-jones
48+
/lib/internal/Magento/Framework/Reflection/ @joni-jones
49+
/lib/internal/Magento/Framework/Component/ @buskamuza
50+
/app/code/Magento/Version/ @buskamuza
51+
/lib/internal/Magento/Framework/Config/ @paliarush
52+
/app/code/Magento/Config/ @paliarush
53+
/lib/internal/Magento/Framework/Console/ @joni-jones
54+
/lib/internal/Magento/Framework/Process/ @joni-jones
55+
/lib/internal/Magento/Framework/Shell/ @joni-jones
56+
/app/code/Magento/Cookie/ @kokoc
57+
/lib/internal/Magento/Framework/Crontab/ @tariqjawed83 @buskamuza
58+
/app/code/Magento/Cron/ @tariqjawed83 @buskamuza
59+
/app/code/Magento/Customer/ @paliarush
60+
/app/code/Magento/CustomerAnalytics/ @paliarush
61+
/app/code/Magento/CustomerImportExport/ @paliarush
62+
/app/code/Magento/Persistent/ @paliarush
63+
/app/code/Magento/Wishlist/ @paliarush
64+
/lib/internal/Magento/Framework/DB/ @akaplya
65+
/lib/internal/Magento/Framework/EntityManager/ @akaplya
66+
/lib/internal/Magento/Framework/Indexer/ @akaplya
67+
/lib/internal/Magento/Framework/Model/ @akaplya
68+
/lib/internal/Magento/Framework/Mview/ @akaplya
69+
/app/code/Magento/Eav/ @akaplya
70+
/app/code/Magento/Indexer/ @akaplya
71+
/lib/internal/Magento/Framework/Archive/ @joni-jones
72+
/lib/internal/Magento/Framework/Convert/ @joni-jones
73+
/lib/internal/Magento/Framework/Data/ @joni-jones
74+
/lib/internal/Magento/Framework/DomDocument/ @joni-jones
75+
/lib/internal/Magento/Framework/Json/ @joni-jones
76+
/lib/internal/Magento/Framework/Math/ @joni-jones
77+
/lib/internal/Magento/Framework/Parse/ @joni-jones
78+
/lib/internal/Magento/Framework/Serialize/ @joni-jones
79+
/lib/internal/Magento/Framework/Simplexml/ @joni-jones
80+
/lib/internal/Magento/Framework/Stdlib/ @joni-jones
81+
/lib/internal/Magento/Framework/Unserialize/ @joni-jones
82+
/lib/internal/Magento/Framework/Xml/ @joni-jones
83+
/lib/internal/Magento/Framework/XsltProcessor/ @joni-jones
84+
/app/code/Magento/Deploy/ @kandy @buskamuza
85+
/lib/internal/Magento/Framework/Profiler/ @kandy
86+
/app/code/Magento/Developer/ @buskamuza
87+
/app/code/Magento/Directory/ @buskamuza
88+
/lib/internal/Magento/Framework/Exception/ @paliarush
89+
/lib/internal/Magento/Framework/File/ @buskamuza
90+
/lib/internal/Magento/Framework/Filesystem/ @buskamuza
91+
/lib/internal/Magento/Framework/System/ @buskamuza
92+
/lib/internal/Magento/Framework/Css/ @DrewML
93+
/lib/internal/Magento/Framework/Option/ @DrewML
94+
/lib/internal/Magento/Framework/RequireJs/ @DrewML
95+
/lib/internal/Magento/Framework/View/ @melnikovi
96+
/dev/tests/js/ @DrewML
97+
/app/code/Magento/RequireJs/ @DrewML
98+
/app/code/Magento/Theme/ @melnikovi
99+
/app/code/Magento/Ui/ @melnikovi
100+
/lib/internal/Magento/Framework/Intl/ @melnikovi
101+
/lib/internal/Magento/Framework/Locale/ @melnikovi
102+
/lib/internal/Magento/Framework/Phrase/ @melnikovi
103+
/lib/internal/Magento/Framework/Translate/ @melnikovi
104+
/app/code/Magento/Translation/ @melnikovi
105+
/app/code/Magento/ImportExport/ @akaplya
106+
/app/code/Magento/GoogleAdwords/ @buskamuza @melnikovi
107+
/app/code/Magento/Newsletter/ @buskamuza @melnikovi
108+
/app/code/Magento/ProductAlert/ @buskamuza @melnikovi
109+
/app/code/Magento/Rss/ @buskamuza @melnikovi
110+
/app/code/Magento/SendFriend/ @buskamuza @melnikovi
111+
/app/code/Magento/Marketplace/ @buskamuza
112+
/app/code/Magento/MediaStorage/ @buskamuza
113+
/lib/internal/Magento/Framework/Amqp/ @tariqjawed83 @paliarush
114+
/lib/internal/Magento/Framework/Bulk/ @tariqjawed83 @paliarush
115+
/lib/internal/Magento/Framework/Communication/ @tariqjawed83 @paliarush
116+
/app/code/Magento/Amqp/ @tariqjawed83 @paliarush
117+
/app/code/Magento/AsynchronousOperations/ @tariqjawed83 @paliarush
118+
/app/code/Magento/MessageQueue/ @tariqjawed83 @paliarush
119+
/app/code/Magento/MysqlMq/ @tariqjawed83 @paliarush
120+
/app/code/Magento/Sales/ @joni-jones
121+
/app/code/Magento/SalesInventory/ @joni-jones
122+
/app/code/Magento/SalesSequence/ @joni-jones
123+
/lib/internal/Magento/Framework/Event/ @buskamuza @kandy
124+
/lib/internal/Magento/Framework/Interception/ @buskamuza @kandy
125+
/lib/internal/Magento/Framework/ObjectManager/ @buskamuza @kandy
126+
/app/code/Magento/PageCache/ @Andrey @kokoc @paliarush
127+
/app/code/Magento/Authorizenet/ @joni-jones
128+
/app/code/Magento/Braintree/ @joni-jones
129+
/app/code/Magento/OfflinePayments/ @joni-jones
130+
/app/code/Magento/Payment/ @joni-jones
131+
/app/code/Magento/Paypal/ @joni-jones
132+
/app/code/Magento/Signifyd/ @joni-jones
133+
/app/code/Magento/Vault/ @joni-jones
134+
/lib/internal/Magento/Framework/Pricing/ @akaplya
135+
/app/code/Magento/AdvancedPricingImportExport/ @akaplya
136+
/app/code/Magento/CurrencySymbol/ @akaplya
137+
/app/code/Magento/Msrp/ @akaplya
138+
/app/code/Magento/Tax/ @akaplya
139+
/app/code/Magento/TaxImportExport/ @akaplya
140+
/app/code/Magento/Weee/ @akaplya
141+
/app/code/Magento/CatalogRule/ @kokoc
142+
/app/code/Magento/CatalogRuleConfigurable/ @kokoc
143+
/app/code/Magento/CatalogWidget/ @kokoc
144+
/app/code/Magento/Rule/ @kokoc
145+
/app/code/Magento/SalesRule/ @akaplya
146+
/app/code/Magento/ReleaseNotification/ @paliarush
147+
/app/code/Magento/Analytics/ @tariqjawed83 @buskamuza
148+
/app/code/Magento/GoogleAnalytics/ @tariqjawed83 @buskamuza
149+
/app/code/Magento/NewRelicReporting/ @tariqjawed83 @buskamuza
150+
/app/code/Magento/Reports/ @tariqjawed83 @buskamuza
151+
/app/code/Magento/ReviewAnalytics/ @tariqjawed83 @buskamuza
152+
/app/code/Magento/SalesAnalytics/ @tariqjawed83 @buskamuza
153+
/app/code/Magento/WishlistAnalytics/ @tariqjawed83 @buskamuza
154+
/app/code/Magento/GoogleOptimizer/ @paliarush
155+
/app/code/Magento/Robots/ @paliarush
156+
/app/code/Magento/Sitemap/ @paliarush
157+
/lib/internal/Magento/Framework/Search/ @kokoc
158+
/app/code/Magento/AdvancedSearch/ @kokoc
159+
/app/code/Magento/Elasticsearch/ @kokoc
160+
/app/code/Magento/Search/ @kokoc
161+
/lib/internal/Magento/Framework/Acl/ @kokoc
162+
/lib/internal/Magento/Framework/Authorization/ @kokoc
163+
/lib/internal/Magento/Framework/Encryption/ @kokoc
164+
/app/code/Magento/Authorization/ @kokoc
165+
/app/code/Magento/Captcha/ @kokoc
166+
/app/code/Magento/EncryptionKey/ @kokoc
167+
/app/code/Magento/Security/ @kokoc
168+
/lib/internal/Magento/Framework/Autoload/ @buskamuza
169+
/lib/internal/Magento/Framework/Backup/ @buskamuza
170+
/lib/internal/Magento/Framework/Composer/ @buskamuza
171+
/lib/internal/Magento/Framework/Setup/ @buskamuza
172+
/app/code/Magento/Backup/ @buskamuza
173+
/setup/ @buskamuza
174+
/app/code/Magento/Dhl/ @joni-jones
175+
/app/code/Magento/Fedex/ @joni-jones
176+
/app/code/Magento/OfflineShipping/ @joni-jones
177+
/app/code/Magento/Shipping/ @joni-jones
178+
/app/code/Magento/Ups/ @joni-jones
179+
/app/code/Magento/Usps/ @joni-jones
180+
/app/code/Magento/Store/ @akaplya
181+
/lib/internal/Magento/Framework/TestFramework/ @paliarush
182+
/dev/tests/integration/framework/ @buskamuza
183+
/dev/tests/setup-integration/framework/ @paliarush
184+
/dev/tests/static/framework/ @paliarush
185+
/dev/tests/unit/ @paliarush
186+
/dev/tests/api-functional/ @paliarush
187+
/app/code/Magento/UrlRewrite/ @kokoc
188+
/lib/internal/Magento/Framework/Image/ @buskamuza
189+
/lib/internal/Magento/Framework/Mail/ @melnikovi
190+
/lib/internal/Magento/Framework/Filter/ @melnikovi
191+
/lib/internal/Magento/Framework/Validation/ @melnikovi
192+
/lib/internal/Magento/Framework/Validator/ @melnikovi
193+
/lib/internal/Magento/Framework/Api/ @paliarush
194+
/lib/internal/Magento/Framework/GraphQL/ @paliarush
195+
/lib/internal/Magento/Framework/Oauth/ @paliarush
196+
/lib/internal/Magento/Framework/Webapi/ @paliarush
197+
/app/code/Magento/GraphQL/ @paliarush
198+
/app/code/Magento/Integration/ @paliarush
199+
/app/code/Magento/Swagger/ @paliarush
200+
/app/code/Magento/Webapi/ @paliarush
201+
/app/code/Magento/WebapiSecurity/ @paliarush
202+
203+
composer.json @buskamuza
204+
*.js @DrewML
205+
.htaccess* @akaplya
206+
nginx.conf* @akaplya

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,8 +1192,10 @@ protected function _initTypeModels()
11921192
if ($model->isSuitable()) {
11931193
$this->_productTypeModels[$productTypeName] = $model;
11941194
}
1195+
// phpcs:disable Magento2.Performance.ForeachArrayMerge.ForeachArrayMerge
11951196
$this->_fieldsMap = array_merge($this->_fieldsMap, $model->getCustomFieldsMapping());
11961197
$this->_specialAttributes = array_merge($this->_specialAttributes, $model->getParticularAttributes());
1198+
// phpcs:enable
11971199
}
11981200
$this->_initErrorTemplates();
11991201
// remove doubles
@@ -2972,6 +2974,10 @@ private function formatStockDataForRow(array $rowData): array
29722974
$stockItemDo = $this->stockRegistry->getStockItem($row['product_id'], $row['website_id']);
29732975
$existStockData = $stockItemDo->getData();
29742976

2977+
if (isset($rowData['qty']) && $rowData['qty'] == 0 && !isset($rowData['is_in_stock'])) {
2978+
$rowData['is_in_stock'] = 0;
2979+
}
2980+
29752981
$row = array_merge(
29762982
$this->defaultStockData,
29772983
array_intersect_key($existStockData, $this->defaultStockData),

app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public function generateSimpleProducts($parentProduct, $productsData)
106106
$this->fillSimpleProductData(
107107
$newSimpleProduct,
108108
$parentProduct,
109+
// phpcs:ignore Magento2.Performance.ForeachArrayMerge
109110
array_merge($simpleProductData, $configurableAttribute)
110111
);
111112
$newSimpleProduct->save();
@@ -238,10 +239,6 @@ public function duplicateImagesForVariations($productsData)
238239

239240
foreach ($simpleProductData['media_gallery']['images'] as $imageId => $image) {
240241
$image['variation_id'] = $variationId;
241-
if (isset($imagesForCopy[$imageId][0])) {
242-
// skip duplicate image for first product
243-
unset($imagesForCopy[$imageId][0]);
244-
}
245242
$imagesForCopy[$imageId][] = $image;
246243
}
247244
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
declare(strict_types=1);
3+
/**
4+
* Product initialization helper
5+
*
6+
* Copyright © Magento, Inc. All rights reserved.
7+
* See COPYING.txt for license details.
8+
*/
9+
namespace Magento\ConfigurableProduct\Plugin\Product\Initialization;
10+
11+
use Magento\Framework\App\Filesystem\DirectoryList;
12+
13+
/**
14+
* Class CleanConfigurationTmpImages
15+
*
16+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
17+
* @SuppressWarnings(PHPCS.Magento2.Files.LineLength.MaxExceeded)
18+
*/
19+
class CleanConfigurationTmpImages
20+
{
21+
/**
22+
* @var \Magento\MediaStorage\Helper\File\Storage\Database
23+
*/
24+
private $fileStorageDb;
25+
26+
/**
27+
* @var \Magento\Catalog\Model\Product\Media\Config
28+
*/
29+
private $mediaConfig;
30+
31+
/**
32+
* @var \Magento\Framework\Filesystem\Directory\WriteInterface
33+
*/
34+
private $mediaDirectory;
35+
36+
/**
37+
* @var \Magento\Framework\App\RequestInterface
38+
*/
39+
private $request;
40+
41+
/**
42+
* @var \Magento\Framework\Serialize\Serializer\Json
43+
*/
44+
private $serialize;
45+
46+
/**
47+
* @param \Magento\Framework\App\RequestInterface $request
48+
* @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb
49+
* @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig
50+
* @param \Magento\Framework\Filesystem $filesystem
51+
* @param \Magento\Framework\Serialize\Serializer\Json $serialize
52+
*
53+
* @throws \Magento\Framework\Exception\FileSystemException
54+
*/
55+
public function __construct(
56+
\Magento\Framework\App\RequestInterface $request,
57+
\Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb,
58+
\Magento\Catalog\Model\Product\Media\Config $mediaConfig,
59+
\Magento\Framework\Filesystem $filesystem,
60+
\Magento\Framework\Serialize\Serializer\Json $serialize
61+
) {
62+
$this->request = $request;
63+
$this->fileStorageDb = $fileStorageDb;
64+
$this->mediaConfig = $mediaConfig;
65+
$this->serialize = $serialize;
66+
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
67+
}
68+
69+
/**
70+
* Clean Tmp configurable images
71+
*
72+
* @param \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $subject
73+
* @param \Magento\Catalog\Model\Product $configurableProduct
74+
*
75+
* @return \Magento\Catalog\Model\Product
76+
* @throws \Magento\Framework\Exception\FileSystemException
77+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
78+
*/
79+
public function afterInitialize(
80+
\Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $subject,
81+
\Magento\Catalog\Model\Product $configurableProduct
82+
) {
83+
84+
$configurations = $this->getConfigurations();
85+
foreach ($configurations as $simpleProductData) {
86+
if (!isset($simpleProductData['media_gallery']['images'])) {
87+
continue;
88+
}
89+
90+
foreach ($simpleProductData['media_gallery']['images'] as $image) {
91+
$file = $this->getFilenameFromTmp($image['file']);
92+
if ($this->fileStorageDb->checkDbUsage()) {
93+
$filename = $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getTmpMediaShortUrl($file));
94+
$this->fileStorageDb->deleteFile($filename);
95+
} else {
96+
$filename = $this->mediaConfig->getTmpMediaPath($file);
97+
$this->mediaDirectory->delete($filename);
98+
}
99+
}
100+
}
101+
102+
return $configurableProduct;
103+
}
104+
105+
/**
106+
* Trim .tmp ending from filename
107+
*
108+
* @param string $file
109+
* @return string
110+
*/
111+
private function getFilenameFromTmp($file)
112+
{
113+
return strrpos($file, '.tmp') === strlen($file) - 4 ? substr($file, 0, strlen($file) - 4) : $file;
114+
}
115+
116+
/**
117+
* Get configurations from request
118+
*
119+
* @return array
120+
*/
121+
private function getConfigurations()
122+
{
123+
$result = [];
124+
$configurableMatrix = $this->request->getParam('configurable-matrix-serialized', "[]");
125+
if (isset($configurableMatrix) && $configurableMatrix !== "") {
126+
$configurableMatrix = $this->serialize->unserialize($configurableMatrix) ?? [];
127+
128+
foreach ($configurableMatrix as $item) {
129+
if (empty($item['was_changed']) && empty($item['newProduct'])) {
130+
continue;
131+
}
132+
133+
$result[] = $item;
134+
}
135+
}
136+
137+
return $result;
138+
}
139+
}

app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ public function testAfterInitialize()
187187
*
188188
* @param array $expectedData
189189
* @param bool $hasDataChanges
190+
* @param bool $wasChanged
190191
* @return Product|\PHPUnit_Framework_MockObject_MockObject
191192
*/
192193
protected function getProductMock(array $expectedData = null, $hasDataChanges = false, $wasChanged = false)

0 commit comments

Comments
 (0)