@gianis6 We have the same issue and tracked it back to the LinkedProductSelectBuilderComposite which builds a bunch of SELECT statements. Each of the linkedProductSelectBuilder objects in that class get the StockStatusBaseSelectProcessor class injected into it (module-catalog-inventory/etc/di.xml). That stock status base select processor adds the table and where clause needed to restrict products that are out of stock.
So, my solution is to remove the StockStatusBaseSelectProcessor from the CompositeBaseSelectProcessor when building the select statements.
WARNING: This code may be used by several components in Magento 2. We're still testing to see if it has any adverse effects. If you use this, please run a full UAT to make sure it doesn't break other code.
In the {Vendor}/{Module}/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Model\ResourceModel\Product\CompositeBaseSelectProcessor" type="{Vendor}\{Module}\Model\ResourceModel\Product\CompositeBaseSelectProcessor" />
</config>
In the {Vendor}/{Module}/Model/ResourceModel/Product/CompositeBaseSelectProcessor.php
namespace {Vendor}\{Module}\Model\ResourceModel\Product;
use Magento\CatalogInventory\Model\ResourceModel\Product\StockStatusBaseSelectProcessor;
class CompositeBaseSelectProcessor extends \Magento\Catalog\Model\ResourceModel\Product\CompositeBaseSelectProcessor
{
public function __construct(
array $baseSelectProcessors
) {
// REMOVE THE STOCK STATUS PROCESSOR
//...................................
$finalProcessors = array();
foreach ($baseSelectProcessors as $baseSelectProcessor) {
if(!is_a($baseSelectProcessor, StockStatusBaseSelectProcessor::class)) {
$finalProcessors[] = $baseSelectProcessor;
}
}
parent::__construct($finalProcessors);
}
}
Any other ideas on how to selectively remove the StockStatusBaseSelectProcessor only when we need to would be greatly appreciated.