834d2b04d96b408c3195b4f6898a511db21b13ec
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Configuration / TypoScript / ConditionMatching / ConditionMatcher.php
1 <?php
2 namespace TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching;
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\Backend\Controller\EditDocumentController;
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcher;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21
22 /**
23 * Matching TypoScript conditions for backend disposal.
24 *
25 * Used with the TypoScript parser.
26 * Matches browserinfo, IPnumbers for use with templates
27 */
28 class ConditionMatcher extends AbstractConditionMatcher
29 {
30 /**
31 * Constructor for this class
32 */
33 public function __construct()
34 {
35 }
36
37 /**
38 * Evaluates a TypoScript condition given as input, eg. "[browser=net][...(other conditions)...]"
39 *
40 * @param string $string The condition to match against its criteria.
41 * @return bool Whether the condition matched
42 * @see \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser::parse()
43 */
44 protected function evaluateCondition($string)
45 {
46 list($key, $value) = GeneralUtility::trimExplode('=', $string, false, 2);
47 $result = $this->evaluateConditionCommon($key, $value);
48 if (is_bool($result)) {
49 return $result;
50 } else {
51 switch ($key) {
52 case 'usergroup':
53 $groupList = $this->getGroupList();
54 $values = GeneralUtility::trimExplode(',', $value, true);
55 foreach ($values as $test) {
56 if ($test === '*' || GeneralUtility::inList($groupList, $test)) {
57 return true;
58 }
59 }
60 break;
61 case 'adminUser':
62 if ($this->isUserLoggedIn()) {
63 return !((bool)$value xor $this->isAdminUser());
64 }
65 break;
66 case 'treeLevel':
67 $values = GeneralUtility::trimExplode(',', $value, true);
68 $treeLevel = count($this->rootline) - 1;
69 // If a new page is being edited or saved the treeLevel is higher by one:
70 if ($this->isNewPageWithPageId($this->pageId)) {
71 $treeLevel++;
72 }
73 foreach ($values as $test) {
74 if ($test == $treeLevel) {
75 return true;
76 }
77 }
78 break;
79 case 'PIDupinRootline':
80 case 'PIDinRootline':
81 $values = GeneralUtility::trimExplode(',', $value, true);
82 if ($key === 'PIDinRootline' || !in_array($this->pageId, $values) || $this->isNewPageWithPageId($this->pageId)) {
83 foreach ($values as $test) {
84 foreach ($this->rootline as $rl_dat) {
85 if ($rl_dat['uid'] == $test) {
86 return true;
87 }
88 }
89 }
90 }
91 break;
92 default:
93 $conditionResult = $this->evaluateCustomDefinedCondition($string);
94 if ($conditionResult !== null) {
95 return $conditionResult;
96 }
97 }
98 }
99 return false;
100 }
101
102 /**
103 * Returns GP / ENV vars
104 *
105 * @param string $var Identifier
106 * @return mixed The value of the variable pointed to or NULL if variable did not exist
107 * @access private
108 */
109 protected function getVariable($var)
110 {
111 $vars = explode(':', $var, 2);
112 return $this->getVariableCommon($vars);
113 }
114
115 /**
116 * Get the usergroup list of the current user.
117 *
118 * @return string The usergroup list of the current user
119 */
120 protected function getGroupList()
121 {
122 return $this->getBackendUserAuthentication()->groupList;
123 }
124
125 /**
126 * Tries to determine the ID of the page currently processed.
127 * When User/Group TS-Config is parsed when no specific page is handled
128 * (i.e. in the Extension Manager, etc.) this function will return "0", so that
129 * the accordant conditions (e.g. PIDinRootline) will return "FALSE"
130 *
131 * @return int The determined page id or otherwise 0
132 */
133 protected function determinePageId()
134 {
135 $pageId = 0;
136 $editStatement = GeneralUtility::_GP('edit');
137 $commandStatement = GeneralUtility::_GP('cmd');
138 // Determine id from module that was called with an id:
139 if ($id = (int)GeneralUtility::_GP('id')) {
140 $pageId = $id;
141 } elseif (is_array($editStatement)) {
142 list($table, $uidAndAction) = each($editStatement);
143 list($uid, $action) = each($uidAndAction);
144 if ($action === 'edit') {
145 $pageId = $this->getPageIdByRecord($table, $uid);
146 } elseif ($action === 'new') {
147 $pageId = $this->getPageIdByRecord($table, $uid, true);
148 }
149 } elseif (is_array($commandStatement)) {
150 list($table, $uidActionAndTarget) = each($commandStatement);
151 list($uid, $actionAndTarget) = each($uidActionAndTarget);
152 list($action, $target) = each($actionAndTarget);
153 if ($action === 'delete') {
154 $pageId = $this->getPageIdByRecord($table, $uid);
155 } elseif ($action === 'copy' || $action === 'move') {
156 $pageId = $this->getPageIdByRecord($table, $target, true);
157 }
158 }
159 return $pageId;
160 }
161
162 /**
163 * Gets the properties for the current page.
164 *
165 * @return array The properties for the current page.
166 */
167 protected function getPage()
168 {
169 $pageId = isset($this->pageId) ? $this->pageId : $this->determinePageId();
170 return BackendUtility::getRecord('pages', $pageId);
171 }
172
173 /**
174 * Gets the page id by a record.
175 *
176 * @param string $table Name of the table
177 * @param int $id Id of the accordant record
178 * @param bool $ignoreTable Whether to ignore the page, if TRUE a positive
179 * @return int Id of the page the record is persisted on
180 */
181 protected function getPageIdByRecord($table, $id, $ignoreTable = false)
182 {
183 $pageId = 0;
184 $id = (int)$id;
185 if ($table && $id) {
186 if (($ignoreTable || $table === 'pages') && $id >= 0) {
187 $pageId = $id;
188 } else {
189 $record = BackendUtility::getRecordWSOL($table, abs($id), '*', '', false);
190 $pageId = $record['pid'];
191 }
192 }
193 return $pageId;
194 }
195
196 /**
197 * Determine if record of table 'pages' with the given $pid is currently created in TCEforms.
198 * This information is required for conditions in BE for PIDupinRootline.
199 *
200 * @param int $pageId The pid the check for as parent page
201 * @return bool TRUE if the is currently a new page record being edited with $pid as uid of the parent page
202 */
203 protected function isNewPageWithPageId($pageId)
204 {
205 if (isset($GLOBALS['SOBE']) && $GLOBALS['SOBE'] instanceof EditDocumentController) {
206 $pageId = (int)$pageId;
207 $elementsData = $GLOBALS['SOBE']->elementsData;
208 $data = $GLOBALS['SOBE']->data;
209 // If saving a new page record:
210 if (is_array($data) && isset($data['pages']) && is_array($data['pages'])) {
211 foreach ($data['pages'] as $uid => $fields) {
212 if (strpos($uid, 'NEW') === 0 && $fields['pid'] == $pageId) {
213 return true;
214 }
215 }
216 }
217 // If editing a new page record (not saved yet):
218 if (is_array($elementsData)) {
219 foreach ($elementsData as $element) {
220 if ($element['cmd'] === 'new' && $element['table'] === 'pages') {
221 if ($element['pid'] < 0) {
222 $pageRecord = BackendUtility::getRecord('pages', abs($element['pid']), 'pid');
223 $element['pid'] = $pageRecord['pid'];
224 }
225 if ($element['pid'] == $pageId) {
226 return true;
227 }
228 }
229 }
230 }
231 }
232 return false;
233 }
234
235 /**
236 * Determines the rootline for the current page.
237 *
238 * @return array The rootline for the current page.
239 */
240 protected function determineRootline()
241 {
242 $pageId = isset($this->pageId) ? $this->pageId : $this->determinePageId();
243 return BackendUtility::BEgetRootLine($pageId, '', true);
244 }
245
246 /**
247 * Get the id of the current user.
248 *
249 * @return int The id of the current user
250 */
251 protected function getUserId()
252 {
253 return $this->getBackendUserAuthentication()->user['uid'];
254 }
255
256 /**
257 * Determines if a user is logged in.
258 *
259 * @return bool Determines if a user is logged in
260 */
261 protected function isUserLoggedIn()
262 {
263 return (bool)$this->getBackendUserAuthentication()->user['uid'];
264 }
265
266 /**
267 * Determines whether the current user is admin.
268 *
269 * @return bool Whether the current user is admin
270 */
271 protected function isAdminUser()
272 {
273 return $this->getBackendUserAuthentication()->isAdmin();
274 }
275
276 /**
277 * Set/write a log message.
278 *
279 * @param string $message The log message to set/write
280 */
281 protected function log($message)
282 {
283 if (is_object($this->getBackendUserAuthentication())) {
284 $this->getBackendUserAuthentication()->writelog(3, 0, 1, 0, $message, []);
285 }
286 }
287
288 /**
289 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
290 */
291 protected function getBackendUserAuthentication()
292 {
293 return $GLOBALS['BE_USER'];
294 }
295 }