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