Magento, Magento 2

Custom Cache Type

Custom Cache Type

Hello Everyone, Welcome to my blog. First of all for those people who don’t know anything about me please check out this link for more information. 

If you want to connect with me or want to discuss any specific topic, want to share your view or anything, please feel free to write a comment below or write me an email on my email id i.e. admin@asolutions.co.in  I will definitely try to address all your queries.

Today, I am going to discuss how to create a custom cache type and how to utilize it in our extensions. This code is based on partial caching. So let’s get started 

Following are the steps that we are going to follow to create our custom cache type

  1. Create cache.xml
  2. Create a Model Class
  3. Create Storage Class
  4. Change Constructor Parameter
  5. Create Block Class to Read Data From Cache

Create cache.xml

To create our custom cache type, we need to create a cache.xml file inside the Namespace\Modulename\etc\cache.xml. Once you have created a cache.xml file add the following content in that file.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="urn:magento:framework:Cache/etc/cache.xsd">
	<type name="mymodule_custom_cache" translate="label,description"
		instance="MyFirstModule\Mymodule\Model\CacheType">
		<label>My Module Cache Type Label</label>
		<description>My Module Cache Type Description</description>
	</type>
</config>

The cache.xml file has the following attribute.

  1. name: It’s a required attribute and we need to define our unique cache id here.
  2. translate: Parameters that will be translated on the “Cache Management” page.
  3. Instance: Our class name which is used to define our cache tad and cache id.

In the cache.xml file, we need to pass two parameters i.e. “label” and the “description”. These parameters use to display label and the cache description on cache management page i.e. System > Tools > Cache Management

Create Model Class

Create a model class in Namespace\Modulename\Model\CacheType.php Here I have used MyFirstModule as Namespace and MyModule as a module name. Add the following content to the file.

<?php
namespace MyFirstModule\Mymodule\Model;

/**
 * Used classed
 */
use Magento\Framework\App\Cache\Type\FrontendPool;
use Magento\Framework\Cache\Frontend\Decorator\TagScope;

/**
 * Cache Type class
 * @author Ashish
 *        
 */
class CacheType extends TagScope
{

    /**
     * Cache type code unique among all cache types
     */
    const TYPE_IDENTIFIER = 'mymodule_custom_cache';

    /**
     * The tag name that limits the cache cleaning scope within a particular tag
     */
    const CACHE_TAG = 'MYMODULE_CUSTOM_CACHE';

    /**
     * Construct
     *
     * @param FrontendPool $frontend
     */
    public function __construct(FrontendPool $frontend)
    {
        parent::__construct($frontend->get(self::TYPE_IDENTIFIER), self::CACHE_TAG);
    }
}

We must specify the following parameters:

  • MyFirstModule\MyModule defines the name of a module that uses a cache type. A module can use several cache types and a cache type can be used in several modules.
  • const TYPE_IDENTIFIER = ‘mymodule_custom_cache’ defines the unique identifier of a cache type.
  • const CACHE_TAG = ‘MYMODULE_CUSTOM_CACHE’  defines the unique tag to be used in the cache type scoping.

One we have created the model class, flush the Magento cache using the following command, and, enable our new cache type.

php bin\magento cache:enable
php bin\magento cache:flush

After Navigate to Magento Admin >System >Tool >Cache Management and you will be able to see your cache type there 

Now, we are moving towards how to utilize this cache in our code. For that purpose, we need to create a storage manager class in our module, which will help us to load, save, and check our cache tag. Let’s create a storage management class inside MyFirstModule\MyModule\Model\ directory i.e. MyFirstModule\MyModule\Model\MymoduleStorage.php 

<?php
namespace MyFirstModule\Mymodule\Model;

use Magento\Framework\App\ObjectManager;
use Magento\Framework\Cache\FrontendInterface;
use Magento\Framework\Serialize\SerializerInterface;

class MymoduleStorage
{

    /**
     * Cache id
     *
     * @var string
     */
    const CACHE_ID = 'mymodule_custom_cache';

    /**
     * Cache tag
     *
     * @var string
     */
    const CACHE_TAG = 'data';

    /**
     *
     * @var FrontendInterface
     */
    private $cache;

    /**
     *
     * @var SerializerInterface
     */
    private $serializer;

