Skip to content

Commit a48940c

Browse files
committed
Merge remote-tracking branch 'mainline/2.2-develop' into MPI-PR
2 parents 7a17373 + 3572ee9 commit a48940c

File tree

39 files changed

+350
-4219
lines changed

39 files changed

+350
-4219
lines changed

app/code/Magento/Analytics/Block/Adminhtml/System/Config/CollectionTimeLabel.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,45 @@
55
*/
66
namespace Magento\Analytics\Block\Adminhtml\System\Config;
77

8+
use Magento\Framework\App\ObjectManager;
9+
810
/**
911
* Provides label with default Time Zone
1012
*/
1113
class CollectionTimeLabel extends \Magento\Config\Block\System\Config\Form\Field
1214
{
1315
/**
14-
* Add default time zone to comment
16+
* @var \Magento\Framework\Locale\ResolverInterface
17+
*/
18+
private $localeResolver;
19+
20+
/**
21+
* @param \Magento\Backend\Block\Template\Context $context
22+
* @param array $data
23+
* @param \Magento\Framework\Locale\ResolverInterface|null $localeResolver
24+
*/
25+
public function __construct(
26+
\Magento\Backend\Block\Template\Context $context,
27+
array $data = [],
28+
\Magento\Framework\Locale\ResolverInterface $localeResolver = null
29+
) {
30+
$this->localeResolver = $localeResolver ?:
31+
ObjectManager::getInstance()->get(\Magento\Framework\Locale\ResolverInterface::class);
32+
parent::__construct($context, $data);
33+
}
34+
35+
/**
36+
* Add current time zone to comment, properly translated according to locale
1537
*
1638
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
1739
* @return string
1840
*/
1941
public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
2042
{
2143
$timeZoneCode = $this->_localeDate->getConfigTimezone();
22-
$getLongTimeZoneName = \IntlTimeZone::createTimeZone($timeZoneCode)->getDisplayName();
44+
$locale = $this->localeResolver->getLocale();
45+
$getLongTimeZoneName = \IntlTimeZone::createTimeZone($timeZoneCode)
46+
->getDisplayName(false, \IntlTimeZone::DISPLAY_LONG, $locale);
2347
$element->setData(
2448
'comment',
2549
sprintf("%s (%s)", $getLongTimeZoneName, $timeZoneCode)

app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,27 @@ class SaveHandler
3131
private $linkResource;
3232

3333
/**
34+
* @var linkTypeProvider
35+
*/
36+
private $linkTypeProvider;
37+
38+
/**
39+
* SaveHandler constructor.
3440
* @param MetadataPool $metadataPool
3541
* @param Link $linkResource
3642
* @param ProductLinkRepositoryInterface $productLinkRepository
43+
* @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
3744
*/
3845
public function __construct(
3946
MetadataPool $metadataPool,
4047
Link $linkResource,
41-
ProductLinkRepositoryInterface $productLinkRepository
48+
ProductLinkRepositoryInterface $productLinkRepository,
49+
\Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
4250
) {
4351
$this->metadataPool = $metadataPool;
4452
$this->linkResource = $linkResource;
4553
$this->productLinkRepository = $productLinkRepository;
54+
$this->linkTypeProvider = $linkTypeProvider;
4655
}
4756

4857
/**
@@ -55,17 +64,50 @@ public function execute($entityType, $entity)
5564
{
5665
$link = $entity->getData($this->metadataPool->getMetadata($entityType)->getLinkField());
5766
if ($this->linkResource->hasProductLinks($link)) {
58-
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
67+
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
5968
foreach ($this->productLinkRepository->getList($entity) as $link) {
6069
$this->productLinkRepository->delete($link);
6170
}
6271
}
63-
$productLinks = $entity->getProductLinks();
72+
73+
// Build links per type
74+
$linksByType = [];
75+
foreach ($entity->getProductLinks() as $link) {
76+
$linksByType[$link->getLinkType()][] = $link;
77+
}
78+
79+
// Set array position as a fallback position if necessary
80+
foreach ($linksByType as $linkType => $links) {
81+
if (!$this->hasPosition($links)) {
82+
array_walk($linksByType[$linkType], function ($productLink, $position) {
83+
$productLink->setPosition(++$position);
84+
});
85+
}
86+
}
87+
88+
// Flatten multi-dimensional linksByType in ProductLinks
89+
$productLinks = array_reduce($linksByType, 'array_merge', []);
90+
6491
if (count($productLinks) > 0) {
6592
foreach ($entity->getProductLinks() as $link) {
6693
$this->productLinkRepository->save($link);
6794
}
6895
}
6996
return $entity;
7097
}
98+
99+
/**
100+
* Check if at least one link without position
101+
* @param array $links
102+
* @return bool
103+
*/
104+
private function hasPosition(array $links)
105+
{
106+
foreach ($links as $link) {
107+
if (!array_key_exists('position', $link->getData())) {
108+
return false;
109+
}
110+
}
111+
return true;
112+
}
71113
}

app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
*/
66
namespace Magento\CatalogInventory\Model\ResourceModel\Stock;
77

8-
use Magento\CatalogInventory\Model\Stock;
98
use Magento\CatalogInventory\Api\StockConfigurationInterface;
9+
use Magento\CatalogInventory\Model\Stock;
1010
use Magento\Framework\App\ObjectManager;
1111

1212
/**
@@ -46,19 +46,23 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
4646
* @param \Magento\Store\Model\WebsiteFactory $websiteFactory
4747
* @param \Magento\Eav\Model\Config $eavConfig
4848
* @param string $connectionName
49+
* @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
4950
*/
5051
public function __construct(
5152
\Magento\Framework\Model\ResourceModel\Db\Context $context,
5253
\Magento\Store\Model\StoreManagerInterface $storeManager,
5354
\Magento\Store\Model\WebsiteFactory $websiteFactory,
5455
\Magento\Eav\Model\Config $eavConfig,
55-
$connectionName = null
56+
$connectionName = null,
57+
$stockConfiguration = null
5658
) {
5759
parent::__construct($context, $connectionName);
5860

5961
$this->_storeManager = $storeManager;
6062
$this->_websiteFactory = $websiteFactory;
6163
$this->eavConfig = $eavConfig;
64+
$this->stockConfiguration = $stockConfiguration ?: ObjectManager::getInstance()
65+
->get(StockConfigurationInterface::class);
6266
}
6367

6468
/**
@@ -204,7 +208,7 @@ public function getProductCollection($lastEntityId = 0, $limit = 1000)
204208
*/
205209
public function addStockStatusToSelect(\Magento\Framework\DB\Select $select, \Magento\Store\Model\Website $website)
206210
{
207-
$websiteId = $this->getStockConfiguration()->getDefaultScopeId();
211+
$websiteId = $this->getWebsiteId($website->getId());
208212
$select->joinLeft(
209213
['stock_status' => $this->getMainTable()],
210214
'e.entity_id = stock_status.product_id AND stock_status.website_id=' . $websiteId,
@@ -221,7 +225,7 @@ public function addStockStatusToSelect(\Magento\Framework\DB\Select $select, \Ma
221225
*/
222226
public function addStockDataToCollection($collection, $isFilterInStock)
223227
{
224-
$websiteId = $this->getStockConfiguration()->getDefaultScopeId();
228+
$websiteId = $this->getWebsiteId();
225229
$joinCondition = $this->getConnection()->quoteInto(
226230
'e.entity_id = stock_status_index.product_id' . ' AND stock_status_index.website_id = ?',
227231
$websiteId
@@ -255,7 +259,7 @@ public function addStockDataToCollection($collection, $isFilterInStock)
255259
*/
256260
public function addIsInStockFilterToCollection($collection)
257261
{
258-
$websiteId = $this->getStockConfiguration()->getDefaultScopeId();
262+
$websiteId = $this->getWebsiteId();
259263
$joinCondition = $this->getConnection()->quoteInto(
260264
'e.entity_id = stock_status_index.product_id' . ' AND stock_status_index.website_id = ?',
261265
$websiteId
@@ -277,6 +281,19 @@ public function addIsInStockFilterToCollection($collection)
277281
return $this;
278282
}
279283

284+
/**
285+
* @param \Magento\Store\Model\Website $websiteId
286+
* @return int
287+
*/
288+
private function getWebsiteId($websiteId = null)
289+
{
290+
if (null === $websiteId) {
291+
$websiteId = $this->stockConfiguration->getDefaultScopeId();
292+
}
293+
294+
return $websiteId;
295+
}
296+
280297
/**
281298
* Retrieve Product(s) status for store
282299
* Return array where key is a product_id, value - status
@@ -335,18 +352,4 @@ public function getProductStatus($productIds, $storeId = null)
335352
}
336353
return $statuses;
337354
}
338-
339-
/**
340-
* @return StockConfigurationInterface
341-
*
342-
* @deprecated 100.1.0
343-
*/
344-
private function getStockConfiguration()
345-
{
346-
if ($this->stockConfiguration === null) {
347-
$this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance()
348-
->get(\Magento\CatalogInventory\Api\StockConfigurationInterface::class);
349-
}
350-
return $this->stockConfiguration;
351-
}
352355
}

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

Lines changed: 2 additions & 0 deletions
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');

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
use Magento\Catalog\Api\Data\ProductInterface;
1111
use Magento\Catalog\Api\Data\ProductInterfaceFactory;
1212
use Magento\Catalog\Api\ProductRepositoryInterface;
13-
use Magento\ConfigurableProduct\Model\Product\Type\Collection\SalableProcessor;
1413
use Magento\Catalog\Model\Config;
14+
use Magento\Catalog\Model\Product\Gallery\ReadHandler as GalleryReadHandler;
15+
use Magento\ConfigurableProduct\Model\Product\Type\Collection\SalableProcessor;
1516
use Magento\Framework\App\ObjectManager;
1617
use Magento\Framework\EntityManager\MetadataPool;
17-
use Magento\Catalog\Model\Product\Gallery\ReadHandler as GalleryReadHandler;
1818

1919
/**
2020
* Configurable product type implementation
@@ -267,7 +267,6 @@ public function __construct(
267267
$productRepository,
268268
$serializer
269269
);
270-
271270
}
272271

273272
/**
@@ -1277,6 +1276,8 @@ public function getSalableUsedProducts(\Magento\Catalog\Model\Product $product,
12771276
* Load collection on sub-products for specified configurable product
12781277
*
12791278
* Load collection of sub-products, apply result to specified configurable product and store result to cache
1279+
* Please note $salableOnly parameter is used for backwards compatibility because of deprecated method
1280+
* getSalableUsedProducts
12801281
* Number of loaded sub-products depends on $salableOnly parameter
12811282
* $salableOnly = true - result array contains only salable sub-products
12821283
* $salableOnly = false - result array contains all sub-products
@@ -1293,7 +1294,7 @@ private function loadUsedProducts(\Magento\Catalog\Model\Product $product, $cach
12931294
if (!$product->hasData($dataFieldName)) {
12941295
$usedProducts = $this->readUsedProductsCacheData($cacheKey);
12951296
if ($usedProducts === null) {
1296-
$collection = $this->getConfiguredUsedProductCollection($product);
1297+
$collection = $this->getConfiguredUsedProductCollection($product, false);
12971298
if ($salableOnly) {
12981299
$collection = $this->salableProcessor->process($collection);
12991300
}
@@ -1387,13 +1388,18 @@ private function getUsedProductsCacheKey($keyParts)
13871388
* Retrieve related products collection with additional configuration
13881389
*
13891390
* @param \Magento\Catalog\Model\Product $product
1391+
* @param bool $skipStockFilter
13901392
* @return \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection
13911393
*/
1392-
private function getConfiguredUsedProductCollection(\Magento\Catalog\Model\Product $product)
1393-
{
1394+
private function getConfiguredUsedProductCollection(
1395+
\Magento\Catalog\Model\Product $product,
1396+
$skipStockFilter = true
1397+
) {
13941398
$collection = $this->getUsedProductCollection($product);
1399+
if ($skipStockFilter) {
1400+
$collection->setFlag('has_stock_status_filter', true);
1401+
}
13951402
$collection
1396-
->setFlag('has_stock_status_filter', true)
13971403
->addAttributeToSelect($this->getCatalogConfig()->getProductAttributes())
13981404
->addFilterByRequiredOptions()
13991405
->setStoreId($product->getStoreId());

app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@
88
use Magento\Catalog\Api\Data\ProductExtensionInterface;
99
use Magento\Catalog\Api\Data\ProductInterface;
1010
use Magento\Catalog\Model\Config;
11-
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
12-
use Magento\Framework\EntityManager\EntityMetadata;
13-
use Magento\Framework\EntityManager\MetadataPool;
14-
use Magento\Customer\Model\Session;
15-
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\CollectionFactory;
16-
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection;
1711
use Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface;
18-
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
12+
use Magento\ConfigurableProduct\Model\Product\Type\Collection\SalableProcessor;
13+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
1914
use Magento\ConfigurableProduct\Model\Product\Type\Configurable\AttributeFactory;
15+
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection;
16+
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\CollectionFactory;
17+
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ProductCollection;
2018
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\ConfigurableFactory;
19+
use Magento\Customer\Model\Session;
2120
use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend;
2221
use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;
23-
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ProductCollection;
24-
use Magento\ConfigurableProduct\Model\Product\Type\Collection\SalableProcessor;
22+
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
23+
use Magento\Framework\EntityManager\EntityMetadata;
24+
use Magento\Framework\EntityManager\MetadataPool;
2525

2626
/**
2727
* @SuppressWarnings(PHPMD.LongVariable)

dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock

Lines changed: 0 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock

Lines changed: 0 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)