-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Magento 2.1.3 out of stock associated products to configurable are not full page cache cleaned #8009
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Even if the configurable product id is sent to be cleaned from cache type full_page, there are additional things to do. 'block_html' and 'collections' cache types must be cleaned too by the cache tag of the configurable product's id. The id of the configurable product is added in many cached blocks tags/identities. |
@daniel-ifrim Thanks for reporting this issue. |
It seems we have this issue because we are using Amasty Stock Alert module, I'm not certain. |
Isn't this issue fixed on 2.1.4? Related issue for bundle products #10236. |
Disregard my last comment, the issue isn't fixed if the Stock\Item of a product is updated. I think Magento should consider implementing an Workaround: <type name="Magento\CatalogInventory\Model\Indexer\Stock">
<plugin sortOrder="1" name="hoKingdoStock" type="Ho\Kingdo\Plugin\ProductCacheTagStrategy"/>
</type> <?php
/**
* Copyright © 2017 H&O E-commerce specialisten B.V. (http://www.h-o.nl/)
* See LICENSE.txt for license details.
*/
namespace Ho\Kingdo\Plugin;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Indexer\CacheContext;
class ProductCacheTagStrategy
{
/**
* @var \Magento\Bundle\Model\ResourceModel\Selection
*/
private $selection;
/**
* @var MetadataPool
*/
private $metadataPool;
/**
* @var CacheContext
*/
private $cacheContext;
/**
* @var \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable
*/
private $configurableType;
/**
* BundleProductCacheTagStrategy constructor.
*
* @param \Magento\Bundle\Model\ResourceModel\Selection $selection
* @param CacheContext $cacheContext
* @param \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $configurableType
* @param MetadataPool $metadataPool
*/
public function __construct(
\Magento\Bundle\Model\ResourceModel\Selection $selection,
\Magento\Framework\Indexer\CacheContext $cacheContext,
\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $configurableType,
MetadataPool $metadataPool
) {
$this->selection = $selection;
$this->metadataPool = $metadataPool;
$this->cacheContext = $cacheContext;
$this->configurableType = $configurableType;
}
/**
* Retrieve array of related bundle product ids by selection product id(s)
*
* @see \Magento\Bundle\Model\ResourceModel\Selection::getParentIdsByChild(), that method seems to be broken.
* @param int|array $childId
* @return array
*/
public function getBundleParentIdsByChild($childId)
{
$connection = $this->selection->getConnection();
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
$select = $connection->select()->distinct(
true
)->from(
$this->selection->getMainTable(),
''
)->join(
['e' => $this->metadataPool->getMetadata(ProductInterface::class)->getEntityTable()],
'e.' . $metadata->getLinkField() . ' = ' . $this->selection->getMainTable() . '.parent_product_id',
['e.entity_id as parent_product_id']
)->where(
$this->selection->getMainTable().'.product_id IN(?)',
$childId
);
return $connection->fetchCol($select);
}
/**
* @param $ids
* @return \string[]
*/
private function getConfigurableParentIdsByChild($ids)
{
return $this->configurableType->getParentIdsByChild($ids);
}
/**
* Also Register the parent of the stock item after it has been reindexed.
*
* @param \Magento\CatalogInventory\Model\Indexer\Stock $subject
* @param $ids
*/
public function beforeExecute(\Magento\CatalogInventory\Model\Indexer\Stock $subject, $ids)
{
$parentIds = array_merge($this->getBundleParentIdsByChild($ids), $this->getConfigurableParentIdsByChild($ids));
$this->cacheContext->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $parentIds);
}
} |
Flush full page cache for all products that have been reindexed. Not only the child products, but also parent products. This is already the case in 2.2-develop.
Hi @daniel-ifrim |
…ot full page cache cleaned #8009 - Clear cache for parent product when simple product becomes out of stock.
…ot full page cache cleaned #8009 - Fix tests.
MAGETWO-64282 Out of stock associated products to configurable are not full page cache cleaned #8009 MAGETWO-91532 Schedule update removes tier price MAGETWO-91547 Unable to create Credit memo for order with no payment required MAGETWO-91753 Results of filters with color and other filters are not showing product results MAGETWO-67779 Datetime attribute break fulltextsearch in case of Elasticseach MAGETWO-91495 'Invalid data provided for linked products' error on 'Save & Duplicate' product action MAGETWO-91723 Text Attribute doesn't display all character on product page MAGETWO-91553 Admin user with role scope set to custom is unable to view abandoned carts report MAGETWO-91614 [B2B] Cannot filter customers by status MAGETWO-69021 salesOrderRepositoryV1 API Missing Extension Attributes
…ot full page cache cleaned #8009
…ot full page cache cleaned #8009
In Magento 2.1.3 strictly:
When a associated product goes out of stock the product page of the configurable product is not updated. The cache (full page cache type) is not cleaned, especially when indexer mode is set to 'Update by Schedule'/MView is enabled.
This issue is introduced into Magento 2.1.3 because
Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
sends to 'CacheContext' the product ids of the simple associated product.
In Magento 2.1.2 the blocks of configurable product page had identities (cache identities, function getIdentities()) containing ids of simple associated products too. But in Magento 2.1.3 these ids are no longer included in these identities. Only the parent configurable product ids are in identities.
On short, the configurable product page is not cache cleaned. Same behavior for categories pages that this product is assigned to.
Preconditions
Set indexer mode to 'Update by Schedule' / Mview enabled
Have all cache types enabled in admin (including full page cache). I used in this test 'built-in full page cache'. The issue should happen when using Varnish too.
Steps to reproduce
I use a simple product associated of configurable product SKU 'WT09' in Magento 2.1.3 with sample.
This configurable product has swatches but the issue is the same to configurable products without swatches.
With swatches you can actually visually see when an option is not available (product is out of stock).
Please note that by doing this you also load the configurable product page to full page cache.
Loading before checkout the configurable product page into full page cache type is important to demonstrate this issue.
Why after 1-3 minutes: to give time to Magento cron to run the cron task:
Expected result
The configurable product page should have it's options updated visually. More exactly, the associated simple product unique combinations of options should be marked as 'out of stock'. In the case of sku 'WT09', we should see the 'disabled' swatch for that associated simple product.
If you clean cache from console you'll see the expected result. Cleaning cache from console after each purchase is not a solution.
Actual result
In
Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
there is:Magento\PageCache\Observer\FlushCacheByTags
never gets a configurable product id (in the case - checkout with a product).The categories pages are not cache cleaned too. Same thing, categories pages blocks contain in identities only configurable products ids (no associated product ids).
A possible solution:
In
Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
add to $productIds the configurable product ids just before the line:$this->cacheContext->registerEntities(Product::CACHE_TAG, $productIds);
Actually there is the variable '$processIds' that already contain the parents ids beside initial $productIds.
What happens specifically with Mview enabled, see bellow.
When a product is purchased and goes out of stock after checkout, in
cataloginventory_stock_cl
there are 2 rows inserted because of the quantity subtraction that happens here:\Magento\CatalogInventory\Observer\SubtractQuoteInventoryObserver
and\Magento\CatalogInventory\Observer\ReindexQuoteInventoryObserver
Those 2 rows contain only the simple associated product id. That's fine, only that 'CacheContext' should be 'forced' to get the configurable product id too.
I haven't tested yet but with 'Update on Save'/ Mview disabled,
$productIds
inMagento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
contain the configurable product ids because there is in\Magento\CatalogInventory\Observer\ReindexQuoteInventoryObserver
:Without testing when Mview is disabled, I would say with inder mode 'Update on save', the issue is not there.
The text was updated successfully, but these errors were encountered: