Criação de um mecanismo de pesquisa personalizado

No núcleo do SearchFramework existe a natureza personalizável da classe SearchEngine. Para criar uma subclasse de SearchEngine que será detectada pelo SearchWrapper, tudo o que você precisa fazer é criar um arquivo na pasta custom / Extension / SearchEngines que estende a classe SearchEngine e implementa o método de pesquisa (SearchQuery $ query).

 

Exemplo de pesquisa simulada
O exemplo abaixo mostra um mecanismo de busca que, independente de sua consulta de pesquisa, retornará o Administrador.
use SuiteCRM\Search\SearchEngine;
use SuiteCRM\Search\SearchQuery;
use SuiteCRM\Search\SearchResults;

class FakeSearch extends SearchEngine
{
public function search(SearchQuery $query)
{
return new SearchResults([
‘Users’ => [1]
]);
}
}

 

Exemplo de pesquisa de cidade
O exemplo acima é perfeitamente válido e funcionaria, mas é bastante inútil. Vamos tentar fazer um mecanismo de pesquisa simples que procura contas que têm o endereço em uma determinada cidade.
use SuiteCRM\Search\SearchEngine;
use SuiteCRM\Search\SearchQuery;
use SuiteCRM\Search\SearchResults;
class CitySearch extends SearchEngine
{
public function search(SearchQuery $query)
{
$sql = “SELECT id FROM accounts WHERE billing_address_city = ‘%s’ OR shipping_address_city = ‘%s’ LIMIT %d OFFSET %d”;

 // Format the query with the values
    $sql = sprintf(
        $sql, // SQL Query above
        $query->getSearchString(), // First equals
        $query->getSearchString(), // Second equals
        $query->getSize(), // LIMIT
        $query->getFrom() // OFFSET
    );

    // Get an instance of the dabatabase manager
    $db = DBManagerFactory::getInstance();
    // Perform the query
    $rows = $db->query($sql);
    // Initialize an array with the results
    $results = ['Accounts' => []];

    // Fetch the row and push the id in the results array
    while ($row = $db->fetchRow($rows)) {
        $results['Accounts'][] = $row['id'];
    }

    // Make a new SearchResults object with the results array and return
    return new SearchResults($results);
}

 

Exemplo de personalização de visualização
É possível personalizar como o mecanismo de pesquisa constrói a interface substituindo os métodos displayForm () e displayResults (). Se precisar de um grau mais alto de controle, você pode substituir o método searchAndDisplay () inteiramente.

Por padrão, displayForm () (exibindo a barra de pesquisa) e displayResults () (exibindo resultados e erros) chamam SearchFormController e SearchResultsController respectivamente para criar as visualizações. Essas duas classes devem ser usadas e personalizadas por mecanismos de pesquisa personalizados.

No exemplo abaixo, iremos substituir o método displayResults () para a classe acima e dizer ao mecanismo para carregar um arquivo de modelo diferente. O arquivo de modelo é um arquivo personalizado colocado na mesma pasta do mecanismo e mostrará uma visualização de tabela com três colunas: nome do bean, endereço de entrega e endereço de cobrança. O referido arquivo de modelo smarty pode ser encontrado logo após o código da classe.

use SuiteCRM\Search\SearchEngine;
use SuiteCRM\Search\SearchQuery;
use SuiteCRM\Search\SearchResults;
use SuiteCRM\Search\UI\SearchResultsController;

class CitySearchWithView extends SearchEngine
{
public function search(SearchQuery $query) { // Same as example above. }

public function displayResults(SearchQuery $query, SearchResults $results)
{
    // Override the displayResults() method to change how the `SearchWrapper` will show the results.

    // I have used an anonymous class just for simplicity in the example.
    // The extended controller can be normally placed in a separate file.
    $controller = new class($query, $results) extends SearchResultsController
    {
        public function __construct(SearchQuery $query, SearchResults $results)
        {
            parent::__construct($query, $results);
            // Let us load a custom template file.
            $this->view->setTemplateFile(__DIR__ . '/citysearch.tpl');
        }
    };

    // Finally ask the Controller to render the view.
    $controller->display();
}

 

citysearch.tpl

 

Exemplo de personalização de visualização
É possível personalizar como o mecanismo de pesquisa constrói a interface substituindo os métodos displayForm () e displayResults (). Se precisar de um grau mais alto de controle, você pode substituir o método searchAndDisplay () inteiramente.

Por padrão, displayForm () (exibindo a barra de pesquisa) e displayResults () (exibindo resultados e erros) chamam SearchFormController e SearchResultsController respectivamente para criar as visualizações. Essas duas classes devem ser usadas e personalizadas por mecanismos de pesquisa personalizados.

No exemplo abaixo, iremos substituir o método displayResults () para a classe acima e dizer ao mecanismo para carregar um arquivo de modelo diferente. O arquivo de modelo é um arquivo personalizado colocado na mesma pasta do mecanismo e mostrará uma visualização de tabela com três colunas: nome do bean, endereço de entrega e endereço de cobrança. O referido arquivo de modelo smarty pode ser encontrado logo após o código da classe.

Se você deseja mostrar diretamente uma mensagem de erro ao usuário, pode lançar uma SearchUserFriendlyException. Lembre-se de usar a estrutura de tradução se quiser que o erro seja localizado e nunca mostre detalhes que sejam (muito) técnicos.

Exemplo de envio de uma mensagem de erro amigável:
throw new SearchUserFriendlyException(translate(‘LBL_ERROR_MESSAGE_INVALID_QUERY’));

 

Conclusões
Para aprender mais sobre o Search Framework, não tenha medo de olhar o código em lib \ Search. Pretende ser simples, legível e bem documentado.