Escrevo este posts emocionado, com uma ligeira lágrima escorrendo no rosto rsrs… Finalmente estou disponibilizando a versão do meu plugin Filter Results para CakePHP 2 já com o operador BETWEEN e tudo mais. =D

Filter Results

Basicamente, com o Filter Results para CakePHP 2 você poderá fazer formulários de pesquisa da maneira que você desejar, de forma rápida e padronizada para toda a sua aplicação.

Compatibilidade

IMPORTANTE

Na versão 2.3 do plugin houve uma mudança na arquitetura das funções e nome de arquivos. Se estiver encontrando este problema, baixe a versão 2.0 e continue lendo este artigo ou utilize o tutorial da versão 2.3 clicando aqui.

Instalação

Download

Antes de iniciar, baixe o Filter Results. Copie os arquivos para a pasta /app/Plugin/filter_results ou em outro diretório para plugins do CakePHP.

Se preferir, utilize o git:
git clone -b 2.0 https://github.com/pedroelsner/filter_results.git FilterResults

Ativação

Ative o plugin adicionando ao arquivo /app/Config/bootstrap.php:

Configurações

Vamos adicionar nas variáveis $components e $helpers no AppController.php:

Parâmetros de configuração:

  • auto->paginate Se você definir como TRUE, o Paginate será configurado automaticamente.
  • auto->explode Se você definir como TRUE, o valor de pesquisa será quebrado pelo explode->character e concatenado pela condição explode->concatenate.

Ajuste no DebugKit

Se você estiver utilizando o DebugKit, configure-o desta forma em seu AppController.php:

'DebugKit.Toolbar' => array('panels' => array('history' => false));

Antes de tudo

Para este e os próximos exemplos, vamos ter como base o seguinte banco de dados:

Beleza? Então vamos começar!

Filtro Simples

Bom, após gerar as telas pelo Bake, criamos a seguinte action em nosso Controller:

Arquivo /app/Controller/UsersController.php

Vamos então colocar um filtro sobre a grid(tabela) para pesquisar um usuário pelo nome(name) e configurar o Paginate da action.

Arquivo /app/Controller/UsersController.php

A configuração aqui é bem simples: Criamos um filtro chamado filter1 que utilizará o campo User.name. Este filtro utiliza o operador LIKE e adiciona % antes e depois do conteudo a ser filtrado.

Agora temos apenas que fazer o formulário na View em cima da tabela.

Arquivo /app/View/Users/index.ctp

Pronto! Temos um campo que filtra o usuário pelo nome e compatível com o Paginate. ^^

E mais, o Filter Results automaticamente divide o valor de pesquisa para obter um melhor resultado. Por exemplo: se realizarmos um filtro por ‘Pedro Elsner’, a condição será: WHERE ((User.name LIKE '%Pedro%') AND (User.name LIKE '%Elsner%')).

Explode

A opção explode para os operadores LIKE e NOT LIKE estão ativadas por padrão nas configurações do Filter Results. Mas, como você sabe, você pode desativar na declaração dos components no controller. Se você fizer isto, você pode ativar a função explode para um filtro determinado:

Também é possível mudar as opções de quebra para cada um.

Além disso, você também pode usar a função de quebra junto com outro operador (como =). Veja:

Filtro Simples + Regra Composta

Vamos agora fazer mais uma regra dentro do filtro filter1. Queremos que ele filtre pelo nome(name) ou pelo nome do usuário(username).

Alteramos então apenas o nosso Controller:

Arquivo /app/Controller/UsersController.php

A regra OR pode ser também AND ou NOT.

NOTA: Se você definir mais de uma condição sem especificar a regra, o plugin entenderá como AND automaticamente.

Filtro Simples + Regra Fixa

Vamos supor agora que o nosso filtro filter1 quando informado deva filtrar pelo nome(name) E somente usuários(username) ativos.

Arquivo /app/Controller/UsersController.php

Agregação de Filtros

Automaticamente o Filter Results concatena todos os filtros pela regra AND. Usando o exemplo a seguir, informando ‘Pedro’ no filter1 e ‘elsner’ no filter2 teremos a condição: WHERE (User.name LIKE '%Pedro%') AND (User.usernname LIKE '%elsner%')

NOTA: Podemos concatenar os filtros também pelas regras OR ou NOT.

