2 /***************************************************************
5 * (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
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.
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.
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.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
28 * Contains class for Matching TypoScript conditions
31 * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
33 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
36 * [CLASS/FUNCTION INDEX of SCRIPT]
40 * 77: class t3lib_matchCondition
41 * 91: function match($string)
42 * 311: function testNumber($test,$value)
43 * 333: function matchWild($haystack,$needle)
44 * 363: function whichDevice($useragent)
45 * 413: function browserInfo($useragent)
46 * 511: function browserInfo_version($tmp)
47 * 523: function getGlobal($var,$inArr='')
48 * 548: function getGP_ENV_TSFE($var)
51 * (This index is automatically created/updated by the extension "extdeveval")
67 * Matching TypoScript conditions
69 * Used with the TypoScript parser.
70 * Matches browserinfo, IPnumbers for use with templates
72 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
75 * @see t3lib_TStemplate::matching(), t3lib_TStemplate::generateConfig()
77 class t3lib_matchCondition
{
78 var $matchAlternative=array(); // If this array has elements, the matching returns true if a whole "matchline" is found in the array!
79 var $matchAll=0; // If set all is matched!
81 var $altRootLine=array();
84 * Evaluates a TypoScript condition given as input, eg. "[browser=net][...(other conditions)...]"
86 * @param string The condition to match against its criterias.
87 * @return boolean Returns true or false based on the evaluation.
88 * @see t3lib_tsparser::parse()
89 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=292&cHash=c6c7d43d2f
91 function match($string) {
93 if ($this->matchAll
) return true;
94 if (count($this->matchAlternative
)) {
95 return in_array($string,$this->matchAlternative
);
98 if (!$this->browserInfoArray
) {
99 $this->browserInfoArray
= $this->browserInfo(t3lib_div
::getIndpEnv('HTTP_USER_AGENT'));
101 $browserInfo = $this->browserInfoArray
;
102 $string = trim($string);
103 $string = substr($string,1,strlen($string)-2);
104 $parts = explode('][',$string);
106 while(list(,$val)=each($parts)) {
107 $pcs = explode('=',$val,2);
108 $switchKey = trim($pcs[0]);
111 $values = explode(',',$pcs[1]);
112 while(list(,$test)=each($values)) {
113 if (strstr($browserInfo['browser'].$browserInfo['version'],trim($test))) {
119 $values = explode(',',$pcs[1]);
120 while(list(,$test)=each($values)) {
123 if (strcspn($test,'=<>')==0) {
124 switch(substr($test,0,1)) {
126 if (doubleval(substr($test,1))==$browserInfo['version']) return true;
129 if (doubleval(substr($test,1))>$browserInfo['version']) return true;
132 if (doubleval(substr($test,1))<$browserInfo['version']) return true;
136 if (strpos(' '.$browserInfo['version'],$test)==1) {return true;}
142 $values = explode(',',$pcs[1]);
143 while(list(,$test)=each($values)) {
146 if (strpos(' '.$browserInfo['system'],$test)==1) {return true;}
151 $values = explode(',',$pcs[1]);
152 if (!isset($this->deviceInfo
)) {
153 $this->deviceInfo
= $this->whichDevice(t3lib_div
::getIndpEnv('HTTP_USER_AGENT'));
155 while(list(,$test)=each($values)) {
158 if ($this->deviceInfo
==$test) {return true;}
163 $test = trim($pcs[1]);
165 return $this->matchWild($browserInfo['useragent'],$test);
169 $values = explode(',',$pcs[1]);
170 while(list(,$test)=each($values)) {
173 if (ereg('^\*.+\*$',$test)) {
174 $allLanguages = split('[,;]',t3lib_div
::getIndpEnv('HTTP_ACCEPT_LANGUAGE'));
175 if (in_array(substr($test,1,-1), $allLanguages)) {return true;}
177 if (t3lib_div
::getIndpEnv('HTTP_ACCEPT_LANGUAGE') == $test) {return true;}
183 if (t3lib_div
::cmpIP(t3lib_div
::getIndpEnv('REMOTE_ADDR'), $pcs[1])) {return true;}
186 if (t3lib_div
::cmpFQDN(t3lib_div
::getIndpEnv('REMOTE_ADDR'), $pcs[1])) {return true;}
188 // hour, minute, dayofweek, dayofmonth, month
194 $theEvalTime = $GLOBALS['SIM_EXEC_TIME']; // In order to simulate time properly in templates.
196 case 'hour': $theTestValue = date('H',$theEvalTime); break;
197 case 'minute': $theTestValue = date('i',$theEvalTime); break;
198 case 'dayofweek': $theTestValue = date('w',$theEvalTime); break;
199 case 'dayofmonth': $theTestValue = date('d',$theEvalTime); break;
200 case 'month': $theTestValue = date('m',$theEvalTime); break;
202 $theTestValue = intval($theTestValue);
204 $values = explode(',',$pcs[1]);
206 while(list(,$test)=each($values)) {
208 if (t3lib_div
::testInt($test)) {$test='='.$test;}
210 if ($this->testNumber($test,$theTestValue)) {return true;}
215 if ($GLOBALS['TSFE']->gr_list
!='0,-1') { // '0,-1' is the default usergroups when not logged in!
216 $values = explode(',',$pcs[1]);
217 while(list(,$test)=each($values)) {
220 if ($test=='*' || t3lib_div
::inList($GLOBALS['TSFE']->gr_list
,$test)) {return true;}
226 if ($GLOBALS['TSFE']->loginUser
) {
227 $values = explode(',',$pcs[1]);
228 while(list(,$test)=each($values)) {
231 if ($test=='*' ||
!strcmp($GLOBALS['TSFE']->fe_user
->user
['uid'],$test)) {return true;}
237 $values = explode(',',$pcs[1]);
238 while(list(,$test)=each($values)) {
241 $point = strcspn($test,'=<>');
242 $theVarName = substr($test,0,$point);
243 $nv = $this->getGP_ENV_TSFE(trim($theVarName));
244 if ($this->testNumber(substr($test,$point) ,$nv)) {return true;}
249 $values = explode(',',$pcs[1]);
250 while(list(,$test)=each($values)) {
253 $point = strcspn($test,'=');
254 $theVarName = substr($test,0,$point);
255 $nv = $this->getGP_ENV_TSFE(trim($theVarName));
256 if ($this->matchWild($nv,trim(substr($test,$point+
1)))) {return true;}
261 $values = explode(',',$pcs[1]);
262 $theRootLine = is_array($GLOBALS['TSFE']->tmpl
->rootLine
) ?
$GLOBALS['TSFE']->tmpl
->rootLine
: $this->altRootLine
;
263 $theRLC = count($theRootLine)-1;
264 while(list(,$test)=each($values)) {
266 if ($test==$theRLC) { return true; }
269 case 'PIDupinRootline':
270 case 'PIDinRootline':
271 $values = explode(',',$pcs[1]);
272 if (($switchKey=='PIDinRootline') ||
(!in_array($GLOBALS['TSFE']->id
,$values))) {
273 $theRootLine = is_array($GLOBALS['TSFE']->tmpl
->rootLine
) ?
$GLOBALS['TSFE']->tmpl
->rootLine
: $this->altRootLine
;
275 while(list(,$test)=each($values)) {
278 while(list($rl_key,$rl_dat)=each($theRootLine)) {
279 if ($rl_dat['uid']==$test) { return true; }
285 $values = split('\(|\)',$pcs[1]);
286 $funcName=trim($values[0]);
287 $funcValue = t3lib_div
::trimExplode(',',$values[1]);
288 $pre = $GLOBALS['TSFE']->TYPO3_CONF_VARS
['FE']['userFuncClassPrefix'];
290 !t3lib_div
::isFirstPartOfStr(trim($funcName),$pre) &&
291 !t3lib_div
::isFirstPartOfStr(trim($funcName),'tx_')
293 if (is_object($GLOBALS['TT'])) $GLOBALS['TT']->setTSlogMessage('Match condition: Function "'.$funcName.'" was not prepended with "'.$pre.'"',3);
296 if (function_exists($funcName) && call_user_func($funcName, $funcValue[0])) {
305 * Will evaluate a $value based on an operator: "<", ">" or "=" (default)
307 * @param string The value to compare with on the form [operator][number]. Eg. "< 123"
308 * @param integer The number
309 * @return boolean If $value is "50" and $test is "< 123" then it will return true.
311 function testNumber($test,$value) {
313 switch(substr($test,0,1)) {
315 if (doubleval(substr($test,1))>$value) return true;
318 if (doubleval(substr($test,1))<$value) return true;
321 if (trim(substr($test,1))==$value) return true;
327 * Matching two strings against each other, supporting a "*" wildcard in either end of the $needle
329 * @param string The string in which to find $needle.
330 * @param string The string to find in $haystack
331 * @return boolean 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 "Netscape*" then it returns true.
333 function matchWild($haystack,$needle) {
334 if ($needle && $haystack) {
335 if (substr($needle,0,1)=='*') {$mode.='before';}
336 if (substr($needle,-1,1)=='*') {$mode.='after';}
339 $matchStr = substr($needle,1);
340 if (substr($haystack,-strlen($matchStr))==$matchStr) return true;
343 if (strpos(' '.$haystack,substr($needle,0,-1))==1) return true;
346 if (strstr($haystack,substr($needle,1,-1))) return true;
349 if ($needle==$haystack) return true;
356 * Returns a code for a browsing device based on the input useragent string
358 * @param string User agent string from browser, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
359 * @return string A code. See link.
361 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=296&cHash=a8ae66c7d6
363 function whichDevice($useragent) {
364 $agent=strtolower(trim($useragent));
366 if( strstr($agent, 'avantgo')) {
371 $browser=substr($agent,0,4);
372 $wapviwer=substr(stristr($agent,'wap'),0,3);
373 if( $wapviwer=='wap' ||
384 if( strstr($agent, 'g.r.a.b.') ||
385 strstr($agent, 'utilmind httpget') ||
386 strstr($agent, 'webcapture') ||
387 strstr($agent, 'teleport') ||
388 strstr($agent, 'webcopier')) {
393 if( strstr($agent, 'crawler') ||
394 strstr($agent, 'spider') ||
395 strstr($agent, 'googlebot') ||
396 strstr($agent, 'searchbot') ||
397 strstr($agent, 'infoseek') ||
398 strstr($agent, 'altavista') ||
399 strstr($agent, 'diibot')) {
405 * Generates an array with abstracted browser information
406 * In the function match() this method is called and the result stored in $this->browserInfoArray
408 * @param string The useragent string, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
409 * @return array Contains keys "browser", "version", "system"
413 function browserInfo($useragent) {
414 $useragent = trim($useragent);
415 $browserInfo=Array();
416 $browserInfo['useragent']=$useragent;
419 if (strstr($useragent,'MSIE')) {
420 $browserInfo['browser']='msie';
421 } elseif(strstr($useragent,'Konqueror')) {
422 $browserInfo['browser']='konqueror';
423 } elseif(strstr($useragent,'Opera')) {
424 $browserInfo['browser']='opera';
425 } elseif(strstr($useragent,'Lynx')) {
426 $browserInfo['browser']='lynx';
427 } elseif(strstr($useragent,'PHP')) {
428 $browserInfo['browser']='php';
429 } elseif(strstr($useragent,'AvantGo')) {
430 $browserInfo['browser']='avantgo';
431 } elseif(strstr($useragent,'WebCapture')) {
432 $browserInfo['browser']='acrobat';
433 } elseif(strstr($useragent,'IBrowse')) {
434 $browserInfo['browser']='ibrowse';
435 } elseif(strstr($useragent,'Teleport')) {
436 $browserInfo['browser']='teleport';
437 } elseif(strstr($useragent,'Mozilla')) {
438 $browserInfo['browser']='netscape';
440 $browserInfo['browser']='unknown';
443 switch($browserInfo['browser']) {
445 $browserInfo['version'] = $this->browserInfo_version(substr($useragent,8));
446 if (strstr($useragent,'Netscape6')) {$browserInfo['version']=6;}
449 $tmp = strstr($useragent,'MSIE');
450 $browserInfo['version'] = $this->browserInfo_version(substr($tmp,4));
453 $tmp = strstr($useragent,'Opera');
454 $browserInfo['version'] = $this->browserInfo_version(substr($tmp,5));
457 $tmp = strstr($useragent,'Lynx/');
458 $browserInfo['version'] = $this->browserInfo_version(substr($tmp,5));
461 $tmp = strstr($useragent,'PHP/');
462 $browserInfo['version'] = $this->browserInfo_version(substr($tmp,4));
465 $tmp = strstr($useragent,'AvantGo');
466 $browserInfo['version'] = $this->browserInfo_version(substr($tmp,7));
469 $tmp = strstr($useragent,'WebCapture');
470 $browserInfo['version'] = $this->browserInfo_version(substr($tmp,10));
473 $tmp = strstr($useragent,'IBrowse/');
474 $browserInfo['version'] = $this->browserInfo_version(substr($tmp,8));
477 $tmp = strstr($useragent,'Konqueror/');
478 $browserInfo['version'] = $this->browserInfo_version(substr($tmp,10));
482 $browserInfo['system']='';
483 if (strstr($useragent,'Win')) {
485 if (strstr($useragent,'Win98') ||
strstr($useragent,'Windows 98')) {
486 $browserInfo['system']='win98';
487 } elseif (strstr($useragent,'Win95') ||
strstr($useragent,'Windows 95')) {
488 $browserInfo['system']='win95';
489 } elseif (strstr($useragent,'WinNT') ||
strstr($useragent,'Windows NT')) {
490 $browserInfo['system']='winNT';
491 } elseif (strstr($useragent,'Win16') ||
strstr($useragent,'Windows 311')) {
492 $browserInfo['system']='win311';
494 } elseif (strstr($useragent,'Mac')) {
495 $browserInfo['system']='mac';
497 } elseif (strstr($useragent,'Linux')) {
498 $browserInfo['system']='linux';
499 } elseif (strstr($useragent,'SGI') && strstr($useragent,' IRIX ')) {
500 $browserInfo['system']='unix_sgi';
501 } elseif (strstr($useragent,' SunOS ')) {
502 $browserInfo['system']='unix_sun';
503 } elseif (strstr($useragent,' HP-UX ')) {
504 $browserInfo['system']='unix_hp';
512 * Returns the version of a browser; Basically getting doubleval() of the input string, stripping of any non-numeric values in the beginning of the string first.
514 * @param string A string with version number, eg. "/7.32 blablabla"
515 * @return double Returns double value, eg. "7.32"
517 function browserInfo_version($tmp) {
518 return doubleval(ereg_replace('^[^0-9]*','',$tmp));
522 * Return global variable where the input string $var defines array keys separated by "|"
524 * @param string Global var key, eg. "HTTP_GET_VAR" or "HTTP_GET_VARS|id" to get the id GET parameter back.
525 * @param array Alternative array than $GLOBAL to get variables from.
526 * @return mixed Whatever value. If none, then blank string.
529 function getGlobal($var,$inArr='') {
530 $vars = explode('|',$var);
533 $theVar = is_array($inArr) ?
$inArr[$k] : $GLOBALS[$k];
535 for ($a=1;$a<$c;$a++
) {
536 if (!isset($theVar)) {break;}
537 $theVar = $theVar[trim($vars[$a])];
539 if (!is_array($theVar)) {
547 * Returns GP / ENV / TSFE vars
549 * @param string Identifier
550 * @return mixed The value of the variable pointed to.
552 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=311&cHash=487cbd5cdf
554 function getGP_ENV_TSFE($var) {
555 $vars = explode(':',$var,2);
556 if (count($vars)==1) {
557 $val = $this->getGlobal($var);
559 $splitAgain=explode('|',$vars[1],2);
560 $k=trim($splitAgain[0]);
562 switch((string)trim($vars[0])) {
564 $val = t3lib_div
::_GP($k);
567 $val = $GLOBALS['TSFE']->$k;
573 $val = t3lib_div
::getIndpEnv($k);
576 return trim($vars[1]); // return litteral value...
580 if (count($splitAgain)>1) {
581 if (is_array($val) && trim($splitAgain[1])) {
582 $val=$this->getGlobal($splitAgain[1],$val);
594 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['t3lib/class.t3lib_matchcondition.php']) {
595 include_once($TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['t3lib/class.t3lib_matchcondition.php']);