    /**
     * Constructor.
     *
     * @param FrontendInterface $cache
     * @param SerializerInterface $serializer
     */
    public function __construct(FrontendInterface $cache, SerializerInterface $serializer = null)
    {
        $this->cache = $cache;
        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
    }

    /**
     * Save cache value
     *
     * @param string $cacheId
     * @param string $data
     */
    public function add($cacheId, $data)
    {
        $serializedData = $this->serializer->serialize($data);
        $this->cache->save($serializedData, self::CACHE_TAG, [
            self::CACHE_ID
        ]);
    }

    /**
     * Check whether cache exist
     *
     * @param string $cacheId
     * @param string $data
     * @return number|boolean
     */
    public function isExists($cacheId)
    {
        return $this->cache->test($cacheId);
    }

    /**
     * Remove cache
     *
     * @param string $cacheId
     * @param string $data
     */
    public function remove($cacheId, $data)
    {
        $this->cache->remove($this->getCacheKey($cacheId, $data));
    }

    /**
     * Get Cache key
     *
     * @param string $cacheId
     * @param string $data
     * @return string
     */
    private function getCacheKey($cacheId, $data)
    {
        return 'mymodule_cache_type_' . $cacheId . '_' . $data;
    }

    /**
     * Load data from cache
     *
     * @param string $cacheId
     * @param string $data
     * @return string
     */
    public function load($cacheId)
    {
        return $this->cache->load($cacheId);
    }
}

Here I have defined the functions like

  1. add() to save our cache data into the Magento system
  2. isExists() used to check where the cache tag is present or not.
  3. remove() used to remove the cache tag from the cache.
  4. getCacheKey() a unique key identified for our cache data.
  5. load() used to load the data from the cache.

After that, we need to change the cache parameter used in the above class constructor using di.xml. Used the following code for that.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
	<type name="MyFirstModule\Mymodule\Model\MymoduleStorage">
		<arguments>
			<argument name="cache" xsi:type="object">MyFirstModule\Mymodule\Model\CacheType
			</argument>
		</arguments>
	</type>
</config>

Now its to save some data into our cache type :). I have created a block file that is used to save our dynamic/static data into the cache. The following code will help to do that.

<?php

/**
 * Module namespace
 */
namespace MyFirstModule\Mymodule\Block;

use Magento\Framework\View\Element\Template\Context;
use Magento\Framework\View\Element\Template;
use MyFirstModule\Mymodule\Model\MymoduleStorage;

/**
 * Index block
 *
 * @author Ashish
 *        
 */
class Index extends Template
{

    /**
     * My Cache storage class
     *
     * @var mixed
     */
    private $_mymoduleStorage;

    /**
     * Construct
     *
     * @param Context $context
     * @param MymoduleStorage $mymoduleStorage
     */
    public function __construct(Context $context, MymoduleStorage $mymoduleStorage)
    {
        $this->_mymoduleStorage = $mymoduleStorage;
        parent::__construct($context);
    }

    /**
     * Sample function
     */
    public function getMyName()
    {
        if ($this->getMyModuleStorage()->isExists(MymoduleStorage::CACHE_TAG)) {
            return $this->getMyModuleStorage()->load(MymoduleStorage::CACHE_TAG);
        } else {
            $name = 'Welcome To ASolutions!';
            $this->setMyName($name);
            return $this->getMyModuleStorage()->load(MymoduleStorage::CACHE_TAG);
        }
    }

    /**
     * Set Value for Cache
     */
    public function setMyName($name)
    {
        $this->getMyModuleStorage()->add(MymoduleStorage::CACHE_ID, $name);
    }

    /**
     * Get Storage Class
     *
     * @return mixed|\MyFirstModule\Mymodule\Model\MymoduleStorage
     */
    private function getMyModuleStorage()
    {
        return $this->_mymoduleStorage;
    }
}

Here, I have used getMyName() function to validate the cache and save the value if not present. 

When we enable cache type and test the output in terms of response, you will notice a high performance in response time. We all know that the page load time helps to improve the conversion rate. With the help of this blog you are able to improve the page load time and improve the sale of the website.

In the next blog, we will see how we can save the cache into the database and will learn more about the Full page cache.  You can download this code from here.

Feel free to leave a comment below. Let me know what you think about this blog. Good bye for now and happy coding 🙂

[post-views]

Tagged ,

Leave a Reply

Your email address will not be published. Required fields are marked *