Passed
Push — release-11.5.x ( 282d0d...a0b867 )
by Rafael
36:25
created

FrequentSearchesService   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Test Coverage

Coverage 74.47%

Importance

Changes 0
Metric Value
wmc 18
eloc 51
dl 0
loc 144
ccs 35
cts 47
cp 0.7447
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
B getFrequentSearchTerms() 0 28 7
A hasValidCache() 0 3 1
A getFrequentSearchTermsFromStatistics() 0 28 4
A getCacheIdentifier() 0 14 5
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace ApacheSolrForTypo3\Solr\Domain\Search\FrequentSearches;
19
20
use ApacheSolrForTypo3\Solr\Domain\Search\Statistics\StatisticsRepository;
21
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
22
use ApacheSolrForTypo3\Solr\Util;
23
use TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend;
24
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
25
use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
28
29
/**
30
 * The FrequentSearchesService is used to retrieve the frequent searches from the database or cache.
31
 *
32
 * @author Dimitri Ebert <[email protected]>
33
 * @author Timo Schmidt <[email protected]>
34
 * @copyright (c) 2015-2021 dkd Internet Service GmbH <[email protected]>
35
 */
36
class FrequentSearchesService
37
{
38
    /**
39
     * Instance of the caching frontend used to cache this command's output.
40
     *
41
     * @var AbstractFrontend|null
42
     */
43
    protected ?AbstractFrontend $cache;
44
45
    /**
46
     * @var TypoScriptFrontendController|null
47
     */
48
    protected ?TypoScriptFrontendController $tsfe;
49
50
    /**
51
     * @var StatisticsRepository|null
52
     */
53
    protected ?StatisticsRepository $statisticsRepository;
54
55
    /**
56
     * @var TypoScriptConfiguration
57
     */
58
    protected TypoScriptConfiguration $configuration;
59
60
    /**
61
     * @param TypoScriptConfiguration $typoscriptConfiguration
62
     * @param AbstractFrontend|null $cache
63
     * @param TypoScriptFrontendController|null $tsfe
64
     * @param StatisticsRepository|null $statisticsRepository
65
     */
66 2
    public function __construct(
67
        TypoScriptConfiguration $typoscriptConfiguration,
68
        AbstractFrontend $cache = null,
69
        TypoScriptFrontendController $tsfe = null,
70
        StatisticsRepository $statisticsRepository = null
71
    ) {
72 2
        $this->configuration = $typoscriptConfiguration;
73 2
        $this->cache = $cache;
74 2
        $this->tsfe = $tsfe;
75 2
        $this->statisticsRepository = $statisticsRepository ?? GeneralUtility::makeInstance(StatisticsRepository::class);
76
    }
77
78
    /**
79
     * Generates an array with terms and hits
80
     *
81
     * @return array Tags as array with terms and hits
82
     * @throws AspectNotFoundException
83
     */
84 2
    public function getFrequentSearchTerms(): array
85
    {
86 2
        $frequentSearchConfiguration = $this->configuration->getSearchFrequentSearchesConfiguration();
87
88 2
        $identifier = $this->getCacheIdentifier($frequentSearchConfiguration);
89
90 2
        if ($this->hasValidCache() && $this->cache->has($identifier)) {
91 1
            $terms = $this->cache->get($identifier);
92
        } else {
93 1
            $terms = $this->getFrequentSearchTermsFromStatistics($frequentSearchConfiguration);
94
95 1
            if (isset($frequentSearchConfiguration['sortBy']) && $frequentSearchConfiguration['sortBy'] === 'hits') {
96
                arsort($terms);
97
            } else {
98 1
                ksort($terms);
99
            }
100
101 1
            $lifetime = null;
102 1
            if (isset($frequentSearchConfiguration['cacheLifetime'])) {
103
                $lifetime = (int)($frequentSearchConfiguration['cacheLifetime']);
104
            }
105
106 1
            if ($this->hasValidCache()) {
107 1
                $this->cache->set($identifier, $terms, [], $lifetime);
108
            }
109
        }
110
111 2
        return $terms;
112
    }
113
114
    /**
115
     * Gets frequent search terms from the statistics tracking table.
116
     *
117
     * @param array $frequentSearchConfiguration
118
     * @return array Array of frequent search terms, keys are the terms, values are hits
119
     * @throws AspectNotFoundException
120
     */
121 1
    protected function getFrequentSearchTermsFromStatistics(array $frequentSearchConfiguration = []): array
122
    {
123 1
        $terms = [];
124
125 1
        if ($frequentSearchConfiguration['select.']['checkRootPageId']) {
126 1
            $checkRootPidWhere = 'root_pid = ' . $this->tsfe->tmpl->rootLine[0]['uid'];
127
        } else {
128
            $checkRootPidWhere = '1';
129
        }
130 1
        if ($frequentSearchConfiguration['select.']['checkLanguage']) {
131 1
            $checkLanguageWhere = ' AND language =' . Util::getLanguageUid();
132
        } else {
133
            $checkLanguageWhere = '';
134
        }
135
136 1
        $frequentSearchConfiguration['select.']['ADD_WHERE'] = $checkRootPidWhere .
137 1
            $checkLanguageWhere . ' ' .
138 1
            $frequentSearchConfiguration['select.']['ADD_WHERE'];
139
140 1
        $frequentSearchTerms = $this->statisticsRepository
141 1
            ->getFrequentSearchTermsFromStatisticsByFrequentSearchConfiguration($frequentSearchConfiguration);
0 ignored issues
show
Bug introduced by
The method getFrequentSearchTermsFr...ntSearchConfiguration() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

141
        /** @scrutinizer ignore-call */ 
142
        $frequentSearchTerms = $this->statisticsRepository

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
142
143 1
        foreach ($frequentSearchTerms as $term) {
144 1
            $cleanedTerm = html_entity_decode($term['search_term'], ENT_QUOTES, 'UTF-8');
145 1
            $terms[$cleanedTerm] = $term['hits'];
146
        }
147
148 1
        return $terms;
149
    }
150
151
    /**
152
     * @param array $frequentSearchConfiguration
153
     * @return string
154
     * @throws AspectNotFoundException
155
     */
156
    protected function getCacheIdentifier(array $frequentSearchConfiguration): string
157
    {
158
        // Use configuration as cache identifier
159
        $identifier = 'frequentSearchesTags';
160
161
        if (isset($frequentSearchConfiguration['select.']['checkRootPageId']) && $frequentSearchConfiguration['select.']['checkRootPageId']) {
162
            $identifier .= '_RP' . (int)$this->tsfe->tmpl->rootLine[0]['uid'];
163
        }
164
        if (isset($frequentSearchConfiguration['select.']['checkLanguage']) && $frequentSearchConfiguration['select.']['checkLanguage']) {
165
            $identifier .= '_L' . Util::getLanguageUid();
166
        }
167
168
        $identifier .= '_' . md5(serialize($frequentSearchConfiguration));
169
        return $identifier;
170
    }
171
172
    /**
173
     * Checks if this service has a valid cache class
174
     *
175
     * @return bool
176
     */
177 2
    protected function hasValidCache(): bool
178
    {
179 2
        return $this->cache instanceof FrontendInterface;
180
    }
181
}
182