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