/** * Rotate the log files * * @deprecated Deprecated since Contao 4.0, to be removed in Contao 5.0. * Use the logger service instead, which rotates its log files automatically. */ public function rotateLogs() { @trigger_error('Using Automator::rotateLogs() has been deprecated and will no longer work in Contao 5.0. Use the logger service instead, which rotates its log files automatically.', E_USER_DEPRECATED); $arrFiles = preg_grep('/\\.log$/', scan(TL_ROOT . '/system/logs')); foreach ($arrFiles as $strFile) { $objFile = new \File('system/logs/' . $strFile . '.9'); // Delete the oldest file if ($objFile->exists()) { $objFile->delete(); } // Rotate the files (e.g. error.log.4 becomes error.log.5) for ($i = 8; $i > 0; $i--) { $strGzName = 'system/logs/' . $strFile . '.' . $i; if (file_exists(TL_ROOT . '/' . $strGzName)) { $objFile = new \File($strGzName); $objFile->renameTo('system/logs/' . $strFile . '.' . ($i + 1)); } } // Add .1 to the latest file $objFile = new \File('system/logs/' . $strFile); $objFile->renameTo('system/logs/' . $strFile . '.1'); } }
/** * Rotate the log files */ public function rotateLogs() { $arrFiles = preg_grep('/\\.log$/', scan(TL_ROOT . '/system/logs')); foreach ($arrFiles as $strFile) { $objFile = new \File('system/logs/' . $strFile . '.9'); // Delete the oldest file if ($objFile->exists()) { $objFile->delete(); } // Rotate the files (e.g. error.log.4 becomes error.log.5) for ($i = 8; $i > 0; $i--) { $strGzName = 'system/logs/' . $strFile . '.' . $i; if (file_exists(TL_ROOT . '/' . $strGzName)) { $objFile = new \File($strGzName); $objFile->renameTo('system/logs/' . $strFile . '.' . ($i + 1)); } } // Add .1 to the latest file $objFile = new \File('system/logs/' . $strFile); $objFile->renameTo('system/logs/' . $strFile . '.1'); } }
/** * Generate the module */ 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') && !BE_USER_LOGGED_IN) { $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($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(); $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', $arrResult[$i]['text'], $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']; } }
/** * Ajax actions that do not require a data container object */ public function executePreActions() { /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); switch ($this->strAction) { // Toggle navigation menu case 'toggleNavigation': $bemod = $objSessionBag->get('backend_modules'); $bemod[\Input::post('id')] = intval(\Input::post('state')); $objSessionBag->set('backend_modules', $bemod); throw new NoContentResponseException(); // Load a navigation menu group // Load a navigation menu group case 'loadNavigation': $bemod = $objSessionBag->get('backend_modules'); $bemod[\Input::post('id')] = intval(\Input::post('state')); $objSessionBag->set('backend_modules', $bemod); $this->import('BackendUser', 'User'); /** @var \BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_navigation'); $navigation = $this->User->navigation(); $objTemplate->modules = $navigation[\Input::post('id')]['modules']; throw new ResponseException($objTemplate->getResponse()); // Toggle nodes of the file or page tree // Toggle nodes of the file or page tree case 'toggleStructure': case 'toggleFileManager': case 'togglePagetree': case 'toggleFiletree': $this->strAjaxId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', \Input::post('id')); $this->strAjaxKey = str_replace('_' . $this->strAjaxId, '', \Input::post('id')); if (\Input::get('act') == 'editAll') { $this->strAjaxKey = preg_replace('/(.*)_[0-9a-zA-Z]+$/', '$1', $this->strAjaxKey); $this->strAjaxName = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', \Input::post('name')); } $nodes = $objSessionBag->get($this->strAjaxKey); $nodes[$this->strAjaxId] = intval(\Input::post('state')); $objSessionBag->set($this->strAjaxKey, $nodes); throw new NoContentResponseException(); // Load nodes of the file or page tree // Load nodes of the file or page tree case 'loadStructure': case 'loadFileManager': case 'loadPagetree': case 'loadFiletree': $this->strAjaxId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', \Input::post('id')); $this->strAjaxKey = str_replace('_' . $this->strAjaxId, '', \Input::post('id')); if (\Input::get('act') == 'editAll') { $this->strAjaxKey = preg_replace('/(.*)_[0-9a-zA-Z]+$/', '$1', $this->strAjaxKey); $this->strAjaxName = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', \Input::post('name')); } $nodes = $objSessionBag->get($this->strAjaxKey); $nodes[$this->strAjaxId] = intval(\Input::post('state')); $objSessionBag->set($this->strAjaxKey, $nodes); break; // Toggle the visibility of a fieldset // Toggle the visibility of a fieldset case 'toggleFieldset': $fs = $objSessionBag->get('fieldset_states'); $fs[\Input::post('table')][\Input::post('id')] = intval(\Input::post('state')); $objSessionBag->set('fieldset_states', $fs); throw new NoContentResponseException(); // Check whether the temporary directory is writeable // Check whether the temporary directory is writeable case 'liveUpdate': \Config::set('liveUpdateId', \Input::post('id')); \Config::persist('liveUpdateId', \Input::post('id')); // Check whether the temp directory is writeable try { $objFile = new \File('system/tmp/' . md5(uniqid(mt_rand(), true))); $objFile->close(); $objFile->delete(); } catch (\Exception $e) { if ($e->getCode() == 0) { \System::loadLanguageFile('tl_maintenance'); throw new ResponseException($this->convertToResponse('<p class="tl_error">' . $GLOBALS['TL_LANG']['tl_maintenance']['notWriteable'] . '</p>')); } } throw new NoContentResponseException(); // Toggle checkbox groups // Toggle checkbox groups case 'toggleCheckboxGroup': $state = $objSessionBag->get('checkbox_groups'); $state[\Input::post('id')] = intval(\Input::post('state')); $objSessionBag->set('checkbox_groups', $state); break; // HOOK: pass unknown actions to callback functions // HOOK: pass unknown actions to callback functions default: if (isset($GLOBALS['TL_HOOKS']['executePreActions']) && is_array($GLOBALS['TL_HOOKS']['executePreActions'])) { foreach ($GLOBALS['TL_HOOKS']['executePreActions'] as $callback) { $this->import($callback[0]); $this->{$callback}[0]->{$callback}[1]($this->strAction); } } break; } }