Jump to content

Welcome, Guest!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

  • 0
braffas

PageCache bug (and solution)

Question

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);
    }
}

Share this post


Link to post
Share on other sites

2 answers to this question

Recommended Posts

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...