Como criar um indexador (indexer) personalizado no Magento 2
Tags: php, braziliandevs, magento2, tutorial
Published: 2022-11-28 12:34:05

## Contextualizando

### O que é indíce (index)?

Índice é um recurso que o servidores de SQL disponibiliza afim de ordenar dados em uma determinada sequência, afim de retornar os resultados de maneira mais eficiente, ou seja, os índices são empregados em uma consulta para ajudar a encontrar registros com um valor específico em uma coluna de forma rápida, para aumentar o desempenho na execução de consultas.

Os índices fazem a representação dos dados originais para leitura e busca otimizadas, e também, podem conter resultados de agregações e vários cálculos. Os dados de índice sempre podem ser recriados a partir de um dicionário usando um determinado algoritmo.

### O que é a indexação?

A indexação é como o Magento transforma dados (como produtos e categorias) para melhorar o desempenho da vitrine da loja. À medida que os dados mudam, os dados transformados devem ser atualizados ou reindexados.

---

## Código para criação do indexador

### indexer.xml

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

```xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd">
    <indexer id="{index_id}" view_id="{view_id}" class="{Vendor}\{Class}\Model\Indexer\{IndexerClassName}">
        <title translate="true">{Indexer Title}</title>
        <description translate="true">{Indexer Description}</description>

        <fieldset name="{fieldset_id}"
                  source="{Vendor}\{Class}\Model\ResourceModel\Design\Config\Scope\Collection"
                  provider="{Vendor}\{Class}\Model\Indexer\Design\Config\FieldsProvider">
            <field name="{field_id}" xsi:type="filterable" dataType="int"/>
        </fieldset>
        <saveHandler class="{Vendor}\{Class}\Indexer\SaveHandler\{GridName}"/>
        <structure class="{Vendor}\{Class}\Indexer\{GridStructureName}"/>
    </indexer>
</config>
```

#### Atributos do indexer

| Atributo | Descrição | Obrigatório |
| --- | --- | --- |
| id | ID único do índice. | Sim |
| class | A classe que processa os métodos do indexador (executeFull, executeList, executeRow). | Não |
| primary | O provedor de código. | Não |
| shared_index | Use esta opção para melhorar o desempenho se seu indexador estiver relacionado a outro indexador. | Não |
| view_id | O ID do elemento de visualização definido no arquivo de configuração mview.xml. | Não |

#### Nós filhos do indexer

O nó `<indexer>` pode alguns nós filhos, o nó `<title>` (que exibirá como o título do indexador) e o nó `<description>` (que exibirá a descrição do indexador).

| Nó | Descrição |
| --- | --- |
| title | O título a ser exibido na página de indexadores. |
| description | A descrição a ser exibida na página de indexadores. |
| fieldset | Descreve os campos, a origem e o provedor de dados da tabela de índices simples. |
| saveHandler | Um ponto de extensão. A classe para processar (excluir, salvar, atualizar) itens ao indexar. |
| structure | A classe que processa (cria, remove) tabelas de índice simples. |

### Classe Indexer

Está classe deve implementar as interfaces `\Magento\Framework\Indexer\ActionInterface` e `\Magento\Framework\Mview\ActionInterface`, onde será necessário a implementação de quatro métodos com as seguintes descrições

- `executeFull()`: este método realiza a reindexação completa, ou seja, realiza um processamento de todas as entidades de um dicionário específico. Este método também é o realizado quando for executado pela linha de comando;
- `executeList(array $ids)`: este método realiza a reindexação de lista, ou seja, realiza o processamento de um conjunto de entradas de dicionário, onde `$ids` é um array dos IDs das entidades;
- `executeRow($id)`: este método realiza a reindexação de linhas, ou seja, realiza o processamento de uma única entrada de um dicionário e funciona em tempo de execução para uma única entidade usando plugins;
- `execute($ids)`: este método realiza a reindexação de processos no modo “Atualização de Agendamento” pelo arquivo `mview.xml`.

```php
<?php

namespace {Vendor}\{Class}\Model\Indexer;

class {IndexerClassName} implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
{
    public function execute($ids)
    {
        //code here!
    }

    public function executeFull()
    {
        //code here!
    }
   
    public function executeList(array $ids)
    {
        //code here!
    }

    public function executeRow($id)
    {
        //code here!
    }
}
```

### mview.xml

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

```xml
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Mview/etc/mview.xsd">
    <view id="{view_id}" class="{Vendor}\{Class}\Model\Indexer\{IndexerClassName}" group="indexer">
        <subscriptions>
            <table name="{table_name}" entity_column="{entity_id}" />
        </subscriptions>
    </view>
</config>
```

#### Atributos do mview

| Nós | Descrição | Obrigatório |
| --- | --- | --- |
| id | O ID do elemento de visualização. | Sim |
| class | A classe que processa o método do indexador (execute). | Sim |
| group | Lista de opções do widget. | Sim |

O nó `<view>` só possui apenas um tipo de nó filho, o nó `<subscriptions>`, este nó não possui atributos e possui também apenas um tipo de nó como filho, o nó `<table>`. O nó `<table>` não possui nenhum nó filho e possui dois atributos: o atributo `name` é responsável por identificar o nome da tabela que será indexada e o atributo `entity_column` é o atributo responsável por identificar a coluna de identificador único primário desta tabela.

### Comandos

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

```bash
bin/magento indexer:status {index_id}
```

É possível utilizar o seguinte comando para reindexar todos os indexadores ou indexadores específicos.

```bash
# Reindexar um indexador específico
bin/magento indexer:reindex {index_id}

# Reindexar todos os indexadores
bin/magento indexer:reindex
```

É possível especificar a configuração do indexador com o seguinte comando:

```bash
bin/magento indexer:set-mode {realtime|schedule} {index_id}
```

- `realtime`: Define os indexadores selecionados para atualização ao salvar;
- `schedule`: Define os indexadores especificados a serem salvos de acordo com o cronograma do cron.

---

## 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/
            - indexer.xml
            - mview.xml
            - module.xml
          - Model/
              - Indexer/
	              - {ClassIndexerName}.php
          - registration.php
          - composer.json
```