mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 13:54:23 +00:00
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:
parent
2732bb1553
commit
d20404bc3c
@ -27,6 +27,7 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
use Chill\MainBundle\Search\UnknowSearchDomainException;
|
use Chill\MainBundle\Search\UnknowSearchDomainException;
|
||||||
use Chill\MainBundle\Search\UnknowSearchNameException;
|
use Chill\MainBundle\Search\UnknowSearchNameException;
|
||||||
use Chill\MainBundle\Search\ParsingException;
|
use Chill\MainBundle\Search\ParsingException;
|
||||||
|
use Chill\MainBundle\Search\SearchInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -55,11 +56,29 @@ class SearchController extends Controller
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if ($name === NULL) {
|
if ($name === NULL) {
|
||||||
|
// no specific search selected. Rendering result in "preview" mode
|
||||||
$results = $this->get('chill.main.search_provider')
|
$results = $this->get('chill.main.search_provider')
|
||||||
->getSearchResults($request->query->get('q'));
|
->getSearchResults(
|
||||||
|
$pattern,
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
array(SearchInterface::SEARCH_PREVIEW => true)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// we want search on a specific search provider. Display full results.
|
||||||
|
|
||||||
|
// create a paginator to get the startPage and stopPage
|
||||||
|
/* @var $paginatorFactory \Chill\MainBundle\Pagination\PaginatorFactory */
|
||||||
|
$paginatorFactory = $this->get('chill_main.paginator_factory');
|
||||||
|
|
||||||
$results = [$this->get('chill.main.search_provider')
|
$results = [$this->get('chill.main.search_provider')
|
||||||
->getResultByName($pattern, $name)];
|
->getResultByName(
|
||||||
|
$pattern,
|
||||||
|
$name,
|
||||||
|
$paginatorFactory->getCurrentPageFirstItemNumber(),
|
||||||
|
$paginatorFactory->getCurrentItemPerPage(),
|
||||||
|
array(SearchInterface::SEARCH_PREVIEW => false)
|
||||||
|
)];
|
||||||
}
|
}
|
||||||
} catch (UnknowSearchDomainException $ex) {
|
} catch (UnknowSearchDomainException $ex) {
|
||||||
return $this->render('ChillMainBundle:Search:error.html.twig',
|
return $this->render('ChillMainBundle:Search:error.html.twig',
|
||||||
|
@ -46,6 +46,8 @@ Invalid terms : Recherche invalide
|
|||||||
You should not have more than one domain. : Vous ne devriez pas avoir plus d'un domaine de recherche.
|
You should not have more than one domain. : Vous ne devriez pas avoir plus d'un domaine de recherche.
|
||||||
#used for page title
|
#used for page title
|
||||||
Search %pattern%: Recherche de "%pattern%"
|
Search %pattern%: Recherche de "%pattern%"
|
||||||
|
Results %start%-%end% of %total%: Résultats %start%-%end% sur %total%
|
||||||
|
See all results: Voir tous les résultats
|
||||||
|
|
||||||
#admin
|
#admin
|
||||||
Create: Créer
|
Create: Créer
|
||||||
|
@ -31,6 +31,9 @@ namespace Chill\MainBundle\Search;
|
|||||||
*/
|
*/
|
||||||
interface SearchInterface
|
interface SearchInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const SEARCH_PREVIEW_OPTION = '_search_preview';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the result in a html string. The string will be inclued (as raw)
|
* return the result in a html string. The string will be inclued (as raw)
|
||||||
* into a global view.
|
* into a global view.
|
||||||
@ -39,6 +42,16 @@ interface SearchInterface
|
|||||||
* {% for result as resultsFromDifferentSearchInterface %}
|
* {% for result as resultsFromDifferentSearchInterface %}
|
||||||
* {{ result|raw }}
|
* {{ result|raw }}
|
||||||
* {% endfor %}
|
* {% 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 array $terms the string to search
|
||||||
* @param int $start the first result (for pagination)
|
* @param int $start the first result (for pagination)
|
||||||
|
@ -9,6 +9,16 @@ use Chill\MainBundle\Search\SearchInterface;
|
|||||||
* installed into the app.
|
* installed into the app.
|
||||||
* the service is callable from the container with
|
* the service is callable from the container with
|
||||||
* $container->get('chill.main.search_provider')
|
* $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
|
class SearchProvider
|
||||||
{
|
{
|
||||||
@ -18,7 +28,7 @@ class SearchProvider
|
|||||||
* @var SearchInterface[]
|
* @var SearchInterface[]
|
||||||
*/
|
*/
|
||||||
private $searchServices = array();
|
private $searchServices = array();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return search services in an array, ordered by
|
* return search services in an array, ordered by
|
||||||
* the order key (defined in service definition)
|
* the order key (defined in service definition)
|
||||||
@ -63,6 +73,15 @@ class SearchProvider
|
|||||||
return $terms;
|
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)
|
private function extractDomain(&$subject)
|
||||||
{
|
{
|
||||||
preg_match_all('/@([a-z]+)/', $subject, $terms);
|
preg_match_all('/@([a-z]+)/', $subject, $terms);
|
||||||
@ -123,10 +142,12 @@ class SearchProvider
|
|||||||
* @param string $pattern
|
* @param string $pattern
|
||||||
* @param number $start
|
* @param number $start
|
||||||
* @param number $limit
|
* @param number $limit
|
||||||
|
* @param array $options
|
||||||
* @return array of html results
|
* @return array of html results
|
||||||
* @throws UnknowSearchDomainException if the domain is unknow
|
* @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);
|
$terms = $this->parse($pattern);
|
||||||
$results = array();
|
$results = array();
|
||||||
@ -140,7 +161,7 @@ class SearchProvider
|
|||||||
if ($terms['_domain'] !== NULL) {
|
if ($terms['_domain'] !== NULL) {
|
||||||
foreach ($sortedSearchServices as $service) {
|
foreach ($sortedSearchServices as $service) {
|
||||||
if ($service->supports($terms['_domain'])) {
|
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
|
} else { // no domain provided, we use default search
|
||||||
foreach($sortedSearchServices as $service) {
|
foreach($sortedSearchServices as $service) {
|
||||||
if ($service->isActiveByDefault()) {
|
if ($service->isActiveByDefault()) {
|
||||||
$results[] = $service->renderResult($terms, $start, $limit);
|
$results[] = $service->renderResult($terms, $start, $limit, $options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,7 +182,8 @@ class SearchProvider
|
|||||||
return $results;
|
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);
|
$terms = $this->parse($pattern);
|
||||||
$search = $this->getByName($name);
|
$search = $this->getByName($name);
|
||||||
@ -171,7 +193,7 @@ class SearchProvider
|
|||||||
throw new ParsingException("The domain is not supported for the search name");
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user