[CLEANUP] Replace count with empty in EXT:core
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Configuration / TypoScript / ConditionMatching / AbstractConditionMatcher.php
1 <?php
2 namespace TYPO3\CMS\Core\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\Core\Utility\GeneralUtility;
18
19 /**
20 * Matching TypoScript conditions
21 *
22 * Used with the TypoScript parser.
23 * Matches browserinfo, IPnumbers for use with templates
24 *
25 * @author Oliver Hader <oliver@typo3.org>
26 */
27 abstract class AbstractConditionMatcher {
28
29 /**
30 * Id of the current page.
31 *
32 * @var int
33 */
34 protected $pageId;
35
36 /**
37 * The rootline for the current page.
38 *
39 * @var array
40 */
41 protected $rootline;
42
43 /**
44 * Whether to simulate the behaviour and match all conditions
45 * (used in TypoScript object browser).
46 *
47 * @var bool
48 */
49 protected $simulateMatchResult = FALSE;
50
51 /**
52 * Whether to simulat the behaviour and match specific conditions
53 * (used in TypoScript object browser).
54 *
55 * @var array
56 */
57 protected $simulateMatchConditions = array();
58
59 /**
60 * Sets the id of the page to evaluate conditions for.
61 *
62 * @param int $pageId Id of the page (must be positive)
63 * @return void
64 */
65 public function setPageId($pageId) {
66 if (is_integer($pageId) && $pageId > 0) {
67 $this->pageId = $pageId;
68 }
69 }
70
71 /**
72 * Gets the id of the page to evaluate conditions for.
73 *
74 * @return int Id of the page
75 */
76 public function getPageId() {
77 return $this->pageId;
78 }
79
80 /**
81 * Sets the rootline.
82 *
83 * @param array $rootline The rootline to be used for matching (must have elements)
84 * @return void
85 */
86 public function setRootline(array $rootline) {
87 if (!empty($rootline)) {
88 $this->rootline = $rootline;
89 }
90 }
91
92 /**
93 * Gets the rootline.
94 *
95 * @return array The rootline to be used for matching
96 */
97 public function getRootline() {
98 return $this->rootline;
99 }
100
101 /**
102 * Sets whether to simulate the behaviour and match all conditions.
103 *
104 * @param bool $simulateMatchResult Whether to simulate positive matches
105 * @return void
106 */
107 public function setSimulateMatchResult($simulateMatchResult) {
108 if (is_bool($simulateMatchResult)) {
109 $this->simulateMatchResult = $simulateMatchResult;
110 }
111 }
112
113 /**
114 * Sets whether to simulate the behaviour and match specific conditions.
115 *
116 * @param array $simulateMatchConditions Conditions to simulate a match for
117 * @return void
118 */
119 public function setSimulateMatchConditions(array $simulateMatchConditions) {
120 $this->simulateMatchConditions = $simulateMatchConditions;
121 }
122
123 /**
124 * Normalizes an expression and removes the first and last square bracket.
125 * + OR normalization: "...]OR[...", "...]||[...", "...][..." --> "...]||[..."
126 * + AND normalization: "...]AND[...", "...]&&[..." --> "...]&&[..."
127 *
128 * @param string $expression The expression to be normalized (e.g. "[A] && [B] OR [C]")
129 * @return string The normalized expression (e.g. "[A]&&[B]||[C]")
130 */
131 protected function normalizeExpression($expression) {
132 $normalizedExpression = preg_replace(array(
133 '/\\]\\s*(OR|\\|\\|)?\\s*\\[/i',
134 '/\\]\\s*(AND|&&)\\s*\\[/i'
135 ), array(
136 ']||[',
137 ']&&['
138 ), trim($expression));
139 return $normalizedExpression;
140 }
141
142 /**
143 * Matches a TypoScript condition expression.
144 *
145 * @param string $expression The expression to match
146 * @return bool Whether the expression matched
147 */
148 public function match($expression) {
149 // Return directly if result should be simulated:
150 if ($this->simulateMatchResult) {
151 return $this->simulateMatchResult;
152 }
153 // Return directly if matching for specific condition is simulated only:
154 if (!empty($this->simulateMatchConditions)) {
155 return in_array($expression, $this->simulateMatchConditions);
156 }
157 // Sets the current pageId if not defined yet:
158 if (!isset($this->pageId)) {
159 $this->pageId = $this->determinePageId();
160 }
161 // Sets the rootline if not defined yet:
162 if (!isset($this->rootline)) {
163 $this->rootline = $this->determineRootline();
164 }
165 $result = FALSE;
166 $normalizedExpression = $this->normalizeExpression($expression);
167 // First and last character must be square brackets (e.g. "[A]&&[B]":
168 if ($normalizedExpression[0] === '[' && substr($normalizedExpression, -1) === ']') {
169 $innerExpression = substr($normalizedExpression, 1, -1);
170 $orParts = explode(']||[', $innerExpression);
171 foreach ($orParts as $orPart) {
172 $andParts = explode(']&&[', $orPart);
173 foreach ($andParts as $andPart) {
174 $result = $this->evaluateCondition($andPart);
175 // If condition in AND context fails, the whole block is FALSE:
176 if ($result === FALSE) {
177 break;
178 }
179 }
180 // If condition in OR context succeeds, the whole expression is TRUE:
181 if ($result === TRUE) {
182 break;
183 }
184 }
185 }
186 return $result;
187 }
188
189 /**
190 * Evaluates a TypoScript condition given as input, eg. "[applicationContext = Production][...(other condition)...]"
191 *
192 * @param string $key The condition to match against its criterias.
193 * @param string $value
194 * @return NULL|boolean Result of the evaluation; NULL if condition could not be evaluated
195 */
196 protected function evaluateConditionCommon($key, $value) {
197 if (GeneralUtility::inList('browser,device,version,system,useragent', strtolower($key))) {
198 GeneralUtility::deprecationLog(
199 'Usage of client related conditions (browser, device, version, system, useragent) is deprecated since 7.0.'
200 );
201 $browserInfo = $this->getBrowserInfo(GeneralUtility::getIndpEnv('HTTP_USER_AGENT'));
202 }
203 $keyParts = GeneralUtility::trimExplode('|', $key);
204 switch ($keyParts[0]) {
205 case 'applicationContext':
206 $values = GeneralUtility::trimExplode(',', $value, TRUE);
207 $currentApplicationContext = GeneralUtility::getApplicationContext();
208 foreach ($values as $applicationContext) {
209 if ($this->searchStringWildcard($currentApplicationContext, $applicationContext)) {
210 return TRUE;
211 }
212 }
213 return FALSE;
214 break;
215 case 'browser':
216 $values = GeneralUtility::trimExplode(',', $value, TRUE);
217 // take all identified browsers into account, eg chrome deliver
218 // webkit=>532.5, chrome=>4.1, safari=>532.5
219 // so comparing string will be
220 // "webkit532.5 chrome4.1 safari532.5"
221 $all = '';
222 foreach ($browserInfo['all'] as $key => $value) {
223 $all .= $key . $value . ' ';
224 }
225 foreach ($values as $test) {
226 if (stripos($all, $test) !== FALSE) {
227 return TRUE;
228 }
229 }
230 return FALSE;
231 break;
232 case 'version':
233 $values = GeneralUtility::trimExplode(',', $value, TRUE);
234 foreach ($values as $test) {
235 if (strcspn($test, '=<>') == 0) {
236 switch ($test[0]) {
237 case '=':
238 if (doubleval(substr($test, 1)) == $browserInfo['version']) {
239 return TRUE;
240 }
241 break;
242 case '<':
243 if (doubleval(substr($test, 1)) > $browserInfo['version']) {
244 return TRUE;
245 }
246 break;
247 case '>':
248 if (doubleval(substr($test, 1)) < $browserInfo['version']) {
249 return TRUE;
250 }
251 break;
252 }
253 } elseif (strpos(' ' . $browserInfo['version'], $test) == 1) {
254 return TRUE;
255 }
256 }
257 return FALSE;
258 break;
259 case 'system':
260 $values = GeneralUtility::trimExplode(',', $value, TRUE);
261 // Take all identified systems into account, e.g. mac for iOS, Linux
262 // for android and Windows NT for Windows XP
263 $allSystems = ' ' . implode(' ', $browserInfo['all_systems']);
264 foreach ($values as $test) {
265 if (stripos($allSystems, $test) !== FALSE) {
266 return TRUE;
267 }
268 }
269 return FALSE;
270 break;
271 case 'device':
272 if (!isset($this->deviceInfo)) {
273 $this->deviceInfo = $this->getDeviceType(GeneralUtility::getIndpEnv('HTTP_USER_AGENT'));
274 }
275 $values = GeneralUtility::trimExplode(',', $value, TRUE);
276 foreach ($values as $test) {
277 if ($this->deviceInfo == $test) {
278 return TRUE;
279 }
280 }
281 return FALSE;
282 break;
283 case 'useragent':
284 $test = trim($value);
285 if ($test !== '') {
286 return $this->searchStringWildcard((string)$browserInfo['useragent'], $test);
287 } else {
288 return FALSE;
289 }
290 break;
291 case 'language':
292 if (GeneralUtility::getIndpEnv('HTTP_ACCEPT_LANGUAGE') === $value) {
293 return TRUE;
294 }
295 $values = GeneralUtility::trimExplode(',', $value, TRUE);
296 foreach ($values as $test) {
297 if (preg_match('/^\\*.+\\*$/', $test)) {
298 $allLanguages = preg_split('/[,;]/', GeneralUtility::getIndpEnv('HTTP_ACCEPT_LANGUAGE'));
299 if (in_array(substr($test, 1, -1), $allLanguages)) {
300 return TRUE;
301 }
302 } elseif (GeneralUtility::getIndpEnv('HTTP_ACCEPT_LANGUAGE') == $test) {
303 return TRUE;
304 }
305 }
306 return FALSE;
307 break;
308 case 'IP':
309 if ($value === 'devIP') {
310 $value = trim($GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']);
311 }
312
313 return (bool)GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $value);
314 break;
315 case 'hostname':
316 return (bool)GeneralUtility::cmpFQDN(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $value);
317 break;
318 case 'hour':
319 case 'minute':
320 case 'month':
321 case 'year':
322 case 'dayofweek':
323 case 'dayofmonth':
324 case 'dayofyear':
325 // In order to simulate time properly in templates.
326 $theEvalTime = $GLOBALS['SIM_EXEC_TIME'];
327 switch ($key) {
328 case 'hour':
329 $theTestValue = date('H', $theEvalTime);
330 break;
331 case 'minute':
332 $theTestValue = date('i', $theEvalTime);
333 break;
334 case 'month':
335 $theTestValue = date('m', $theEvalTime);
336 break;
337 case 'year':
338 $theTestValue = date('Y', $theEvalTime);
339 break;
340 case 'dayofweek':
341 $theTestValue = date('w', $theEvalTime);
342 break;
343 case 'dayofmonth':
344 $theTestValue = date('d', $theEvalTime);
345 break;
346 case 'dayofyear':
347 $theTestValue = date('z', $theEvalTime);
348 break;
349 }
350 $theTestValue = (int)$theTestValue;
351 // comp
352 $values = GeneralUtility::trimExplode(',', $value, TRUE);
353 foreach ($values as $test) {
354 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($test)) {
355 $test = '=' . $test;
356 }
357 if ($this->compareNumber($test, $theTestValue)) {
358 return TRUE;
359 }
360 }
361 return FALSE;
362 break;
363 case 'compatVersion':
364 return GeneralUtility::compat_version($value);
365 break;
366 case 'loginUser':
367 if ($this->isUserLoggedIn()) {
368 $values = GeneralUtility::trimExplode(',', $value, TRUE);
369 foreach ($values as $test) {
370 if ($test == '*' || (string)$this->getUserId() === (string)$test) {
371 return TRUE;
372 }
373 }
374 } elseif ($value === '') {
375 return TRUE;
376 }
377 return FALSE;
378 break;
379 case 'page':
380 if ($keyParts[1]) {
381 $page = $this->getPage();
382 $property = $keyParts[1];
383 if (!empty($page) && isset($page[$property]) && (string)$page[$property] === (string)$value) {
384 return TRUE;
385 }
386 }
387 return FALSE;
388 break;
389 case 'globalVar':
390 $values = GeneralUtility::trimExplode(',', $value, TRUE);
391 foreach ($values as $test) {
392 $point = strcspn($test, '!=<>');
393 $theVarName = substr($test, 0, $point);
394 $nv = $this->getVariable(trim($theVarName));
395 $testValue = substr($test, $point);
396 if ($this->compareNumber($testValue, $nv)) {
397 return TRUE;
398 }
399 }
400 return FALSE;
401 break;
402 case 'globalString':
403 $values = GeneralUtility::trimExplode(',', $value, TRUE);
404 foreach ($values as $test) {
405 $point = strcspn($test, '=');
406 $theVarName = substr($test, 0, $point);
407 $nv = (string)$this->getVariable(trim($theVarName));
408 $testValue = substr($test, $point + 1);
409 if ($this->searchStringWildcard($nv, trim($testValue))) {
410 return TRUE;
411 }
412 }
413 return FALSE;
414 break;
415 case 'userFunc':
416 $matches = array();
417 preg_match_all('/^\s*([^\(\s]+)\s*(?:\((.*)\))?\s*$/', $value, $matches);
418 $funcName = $matches[1][0];
419 $funcValues = $matches[2][0] ? $this->parseUserFuncArguments($matches[2][0]) : array();
420 if (is_callable($funcName) && call_user_func_array($funcName, $funcValues)) {
421 return TRUE;
422 }
423 return FALSE;
424 break;
425 }
426 return NULL;
427 }
428
429 /**
430 * Evaluates a TypoScript condition given as input with a custom class name,
431 * e.g. "[MyCompany\MyPackage\ConditionMatcher\MyOwnConditionMatcher = myvalue]"
432 *
433 * @param string $condition The condition to match
434 * @return NULL|boolean Result of the evaluation; NULL if condition could not be evaluated
435 * @throws \TYPO3\CMS\Core\Configuration\TypoScript\Exception\InvalidTypoScriptConditionException
436 */
437 protected function evaluateCustomDefinedCondition($condition) {
438 $conditionResult = NULL;
439
440 list($conditionClassName, $conditionParameters) = GeneralUtility::trimExplode(' ', $condition, FALSE, 2);
441
442 // Check if the condition class name is a valid class
443 // This is necessary to not stop here for the conditions ELSE and GLOBAL
444 if (class_exists($conditionClassName)) {
445 // Use like this: [MyCompany\MyPackage\ConditionMatcher\MyOwnConditionMatcher = myvalue]
446 /** @var \TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\AbstractCondition $conditionObject */
447 $conditionObject = GeneralUtility::makeInstance($conditionClassName);
448 if (($conditionObject instanceof \TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\AbstractCondition) === FALSE) {
449 throw new \TYPO3\CMS\Core\Configuration\TypoScript\Exception\InvalidTypoScriptConditionException(
450 '"' . $conditionClassName . '" is not a valid TypoScript Condition object.',
451 1410286153
452 );
453 }
454
455 $conditionParameters = $this->parseUserFuncArguments($conditionParameters);
456 $conditionObject->setConditionMatcherInstance($this);
457 $conditionResult = $conditionObject->matchCondition($conditionParameters);
458 }
459
460 return $conditionResult;
461 }
462
463 /**
464 * Parses arguments to the userFunc.
465 *
466 * @param string $arguments
467 * @return array
468 */
469 protected function parseUserFuncArguments($arguments) {
470 $result = array();
471 $arguments = trim($arguments);
472 while ($arguments) {
473 if ($arguments[0] === ',') {
474 $result[] = '';
475 $arguments = substr($arguments, 1);
476 } else {
477 $pos = strcspn($arguments, ',\'"');
478 if ($pos == 0) {
479 // We hit a quote of some kind
480 $quote = $arguments[0];
481 $segment = preg_replace('/^(.*?[^\\\])' . $quote . '.*$/', '\1', substr($arguments, 1));
482 $segment = str_replace('\\' . $quote, $quote, $segment);
483 $result[] = $segment;
484 $offset = strpos($arguments, ',', strlen($segment) + 2);
485 if ($offset === FALSE) {
486 $offset = strlen($arguments);
487 }
488 $arguments = substr($arguments, $offset);
489 } else {
490 $result[] = trim(substr($arguments, 0, $pos));
491 $arguments = substr($arguments, $pos + 1);
492 }
493 }
494 $arguments = trim($arguments);
495 };
496 return $result;
497 }
498
499 /**
500 * Get variable common
501 *
502 * @param array $vars
503 * @return mixed Whatever value. If none, then NULL.
504 */
505 protected function getVariableCommon(array $vars) {
506 $value = NULL;
507 if (count($vars) === 1) {
508 $value = $this->getGlobal($vars[0]);
509 } else {
510 $splitAgain = explode('|', $vars[1], 2);
511 $k = trim($splitAgain[0]);
512 if ($k) {
513 switch ((string)trim($vars[0])) {
514 case 'GP':
515 $value = GeneralUtility::_GP($k);
516 break;
517 case 'GPmerged':
518 $value = GeneralUtility::_GPmerged($k);
519 break;
520 case 'ENV':
521 $value = getenv($k);
522 break;
523 case 'IENV':
524 $value = GeneralUtility::getIndpEnv($k);
525 break;
526 case 'LIT':
527 return trim($vars[1]);
528 break;
529 default:
530 return NULL;
531 }
532 // If array:
533 if (count($splitAgain) > 1) {
534 if (is_array($value) && trim($splitAgain[1]) !== '') {
535 $value = $this->getGlobal($splitAgain[1], $value);
536 } else {
537 $value = '';
538 }
539 }
540 }
541 }
542 return $value;
543 }
544
545 /**
546 * Evaluates a $leftValue based on an operator: "<", ">", "<=", ">=", "!=" or "="
547 *
548 * @param string $test The value to compare with on the form [operator][number]. Eg. "< 123
549 * @param float $leftValue The value on the left side
550 * @return bool If $value is "50" and $test is "< 123" then it will return TRUE.
551 */
552 protected function compareNumber($test, $leftValue) {
553 if (preg_match('/^(!?=+|<=?|>=?)\\s*([^\\s]*)\\s*$/', $test, $matches)) {
554 $operator = $matches[1];
555 $rightValue = $matches[2];
556 switch ($operator) {
557 case '>=':
558 return $leftValue >= doubleval($rightValue);
559 break;
560 case '<=':
561 return $leftValue <= doubleval($rightValue);
562 break;
563 case '!=':
564 // multiple values may be split with '|'
565 // see if none matches ("not in list")
566 $found = FALSE;
567 $rightValueParts = GeneralUtility::trimExplode('|', $rightValue);
568 foreach ($rightValueParts as $rightValueSingle) {
569 if ($leftValue == doubleval($rightValueSingle)) {
570 $found = TRUE;
571 break;
572 }
573 }
574 return $found === FALSE;
575 break;
576 case '<':
577 return $leftValue < doubleval($rightValue);
578 break;
579 case '>':
580 return $leftValue > doubleval($rightValue);
581 break;
582 default:
583 // nothing valid found except '=', use '='
584 // multiple values may be split with '|'
585 // see if one matches ("in list")
586 $found = FALSE;
587 $rightValueParts = GeneralUtility::trimExplode('|', $rightValue);
588 foreach ($rightValueParts as $rightValueSingle) {
589 if ($leftValue == $rightValueSingle) {
590 $found = TRUE;
591 break;
592 }
593 }
594 return $found;
595 }
596 }
597 return FALSE;
598 }
599
600 /**
601 * Matching two strings against each other, supporting a "*" wildcard or (if wrapped in "/") PCRE regular expressions
602 *
603 * @param string $haystack The string in which to find $needle.
604 * @param string $needle The string to find in $haystack
605 * @return bool Returns TRUE if $needle matches or is found in (according to wildcards) in $haystack. Eg. if $haystack is "Netscape 6.5" and $needle is "Net*" or "Net*ape" then it returns TRUE.
606 */
607 protected function searchStringWildcard($haystack, $needle) {
608 $result = FALSE;
609 if ($haystack === $needle) {
610 $result = TRUE;
611 } elseif ($needle) {
612 if (preg_match('/^\\/.+\\/$/', $needle)) {
613 // Regular expression, only "//" is allowed as delimiter
614 $regex = $needle;
615 } else {
616 $needle = str_replace(array('*', '?'), array('###MANY###', '###ONE###'), $needle);
617 $regex = '/^' . preg_quote($needle, '/') . '$/';
618 // Replace the marker with .* to match anything (wildcard)
619 $regex = str_replace(array('###MANY###', '###ONE###'), array('.*', '.'), $regex);
620 }
621 $result = (bool)preg_match($regex, $haystack);
622 }
623 return $result;
624 }
625
626 /**
627 * Generates an array with abstracted browser information
628 *
629 * @param string $userAgent The useragent string, \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('HTTP_USER_AGENT')
630 * @return array Contains keys "browser", "version", "system
631 */
632 protected function getBrowserInfo($userAgent) {
633 return \TYPO3\CMS\Core\Utility\ClientUtility::getBrowserInfo($userAgent);
634 }
635
636 /**
637 * Gets a code for a browsing device based on the input useragent string.
638 *
639 * @param string $userAgent The useragent string, \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('HTTP_USER_AGENT')
640 * @return string Code for the specific device type
641 * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
642 */
643 protected function getDeviceType($userAgent) {
644 return \TYPO3\CMS\Core\Utility\ClientUtility::getDeviceType($userAgent);
645 }
646
647 /**
648 * Return global variable where the input string $var defines array keys separated by "|"
649 * Example: $var = "HTTP_SERVER_VARS | something" will return the value $GLOBALS['HTTP_SERVER_VARS']['something'] value
650 *
651 * @param string $var Global var key, eg. "HTTP_GET_VAR" or "HTTP_GET_VARS|id" to get the GET parameter "id" back.
652 * @param array $source Alternative array than $GLOBAL to get variables from.
653 * @return mixed Whatever value. If none, then blank string.
654 */
655 protected function getGlobal($var, $source = NULL) {
656 $vars = explode('|', $var);
657 $c = count($vars);
658 $k = trim($vars[0]);
659 $theVar = isset($source) ? $source[$k] : $GLOBALS[$k];
660 for ($a = 1; $a < $c; $a++) {
661 if (!isset($theVar)) {
662 break;
663 }
664 $key = trim($vars[$a]);
665 if (is_object($theVar)) {
666 $theVar = $theVar->{$key};
667 } elseif (is_array($theVar)) {
668 $theVar = $theVar[$key];
669 } else {
670 return '';
671 }
672 }
673 if (!is_array($theVar) && !is_object($theVar)) {
674 return $theVar;
675 } else {
676 return '';
677 }
678 }
679
680 /**
681 * Evaluates a TypoScript condition given as input, eg. "[browser=net][...(other conditions)...]"
682 *
683 * @param string $string The condition to match against its criterias.
684 * @return bool Whether the condition matched
685 * @see \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser::parse()
686 */
687 abstract protected function evaluateCondition($string);
688
689 /**
690 * Gets the value of a variable.
691 *
692 * Examples of names:
693 * + TSFE:id
694 * + GP:firstLevel|secondLevel
695 * + _GET|firstLevel|secondLevel
696 * + LIT:someLiteralValue
697 *
698 * @param string $name The name of the variable to fetch the value from
699 * @return mixed The value of the given variable (string) or NULL if variable did not exist
700 */
701 abstract protected function getVariable($name);
702
703 /**
704 * Gets the usergroup list of the current user.
705 *
706 * @return string The usergroup list of the current user
707 */
708 abstract protected function getGroupList();
709
710 /**
711 * Determines the current page Id.
712 *
713 * @return int The current page Id
714 */
715 abstract protected function determinePageId();
716
717 /**
718 * Gets the properties for the current page.
719 *
720 * @return array The properties for the current page.
721 */
722 abstract protected function getPage();
723
724 /**
725 * Determines the rootline for the current page.
726 *
727 * @return array The rootline for the current page.
728 */
729 abstract protected function determineRootline();
730
731 /**
732 * Gets the id of the current user.
733 *
734 * @return int The id of the current user
735 */
736 abstract protected function getUserId();
737
738 /**
739 * Determines if a user is logged in.
740 *
741 * @return bool Determines if a user is logged in
742 */
743 abstract protected function isUserLoggedIn();
744
745 /**
746 * Sets a log message.
747 *
748 * @param string $message The log message to set/write
749 * @return void
750 */
751 abstract protected function log($message);
752
753 }