implementing pagination api on search, and creating a "preview" of results

The search controller return a subset of the 5 first results. If the user want to
see more, the services implementing SearchInterface should add a link "see more",
and make use of the Pagination API to paginate.
This commit is contained in:
2016-08-19 21:33:37 +02:00
parent 2732bb1553
commit d20404bc3c
4 changed files with 64 additions and 8 deletions

View File

@@ -31,6 +31,9 @@ namespace Chill\MainBundle\Search;
*/
interface SearchInterface
{
const SEARCH_PREVIEW_OPTION = '_search_preview';
/**
* return the result in a html string. The string will be inclued (as raw)
* into a global view.
@@ -39,6 +42,16 @@ interface SearchInterface
* {% for result as resultsFromDifferentSearchInterface %}
* {{ result|raw }}
* {% endfor %}
*
* **available options** :
* - SEARCH_PREVIEW_OPTION (boolean) : if renderResult should return a "preview" of
* the results. In this case, a subset of results should be returned, and,
* if the query return more results, a button "see all results" should be
* displayed at the end of the list.
*
* **Interaction between `start` and `limit` and pagination : you should
* take only the given parameters into account; the results from pagination
* should be ignored. (Most of the time, it should be the same).
*
* @param array $terms the string to search
* @param int $start the first result (for pagination)

View File

@@ -9,6 +9,16 @@ use Chill\MainBundle\Search\SearchInterface;
* installed into the app.
* the service is callable from the container with
* $container->get('chill.main.search_provider')
*
* the syntax for search string is :
* - domain, which begin with `@`. Example: `@person`. Restrict the search to some
* entities. It may exists multiple search provider for the same domain (example:
* a search provider for people which performs regular search, and suggestion search
* with phonetical algorithms
* - terms, which are the terms of the search. There are terms with argument (example :
* `birthdate:2016-04-01` and the default term, which is the search without argument
* and without domain.
*
*/
class SearchProvider
{
@@ -18,7 +28,7 @@ class SearchProvider
* @var SearchInterface[]
*/
private $searchServices = array();
/*
* return search services in an array, ordered by
* the order key (defined in service definition)
@@ -63,6 +73,15 @@ class SearchProvider
return $terms;
}
/**
* Extract the domain of the subject
*
* The domain begins with `@`. Example: `@person`, `@report`, ....
*
* @param type $subject
* @return string
* @throws ParsingException
*/
private function extractDomain(&$subject)
{
preg_match_all('/@([a-z]+)/', $subject, $terms);
@@ -123,10 +142,12 @@ class SearchProvider
* @param string $pattern
* @param number $start
* @param number $limit
* @param array $options
* @return array of html results
* @throws UnknowSearchDomainException if the domain is unknow
*/
public function getSearchResults($pattern, $start = 0, $limit = 50)
public function getSearchResults($pattern, $start = 0, $limit = 50,
array $options = array())
{
$terms = $this->parse($pattern);
$results = array();
@@ -140,7 +161,7 @@ class SearchProvider
if ($terms['_domain'] !== NULL) {
foreach ($sortedSearchServices as $service) {
if ($service->supports($terms['_domain'])) {
$results[] = $service->renderResult($terms, $start, $limit);
$results[] = $service->renderResult($terms, $start, $limit, $options);
}
}
@@ -150,7 +171,7 @@ class SearchProvider
} else { // no domain provided, we use default search
foreach($sortedSearchServices as $service) {
if ($service->isActiveByDefault()) {
$results[] = $service->renderResult($terms, $start, $limit);
$results[] = $service->renderResult($terms, $start, $limit, $options);
}
}
}
@@ -161,7 +182,8 @@ class SearchProvider
return $results;
}
public function getResultByName($pattern, $name, $start = 0, $limit = 50)
public function getResultByName($pattern, $name, $start = 0, $limit = 50,
array $options = array())
{
$terms = $this->parse($pattern);
$search = $this->getByName($name);
@@ -171,7 +193,7 @@ class SearchProvider
throw new ParsingException("The domain is not supported for the search name");
}
return $search->renderResult($terms, $start, $limit);
return $search->renderResult($terms, $start, $limit, $options);
}
/**