/**
  * Generate the module
  */
 protected function compile()
 {
     /** @var \PageModel $objPage */
     global $objPage;
     // Mark the x and y parameter as used (see #4277)
     if (isset($_GET['x'])) {
         \Input::get('x');
         \Input::get('y');
     }
     // Trigger the search module from a custom form
     if (!isset($_GET['keywords']) && \Input::post('FORM_SUBMIT') == 'tl_search') {
         $_GET['keywords'] = \Input::post('keywords');
         $_GET['query_type'] = \Input::post('query_type');
         $_GET['per_page'] = \Input::post('per_page');
     }
     $blnFuzzy = $this->fuzzy;
     $strQueryType = \Input::get('query_type') ?: $this->queryType;
     $strKeywords = trim(\Input::get('keywords'));
     /** @var \FrontendTemplate|object $objFormTemplate */
     $objFormTemplate = new \FrontendTemplate($this->searchType == 'advanced' ? 'mod_search_advanced' : 'mod_search_simple');
     $objFormTemplate->uniqueId = $this->id;
     $objFormTemplate->queryType = $strQueryType;
     $objFormTemplate->keyword = specialchars($strKeywords);
     $objFormTemplate->keywordLabel = $GLOBALS['TL_LANG']['MSC']['keywords'];
     $objFormTemplate->optionsLabel = $GLOBALS['TL_LANG']['MSC']['options'];
     $objFormTemplate->search = specialchars($GLOBALS['TL_LANG']['MSC']['searchLabel']);
     $objFormTemplate->matchAll = specialchars($GLOBALS['TL_LANG']['MSC']['matchAll']);
     $objFormTemplate->matchAny = specialchars($GLOBALS['TL_LANG']['MSC']['matchAny']);
     $objFormTemplate->id = \Config::get('disableAlias') && \Input::get('id') ? \Input::get('id') : false;
     $objFormTemplate->action = ampersand(\Environment::get('indexFreeRequest'));
     // Redirect page
     if ($this->jumpTo && ($objTarget = $this->objModel->getRelated('jumpTo')) !== null) {
         $objFormTemplate->action = $this->generateFrontendUrl($objTarget->row());
     }
     $this->Template->form = $objFormTemplate->parse();
     $this->Template->pagination = '';
     $this->Template->results = '';
     // Execute the search if there are keywords
     if ($strKeywords != '' && $strKeywords != '*' && !$this->jumpTo) {
         // Reference page
         if ($this->rootPage > 0) {
             $intRootId = $this->rootPage;
             $arrPages = $this->Database->getChildRecords($this->rootPage, 'tl_page');
             array_unshift($arrPages, $this->rootPage);
         } else {
             $intRootId = $objPage->rootId;
             $arrPages = $this->Database->getChildRecords($objPage->rootId, 'tl_page');
         }
         // customize by module
         $arrFilterPages = deserialize($this->filterPages, true);
         if (!empty($arrFilterPages) && $this->pageMode) {
             if ($this->addPageDepth) {
                 $arrFilterPages = array_merge($arrFilterPages, \Database::getInstance()->getChildRecords($arrFilterPages, 'tl_page'));
             }
             switch ($this->pageMode) {
                 case 'include':
                     $arrPages = $arrFilterPages;
                     break;
                 case 'exclude':
                     $arrPages = array_diff($arrPages, $arrFilterPages);
                     break;
             }
         }
         // HOOK: add custom logic (see #5223)
         if (isset($GLOBALS['TL_HOOKS']['customizeSearch']) && is_array($GLOBALS['TL_HOOKS']['customizeSearch'])) {
             foreach ($GLOBALS['TL_HOOKS']['customizeSearch'] as $callback) {
                 $this->import($callback[0]);
                 $this->{$callback}[0]->{$callback}[1]($arrPages, $strKeywords, $strQueryType, $blnFuzzy);
             }
         }
         // Return if there are no pages
         if (!is_array($arrPages) || empty($arrPages)) {
             $this->log('No searchable pages found', __METHOD__, TL_ERROR);
             return;
         }
         $arrResult = null;
         $strChecksum = md5($strKeywords . $strQueryType . $intRootId . $blnFuzzy . implode(',', $arrPages));
         $query_starttime = microtime(true);
         $strCacheFile = 'system/cache/search/' . $strChecksum . '.json';
         //			 Load the cached result
         if (file_exists(TL_ROOT . '/' . $strCacheFile)) {
             $objFile = new \File($strCacheFile, true);
             if ($objFile->mtime > time() - 1800) {
                 $arrResult = json_decode($objFile->getContent(), true);
             } else {
                 $objFile->delete();
             }
         }
         // Cache the result
         if ($arrResult === null) {
             try {
                 $objSearch = \Search::searchFor($strKeywords, $strQueryType == 'or', $arrPages, 0, 0, $blnFuzzy);
                 $arrResult = $objSearch->fetchAllAssoc();
             } catch (\Exception $e) {
                 $this->log('Website search failed: ' . $e->getMessage(), __METHOD__, TL_ERROR);
                 $arrResult = array();
             }
             \File::putContent($strCacheFile, json_encode($arrResult));
         }
         $query_endtime = microtime(true);
         $objSearchResults = new SearchResultList(array_values($arrResult), $this->objModel);
         $count = $objSearchResults->count();
         $this->Template->count = $count;
         $this->Template->page = null;
         $this->Template->keywords = $strKeywords;
         // No results
         if ($count < 1) {
             $this->Template->header = sprintf($GLOBALS['TL_LANG']['MSC']['sEmpty'], $strKeywords);
             $this->Template->duration = substr($query_endtime - $query_starttime, 0, 6) . ' ' . $GLOBALS['TL_LANG']['MSC']['seconds'];
             return;
         }
         $from = 1;
         $to = $count;
         // Pagination
         if ($this->perPage > 0) {
             $id = 'page_s' . $this->id;
             $page = \Input::get($id) !== null ? \Input::get($id) : 1;
             $per_page = \Input::get('per_page') ?: $this->perPage;
             // Do not index or cache the page if the page number is outside the range
             if ($page < 1 || $page > max(ceil($count / $per_page), 1)) {
                 /** @var \PageError404 $objHandler */
                 $objHandler = new $GLOBALS['TL_PTY']['error_404']();
                 $objHandler->generate($objPage->id);
             }
             $from = ($page - 1) * $per_page + 1;
             $to = $from + $per_page > $count ? $count : $from + $per_page - 1;
             // Pagination menu
             if ($to < $count || $from > 1) {
                 $objPagination = new \Pagination($count, $per_page, \Config::get('maxPaginationLinks'), $id);
                 $this->Template->pagination = $objPagination->generate("\n  ");
             }
             $this->Template->page = $page;
         }
         // Get the results
         for ($i = $from - 1; $i < $to && $i < $count; $i++) {
             /** @var \FrontendTemplate|object $objTemplate */
             $objTemplate = new \FrontendTemplate($this->searchTpl ?: 'search_default');
             if (!$objSearchResults->offsetExists($i)) {
                 continue;
             }
             $objResult = $objSearchResults->offsetGet($i);
             $objTemplate->url = $objResult->url;
             $objTemplate->link = $objResult->title;
             $objTemplate->href = $objResult->url;
             $objTemplate->target = $objResult->isValidFile() ? $objPage->outputFormat == 'xhtml' ? ' onclick="return !window.open(this.href)"' : ' target="_blank"' : '';
             $objTemplate->title = specialchars($objResult->title);
             $objTemplate->class = ($i == $from - 1 ? 'first ' : '') . ($i == $to - 1 || $i == $count - 1 ? 'last ' : '') . ($i % 2 == 0 ? 'even' : 'odd');
             $objTemplate->relevance = sprintf($GLOBALS['TL_LANG']['MSC']['relevance'], number_format($objResult->relevance / $objSearchResults->first()->relevance * 100, 2) . '%');
             $objTemplate->filesize = $objResult->filesize;
             $objTemplate->matches = $objResult->matches;
             $arrContext = array();
             $arrMatches = trimsplit(',', $objResult->matches);
             // Get the context
             foreach ($arrMatches as $strWord) {
                 $arrChunks = array();
                 preg_match_all('/(^|\\b.{0,' . $this->contextLength . '}\\PL)' . str_replace('+', '\\+', $strWord) . '(\\PL.{0,' . $this->contextLength . '}\\b|$)/ui', $objResult->text, $arrChunks);
                 foreach ($arrChunks[0] as $strContext) {
                     $arrContext[] = ' ' . $strContext . ' ';
                 }
             }
             // Shorten the context and highlight all keywords
             if (!empty($arrContext)) {
                 $objTemplate->context = trim(\String::substrHtml(implode('…', $arrContext), $this->totalLength));
                 $objTemplate->context = preg_replace('/(\\PL)(' . implode('|', $arrMatches) . ')(\\PL)/ui', '$1<span class="highlight">$2</span>$3', $objTemplate->context);
                 $objTemplate->hasContext = true;
             }
             $this->Template->results .= $objTemplate->parse();
         }
         $this->Template->header = vsprintf($GLOBALS['TL_LANG']['MSC']['sResults'], array($from, $to, $count, $strKeywords));
         $this->Template->duration = substr($query_endtime - $query_starttime, 0, 6) . ' ' . $GLOBALS['TL_LANG']['MSC']['seconds'];
     }
 }
예제 #2
0
 public static function SearchNewNavigatorEvent(User $user, PacketParser $packet, ClassContainer $util)
 {
     $name = $packet->readString();
     $junk = $packet->readString();
     switch ($name) {
         case "official_view":
             $navigatorlength = 2;
             break;
         case "myworld_view":
             $navigatorlength = 5;
             break;
         case "hotel_view":
         case "roomads_view":
             $navigatorlength = count($util->Cache->navigatorcategories) + 1;
             break;
         default:
             $navigatorlength = 1;
             break;
     }
     $response = new PacketConstructor();
     $response->SetHeader($util->HeaderManager->Outgoing("SearchResultSetComposer"));
     $response->WriteString($name);
     $response->WriteString($junk);
     //$response->WriteInt32(strlen($junk) > 0 ? 1 : $navigatorlength);
     if (strlen($junk) > 0) {
         $response->WriteInt32(strlen($junk) > 0 ? 1 : $navigatorlength);
         SearchResultList::SerializeSearches($junk, $response, $util);
     } else {
         $response->WriteInt32(0);
         //SearchResultList::SerializeSearchResultListStatics($name, true, $response, $util);
     }
     $user->Send($response->Finalize());
 }