Skip to content

Commit b75a39d

Browse files
committed
Merge branch 'mainline_develop' into api_coverage
2 parents 6e2fa56 + 6fe5623 commit b75a39d

File tree

22 files changed

+786
-194
lines changed

22 files changed

+786
-194
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,7 +1617,15 @@ public function setIsDuplicable($value)
16171617
*/
16181618
public function isSalable()
16191619
{
1620-
if ($this->hasData('salable') && !$this->_catalogProduct->getSkipSaleableCheck()) {
1620+
if ($this->_catalogProduct->getSkipSaleableCheck()) {
1621+
return true;
1622+
}
1623+
if (($this->getOrigData('status') != $this->getData('status'))
1624+
|| $this->isStockStatusChanged()) {
1625+
$this->unsetData('salable');
1626+
}
1627+
1628+
if ($this->hasData('salable')) {
16211629
return $this->getData('salable');
16221630
}
16231631
$this->_eventManager->dispatch('catalog_product_is_salable_before', ['product' => $this]);
@@ -1630,7 +1638,7 @@ public function isSalable()
16301638
['product' => $this, 'salable' => $object]
16311639
);
16321640
$this->setData('salable', $object->getIsSalable());
1633-
return $object->getIsSalable();
1641+
return $this->getData('salable');
16341642
}
16351643

16361644
/**
@@ -1640,7 +1648,7 @@ public function isSalable()
16401648
*/
16411649
public function isAvailable()
16421650
{
1643-
return $this->getTypeInstance()->isSalable($this) || $this->_catalogProduct->getSkipSaleableCheck();
1651+
return $this->_catalogProduct->getSkipSaleableCheck() || $this->getTypeInstance()->isSalable($this);
16441652
}
16451653

16461654
/**

app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ class Full
156156
*/
157157
private $iteratorFactory;
158158

159+
/**
160+
* @var \Magento\Framework\EntityManager\MetadataPool
161+
*/
162+
private $metadataPool;
163+
159164
/**
160165
* @param ResourceConnection $resource
161166
* @param \Magento\Catalog\Model\Product\Type $catalogProductType
@@ -175,6 +180,7 @@ class Full
175180
* @param \Magento\Framework\Search\Request\DimensionFactory $dimensionFactory
176181
* @param \Magento\Framework\Indexer\ConfigInterface $indexerConfig
177182
* @param \Magento\CatalogSearch\Model\Indexer\Fulltext\Action\IndexIteratorFactory $indexIteratorFactory
183+
* @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
178184
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
179185
*/
180186
public function __construct(
@@ -195,7 +201,8 @@ public function __construct(
195201
\Magento\CatalogSearch\Model\ResourceModel\Fulltext $fulltextResource,
196202
\Magento\Framework\Search\Request\DimensionFactory $dimensionFactory,
197203
\Magento\Framework\Indexer\ConfigInterface $indexerConfig,
198-
\Magento\CatalogSearch\Model\Indexer\Fulltext\Action\IndexIteratorFactory $indexIteratorFactory
204+
\Magento\CatalogSearch\Model\Indexer\Fulltext\Action\IndexIteratorFactory $indexIteratorFactory,
205+
\Magento\Framework\EntityManager\MetadataPool $metadataPool = null
199206
) {
200207
$this->resource = $resource;
201208
$this->connection = $resource->getConnection();
@@ -216,6 +223,8 @@ public function __construct(
216223
$this->fulltextResource = $fulltextResource;
217224
$this->dimensionFactory = $dimensionFactory;
218225
$this->iteratorFactory = $indexIteratorFactory;
226+
$this->metadataPool = $metadataPool ?: \Magento\Framework\App\ObjectManager::getInstance()
227+
->get(\Magento\Framework\EntityManager\MetadataPool::class);
219228
}
220229

221230
/**
@@ -252,14 +261,22 @@ protected function getTable($table)
252261
*/
253262
protected function getProductIdsFromParents(array $entityIds)
254263
{
255-
return $this->connection
264+
/** @var \Magento\Framework\EntityManager\EntityMetadataInterface $metadata */
265+
$metadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
266+
$fieldForParent = $metadata->getLinkField();
267+
268+
$select = $this->connection
256269
->select()
257-
->from($this->getTable('catalog_product_relation'), 'parent_id')
270+
->from(['relation' => $this->getTable('catalog_product_relation')], [])
258271
->distinct(true)
259272
->where('child_id IN (?)', $entityIds)
260273
->where('parent_id NOT IN (?)', $entityIds)
261-
->query()
262-
->fetchAll(\Zend_Db::FETCH_COLUMN);
274+
->join(
275+
['cpe' => $this->getTable('catalog_product_entity')],
276+
'relation.parent_id = cpe.' . $fieldForParent,
277+
['cpe.entity_id']
278+
);
279+
return $this->connection->fetchCol($select);
263280
}
264281

265282
/**
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\ConfigurableProduct\Model\Product\Type\Collection;
7+
8+
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
10+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
11+
use Magento\CatalogInventory\Model\ResourceModel\Stock\StatusFactory;
12+
13+
/**
14+
* This class is responsible for adding additional filters for products collection
15+
* to check if the product from this collection available to buy.
16+
*/
17+
class SalableProcessor
18+
{
19+
/**
20+
* @var StatusFactory
21+
*/
22+
private $stockStatusFactory;
23+
24+
/**
25+
* @param StatusFactory $stockStatusFactory
26+
*/
27+
public function __construct(StatusFactory $stockStatusFactory)
28+
{
29+
$this->stockStatusFactory = $stockStatusFactory;
30+
}
31+
32+
/**
33+
* Adds filters to the collection to help determine if product is available for sale.
34+
*
35+
* This method adds several additional checks for a children products availability.
36+
* Children products should be enabled and available in stock to be sold.
37+
* It also adds the specific flag to the collection to prevent the case
38+
* when filter already added and therefore may break the collection.
39+
*
40+
* @param Collection $collection
41+
* @return Collection
42+
*/
43+
public function process(Collection $collection)
44+
{
45+
$collection->addAttributeToFilter(
46+
ProductInterface::STATUS,
47+
Status::STATUS_ENABLED
48+
);
49+
50+
$stockFlag = 'has_stock_status_filter';
51+
if (!$collection->hasFlag($stockFlag)) {
52+
$stockStatusResource = $this->stockStatusFactory->create();
53+
$stockStatusResource->addStockDataToCollection($collection, true);
54+
$collection->setFlag($stockFlag, true);
55+
}
56+
57+
return $collection;
58+
}
59+
}

0 commit comments

Comments
 (0)