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