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.