Setting the value of 'Display Out of Stock Products' in the backend to 'No' does not have the effect desired. If you set this to 'No' you would expect that only products that are in stock are shown.
We traced this issue back to Magento\CatalogInventory\Helper\Stock.
In the function addIsInStockFilterToCollection a flag check is done on 'require_stock_items'. Because this flag is never set or used in Magento (wtf!), it causes the second parameter in addStockDataToCollection to always be false. This has the undesired effect that out of stock products are shown...
public function addIsInStockFilterToCollection($collection)
{
$stockFlag = 'has_stock_status_filter';
if (!$collection->hasFlag($stockFlag)) {
$isShowOutOfStock = $this->scopeConfig->getValue(
\Magento\CatalogInventory\Model\Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
$resource = $this->getStockStatusResource();
$resource->addStockDataToCollection(
$collection,
!$isShowOutOfStock && $collection->getFlag('require_stock_items')
);
$collection->setFlag($stockFlag, true);
}
}
It is our opinion that the '&& $collection->getFlag('require_stock_items')' should be removed as it is never set or referenced in the entire Magento project. Removing this part also fixes the fact the out-of-stock products are shown
git blame shows it was introduced in https://github.com/magento/magento2/commit/c966dc171b2a18cea3ff36ad545d8810441d3a83 and this flag probably exists in another edition only (thus should be treated as always true here).
I can verify this is still a problem, it should properly just change && to ||.
I created a PR that seems to fix this for me: https://github.com/magento/magento2/pull/8736
I don't think the value should be changed to an 'or' because the flag that's being referenced does not exist in the CE edition. Like @orlangur said, it would be better to replace the flag value with true or just remove it all together ?
The fix we are currently using which works, is:
public function addIsInStockFilterToCollection($collection)
{
$stockFlag = 'has_stock_status_filter';
if (!$collection->hasFlag($stockFlag)) {
$isShowOutOfStock = $this->scopeConfig->getValue(
\Magento\CatalogInventory\Model\Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
$resource = $this->getStockStatusResource();
$resource->addStockDataToCollection(
$collection,
!$isShowOutOfStock
);
$collection->setFlag($stockFlag, true);
}
}
@koenner01 No but I think the flag is valuable in some use cases, where you would want to limit what your collection contains to products in store, and this is then an easy way.
But is it not weird and confusing to leave a flag in the code that isn't referenced anywhere in the entire CE ?
No I don't think so. Their are lots of things in CE not used anywhere the easiest thing I could think of would be lots of the events fired in Magento (I know this isn't an event).
Also if EE or ECE base code starts being different from the CE project it will be super confusing for extension providers / SI's.
Doesn't it make more sense then that we should set the flag value to true if its value is non existent ?
That way the flag is still being referenced (and open for use in other classes) but still doesn't block the stockFilter function.
@koenner01, dunno what's the reasoning behind PR acceptance (just a quick-fix as a temporary solution?).
I believe https://github.com/magento/magento2/commit/c966dc171b2a18cea3ff36ad545d8810441d3a83 is simply wrong from modularity perspective and should be done as plugin/interceptor or any other way of extending CE behavior NOT residing in CE repository but in another one where all operations with this flag occur.
I think @koenner01 is true : If the flag is NULL then it means that it has not been set before. Then I think the best way is to add a default value to true.
Hello,
@Corefix, @koenner01 have You guys tested the fix on 2.1.6, 2.1.7? With this fix I've got 500 error on Cart when some simple product of configurable is in Quote and on that moment is out of stock.
PHP Fatal error: Uncaught Error: Call to a member function getPrice() on null in ../vendor/magento/module-configurable-product/Model/Product/Type/Configurable/Price.php:43\nStack trace:\n#0 ../vendor/magento/module-catalog/Model/Product.php(554)
@aholovan: https://github.com/magento/magento2/issues/5519#issuecomment-282315348
@koenner01 We cannot reproduce this issue as described. Please provide the detailed steps we must follow to reproduce this issue. In addition, identify the web server you are running, the versions of PHP and MySQL, and any other information needed to reproduce your issue.
According to contributor guide, tickets without response for two weeks should be closed.
If this issue still reproducible please feel free to create the new one: format new issue according to the Issue reporting guidelines: with steps to reproduce, actual result and expected result and specify Magento version.
Internal ticket to track issue progress: MAGETWO-65334