Como criar um cache personalizado no Magento 2
Tags: php, tutorial, braziliandevs, magento2
Published: 2022-07-18 13:14:54

## Contextualizando

### O que é *cache*?

Um *cache* é uma camada de armazenamento físico de dados de alta velocidade que guarda um subconjunto de dados, geralmente temporário por natureza, para que futuras solicitações referentes a esses dados sejam atendidas de modo mais rápido do que é possível fazer ao acessar o local de armazenamento principal de dados. O armazenamento em *cache* permite reutilizar com eficiência dados recuperados ou computados anteriormente.

Os dados em um *cache* geralmente são armazenados no hardware de acesso rápido, como uma *Random-Access Memory* (RAM – Memória de acesso aleatório), e também podem ser usados em paralelo com um componente de software. O principal objetivo de um *cache* é aumentar a performance da recuperação de dados ao reduzir a necessidade de acessar a camada subjacente mais lenta de armazenamento.

### Quais os tipos de *cache* do Magento?

| id | Name | Descrição |
| --- | --- | --- |
| config | Configuração | O Magento coleta a configuração de todos os módulos, mescla e salva o resultado mesclado no *cache*. Esse *cache* contém configurações específicas da loja armazenadas no sistema de arquivos e no banco de dados. |
| layout | Layout | Compilados das páginas de layout, ou seja, os componentes de layout de todos os componentes. Deve limpar esse tipo de *cache* após modificar os arquivos de layout. |
| block_html | Saída do Bloco HTML | Fragmentosda página HTML por bloco. Deve limpar esse tipo de *cache* após modificar a camada de visualização. |
| collections | Dados das Coleções | Resultados de consultas de banco de dados. Deve limpar esse tipo de *cache* se o módulo personalizado usa lógica que resulta em entradas de *cache* que o Magento não pode limpar. |
| db_ddl | DDL | *Cache* para o esquema do banco de dados. Deve limpar esse tipo de *cache* depois de fazer alterações personalizadas no esquema do banco de dados. |
| compiled_config | Configurações Compiladas | Configuração de compilação. |
| eav | Valores dos Atributos das Entidades (EAV) | Metadados relacionados a atributos EAV. Normalmente, não é necessário limpar ou liberar esse tipo de *cache*. |
| full_page | *Cache* das Páginas | Páginas geradas com HTML. Deve limpar esse tipo de *cache* após modificar o nível de código que afeta a saída HTML. |
| reflection | Reflexão | Remove uma dependência entre o módulo Webapi e o módulo de Cliente. |
| translate | Traduções | *Cache* das traduções. |
| config_integration | Configurações de Integração | Deve limpar esse tipo de *cache* após alterar ou adicionar integrações. |
| config_integration_api | Configurações de Integração das APIs | Configuração de integração das APIs compiladas das Integrações da Loja. |
| config_webservice | Configurações de Web Services | Armazenando em *cache* da estrutura da API da Web. |
| customer_notification | Notificações de Clientes | Notificações temporárias que aparecem na interface do usuário. |

---

## Código para criação do *cache*

### cache.xml

Este arquivo deve estar localizado na pasta `\{Vendor}\{Module}\etc\cache.xml`. 

O nó `<type>` deve ter o atributo `id`, especificando o ID do *cache* que será criado e pode ter os atributos `tranlate` (que espera os atributos que podem ser traduzidos) e `instance` (que é a classe de modelo). Este nó também pode ter dois nós filhos, o nó `<label>` (que exibirá como o rótulo identificando o nome do *cache*) e o nó `<description>` (que exibirá a descrição sobre o *cache*).

```xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Cache/etc/cache.xsd">
    <type name="{cache_name}" translate="label,description" instance="{Vendor}\{Module}\Model\Cache\{ClassCacheName}">
        <label>{Cache Label}</label>
        <description>{Cache Description}</description>
    </type>
</config>
```

### Classe

