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