Passed
Push — master ( 94f5b1...0f0c33 )
by Timo
20:47
created

getLastSearchesFromFrontendSession()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace ApacheSolrForTypo3\Solr\Domain\Search\LastSearches;
4
5
/***************************************************************
6
 *  Copyright notice
7
 *
8
 *  (c) 2015-2016 Timo Schmidt <[email protected]>
9
 *  All rights reserved
10
 *
11
 *  This script is part of the TYPO3 project. The TYPO3 project is
12
 *  free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  The GNU General Public License can be found at
18
 *  http://www.gnu.org/copyleft/gpl.html.
19
 *
20
 *  This script is distributed in the hope that it will be useful,
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *  GNU General Public License for more details.
24
 *
25
 *  This copyright notice MUST APPEAR in all copies of the script!
26
 ***************************************************************/
27
28
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
29
use TYPO3\CMS\Core\Database\DatabaseConnection;
30
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
31
32
/**
33
 * The LastSearchesService is responsible to return the LastSearches from the session or database,
34
 * depending on the configuration.
35
 *
36
 * @author Timo Schmidt <[email protected]>
37
 */
38
class LastSearchesService
39
{
40
41
    /**
42
     * @var TypoScriptConfiguration
43
     */
44
    protected $configuration;
45
46
    /**
47
     * @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
48
     */
49
    protected $tsfe;
50
51
    /**
52
     * @var \TYPO3\CMS\Core\Database\DatabaseConnection
53
     */
54
    protected $database;
55
56
    /**
57
     * @param TypoScriptConfiguration $typoscriptConfiguration
58
     * @param TypoScriptFrontendController $tsfe
59
     * @param DatabaseConnection $database
60
     */
61 25
    public function __construct(TypoScriptConfiguration $typoscriptConfiguration, TypoScriptFrontendController $tsfe, DatabaseConnection $database)
62
    {
63 25
        $this->configuration = $typoscriptConfiguration;
64 25
        $this->tsfe = $tsfe;
65 25
        $this->database = $database;
66 25
    }
67
68
    /**
69
     * Retrieves the last searches from the session or database depending on the configuration.
70
     *
71
     * @return array
72
     */
73 25
    public function getLastSearches()
74
    {
75 25
        $lastSearchesKeywords = [];
76 25
        $mode   = $this->configuration->getSearchLastSearchesMode();
77 25
        $limit  = $this->configuration->getSearchLastSearchesLimit();
78
79
        switch ($mode) {
80 25
            case 'user':
81 23
                $lastSearchesKeywords = $this->getLastSearchesFromSession($limit);
82 23
                break;
83 2
            case 'global':
84 2
                $lastSearchesKeywords = $this->getLastSearchesFromDatabase($limit);
85 2
                break;
86
        }
87
88 25
        return $lastSearchesKeywords;
89
    }
90
91
    /**
92
     * Saves the keywords to the last searches in the database or session depending on the configuration.
93
     *
94
     * @param string $keywords
95
     * @throws \UnexpectedValueException
96
     */
97 15
    public function addToLastSearches($keywords)
98
    {
99 15
        $mode   = $this->configuration->getSearchLastSearchesMode();
100
        switch ($mode) {
101 15
            case 'user':
102 14
                $this->storeKeywordsToSession($keywords);
103 14
                break;
104 1
            case 'global':
105 1
                $this->storeKeywordsToDatabase($keywords);
106 1
                break;
107
            default:
108
                throw new \UnexpectedValueException(
109
                    'Unknown mode for plugin.tx_solr.search.lastSearches.mode, valid modes are "user" or "global".',
110
                    1342456570
111
                );
112
        }
113 15
    }
114
115
    /**
116
     * Gets the last searched keywords from the user's session
117
     *
118
     * @param int $limit
119
     * @return array An array containing the last searches of the current user
120
     */
121 23
    protected function getLastSearchesFromSession($limit)
122
    {
123 23
        $lastSearches = $this->getLastSearchesFromFrontendSession();
124
125 23
        if (!is_array($lastSearches)) {
126 22
            return [];
127
        }
128
129 3
        $lastSearches = array_slice(array_reverse(array_unique($lastSearches)), 0, $limit);
130
131 3
        return $lastSearches;
132
    }
133
134
    /**
135
     * Gets the last searched keywords from the database
136
     *
137
     * @param int $limit
138
     * @return array An array containing the last searches of the current user
139
     */
140 2
    protected function getLastSearchesFromDatabase($limit = 10)
141
    {
142 2
        $lastSearchesRows = $this->database->exec_SELECTgetRows(
143 2
            'DISTINCT keywords',
144 2
            'tx_solr_last_searches',
145 2
            '',
146 2
            '',
147 2
            'tstamp DESC',
148
            $limit
149 2
        );
150
151
        // If no records could be found return empty result
152 2
        if (empty($lastSearchesRows)) {
153 1
            return [];
154
        }
155
156 2
        $lastSearches = [];
157
158 2
        foreach ($lastSearchesRows as $row) {
159 2
            $lastSearches[] = html_entity_decode($row['keywords'], ENT_QUOTES, 'UTF-8');
160 2
        }
161
162 2
        return $lastSearches;
163
    }
164
165
    /**
166
     * @return mixed
167
     */
168 22
    protected function getLastSearchesFromFrontendSession()
169
    {
170 22
        return $this->tsfe->fe_user->getKey('ses', 'tx_solr_lastSearches');
171
    }
172
173
    /**
174
     * Stores the keywords from the current query to the user's session.
175
     *
176
     * @param string $keywords The current query's keywords
177
     * @return void
178
     */
179 14
    protected function storeKeywordsToSession($keywords)
180
    {
181 14
        $currentLastSearches = $this->tsfe->fe_user->getKey('ses', 'tx_solr_lastSearches');
182
183 14
        if (!is_array($currentLastSearches)) {
184 14
            $currentLastSearches = [];
185 14
        }
186
187 14
        $lastSearches = $currentLastSearches;
188 14
        $newLastSearchesCount = array_push($lastSearches, $keywords);
189
190 14
        while ($newLastSearchesCount > $this->configuration->getSearchLastSearchesLimit()) {
191
            array_shift($lastSearches);
192
            $newLastSearchesCount = count($lastSearches);
193
        }
194
195 14
        $this->tsfe->fe_user->setKey(
196 14
            'ses',
197 14
            'tx_solr_lastSearches',
198
            $lastSearches
199 14
        );
200 14
    }
201
202
    /**
203
     * Stores the keywords from the current query to the database.
204
     *
205
     * @param string $keywords The current query's keywords
206
     * @return void
207
     */
208 1
    protected function storeKeywordsToDatabase($keywords)
209
    {
210 1
        $nextSequenceId = $this->getNextSequenceId();
211
212 1
        $this->database->sql_query(
213
            'INSERT INTO tx_solr_last_searches (sequence_id, tstamp, keywords)
214
			VALUES ('
215 1
            . $nextSequenceId . ', '
216 1
            . time() . ', '
217 1
            . $this->database->fullQuoteStr($keywords,
218 1
                'tx_solr_last_searches')
219 1
            . ')
220 1
			ON DUPLICATE KEY UPDATE tstamp = ' . time() . ', keywords = ' . $this->database->fullQuoteStr($keywords,
221 1
                'tx_solr_last_searches')
222 1
        );
223 1
    }
224
225
    /**
226
     * Gets the sequence id for the next search entry.
227
     *
228
     * @return int The id to be used as the next sequence id for storing the last search keywords.
229
     */
230 1
    protected function getNextSequenceId()
231
    {
232 1
        $nextSequenceId = 0;
233 1
        $numberOfLastSearchesToLog = (int) $this->configuration->getSearchLastSearchesLimit();
234
235 1
        $row = $this->database->exec_SELECTgetRows(
236 1
            '(sequence_id + 1) % ' . $numberOfLastSearchesToLog . ' as next_sequence_id',
237 1
            'tx_solr_last_searches',
238 1
            '',
239 1
            '',
240 1
            'tstamp DESC',
241
            1
242 1
        );
243
244 1
        if (!empty($row)) {
245 1
            $nextSequenceId = $row[0]['next_sequence_id'];
246 1
        }
247
248 1
        return $nextSequenceId;
249
    }
250
}
251