diff --git a/Controller/SearchController.php b/Controller/SearchController.php index 1ae8dc158..0d17c8425 100644 --- a/Controller/SearchController.php +++ b/Controller/SearchController.php @@ -27,6 +27,7 @@ use Symfony\Component\HttpFoundation\Request; use Chill\MainBundle\Search\UnknowSearchDomainException; use Chill\MainBundle\Search\UnknowSearchNameException; use Chill\MainBundle\Search\ParsingException; +use Chill\MainBundle\Search\SearchInterface; /** * @@ -55,11 +56,29 @@ class SearchController extends Controller try { if ($name === NULL) { + // no specific search selected. Rendering result in "preview" mode $results = $this->get('chill.main.search_provider') - ->getSearchResults($request->query->get('q')); + ->getSearchResults( + $pattern, + 0, + 5, + array(SearchInterface::SEARCH_PREVIEW => true) + ); } 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') - ->getResultByName($pattern, $name)]; + ->getResultByName( + $pattern, + $name, + $paginatorFactory->getCurrentPageFirstItemNumber(), + $paginatorFactory->getCurrentItemPerPage(), + array(SearchInterface::SEARCH_PREVIEW => false) + )]; } } catch (UnknowSearchDomainException $ex) { return $this->render('ChillMainBundle:Search:error.html.twig', diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 327c20d5c..4c2eabe0e 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -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. #used for page title 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 Create: Créer diff --git a/Search/SearchInterface.php b/Search/SearchInterface.php index 53182f7fe..1933b30ea 100644 --- a/Search/SearchInterface.php +++ b/Search/SearchInterface.php @@ -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) diff --git a/Search/SearchProvider.php b/Search/SearchProvider.php index c974b6e98..57241f8d2 100644 --- a/Search/SearchProvider.php +++ b/Search/SearchProvider.php @@ -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); } /**