PageCache bug (and solution)



  • Categories are not removed from the cache (Redis etc) when invalidated, because the cache keys are deleted before they are collected. See fix below.

    /**
     * Invalidate an entity from the cache
     *
     * @param string   $entityType
     * @param int|null $idEntity
     *
     * @since 1.0.0
     */
    public static function invalidateEntity($entityType, $idEntity = null)
    {
        $keysToInvalidate = [];
    
        if ($entityType === 'product') {
            // Refresh the homepage
            $keysToInvalidate = array_merge(
                $keysToInvalidate,
                static::getKeysToInvalidate('index')
            );
    
            Db::getInstance()->delete(
                'page_cache',
                '`entity_type` = \'index\''
            );
            if ($idEntity) {
                // Invalidate product's categories only
                $product = new Product((int) $idEntity);
                if ($product) {
                    $categories = $product->getCategories();
                    foreach ($categories as $idCategory) {
    
                        //Edit by Kasper: Moved to the top in the loop to collect the keys before they are deleted.
                        $keysToInvalidate = array_merge(
                            $keysToInvalidate,
                            static::getKeysToInvalidate('category', $idCategory)
                        );
    
                       //Edit by Kasper: Moved to the bottom of the loop so we can delete the keys after they are collected.
                        Db::getInstance()->delete(
                            'page_cache',
                            '`entity_type` = \'category\' AND `id_entity` = '.(int) $idCategory
                        );
    
                    }
                }
            } else {
                // Invalidate all parent categories
                Db::getInstance()->delete(
                    'page_cache',
                    '`entity_type` = \'category\''
                );
                $keysToInvalidate = array_merge(
                    $keysToInvalidate,
                    static::getKeysToInvalidate('category')
                );
            }
        }
    
        $keysToInvalidate = array_merge(
            $keysToInvalidate,
            static::getKeysToInvalidate($entityType, $idEntity)
        );
        Db::getInstance()->delete(
            'page_cache',
            '`entity_type` = \''.pSQL($entityType).'\''.($idEntity ? ' AND `id_entity` = '.(int) $idEntity : '')
        );
    
        $cache = Cache::getInstance();
        foreach ($keysToInvalidate as $item) {
            $cache->delete($item);
        }
    }

  • administrators



  • Yes, perfect.


  • administrators

    Nice. Thanks for letting us know.



  • Good job, @braffas


Log in to reply
 

Looks like your connection to thirty bees forum was lost, please wait while we try to reconnect.