Vamos alterar nosso exemplo para concatenar os filtros pela regra OR, e, se o filtro1 for informado queremos apenas usuários ativos. Desta vamos obter a condição: WHERE ((User.name LIKE '%Pedro%') AND (User.active = 1)) OR (User.usernname LIKE '%elsner%')

Filtro de Seleção

Vamos mudar nosso filtro. Além de filtrar pelo nome, queremos agora filtrar também pelo grupo do usuário(Group.name) desejado através de um campo de seleção.

Arquivo /app/Controller/UsersController.php

Arquivo /app/View/Users/index.ctp

Pronto! Use e abuse de quantos filtros desejar.

Para deixar bem claro, veja a imagem abaixo. Nela temos a View de Produtos, onde é possível filtrar por: Cor, Dimensão, Gramatura, Material e Nome.

Filtro Avançado

Em alguns casos queremos algo diferente diferente, por exemplo, desejamos que o usuário possa escolher o campo e o operador para realizar o filtro.

Arquivo /app/Controller/UsersController.php

NOTA: Perceba que desta vez criamos o filtro filter1 sem nenhum parâmetro. Isto porque as regras serão selecionadas na View.

Arquivo /app/View/Users/index.ctp

Agora, primeiro você pode selecionar o campo (automaticamente o Filter Results lista os campos da tabela), depois o operador e informar o valor desejado para o filtro.

Haverá situações em que você precisará personalizar os operadores para seleção. Por exemplo, vamos deixar somente os campos User.id, User.name e User.username para seleção, e os operadores LIKE e =.

Para isso, mudamos somente a View:

Arquivo /app/View/Users/index.ctp

Operadores

O Filter Resultes possuí operadores pré-definidos, abaixo você encontra todas as opções disponíveis para você utilizar em seus filtros personalizados.

BETWEEN

Também é possível utilizar o operador BETWEEN para consulta entre valores numéricos ou de data. Configure o campo de filtro desta forma:

Para campos de data, adicione a opção 'date' => true para converte a data informada para o formato YYYY-MM-DD:

Relacionamentos HABTM

Por padrão, nos relacionamentos HABTM o CakePHP realiza várias consultas a parte e depois faz um merge nos resultados em um único array. Você já deve ter percebido isso, mas se não, verifique a janela de debug enquanto você faz find() em uma relação HABTM.

Para filtramos nessas relações, precisamos criar alguns “hacks” para que o CakePHP gere um único select, assim o plugin filtra o resultado com comandos where simples.

Todas as informações e explicações necessárias para criar os “hacks” você encontra neste tutorial: Pesquisando em relações HABTM no CakePHP

Agradecimentos

Deixo aqui registrado meu muito obrigado para todos os colegas que de alguma forma contribuíram para o desenvolvimento deste plugin.

Em especial para:

Quer copiar esse post no seu site? Você pode!

Segundo a licença da Creative Commons 3.0 (CC BY SA 3.0) você pode copiar e distribuir esse conteúdo desde que faça menção ao autor original, para isso é só copiar esse código no final do artigo quando for publicá-lo em seu site:

