As consultas abaixo não são SQL puro, são DQLs (Doctrine Query Language)
Por padrão, a busca por palavra-chave da API do Mapas Culturais retorna os objetos encontrados na query abaixo, ou seja, uma busca baseada somente no nome do objeto:
SELECT
DISTINCT e.id
FROM
{$entity_class} e
WHERE
unaccent(lower(e.name)) LIKE unaccent(lower(:keyword))
O Mapas Culturais oferece dois hooks para modificar a query acima: o primeiro permite adicionar joins à consulta e o segundo permite adicionar operações dentro da cláusula WHERE:
- repo($entity).getIdsByKeywordDQL.join - utilizado para adicionar novos joins à consulta, representado na consulta abaixo pela variável $HOOK_JOINS;
- repo($entity).getIdsByKeywordDQL.where - utilizado para adicionar operações dentro da cláusula WHERE, reprensetado na consulta abaixo pela variável $HOOK_WHERE.
SELECT
DISTINCT e.id
FROM
{$entity_class} e
$HOOK_JOINS
WHERE
unaccent(lower(e.name)) LIKE unaccent(lower(:keyword))
$HOOK_WHERE
Vamos usar como exemplo um metadado chamado num_entidade, que seria um código que representa a entidade no sistema e que, quando alguém fizesse uma busca por palavra-chave informando tal código, o sistema deveria retornar este objeto. Vamos supor ainda que este código só é aplicado a agentes e espaços, porém para aplicar a todas as entidades que usam busca por palavra-chave (repositórios que usam o trait MapasCulturais\Traits\RepositoryKeyword) basta substituir a parte do hook <<Agent|Space>> por <<*>>
$app = \MapasCulturais\App::i(); // instância da aplicação
// adiciona o join do metadado
$app->hook('repo(<<Agent|Space>>).getIdsByKeywordDQL.join', function(&$joins, $keyword){
$joins .= "
LEFT JOIN
e.__metadata num_entitdade
WITH
num_entidade.key = 'num_entidade'";
});
// filtra pelo valor do keyword
$app->hook('repo(<<Agent|Space>>).getIdsByKeywordDQL.where', function(&$where, $keyword){
// a variável $keyword está disponível aqui porém não é recomendado que esta seja utilizada diretamente na consulta
// pois ela já estará disponível dentro da consulta pelo parâmetro :keyword.
$where .= " OR lower(num_entidade.value) LIKE lower(:keyword)";
});
Agora vamos utilizar como exemplo uma taxonomia chamada "categoria"
$app->hook('repo(<<*>>).getIdsByKeywordDQL.join', function(&$joins, $keyword) {
$taxonomy = App::i()->getRegisteredTaxonomyBySlug('categoria');
$joins .= "LEFT JOIN e.__termRelations categoria_tr
LEFT JOIN
categoria_tr.term
categoria
WITH
categoria.taxonomy = '{$taxonomy->id}'";
});
$app->hook('repo(<<*>>).getIdsByKeywordDQL.where', function(&$where, $keyword) {
$where .= " OR unaccent(lower(categoria.term)) LIKE unaccent(lower(:keyword)) ";
});