* @author Timo Schmidt * @copyright (c) 2015-2021 dkd Internet Service GmbH */ class FrequentSearchesService { /** * Instance of the caching frontend used to cache this command's output. * * @var AbstractFrontend */ protected $cache; /** * @var TypoScriptFrontendController */ protected $tsfe; /** * @var StatisticsRepository */ protected $statisticsRepository; /** * @var TypoScriptConfiguration */ protected $configuration; /** * @param TypoScriptConfiguration $typoscriptConfiguration * @param AbstractFrontend|null $cache * @param TypoScriptFrontendController|null $tsfe * @param StatisticsRepository|null $statisticsRepository */ public function __construct( TypoScriptConfiguration $typoscriptConfiguration, AbstractFrontend $cache = null, TypoScriptFrontendController $tsfe = null, StatisticsRepository $statisticsRepository = null ) { $this->configuration = $typoscriptConfiguration; $this->cache = $cache; $this->tsfe = $tsfe; $this->statisticsRepository = $statisticsRepository ?? GeneralUtility::makeInstance(StatisticsRepository::class); } /** * Generates an array with terms and hits * * @return array Tags as array with terms and hits */ public function getFrequentSearchTerms() : array { $frequentSearchConfiguration = $this->configuration->getSearchFrequentSearchesConfiguration(); $identifier = $this->getCacheIdentifier($frequentSearchConfiguration); if ($this->hasValidCache() && $this->cache->has($identifier)) { $terms = $this->cache->get($identifier); } else { $terms = $this->getFrequentSearchTermsFromStatistics($frequentSearchConfiguration); if ($frequentSearchConfiguration['sortBy'] === 'hits') { arsort($terms); } else { ksort($terms); } $lifetime = null; if (isset($frequentSearchConfiguration['cacheLifetime'])) { $lifetime = intval($frequentSearchConfiguration['cacheLifetime']); } if ($this->hasValidCache()) { $this->cache->set($identifier, $terms, [], $lifetime); } } return $terms; } /** * Gets frequent search terms from the statistics tracking table. * * @param array $frequentSearchConfiguration * @return array Array of frequent search terms, keys are the terms, values are hits */ protected function getFrequentSearchTermsFromStatistics(array $frequentSearchConfiguration) : array { $terms = []; if ($frequentSearchConfiguration['select.']['checkRootPageId']) { $checkRootPidWhere = 'root_pid = ' . $this->tsfe->tmpl->rootLine[0]['uid']; } else { $checkRootPidWhere = '1'; } if ($frequentSearchConfiguration['select.']['checkLanguage']) { $checkLanguageWhere = ' AND language =' . Util::getLanguageUid(); } else { $checkLanguageWhere = ''; } $frequentSearchConfiguration['select.']['ADD_WHERE'] = $checkRootPidWhere . $checkLanguageWhere . ' ' . $frequentSearchConfiguration['select.']['ADD_WHERE']; $frequentSearchTerms = $this->statisticsRepository ->getFrequentSearchTermsFromStatisticsByFrequentSearchConfiguration($frequentSearchConfiguration); if (!is_array($frequentSearchTerms)) { return $terms; } foreach ($frequentSearchTerms as $term) { $cleanedTerm = html_entity_decode($term['search_term'], ENT_QUOTES, 'UTF-8'); $terms[$cleanedTerm] = $term['hits']; } return $terms; } /** * @param array $frequentSearchConfiguration * @return string */ protected function getCacheIdentifier(array $frequentSearchConfiguration) : string { // Use configuration as cache identifier $identifier = 'frequentSearchesTags'; if ($frequentSearchConfiguration['select.']['checkRootPageId']) { $identifier .= '_RP' . (int)$this->tsfe->tmpl->rootLine[0]['uid']; } if ($frequentSearchConfiguration['select.']['checkLanguage']) { $identifier .= '_L' . Util::getLanguageUid(); } $identifier .= '_' . md5(serialize($frequentSearchConfiguration)); return $identifier; } /** * Checks if this service has a valid cache class * * @return bool */ protected function hasValidCache(): bool { return ($this->cache instanceof FrontendInterface); } }