172 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
// https://www.drupal.org/docs/8/modules/search-api/developer-documentation/executing-a-search-in-code
 | 
						|
 | 
						|
namespace Drupal\materio_sapi\Controller;
 | 
						|
 | 
						|
use Drupal\Core\Controller\ControllerBase;
 | 
						|
use Symfony\Component\HttpFoundation\JsonResponse;
 | 
						|
use Symfony\Component\HttpFoundation\Request;
 | 
						|
use Drupal\Component\Utility\Tags;
 | 
						|
use Drupal\Component\Utility\Unicode;
 | 
						|
use Drupal\search_api\Entity\Index;
 | 
						|
 | 
						|
// https://drupal.stackexchange.com/questions/225008/programatically-use-search-api
 | 
						|
 | 
						|
/**
 | 
						|
 * Defines a route controller for materio sapi search (regular and ajax).
 | 
						|
 */
 | 
						|
class Base extends ControllerBase {
 | 
						|
 | 
						|
  private $limit = 15;
 | 
						|
  private $offset = 0;
 | 
						|
 | 
						|
  private function sapiQuery(){
 | 
						|
    $this->index = Index::load('database');
 | 
						|
    $this->query = $this->index->query();
 | 
						|
 | 
						|
    // Change the parse mode for the search.
 | 
						|
    $parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode')
 | 
						|
      ->createInstance('direct');
 | 
						|
    $parse_mode->setConjunction('OR');
 | 
						|
    $this->query->setParseMode($parse_mode);
 | 
						|
 | 
						|
    // Set fulltext search keywords and fields.
 | 
						|
    $this->query->keys($this->keys);
 | 
						|
    // $this->query->setFulltextFields(['name']);
 | 
						|
 | 
						|
    // Set additional conditions.
 | 
						|
    // $this->query->addCondition('status', 1)
 | 
						|
    //   ->addCondition('author', 1, '<>');
 | 
						|
 | 
						|
    // Restrict the search to specific languages.
 | 
						|
    // $this->query->setLanguages(['de', 'it']);
 | 
						|
 | 
						|
    // Do paging.
 | 
						|
    $this->query->range($this->offset, $this->limit);
 | 
						|
 | 
						|
    // Add sorting.
 | 
						|
    $this->query->sort('search_api_relevance', 'DESC');
 | 
						|
 | 
						|
    // Set one or more tags for the query.
 | 
						|
    // @see hook_search_api_query_TAG_alter()
 | 
						|
    // @see hook_search_api_results_TAG_alter()
 | 
						|
    $this->query->addTag('materio_sapi_search');
 | 
						|
 | 
						|
    $this->results = $this->query->execute();
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * get params from request
 | 
						|
   */
 | 
						|
  private function parseRequest(Request $request){
 | 
						|
    // Get the typed string from the URL, if it exists.
 | 
						|
    $this->keys = $request->query->get('keys');
 | 
						|
    if($this->keys){
 | 
						|
      $this->keys = Unicode::strtolower($this->keys);
 | 
						|
      // $this->keys = Tags::explode($this->keys);
 | 
						|
      \Drupal::logger('materio_sapi')->notice($this->keys);
 | 
						|
    }
 | 
						|
    $this->term = $request->query->get('term');
 | 
						|
    $this->offset = $request->query->get('offset') ?? $this->offset;
 | 
						|
    $this->limit = $request->query->get('limit') ?? $this->limit;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Handler for ajax search.
 | 
						|
   */
 | 
						|
  public function getResults(Request $request) {
 | 
						|
    $this->parseRequest($request);
 | 
						|
 | 
						|
    $resp = [
 | 
						|
      'keys' => $this->keys,
 | 
						|
      'term' => $this->term,
 | 
						|
      'range' => array(
 | 
						|
        'offset' => $this->offset,
 | 
						|
        'limit' => $this->limit
 | 
						|
      ),
 | 
						|
    ];
 | 
						|
 | 
						|
    if ($this->keys) {
 | 
						|
      $this->sapiQuery();
 | 
						|
 | 
						|
      $resp['count'] = $this->results->getResultCount();
 | 
						|
      $resp['infos'] = t('The search found @count result(s) with keywords @keys.', array(
 | 
						|
        "@count" => $resp['count'],
 | 
						|
        "@keys" => $this->keys
 | 
						|
      ));
 | 
						|
 | 
						|
 | 
						|
      $resp['options'] = $this->query->getOptions();
 | 
						|
 | 
						|
      // $items = [];
 | 
						|
      $uuids = [];
 | 
						|
      $nids = [];
 | 
						|
      foreach ($this->results as $result) {
 | 
						|
        // $nid = $result->getField('nid')->getValues()[0];
 | 
						|
        // $uuid = $result->getField('uuid')->getValues()[0];
 | 
						|
        // $title = $result->getField('title')->getValues()[0]->getText();
 | 
						|
        // $items[] = [
 | 
						|
        //   'nid' => $nid,
 | 
						|
        //   'uuid' => $uuid,
 | 
						|
        //   'title' => $title,
 | 
						|
        // ];
 | 
						|
        $uuids[] = $result->getField('uuid')->getValues()[0];
 | 
						|
        $nids[] = $result->getField('nid')->getValues()[0];
 | 
						|
      }
 | 
						|
      // $resp['items'] = $items;
 | 
						|
      $resp['uuids'] = $uuids;
 | 
						|
      $resp['nids'] = $nids;
 | 
						|
    }
 | 
						|
 | 
						|
    return new JsonResponse($resp);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Handler for regular page search.
 | 
						|
   */
 | 
						|
  function pageHandler(Request $request){
 | 
						|
    // \Drupal::logger('materio_sapi')->notice(print_r($request, true));
 | 
						|
 | 
						|
    $this->parseRequest($request);
 | 
						|
 | 
						|
    $resp = [
 | 
						|
      "#title" => 'Base'
 | 
						|
    ];
 | 
						|
 | 
						|
    if ($this->keys) {
 | 
						|
      $resp['#title'] = $this->keys;
 | 
						|
 | 
						|
      $this->sapiQuery();
 | 
						|
 | 
						|
      $node_view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
 | 
						|
 | 
						|
      $items = $this->results->getResultItems();
 | 
						|
      $this->items = [];
 | 
						|
      foreach ($items as $item) {
 | 
						|
        // \Drupal::logger('materio_sapi')->notice(print_r($item, true));
 | 
						|
        try {
 | 
						|
          /** @var \Drupal\Core\Entity\EntityInterface $entity */
 | 
						|
          $entity = $item->getOriginalObject()->getValue();
 | 
						|
        }
 | 
						|
        catch (SearchApiException $e) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
        if (!$entity) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
        // TODO: define dynamicly viewmode
 | 
						|
        $this->items[] = $node_view_builder->view($entity, 'teaser');
 | 
						|
 | 
						|
      }
 | 
						|
 | 
						|
      $resp['items'] = $this->items;
 | 
						|
    }else{
 | 
						|
      $resp['#markup'] = "no keys to search for";
 | 
						|
    }
 | 
						|
 | 
						|
    return $resp;
 | 
						|
  }
 | 
						|
}
 |