Contao\ModuleSearch::compile PHP Метод

compile() защищенный Метод

Generate the module
protected compile ( )
    protected function compile()
    {
        // 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'));
        $this->Template->uniqueId = $this->id;
        $this->Template->queryType = $strQueryType;
        $this->Template->keyword = \StringUtil::specialchars($strKeywords);
        $this->Template->keywordLabel = $GLOBALS['TL_LANG']['MSC']['keywords'];
        $this->Template->optionsLabel = $GLOBALS['TL_LANG']['MSC']['options'];
        $this->Template->search = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['searchLabel']);
        $this->Template->matchAll = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['matchAll']);
        $this->Template->matchAny = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['matchAny']);
        $this->Template->action = ampersand(\Environment::get('indexFreeRequest'));
        $this->Template->advanced = $this->searchType == 'advanced';
        // Redirect page
        if ($this->jumpTo && ($objTarget = $this->objModel->getRelated('jumpTo')) instanceof PageModel) {
            /** @var PageModel $objTarget */
            $this->Template->action = $objTarget->getFrontendUrl();
        }
        $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 {
                /** @var PageModel $objPage */
                global $objPage;
                $intRootId = $objPage->rootId;
                $arrPages = $this->Database->getChildRecords($objPage->rootId, 'tl_page');
            }
            // 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)) {
                return;
            }
            $strCachePath = str_replace(TL_ROOT . DIRECTORY_SEPARATOR, '', \System::getContainer()->getParameter('kernel.cache_dir'));
            $arrResult = null;
            $strChecksum = md5($strKeywords . $strQueryType . $intRootId . $blnFuzzy);
            $query_starttime = microtime(true);
            $strCacheFile = $strCachePath . '/contao/search/' . $strChecksum . '.json';
            // Load the cached result
            if (file_exists(TL_ROOT . '/' . $strCacheFile)) {
                $objFile = new \File($strCacheFile);
                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);
            // Sort out protected pages
            if (\Config::get('indexProtected')) {
                $this->import('FrontendUser', 'User');
                foreach ($arrResult as $k => $v) {
                    if ($v['protected']) {
                        if (!FE_USER_LOGGED_IN) {
                            unset($arrResult[$k]);
                        } else {
                            $groups = \StringUtil::deserialize($v['groups']);
                            if (!is_array($groups) || empty($groups) || !count(array_intersect($groups, $this->User->groups))) {
                                unset($arrResult[$k]);
                            }
                        }
                    }
                }
                $arrResult = array_values($arrResult);
            }
            $count = count($arrResult);
            $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)) {
                    throw new PageNotFoundException('Page not found: ' . \Environment::get('uri'));
                }
                $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);
                $objTemplate->url = $arrResult[$i]['url'];
                $objTemplate->link = $arrResult[$i]['title'];
                $objTemplate->href = $arrResult[$i]['url'];
                $objTemplate->title = \StringUtil::specialchars(\StringUtil::stripInsertTags($arrResult[$i]['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($arrResult[$i]['relevance'] / $arrResult[0]['relevance'] * 100, 2) . '%');
                $objTemplate->filesize = $arrResult[$i]['filesize'];
                $objTemplate->matches = $arrResult[$i]['matches'];
                $arrContext = array();
                $strText = \StringUtil::stripInsertTags($arrResult[$i]['text']);
                $arrMatches = \StringUtil::trimsplit(',', $arrResult[$i]['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', $strText, $arrChunks);
                    foreach ($arrChunks[0] as $strContext) {
                        $arrContext[] = ' ' . $strContext . ' ';
                    }
                }
                // Shorten the context and highlight all keywords
                if (!empty($arrContext)) {
                    $objTemplate->context = trim(\StringUtil::substrHtml(implode('…', $arrContext), $this->totalLength));
                    $objTemplate->context = preg_replace('/(\\PL)(' . implode('|', $arrMatches) . ')(\\PL)/ui', '$1<mark class="highlight">$2</mark>$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'];
        }
    }