123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- <?php
- namespace Drupal\edlp_search\Controller;
- use Drupal\Core\Controller\ControllerBase;
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Drupal\Core\Form\FormBuilder;
- use Drupal\search_api\Entity\Index;
- use Drupal\Core\Url;
- use Drupal\Core\Language\LanguageInterface;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\JsonResponse;
- // use Drupal\Core\Cache\CacheableJsonResponse;
- // use Drupal\Core\Cache\CacheableMetadata;
- use Drupal\core\render\RenderContext;
- /**
- * Class EdlpSearchController.
- */
- class EdlpSearchController extends ControllerBase {
- /**
- * The form builder.
- *
- * @var \Drupal\Core\Form\FormBuilder
- */
- protected $formBuilder;
- protected $sapi_index_id;
- /**
- * Construct.
- */
- public function __construct(FormBuilder $formBuilder) {
- $this->formBuilder = $formBuilder;
- $this->sapi_index_id = "collection";
- }
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container) {
- return new static(
- $container->get('form_builder')
- );
- }
- private function getSearchForm(){
- $this->form = $this->formBuilder->getForm('Drupal\edlp_search\Form\EdlpSearchForm');
- }
- private function buildRenderable(){
- $this->getSearchForm();
- $this->renderable = array(
- "#theme" => "edlp_search_search_form",
- '#form' => $this->form
- );
- }
- /**
- * Searchform.
- *
- * @return string
- * Return Hello string.
- */
- public function searchForm() {
- $this->buildRenderable();
- return $this->renderable;
- }
- /**
- * searchFormJson
- */
- public function searchFormJson(){
- $this->buildRenderable();
- $rendered = \Drupal::service('renderer')->render($this->renderable);
- $data = [
- 'rendered' => $rendered,
- 'title' => 'Search',
- ];
- // translations links
- $route_name = 'edlp_search.edlp_search_controller_searchForm';
- $links = \Drupal::languageManager()->getLanguageSwitchLinks(LanguageInterface::TYPE_URL, Url::fromRoute($route_name));
- if (isset($links->links)) {
- $translations_build = [
- '#theme' => 'links__language_block',
- '#links' => $links->links,
- '#attributes' => ['class' => ["language-switcher-{$links->method_id}",],],
- '#set_active_class' => TRUE,
- ];
- $translations_rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($translations_build) {return \Drupal::service('renderer')->render($translations_build);});
- $data['translations_links'] = $translations_rendered;
- }
- // TODO: make respponse cachable
- $response = new JsonResponse();
- $response->setData($data);
- return $response;
- }
- public function autocomplete(Request $request){
- // TODO: get field_name parameter
- $this->request = $request;
- $this->getRequestAutocompleteArgs();
- // run a search on selected field and get the fields unique values
- $this->autocompleteQuery();
- $response = new JsonResponse($this->matches);
- return $response;
- // return array(
- // "#markup" => "autocomplete"
- // );
- }
- /**
- * autocompleteQuery
- */
- private function autocompleteQuery(){
- // TODO: get the sapi index id with settings
- /* @var $sapi_index \Drupal\search_api\IndexInterface */
- $sapi_index = Index::load($this->sapi_index_id);
- // dpm($sapi_index);
- // Create the query.
- $query = $sapi_index->query();
- $query->setSearchID('edlp_search:autocomplete');
- $parse_mode = \Drupal::getContainer()
- ->get('plugin.manager.search_api.parse_mode')
- ->createInstance('direct');
- $query->setParseMode($parse_mode);
- $current_langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
- $query->setLanguages(array($current_langcode));
- // $query->range(0, 20);
- // workflow
- $wf_condition_group = $query->createConditionGroup('OR');
- $wf_condition_group->addCondition('field_workflow', 'corpus_documents_publie', "=");
- // TODO: add condition with the other workflow field
- $query->addConditionGroup($wf_condition_group);
- // Search for keys.
- if (!empty($this->keys)) { // && strlen($this->keys) > 2
- // dpm($this->keys);
- $query->keys($this->keys);
- }
- // else{
- // $this->matches = [];
- // return;
- // }
- if(null !== $this->field_synonyms){
- // select the taxo field AND the synonym field in which search will be performed
- $query->setFulltextFields(array($this->field_name, $this->field_synonyms));
- }else{
- // OR select the unique taxo field in which search will be performed
- $query->setFulltextFields(array($this->field_name));
- }
- $result = $query->execute();
- $items = $result->getResultItems();
- // dpm($items);
- $this->matches = [];
- foreach ($items as $item) {
- // get the field from item
- try {
- /** @var \Drupal\Core\Entity\EntityInterface $entity */
- $fields = $item->getField($this->field_name)->getValues();
- }catch (SearchApiException $e) {
- // if error on getinfg the field, skip item
- continue;
- }
- // if no fields returned, skip item
- if (!$fields) {
- continue;
- }
- // dpm($fields);
- // get field content
- $field_text = $fields[0]->getText();
- // $entity_id = $fields[0]->get('tid');
- // if content already in matches, skip item
- if( in_array($field_text, $this->matches) ){
- continue;
- }
- // add the item to the return list
- // $matches_names = $field_text . '('.$entity_id.')';
- $this->matches[] = $field_text;
- // do not return more than 14 items
- if(count($this->matches) > 14){
- break;
- }
- }
- // dpm($this->matches);
- }
- /**
- * getRequestArgs
- */
- private function getRequestAutocompleteArgs(){
- // args are provided by form definition with autocomplete_route_parameters
- // dpm($this->request);
- $this->field_name = $this->request->query->get('field_name');
- // if($this->request->query->get('field_synonyms')){
- $this->field_synonyms = $this->request->query->get('field_synonyms');
- // }
- // if($this->request->query->get('node_type')){
- // $this->node_type = $this->request->query->get('node_type');
- // }
- $this->keys = $this->request->query->get('q');
- }
- /**
- * searchResults
- */
- public function searchResults(Request $request) {
- $this->request = $request;
- $this->getRequestSearchArgs();
- return $this->getrenderable();
- }
- /**
- * searchResultsJson
- */
- public function searchResultsJson(Request $request){
- $this->request = $request;
- $this->getRequestSearchArgs();
- $renderable = $this->getrenderable();
- $rendered = \Drupal::service('renderer')->render($renderable);
- // build an array of results's nids
- $results_nids = [];
- foreach ($this->items as $item) {
- $results_nids[] = $item->id();
- }
- $response = new JsonResponse();
- $response->setData([
- 'keys'=>$this->keys,
- 'entries' => $this->entries,
- 'entry_names' => $this->entry_names,
- 'langues' => $this->langues,
- 'genres' => $this->genres,
- 'rendered'=> $rendered,
- 'results_nids'=>$results_nids,
- ]);
- return $response;
- }
- /**
- * getRenderable
- */
- private function getRenderable(){
- $this->query();
- $build = array(
- '#theme' => 'edlp_search_results',
- '#items' => $this->items
- );
- if(!count($this->items)){
- $build['#no_results_found'] = array(
- '#markup' => t('Your search yielded no results.')
- );
- // $build['#search_help'] = array(
- // '#markup' => $this->t('<ul>
- // <li>Check if your spelling is correct.</li>
- // <li>Remove quotes around phrases to search for each word individually. <em>bike shed</em> will often show more results than <em>"bike shed"</em>.</li>
- // <li>Consider loosening your query with <em>OR</em>. <em>bike OR shed</em> will often show more results than <em>bike shed</em>.</li>
- // </ul>')
- // );
- }
- return $build;
- }
- /**
- * query
- */
- private function query(){
- // TODO: get the sapi index id with settings
- /* @var $sapi_index \Drupal\search_api\IndexInterface */
- $sapi_index = Index::load($this->sapi_index_id);
- // dpm($sapi_index);
- // Create the query.
- $query = $sapi_index->query();
- // dpm($query);
- $query->setSearchID('edlp_search:ajaxsearch');
- $parse_mode = \Drupal::getContainer()
- ->get('plugin.manager.search_api.parse_mode')
- ->createInstance('direct');
- // $parse_mode->setConjunction('AND');
- $query->setParseMode($parse_mode);
- // search in both languages (if not conditions will not work)
- $query->setLanguages(array('fr','en'));
- // workflow
- $wf_condition_group = $query->createConditionGroup('OR');
- $wf_condition_group->addCondition('field_workflow', 'corpus_documents_publie', "=");
- // TODO: add condition with the other workflow field
- $query->addConditionGroup($wf_condition_group);
- // Search for keys.
- if (!empty($this->keys)) {
- // $query->keys($this->keys);
- $keys_condition_group = $query->createConditionGroup('OR');
- $keys_condition_group->addCondition('title', $this->keys, 'IN');
- $keys_condition_group->addCondition('field_description', $this->keys, 'IN');
- $query->addConditionGroup($keys_condition_group);
- }
- // langues
- if (!empty($this->langues)) {
- $query->addCondition('field_langues', $this->langues, "=");
- }
- // genres
- if (!empty($this->genres)) {
- $query->addCondition('field_genres', $this->genres, "=");
- }
- // TODO: locuteurs
- // entries
- $this->entry_names = [];
- if (!empty($this->entries)){
- $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadMultiple($this->entries);
- $entries_condition_group = $query->createConditionGroup();
- foreach ($terms as $tid => $term) {
- $entries_condition_group->addCondition('field_entrees', (int)$tid, "=");
- $this->entry_names[] = $term->getName();
- }
- // dpm($entries_condition_group);
- $query->addConditionGroup($entries_condition_group);
- }
- $result = $query->execute();
- $items = $result->getResultItems();
- // dpm($items);
- $this->items = [];
- $ids = [];
- foreach ($items as $item) {
- try {
- /** @var \Drupal\Core\Entity\EntityInterface $entity */
- $entity = $item->getOriginalObject()->getValue();
- }
- catch (SearchApiException $e) {
- continue;
- }
- if (!$entity) {
- continue;
- }
- // get distinct results
- if(in_array($entity->id(), $ids)){
- continue;
- }
- $ids[] = $entity->id();
- // record results
- $this->items[] = $entity;
- }
- // dpm($this->items);
- }
- /**
- * getRequestArgs
- */
- private function getRequestSearchArgs(){
- // dpm($this->request);
- $this->keys = $this->request->query->get('keys');
- $this->langues = $this->request->query->get('langues');
- $this->genres = $this->request->query->get('genres');
- $this->entries = $this->request->query->get('entries');
- }
- }
|