<p>Artigo originalmente publicado em <em>24 de junho de 2012</em> por <strong><a href="http://pedroelsner.com/" title="Pedro Elsner, Profissional de TI - São Paulo">Pedro Elsner</a></strong>: <a href="http://pedroelsner.com/2012/06/plugin-filter-results-para-cakephp-2-x/" title="Utilizando Filter Results 2.0 no CakePHP 2.0">Utilizando Filter Results 2.0 no CakePHP 2.0</a></p>
A não menção ao autor original da obra implicará em cópia e/ou distribuição ilegal de propriedade intelectual, o que é crime segundo a Lei n.º 9.610.
  • Adriano Gobbo

    Pedro, vou continuar aqui a te encher a paciência… eu voltei a mexer no meu projeto e instalei bonitinho o seu plugin.
    1 – Não consegui usar conditions… coloquei no getConditions() e nada, fiz um setConditions e nada… coloquei no $this->paginate e o filtro parou de funcionar… como que eu coloco conditions então?
    2 – Colocando o order no setPaginate, desaparece a setinha indicadora do pagination para dizer qual coluna está em ordenação e qual o sentido da ordenação… será que não consegue voltar com isso?

    Valeu!!

  • Francys
  • Adriano Gobbo

    acho que ele está de férias pois não respondeu minha pergunta nem por aqui e nem por twiter nem nada…

  • João Oliveira

    Pedro,

    Estou iniciando…então me desculpe de fizer pergunta besta. rs

    Fiz o Download do componente e segui os passos conforme o tutorial.

    Mas deu alguns erros e precisei mudar o nome de uns arquivos e classes, segue:

    Precisei alterar o nome do arquivo .php para FilterResultsComponent.php
    Precisei alterar o nome da classe FilterComponent para FilterResultsComponent

    pois ele pedia um arquivo com esse nome e uma classe com esse nome.

    Depois deu erro no nome do helper ai tive que mudar para:

    var $helpers = array(
    ‘FilterResults.Search’
    );

    Pois notei que o nome do arquivo tinha mudado.

    Por último tive que alterar o nome na view:

    Search->create();?>
    Search->input(‘filter1’);?>
    Search->end(__(‘Filtrar’, true));?>

    Ai passou. Apareceu o input e consegui fazer o filtro.

    Porque será eu tive que alterar isso tudo? Fiz algo errado?

  • Isso aconteceu porque este tutorial é para a versão 2.0 do plugin e você baixou a versão 2.3.

    Versão 1.3: https://github.com/pedroelsner/filter_results/tree/1.3
    Versão 2.0: https://github.com/pedroelsner/filter_results/tree/2.0
    Versão 2.3: https://github.com/pedroelsner/filter_results/

  • Algumas coisas foram alteradas na versão 2.3, como por exemplo o nome do component e do helper. Veja mais detalhes no changelog: https://github.com/pedroelsner/filter_results/

  • O caso do getConditions() é alguma coisa na configuração do filtro.
    Já sobre a ordenação no setPaginate(), estou verificando….

  • Pode se um bug até então desconhecido atrelado a quantidade de filters.
    Manda o código da action. =)

  • Férias é pros fracos! o/

  • Coloquei um aviso no post para ficar avisar o pessoal! =)

  • João Oliveira

    Grato Pedro. Plugin perfeito e simples de usar!

  • João Oliveira

    Pedro,

    Estou com um probleminha de layout mas acho tem haver mais com o cake, mas mesmo assim vai:

    Já tentei colocar de todas as formas os imputs e submits, mas ele ficam um em casa linha.

    Search->create(‘pesquisa’,array(‘inputDefaults’=>array(‘div’=>false, ‘label’=>false)));?>

    Search->label(‘Nome: ‘);?>

    Search->input(‘filter1’,array(‘class’=>’input-xlarge’));?>

    Search->end(__(‘Filtrar’,array(‘div’=>false)));?>

    Já tirei o div, tentei fazer como vc falou do float:left, mas nada, vc tem alguma sugestão, pois no seu exemplo fica bem diretinho um ao lado do outro inclusive o botão.

    ats,

    João Oliveira

  • João, é só formatar o formulário da mesma forma que fazemos no helper Form do CakePHP (não tem segredo). Se colocar o CSS corretamente eles vão aparecer como você deseja. =)

  • Adriano Gobbo

    Com o que você respondeu no twiter eu entendi… criei uma variável $conditions recebendo o getconditions e ali eu incremento as conditions que preciso… valeu!!!

  • Adriano Gobbo

    Tentei desejar seu bem!!! rs

  • Eu tardo mas não falho em responder =P
    Abraços!

  • Heverton Freitas

    Olá! Excelente plugin!

    Tenho uma duvida meio boba. Tenho um campo created, que vem com dia, mês, ano, hora, minuto e segundo. Eu quero que o filtro faça uma busca apenas pela data, ignorando as horas. Como faço???

  • Acácio Costa

    Olá Pedro, mais uma vez muito obrigado e parabéns por seu trabalho.

    Estava fazendo um filtro com explode, porem se colocava espaços entre o caracter de explosão, “Alex – Pedro” o filtro era montado assim ‘%Alex %’ e ‘% Pedro’, assim não retornava um segmento de palavra tipo ‘Alexandre’, então alterei seu FilterComponent.php na linha 1027

    /**
    * Explode and concatenate the values
    *

    */

    $condition[$this->_filter[‘explode.concatenate’]][$k] = array(

    sprintf(‘%s %s’ , $this->_filter[‘fieldModel’], $this->_filter[‘operator’]) =>

    sprintf(‘%s%s%s’, trim($this->_filter[‘value.before’]), trim($v), trim($this->_filter[‘value.after’]))

    );

    Resolveu meu problema. Espero ter alterado da melhor forma e que possa ser útil.

    Abraço,

    Acácio
    Ps – Estou usando CakePHP 2.3.5

  • Tairo Oliveira

    Tentei implementar a busca Via AJAX, porem não consegui.

    Função AJAX funcionando:

    $(‘#form-filter-results’).submit(function(){
    var dados = jQuery( this ).serialize();
    jQuery.ajax({
    type: “POST”,
    url: “http://localhost/FRAMEWORK/evento/modelos/buscarModelos”,
    data: dados,
    dataType: “json”,
    success: function(data){
    alert( data );
    }
    });

    CONTROLLER

    Para teste, fiz um array em PHP e na View transformei o Array em jSON.

    (echo json_encode($modelos);)

    Com esse exemplo ta funcionando.

    Não sei como retornar os dados para view no formato JSON por exemplo, usando o plugin de busca.

    Vc tem alguma sugestão, de como fazer a busca com AJAX ?

  • Romulo Trindade

    Excelente plugin, fiz como vc descreveu mas esta dando um erro, estou usando cake 2.2.2, o erro Strict (2048): Declaration of FilterFormHelper::submit() should be compatible with FormHelper::submit($caption = NULL, $options = Array) [APPPluginFilterResultsViewHelperFilterFormHelper.php, line 24], vi que um usuario teve mesmo problema, ja fiz a correção mas continua dando o erro.

  • Marcos

    Olá Pedro, estou utilizando o teu plugin, mas estou com problemas para integrá-lo com a paginação em Ajax. Tens alguma sugestão?

  • Valeu Acácio,
    Irei atualizar o plugin =)

  • Busca com AJAX vai ser meio complicado porque o plugin faz 2 requisições a cada filtro:
    1- Para montar os filtros
    2- Para mostrar os resultados

    Vai precisar mudar bastante o plugin.
    Boa sorte! =)

  • Ola Marcos,

    Acredito que será um pouco complicado de fazer, uma vez que o plugin faz 2 requisições, uma para configurar os filtros e outra para exibir o resultado.

    O que você precisa fazer é identificar esses momentos e fazer o retorno correto via AJAX.

  • Marcio Paulo

    Pedro parabéns pelo trabalho.

    Seguinte estou usando o seu plugin, normal (com o cakephp 2.3), com o tipo de filtro avançado, no qual é determinei alguns campos da tabela e o combo de condições gerado pelo plugin.
    estava funcionado até que precisei implementar um controle de registro ativo e inativo, e não consegui colocar um filtro fixo juntamente com o filtro avançado. tem algum exemplo nessa condição?

    Agradeço desde já

  • Lucas Gabriel

    EAE Pedro, beleza?Cara vc pode me ajudar? To tentanto utilizar o PHPExcel para exportar para .xls algumas telas e talz, mas o cake me diz que não posso modificar informação do header etc e talz, isso foi setado no PluginFilterResultsViewHelperSearchHelper.php:1. Eu não consigo encontrar em seu plugin nenhum tipo de output ou echo ou espaço em branco depois de fechar a tag ?>, então não entendo por que isso ocorre. alguma sugestão? ABRAÇOS E MTO OBRIGADO PELO EXCELENTE PLUGIN.

  • Lucas,
    O problema pode estar na primeira linha do arquivo.
    Apague ela e crie novamente.

    Aqui, eu não consigo reproduzir este problema…

  • Rodolfo Souza Nery

    Olá, muito bom trabalho, estou com um problema quando faço qualquer alteração em meu sistema depois que instalei o plugin acontece um erro no setFlahs! Desde já obrigado!

  • steve

    Pedro, thanks for this. It’s working great for my basic filters. I’m trying to save the query string to session to create a “return to previous search” type of function. However, when trying to pass the query string as a url, the url goes all crazy with swapping out the characters that it doesn’t like for the ascii values. Is there anyway to make the query url friendly for feeding it back to the browser?

  • Marcelo

    Pedro,

    Também estou com uma dúvida parecida com a da Camila, referente a data. Gostaria, se possível, de um exemplo de um formulário de filtro com somente um único campo de data. Não estou conseguindo utilizar a opção ‘date’ => true, acho que só funciona para o between né ?! Só consigo efetuar a busca pela data, informando a própria invertida, no padrão do banco MySQL.

    Obrigado pela atenção.

  • Altere o método: _makeConditions no arquivo FilterResultsComponent.php e adicione as linhas abaixo no switch/case ” switch (mb_strtolower($this->_filter[‘operator’], ‘utf-8’)) ”

    case ‘date’ :

    $this->_filter[‘value’] = implode(preg_match(“~/~”, $this->_filter[‘value’]) == 0 ? “/” : “-“, array_reverse(explode(preg_match(“~/~”, $this->_filter[‘value’]) == 0 ? “-” : “/”, $this->_filter[‘value’])));

    $this->_filter[‘operator’] = ‘=’;

    $condition[] = ($this->_isMayExplodeValue()) ? $this->_valueConcatenate() : $this->_value();

    $this->controller->request->data [$this->getOption(‘label’, ‘prefix’)] [$this->_filter[‘field’]] = $this->_getFieldParams();

    break;

    Isto irá adicionar um novo “operator” no seu componente e irá permitir que você passe datas no formado dd-mm-yyyy na sua url (Ex: filter.data:11-03-2014).

    Abs

  • Lucas Gabriel

    Pedro, DEMAIS SEU PLUGIN EU RECOMENDO PRA MTA GENTE. seguinte velhão, não to conseguindo agregar os filtros, por exemplo se os 2 campos são incompatíveis (um deles é o id do responsável e outro o id do país) e eu tenho um registro com responsável 001 no país 001 e outro registro com responsável 002 no país 002. se eu escolher, por exemplo, filtra por responsável 001 e país 002 o filtro me retorna o registro com responsável 001 em vez de retornar vazio. que pode ser isso? abraços!

  • Lucas Gabriel

    PEDRÃO, TENHO UMA PERGUNTA:
    1 – Eu quero ter resultados no meu index.ctp paginados e uma opção “ver tudo”. Isso eu consegui foi fácil.

    2 – Eu quero ainda na página de resultados paginados, poder realizar um filtro e depois clicar em “ver tudo”. E gostaria que quando fizesse isso, pudesse ver “todos” os resultados com o filtro.

    3 – Eu consegui fazer isso passando para a Session o $this->FilterResults->getConditions() do action index (do meu controller) e lendo essa variável no action indexall de meu controller e setando ela como condições para meu “novo” filtro.

    porém o form de filtros não aparece quando faço isso.

    que eu posso fazer cara? AQUELE ABRAÇO!

  • Diego Nassula

    Elsner fiz a instalação do plugin certinho, mas estou recebendo o seguinte erro

    pluginsFilterResults\ControllerComponentFilterComponent.php

    <?php
    class FilterComponent extends Component {

    }

    Notice: If you want to customize this error message, create appViewErrorsmissing_component.ctp

    já tentei de várias formas mas não consigo acertar o \ antes do Controller

  • Diego Martins

    Pedro, estou com o mesmo problema do Anderson. Toda a minha aplicação está configurada para utilizar o charset ISO-8859-1, no core.php. Ao utilizar o plugin, os caracteres ficam com o problema. :/

  • Diego Martins

    Pedro, gostaria de trazer somente os registros ativos (flag situacao = 1) e não to conseguindo criar essa condição no filtro. Como faço? Obrigado!

  • Antonio Francisco

    Olá Pedro, desde já quero lhe parabenizar por seu trabalho e solicitar sua ajuda se possével.
    Minha dívida é a seguinte:
    Tenho
    um formulário em que preciso filtrar a classe do funcionario de acordo
    com o cargo selecionado, e a funcao de acordo com a classe selecionada.
    situacao 1
    Cargo: Analista
    Classe: Analista I, Analista II, Analista III…
    Funcao: desenvolvedor, reparador, etc.

    situacao 2
    Cargo: Tecnico
    Classe: Tecnico I, Tecnico II, Tecnico III…
    Funcao: desenvolvedor, reparador, etc.

    situacao 3
    Cargo: Auxiliar
    Classe: Auxiliar I, Auxiliar II, Auxiliar III…
    Funcao: atendente, porteiro, etc.

    Se puder me ajudar agradeco.
    Att, Antonio Oliveira.
    desconsidere acentuacao e cedilhas(problemas no idioma).

  • Eai galera !!!

    Gostaria de saber como faço para fazer um checbox nos filtros

    Deste modo aqui esta a caixa de seleção:

    ‘filter11’ => array(
    ‘Produto.marca_id’ => array(
    ‘select’ => $this->Filter->select(‘Marcas’, $this->Produto->Marca->find(‘list’)))
    ), /* esse aqui esta funcionando BLZ */
    gostaria de fazer como fazer esse mesmo, mas com checbox para o usuário poder filtrar com mais de uma marca ao mesmo tempo ou uma por vez mas através de checbox !?

    Minha segunda duvida é se tem como colocar para filtrar por um campo das característica do produto como ‘sabor’ .
    Nessa segunda situação o find retorna todos os sabores de todos os produtos cadastrados, nisso acaba repetindo valores(sabor), tem como colocar para não repetir direto no find

    ‘filter12’ => array(
    ‘Produto.sabor’ => array(
    ‘select’ => $this->Filter->select(‘sabor’, $this->Produto->find(‘list’, array(‘fields’ => ‘Produto.sabor’))))
    ),

    Desde já obrigado !!! 🙂

  • Eai galera como faço um botão ( Limpar todos os filtros )

    Desde já obrigado !!!

  • Adriano

    Estou tendo problemas com agregação de filtros, a pesquisa sempre retorna só o primeiro filtro! EX:. WHERE `Usuario`.`nome` LIKE ‘%adriano%’ ….sendo que meu form tem filtro1 (nome) e filtro2 (grupo_id), bem como o controller abaixo.
    function index()
    {
    $this->FilterResults->addFilters(
    array(
    ‘filter1’ => array(
    ‘Usuario.nome’ => array(‘operator’ => ‘LIKE’)
    ),
    ‘filter2’ => array(
    ‘Usuario.grupo_id’ => array(
    ‘select’ => $this->FilterResults->select(‘Grupo’, $this->Usuario->Grupo->find(‘list’))
    )
    )
    )
    );
    $this->paginate[‘conditions’] = $this->FilterResults->getConditions();
    $this->Usuario->recursive = 0;
    $this->set(‘usuarios’, $this->paginate());
    }

  • Adriano

    Estou tendo problemas com agregação de filtros, a pesquisa sempre retorna só o primeiro filtro! EX:. WHERE `Usuario`.`nome` LIKE ‘%adriano%’ ….sendo que meu form tem filtro1 (nome) e filtro2 (grupo_id), bem como o controller abaixo.
    function index()
    {
    $this->FilterResults->addFilters(
    array(
    ‘filter1’ => array(
    ‘Usuario.nome’ => array(‘operator’ => ‘LIKE’)
    ),
    ‘filter2’ => array(
    ‘Usuario.grupo_id’ => array(
    ‘select’ => $this->FilterResults->select(‘Grupo’, $this->Usuario->Grupo->find(‘list’))
    )
    )
    )
    );
    $this->paginate[‘conditions’] = $this->FilterResults->getConditions();
    $this->Usuario->recursive = 0;
    $this->set(‘usuarios’, $this->paginate());
    }

  • Rodrigo

    Boa Noite,

    Estou utilizando a ultima versão de seu Plugin, e meu problema está relacionado com o CSS a ser utilizado. Não é possível deixar o botão de pesquisa ao lado do input, da forma que consta em sua imagem de exemplo.

    Mesmo colocando como float:left ou right não muda nada.
    Teria como me ajudar?

  • Rodrigo

    Boa tarde estou com um problema, acho que simples porém não estou conseguindo resolver. Configurei e fiz todos os passos porém essa mensagem apareceu:

    Fatal Error

    Error: Call to a member function addFilters() on a non-object

  • Madson Souza

    É possível definir o número máximo de registros por página manualmente?

  • Boa noite

    Gostaria de saber se tem como colocar o filtro que pode ser usando mesmo ante de fazer a busca.
    Tipo só listar os ativos, quando busca ele vai nessa lista de ativos e busca por nome.
    Mas de inicio ja gera o paginate somente dos ativos

  • Pedro Escobar

    Boa tarde,
    primeiro, parabéns pelo seu excelente trabalho. Segundo, uso o filter há um bom tempo já, mas atualmente me deparei com um “bug”. Ao utilizar regra composta com explode => true para mais de um campo, apenas o primeiro campo é tratado, os restantes não são considerados o explode.