vendor/pringuin/pimcore-lucene-search/src/LuceneSearchBundle/Controller/FrontendController.php line 126

Open in your IDE?
  1. <?php
  2. namespace LuceneSearchBundle\Controller;
  3. use LuceneSearchBundle\Configuration\Configuration;
  4. use LuceneSearchBundle\Event\RestrictionContextEvent;
  5. use LuceneSearchBundle\Helper\LuceneHelper;
  6. use LuceneSearchBundle\Helper\StringHelper;
  7. use LuceneSearchBundle\LuceneSearchEvents;
  8. use Symfony\Component\HttpFoundation\RequestStack;
  9. use Pimcore\Controller\FrontendController as PimcoreFrontEndController;
  10. class FrontendController extends PimcoreFrontEndController
  11. {
  12.     /**
  13.      * @var RequestStack
  14.      */
  15.     protected $requestStack;
  16.     /**
  17.      * @var Configuration
  18.      */
  19.     protected $configuration;
  20.     /**
  21.      * @var LuceneHelper
  22.      */
  23.     protected $luceneHelper;
  24.     /**
  25.      * @var StringHelper
  26.      */
  27.     private $stringHelper;
  28.     /**
  29.      * @var \Zend_Search_Lucene_Interface
  30.      */
  31.     protected $frontendIndex;
  32.     /**
  33.      * @var array
  34.      */
  35.     protected $categories = [];
  36.     /**
  37.      * category, to restrict query, incoming argument
  38.      *
  39.      * @var array
  40.      */
  41.     protected $queryCategories = [];
  42.     /**
  43.      * query, incoming argument
  44.      *
  45.      * @var String
  46.      */
  47.     protected $query '';
  48.     /**
  49.      * query, incoming argument, unmodified
  50.      *
  51.      * @var String
  52.      */
  53.     protected $untouchedQuery '';
  54.     /**
  55.      * @var string
  56.      */
  57.     protected $searchLanguage null;
  58.     /**
  59.      * @var string
  60.      */
  61.     protected $searchCountry null;
  62.     /**
  63.      * @var bool
  64.      */
  65.     protected $checkRestriction false;
  66.     /**
  67.      * @var bool
  68.      */
  69.     protected $ownHostOnly false;
  70.     /**
  71.      * @var bool
  72.      */
  73.     protected $allowSubDomains false;
  74.     /**
  75.      * @var bool
  76.      */
  77.     protected $fuzzySearchResults false;
  78.     /**
  79.      * @var bool
  80.      */
  81.     protected $searchSuggestion false;
  82.     /**
  83.      * @var int
  84.      */
  85.     protected $maxSuggestions 10;
  86.     /**
  87.      * @var int
  88.      */
  89.     protected $perPage 10;
  90.     /**
  91.      * @var int
  92.      */
  93.     protected $currentPage 1;
  94.     /**
  95.      * FrontendController constructor.
  96.      *
  97.      * @param RequestStack  $requestStack
  98.      * @param Configuration $configuration
  99.      * @param LuceneHelper  $luceneHelper
  100.      * @param StringHelper  $stringHelper
  101.      *
  102.      * @throws \Exception
  103.      */
  104.     public function __construct(
  105.         RequestStack $requestStack,
  106.         Configuration $configuration,
  107.         LuceneHelper $luceneHelper,
  108.         StringHelper $stringHelper
  109.     ) {
  110.         $this->requestStack $requestStack;
  111.         $this->configuration $configuration;
  112.         $this->luceneHelper $luceneHelper;
  113.         $this->stringHelper $stringHelper;
  114.         $requestQuery $this->requestStack->getMasterRequest()->query;
  115.         if (!$this->configuration->getConfig('enabled')) {
  116.             return false;
  117.         }
  118.         try {
  119.             \Zend_Search_Lucene_Analysis_Analyzer::setDefault(
  120.                 new \Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive()
  121.             );
  122.             $this->frontendIndex \Zend_Search_Lucene::open(Configuration::INDEX_DIR_PATH_STABLE);
  123.             //set search term query
  124.             $searchQuery $this->stringHelper->cleanRequestString($requestQuery->get('q'));
  125.             if (!empty($searchQuery)) {
  126.                 $this->query $this->luceneHelper->cleanTerm($searchQuery);
  127.                 $this->untouchedQuery $this->query;
  128.             }
  129.             $localeConfig $this->configuration->getConfig('locale');
  130.             $restrictionConfig $this->configuration->getConfig('restriction');
  131.             $viewConfig $this->configuration->getConfig('view');
  132.             //set Language
  133.             if ($localeConfig['ignore_language'] === false) {
  134.                 $requestLang $requestQuery->get('language');
  135.                 //no language provided, try to get from requestStack.
  136.                 if (empty($requestLang)) {
  137.                     $masterRequest $this->requestStack->getMasterRequest();
  138.                     if ($masterRequest) {
  139.                         $this->searchLanguage $this->requestStack->getMasterRequest()->getLocale();
  140.                     } else {
  141.                         $this->searchLanguage \Pimcore\Tool::getDefaultLanguage();
  142.                     }
  143.                 } else {
  144.                     $this->searchLanguage $requestLang;
  145.                 }
  146.             }
  147.             //Set Categories
  148.             $this->categories $this->configuration->getCategories();
  149.             $queryCategories $requestQuery->get('categories');
  150.             if (!empty($queryCategories)) {
  151.                 if (!is_array($queryCategories)) {
  152.                     $queryCategories = [$queryCategories];
  153.                 }
  154.                 $this->queryCategories array_map('intval'$queryCategories);
  155.             }
  156.             //Set Country
  157.             if ($localeConfig['ignore_country'] === false) {
  158.                 $this->searchCountry $requestQuery->get('country');
  159.                 if ($this->searchCountry == 'global') {
  160.                     $this->searchCountry 'international';
  161.                 } elseif (empty($this->searchCountry)) {
  162.                     $this->searchCountry 'international';
  163.                 }
  164.             } else {
  165.                 $this->searchCountry null;
  166.             }
  167.             //Set Restrictions (Auth)
  168.             $this->checkRestriction $restrictionConfig['enabled'] === true;
  169.             //Set Fuzzy Search
  170.             if ($this->configuration->getConfig('fuzzy_search_results') === true) {
  171.                 $this->fuzzySearchResults true;
  172.             }
  173.             //Set Search Suggestions
  174.             if ($this->configuration->getConfig('search_suggestion') === true) {
  175.                 $this->searchSuggestion true;
  176.             }
  177.             //Set own Host Only
  178.             if ($this->configuration->getConfig('own_host_only') === true) {
  179.                 $this->ownHostOnly true;
  180.             }
  181.             //Set subdomain restriction
  182.             if ($this->configuration->getConfig('allow_subdomains') === true) {
  183.                 $this->allowSubDomains true;
  184.             }
  185.             //Set Entries per Page
  186.             $this->perPage $viewConfig['max_per_page'];
  187.             if (!empty($requestQuery->get('perPage'))) {
  188.                 $this->perPage = (int)$requestQuery->get('perPage');
  189.             }
  190.             //Set max Suggestions
  191.             $this->maxSuggestions $viewConfig['max_suggestions'];
  192.             //Set Current Page
  193.             $currentPage $requestQuery->get('page');
  194.             if (!empty($currentPage)) {
  195.                 $this->currentPage = (int)$currentPage;
  196.             }
  197.         } catch (\Exception $e) {
  198.             throw new \Exception('Error while parsing lucene search params (message was: ' $e->getMessage() . ').');
  199.         }
  200.     }
  201.     /**
  202.      * @param $queryHits
  203.      *
  204.      * @return array
  205.      */
  206.     protected function getValidHits($queryHits)
  207.     {
  208.         $validHits = [];
  209.         if ($this->ownHostOnly === false || $queryHits === null) {
  210.             $validHits $queryHits;
  211.             return $validHits;
  212.         }
  213.         $currentHost \Pimcore\Tool::getHostname();
  214.         $allowedHosts = [];
  215.         if ($this->allowSubDomains === true) {
  216.             // only use hostname.tld for comparison
  217.             $allowedHosts[] = join('.'array_slice(explode('.'$currentHost), -2));
  218.         } else {
  219.             // user entire *.hostname.tld for comparison
  220.             $allowedHosts[] = $currentHost;
  221.         }
  222.         /** @var \Zend_Search_Lucene_Search_QueryHit $hit */
  223.         foreach ($queryHits as $hit) {
  224.             try {
  225.                 $url $hit->getDocument()->getField('url');
  226.             } catch (\Zend_Search_Lucene_Exception $e) {
  227.                 continue;
  228.             }
  229.             $currentHostname parse_url($url->valuePHP_URL_HOST);
  230.             if ($this->allowSubDomains) {
  231.                 $currentHostname join('.'array_slice(explode('.'$currentHostname), -2));
  232.             }
  233.             if (in_array($currentHostname$allowedHosts)) {
  234.                 $validHits[] = $hit;
  235.             }
  236.         }
  237.         return $validHits;
  238.     }
  239.     /**
  240.      * @param \Zend_Search_Lucene_Search_Query_Boolean $query
  241.      */
  242.     protected function addAdditionalSubQueries(\Zend_Search_Lucene_Search_Query_Boolean $query)
  243.     {
  244.         $this->addLanguageQuery($query);
  245.         $this->addCategoryQuery($query);
  246.         $this->addCountryQuery($query);
  247.         $this->addRestrictionQuery($query);
  248.         // optimize boolean query before adding negative subquery
  249.         $query->rewrite($this->frontendIndex);
  250.         $this->addAvailabilityQuery($query);
  251.     }
  252.     /**
  253.      * @param \Zend_Search_Lucene_Search_Query_Boolean $query
  254.      */
  255.     protected function addAvailabilityQuery(\Zend_Search_Lucene_Search_Query_Boolean $query)
  256.     {
  257.         try {
  258.             $availabilityQuery = new \Zend_Search_Lucene_Search_Query_MultiTerm();
  259.         } catch (\Zend_Search_Lucene_Exception $e) {
  260.             return;
  261.         }
  262.         $availabilityQuery->addTerm(new \Zend_Search_Lucene_Index_Term('unavailable''internalAvailability'));
  263.         $query->addSubquery($availabilityQueryfalse);
  264.     }
  265.     /**
  266.      * @param \Zend_Search_Lucene_Search_Query_Boolean $query
  267.      */
  268.     protected function addCountryQuery(\Zend_Search_Lucene_Search_Query_Boolean $query)
  269.     {
  270.         if (empty($this->searchCountry)) {
  271.             return;
  272.         }
  273.         try {
  274.             $countryQuery = new \Zend_Search_Lucene_Search_Query_MultiTerm();
  275.         } catch (\Zend_Search_Lucene_Exception $e) {
  276.             return;
  277.         }
  278.         $countryQuery->addTerm(new \Zend_Search_Lucene_Index_Term('all''country'));
  279.         $country str_replace(['_''-'], ''$this->searchCountry);
  280.         $countryQuery->addTerm(new \Zend_Search_Lucene_Index_Term($country'country'));
  281.         $query->addSubquery($countryQuerytrue);
  282.     }
  283.     /**
  284.      * @param \Zend_Search_Lucene_Search_Query_Boolean $query
  285.      */
  286.     protected function addCategoryQuery(\Zend_Search_Lucene_Search_Query_Boolean $query)
  287.     {
  288.         if (empty($this->queryCategories) || !is_array($this->categories)) {
  289.             return;
  290.         }
  291.         try {
  292.             $categoryQuery = new \Zend_Search_Lucene_Search_Query_MultiTerm();
  293.         } catch (\Zend_Search_Lucene_Exception $e) {
  294.             return;
  295.         }
  296.         foreach ($this->queryCategories as $categoryId) {
  297.             $key array_search($categoryIdarray_column($this->categories'id'));
  298.             if ($key !== false) {
  299.                 $categoryQuery->addTerm(new \Zend_Search_Lucene_Index_Term(true'category_' $categoryId));
  300.             }
  301.         }
  302.         $query->addSubquery($categoryQuerytrue);
  303.     }
  304.     /**
  305.      * @param \Zend_Search_Lucene_Search_Query_Boolean $query
  306.      *
  307.      */
  308.     protected function addLanguageQuery(\Zend_Search_Lucene_Search_Query_Boolean $query)
  309.     {
  310.         if (empty($this->searchLanguage)) {
  311.             return;
  312.         }
  313.         try {
  314.             $languageQuery = new \Zend_Search_Lucene_Search_Query_MultiTerm();
  315.         } catch (\Zend_Search_Lucene_Exception $e) {
  316.             return;
  317.         }
  318.         $languageQuery->addTerm(new \Zend_Search_Lucene_Index_Term('all''lang'));
  319.         if (is_object($this->searchLanguage)) {
  320.             $lang $this->searchLanguage->toString();
  321.         } else {
  322.             $lang $this->searchLanguage;
  323.         }
  324.         $lang strtolower(str_replace('_''-'$lang));
  325.         $languageQuery->addTerm(new \Zend_Search_Lucene_Index_Term($lang'lang'));
  326.         $query->addSubquery($languageQuerytrue);
  327.     }
  328.     /**
  329.      * @param \Zend_Search_Lucene_Search_Query_Boolean $query
  330.      */
  331.     protected function addRestrictionQuery(\Zend_Search_Lucene_Search_Query_Boolean $query)
  332.     {
  333.         if (!$this->checkRestriction) {
  334.             return;
  335.         }
  336.         $event = new RestrictionContextEvent();
  337.         \Pimcore::getEventDispatcher()->dispatch(
  338.             $event,
  339.             LuceneSearchEvents::LUCENE_SEARCH_FRONTEND_RESTRICTION_CONTEXT,
  340.         );
  341.         try {
  342.             $restrictionQuery = new \Zend_Search_Lucene_Search_Query_MultiTerm();
  343.         } catch (\Zend_Search_Lucene_Exception $e) {
  344.             return;
  345.         }
  346.         $restrictionQuery->addTerm(new \Zend_Search_Lucene_Index_Term(true'restrictionGroup_default'));
  347.         $allowedGroups $event->getAllowedRestrictionGroups();
  348.         if (is_array($allowedGroups)) {
  349.             foreach ($allowedGroups as $groupId) {
  350.                 $restrictionQuery->addTerm(new \Zend_Search_Lucene_Index_Term(true'restrictionGroup_' $groupId));
  351.             }
  352.         }
  353.         $query->addSubquery($restrictionQuerytrue);
  354.     }
  355. }