Este arquivo deve extender do arquivo `\Magento\Framework\Cache\Frontend\Decorator\TagScope` e definir os valores das constantes `TYPE_IDENTIFIER` e `CACHE_TAG`.

A constante `TYPE_IDENTIFIER` define o identificador exclusivo de um tipo de *cache*. A constante `CACHE_TAG` define a *tag* exclusiva a ser usada no escopo do tipo de *cache*.

```php
<?php

namespace {Vendor}\{Module}\Model\Cache;

use Magento\Framework\Cache\Frontend\Decorator\TagScope;
use Magento\Framework\App\Cache\Type\FrontendPool;

class {ClassCacheName} extends TagScope
{
    public const TYPE_IDENTIFIER = '{cache_type_id}';
    public const CACHE_TAG = '{CACHE_TYPE_TAG}';

    public function __construct(
        FrontendPool $cacheFrontendPool
    ) {
        parent::__construct(
            $cacheFrontendPool->get(self::TYPE_IDENTIFIER), 
            self::CACHE_TAG
        );
    }
}
```

### Interagindo com o objeto de *Cache*

Para criar, remover, carregar ou fazer alguma outra interação com o *cache* personalizado é possível instanciando a classe (que foi indicada no atributo `instance` do arquivo `cache.xml`) e acessar os métodos herdados.

```php
<?php

namespace {Vendor}\{Module}\{Directory};

use {Vendor}\{Module}\Model\Cache\{ClassCacheName};

class {Class}
{
    public function __construct(
        private {ClassCacheName} $customCache
    ) {
    }

    public function isEnabledCache(): bool
    {
        return $this->customCache->isEnabled('{cache_id}');
    }

    public function saveCache($data)
    {
        ...
        $this->customCache->save($data, '{cache_id}');
        ...
    }

    public function loadCache()
    {
        ...
        return $this->customCache->load('{cache_id}');
    }

    public function cleanCache()
    {
        ...
        $this->customCache->clean('{cache_id}');
        ...
    }
}
```

Para saber todos os métodos possíveis, basta acessar a classe pai da classe instanciada e verificar os métodos disponíveis.

### Comandos

É possível verificar o status de cada *cache* através do seguinte comando:

```bash
bin/magento cache:status
```

Caso o *cache* esteja ativo aparecerá com o valor `1`, e caso esteja desabilitado com o valor `0`. 

O seguinte comando permite habilitar ou desabilitar todos os tipos de *caches* ou apenas um *cache* específico, se passar o ID como argumento.

```bash
# Habilitar todos os caches
bin/magento cache:enable

# Habilitar um cache específico
bin/magento cache:enable {cache_type}

# Desabilitar todos os caches
bin/magento cache:disable

# Desabilitar um cache específico
bin/magento cache:disable {cache_type}
```

Para limpar itens desatualizados do *cache* é possível apagá-los através do seguinte comando:

```bash
# Limpar todos os caches que estão em uso
bin/magento cache:clean

# Limpar um cache específico que está em uso
bin/magento cache:clean {cache_type}

# Apagar todos dos dados dos caches
bin/magento cache:flush

# Apagar todos os dados de um cache específico
bin/magento cache:flush {cache_type}
```

---

## Finalizando

> Valores entre chaves (`{test}`) devem ser alterados na implementação do código.

### Habilitando as alterações

Apague os arquivos que são gerados na compilação do Magento e execute o comando PHP para gerar a configuração das injeções de dependência e todas as classes ausentes que precisam ser geradas (proxys, interceptors, etc) e para limpar todos os *caches* de armazenamento em *cache* do processos.

```bash
rm -rf var/generation/
rm -rf generated/
php bin/magento setup:di:compile
php bin/magento cache:clean
php bin/magento flush
```

### Diretórios e Arquivos

Segue a a lista de diretórios e arquivos que devem ser criados.

```
- app/
  - code/
    - {Vendor}/
        - {Module}/
          - etc/
            - cache.xml
            - module.xml
          - Model/
              - Cache/
	              - {ClassCacheName}.php
          - registration.php
          - composer.json
```