[FEATURE] Improve livesearch results
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / Page / CacheHashCalculator.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Page;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2011-2013 Daniel Pötzinger (poetzinger@aoemedia.de)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * Logic for cHash calculation
31 *
32 * @author Daniel Pötzinger <poetzinger@aoemedia.de>
33 * @coauthor Tolleiv Nietsch <typo3@tolleiv.de>
34 */
35 class CacheHashCalculator implements \TYPO3\CMS\Core\SingletonInterface {
36
37 /**
38 * @var array Parameters that are relevant for cacheHash calculation. Optional.
39 */
40 protected $cachedParametersWhiteList = array();
41
42 /**
43 * @var array Parameters that are not relevant for cacheHash calculation.
44 */
45 protected $excludedParameters = array();
46
47 /**
48 * @var array Parameters that forces a presence of a valid cacheHash.
49 */
50 protected $requireCacheHashPresenceParameters = array();
51
52 /**
53 * @var array Parameters that need a value to be relevant for cacheHash calculation
54 */
55 protected $excludedParametersIfEmpty = array();
56
57 /**
58 * @var bool Whether to exclude all empty parameters for cacheHash calculation
59 */
60 protected $excludeAllEmptyParameters = FALSE;
61
62 /**
63 * Initialise class properties by using the relevant TYPO3 configuration
64 */
65 public function __construct() {
66 $this->setConfiguration($GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']);
67 }
68
69 /**
70 * Calculates the cHash based on the provided parameters
71 *
72 * @param array $params Array of cHash key-value pairs
73 * @return string Hash of all the values
74 */
75 public function calculateCacheHash(array $params) {
76 return !empty($params) ? md5(serialize($params)) : '';
77 }
78
79 /**
80 * Returns the cHash based on provided query parameters and added values from internal call
81 *
82 * @param string $queryString Query-parameters: "&xxx=yyy&zzz=uuu
83 * @return string Hash of all the values
84 */
85 public function generateForParameters($queryString) {
86 $cacheHashParams = $this->getRelevantParameters($queryString);
87 return $this->calculateCacheHash($cacheHashParams);
88 }
89
90 /**
91 * Checks whether a parameter of the given $queryString requires cHash calculation
92 *
93 * @param string $queryString
94 * @return boolean
95 */
96 public function doParametersRequireCacheHash($queryString) {
97 if (empty($this->requireCacheHashPresenceParameters)) {
98 return FALSE;
99 }
100 $hasRequiredParameter = FALSE;
101 $parameterNames = array_keys($this->splitQueryStringToArray($queryString));
102 foreach ($parameterNames as $parameterName) {
103 if (in_array($parameterName, $this->requireCacheHashPresenceParameters)) {
104 $hasRequiredParameter = TRUE;
105 }
106 }
107 return $hasRequiredParameter;
108 }
109
110 /**
111 * Splits the input query-parameters into an array with certain parameters filtered out.
112 * Used to create the cHash value
113 *
114 * @param string $queryString Query-parameters: "&xxx=yyy&zzz=uuu
115 * @return array Array with key/value pairs of query-parameters WITHOUT a certain list of
116 * @see \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::makeCacheHash(), \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::typoLink()
117 */
118 public function getRelevantParameters($queryString) {
119 $parameters = $this->splitQueryStringToArray($queryString);
120 $relevantParameters = array();
121 foreach ($parameters as $parameterName => $parameterValue) {
122 if ($this->isAdminPanelParameter($parameterName) || $this->isExcludedParameter($parameterName) || $this->isCoreParameter($parameterName)) {
123 continue;
124 }
125 if ($this->hasCachedParametersWhiteList() && !$this->isInCachedParametersWhiteList($parameterName)) {
126 continue;
127 }
128 if ((is_null($parameterValue) || $parameterValue === '') && !$this->isAllowedWithEmptyValue($parameterName)) {
129 continue;
130 }
131 $relevantParameters[$parameterName] = $parameterValue;
132 }
133 if (!empty($relevantParameters)) {
134 // Finish and sort parameters array by keys:
135 $relevantParameters['encryptionKey'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
136 ksort($relevantParameters);
137 }
138 return $relevantParameters;
139 }
140
141 /**
142 * Parses the query string and converts it to an array.
143 * Unlike parse_str it only creates an array with one level.
144 *
145 * e.g. foo[bar]=baz will be array('foo[bar]' => 'baz')
146 *
147 * @param $queryString
148 * @return array
149 */
150 protected function splitQueryStringToArray($queryString) {
151 $parameters = array_filter(explode('&', ltrim($queryString, '?')));
152 $parameterArray = array();
153 foreach ($parameters as $parameter) {
154 list($parameterName, $parameterValue) = explode('=', $parameter);
155 $parameterArray[rawurldecode($parameterName)] = rawurldecode($parameterValue);
156 }
157 return $parameterArray;
158 }
159
160 /**
161 * Checks whether the given parameter starts with TSFE_ADMIN_PANEL
162 * stristr check added to avoid bad performance
163 *
164 * @param string $key
165 * @return boolean
166 */
167 protected function isAdminPanelParameter($key) {
168 return stristr($key, 'TSFE_ADMIN_PANEL') !== FALSE && preg_match('/TSFE_ADMIN_PANEL\\[.*?\\]/', $key);
169 }
170
171 /**
172 * Checks whether the given parameter is a core parameter
173 *
174 * @param string $key
175 * @return boolean
176 */
177 protected function isCoreParameter($key) {
178 return \TYPO3\CMS\Core\Utility\GeneralUtility::inList('id,type,no_cache,cHash,MP,ftu', $key);
179 }
180
181 /**
182 * Checks whether the given parameter should be exluded from cHash calculation
183 *
184 * @param string $key
185 * @return boolean
186 */
187 protected function isExcludedParameter($key) {
188 return in_array($key, $this->excludedParameters);
189 }
190
191 /**
192 * Checks whether the given parameter is an exclusive parameter for cHash calculation
193 *
194 * @param string $key
195 * @return boolean
196 */
197 protected function isInCachedParametersWhiteList($key) {
198 return in_array($key, $this->cachedParametersWhiteList);
199 }
200
201 /**
202 * Checks whether cachedParametersWhiteList parameters are configured
203 *
204 * @return boolean
205 */
206 protected function hasCachedParametersWhiteList() {
207 return !empty($this->cachedParametersWhiteList);
208 }
209
210 /**
211 * Check whether the given parameter may be used even with an empty value
212 *
213 * @param $key
214 */
215 protected function isAllowedWithEmptyValue($key) {
216 return !($this->excludeAllEmptyParameters || in_array($key, $this->excludedParametersIfEmpty));
217 }
218
219 /**
220 * Loops through the configuration array and calls the accordant
221 * getters with the value.
222 *
223 * @param $configuration
224 */
225 public function setConfiguration($configuration) {
226 foreach ($configuration as $name => $value) {
227 $setterName = 'set' . ucfirst($name);
228 if (method_exists($this, $setterName)) {
229 $this->{$setterName}($value);
230 }
231 }
232 }
233
234 /**
235 * @param array $cachedParametersWhiteList
236 */
237 protected function setCachedParametersWhiteList(array $cachedParametersWhiteList) {
238 $this->cachedParametersWhiteList = $cachedParametersWhiteList;
239 }
240
241 /**
242 * @param boolean $excludeAllEmptyParameters
243 */
244 protected function setExcludeAllEmptyParameters($excludeAllEmptyParameters) {
245 $this->excludeAllEmptyParameters = $excludeAllEmptyParameters;
246 }
247
248 /**
249 * @param array $excludedParameters
250 */
251 protected function setExcludedParameters(array $excludedParameters) {
252 $this->excludedParameters = $excludedParameters;
253 }
254
255 /**
256 * @param array $excludedParametersIfEmpty
257 */
258 protected function setExcludedParametersIfEmpty(array $excludedParametersIfEmpty) {
259 $this->excludedParametersIfEmpty = $excludedParametersIfEmpty;
260 }
261
262 /**
263 * @param array $requireCacheHashPresenceParameters
264 */
265 protected function setRequireCacheHashPresenceParameters(array $requireCacheHashPresenceParameters) {
266 $this->requireCacheHashPresenceParameters = $requireCacheHashPresenceParameters;
267 }
268
269 }
270
271
272 ?>