* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ namespace Chill\MainBundle\Controller; use Chill\MainBundle\Serializer\Model\Collection; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 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; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\HttpFoundation\JsonResponse; use Chill\MainBundle\Search\SearchProvider; use Symfony\Contracts\Translation\TranslatorInterface; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Search\SearchApi; use Symfony\Component\HttpFoundation\Exception\BadRequestException; /** * Class SearchController * * @package Chill\MainBundle\Controller */ class SearchController extends AbstractController { protected SearchProvider $searchProvider; protected TranslatorInterface $translator; protected PaginatorFactory $paginatorFactory; protected SearchApi $searchApi; function __construct( SearchProvider $searchProvider, TranslatorInterface $translator, PaginatorFactory $paginatorFactory, SearchApi $searchApi ) { $this->searchProvider = $searchProvider; $this->translator = $translator; $this->paginatorFactory = $paginatorFactory; $this->searchApi = $searchApi; } public function searchAction(Request $request, $_format) { $pattern = $request->query->get('q', ''); if ($pattern === ''){ switch($_format) { case 'html': return $this->render('@ChillMain/Search/error.html.twig', array( 'message' => $this->translator->trans("Your search is empty. " . "Please provide search terms."), 'pattern' => $pattern )); case 'json': return new JsonResponse([ 'results' => [], 'pagination' => [ 'more' => false ] ]); } } $name = $request->query->get('name', NULL); try { if ($name === NULL) { if ($_format === 'json') { return new JsonResponse('Currently, we still do not aggregate results ' . 'from different providers', JsonResponse::HTTP_BAD_REQUEST); } // no specific search selected. Rendering result in "preview" mode $results = $this->searchProvider ->getSearchResults( $pattern, 0, 5, array(SearchInterface::SEARCH_PREVIEW_OPTION => true) ); } else { // we want search on a specific search provider. Display full results. $results = [$this->searchProvider ->getResultByName( $pattern, $name, $this->paginatorFactory->getCurrentPageFirstItemNumber(), $this->paginatorFactory->getCurrentItemsPerPage(), array( SearchInterface::SEARCH_PREVIEW_OPTION => false, SearchInterface::REQUEST_QUERY_PARAMETERS => $request ->get(SearchInterface::REQUEST_QUERY_KEY_ADD_PARAMETERS, []) ), $_format )]; if ($_format === 'json') { return new JsonResponse(\reset($results)); } } } catch (UnknowSearchDomainException $ex) { return $this->render('@ChillMain/Search/error.html.twig', array( "message" => $this->translator->trans("The domain %domain% " . "is unknow. Please check your search.", array('%domain%' => $ex->getDomain())), 'pattern' => $pattern )); } catch (UnknowSearchNameException $ex) { throw $this->createNotFoundException("The name ".$ex->getName()." is not found"); } catch (ParsingException $ex) { return $this->render('@ChillMain/Search/error.html.twig', array( "message" => $this->translator->trans('Invalid terms'). ": ".$this->translator->trans($ex->getMessage()), 'pattern' => $pattern )); } return $this->render('@ChillMain/Search/list.html.twig', array('results' => $results, 'pattern' => $pattern) ); } public function searchApi(Request $request, $_format): JsonResponse { //TODO this is an incomplete implementation $query = $request->query->get('q', ''); $types = $request->query->get('type', []); if (count($types) === 0) { throw new BadRequestException("The request must contains at " ." one type"); } $collection = $this->searchApi->getResults($query, $types, []); return $this->json($collection); } public function advancedSearchListAction(Request $request) { /* @var $variable Chill\MainBundle\Search\SearchProvider */ $searchProvider = $this->searchProvider; $advancedSearchProviders = $searchProvider ->getHasAdvancedFormSearchServices(); if(\count($advancedSearchProviders) === 1) { \reset($advancedSearchProviders); return $this->redirectToRoute('chill_main_advanced_search', [ 'name' => \key($advancedSearchProviders) ]); } return $this->render('@ChillMain/Search/choose_list.html.twig'); } public function advancedSearchAction($name, Request $request) { try { /* @var $variable Chill\MainBundle\Search\SearchProvider */ $searchProvider = $this->searchProvider; /* @var $variable Chill\MainBundle\Search\HasAdvancedSearchFormInterface */ $search = $this->searchProvider ->getHasAdvancedFormByName($name); } catch (\Chill\MainBundle\Search\UnknowSearchNameException $e) { throw $this->createNotFoundException("no advanced search for " . "$name"); } if ($request->query->has('q')) { $data = $search->convertTermsToFormData($searchProvider->parse( $request->query->get('q'))); } $form = $this->createAdvancedSearchForm($name, $data ?? []); if ($request->isMethod(Request::METHOD_POST)) { $form->handleRequest($request); if ($form->isValid()) { $pattern = $this->searchProvider ->getHasAdvancedFormByName($name) ->convertFormDataToQuery($form->getData()); return $this->redirectToRoute('chill_main_search', [ 'q' => $pattern, 'name' => $name ]); } } return $this->render('@ChillMain/Search/advanced_search.html.twig', [ 'form' => $form->createView(), 'name' => $name, 'title' => $search->getAdvancedSearchTitle() ]); } protected function createAdvancedSearchForm($name, array $data = []) { $builder = $this ->get('form.factory') ->createNamedBuilder( null, FormType::class, $data, [ 'method' => Request::METHOD_POST ] ); $this->searchProvider ->getHasAdvancedFormByName($name) ->buildForm($builder) ; $builder->add('submit', SubmitType::class, [ 'label' => 'Search' ]); return $builder->getForm(); } }