[TYPO3-core] RFC: fix feature request #568
Wolfgang Klinger
wolfgang at stufenlos.net
Thu Feb 2 10:48:37 CET 2006
*hiya!*
On Wed, 25 Jan 2006, Bernhard Kraft wrote the following:
> I discussed this with Michael and I (we) are ok with this. Better one hook class
> for a single class when it makes sense (like in this case).
>
> It came out that it would be the best to move the one "device_class" hook up like
> you did but add another hook (yes ! 2 hooks right beneath each other) below the
> original one but the second one using the "shared" hook class.
>
> Mark the old one as "deprecated" and state that it will be removed soon. Somebody (Wolfgang, me?)
> should check a complete mirror of TER (when TER2 is here and load doesn't get to high by that)
> for uses of this hook and inform the extension authors.
See attachment, I hope it's ok now.
kind regards
Wolfgang
-------------- next part --------------
--- TYPO3core/t3lib/class.t3lib_matchcondition.php 2006-02-02 08:40:53.000000000 +0100
+++ TYPO3core_testing/t3lib/class.t3lib_matchcondition.php 2006-02-02 10:39:20.000000000 +0100
@@ -80,6 +80,62 @@
var $altRootLine=array();
+ var $hookObjectsArr = array();
+
+ function __construct() {
+ global $TYPO3_CONF_VARS;
+
+ // usage (ext_localconf.php):
+ // $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php'][] = 'EXT:my_ext/class.browserinfo.php:MyBrowserInfoClass';
+ if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php'])) {
+ foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php'] as $classRef) {
+ $this->hookObjectsArr[] = &t3lib_div::getUserObj($classRef, '');
+ }
+ }
+ }
+
+ function t3lib_matchCondition() {
+ $this->__construct();
+ }
+
+ function match($condition_line) {
+ if ($this->matchAll) {
+ return true;
+ }
+ if (count($this->matchAlternative)) {
+ return in_array($condition_line, $this->matchAlternative);
+ }
+
+ // Getting the value from inside of the wrapping
+ // square brackets of the condition line:
+ $insideSqrBrackets = substr(trim($condition_line), 1, strlen($condition_line) - 2);
+
+ // The "weak" operator "||" (OR) takes precedence:
+ // backwards compatible, [XYZ][ZYX] does still work as OR
+ $orParts = preg_split('/\]\s*(\|\|){0,1}\s*\[/',$insideSqrBrackets);
+ foreach($orParts as $partString) {
+ $matches = false;
+
+ // Splits by the "&&" (AND) operator:
+ $andParts = preg_split('/\]\s*&&\s*\[/',$partString);
+ foreach($andParts as $condStr) {
+ $matches = $this->evalConditionStr($condStr);
+ // only true AND true = true
+ if (false === $matches) {
+ break;
+ }
+ }
+
+ // true OR false = true
+ if (true === $matches) {
+ break;
+ }
+ }
+
+ return $matches;
+ }
+
+
/**
* Evaluates a TypoScript condition given as input, eg. "[browser=net][...(other conditions)...]"
*
@@ -88,29 +144,19 @@
* @see t3lib_tsparser::parse()
* @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=292&cHash=c6c7d43d2f
*/
- function match($string) {
+ function evalConditionStr($string) {
if ( !is_array( $this->altRootLine ) ) {
$this->altRootLine = array();
}
-
- if ($this->matchAll) return true;
- if (count($this->matchAlternative)) {
- return in_array($string,$this->matchAlternative);
- }
-
- if (!$this->browserInfoArray) {
- $this->browserInfoArray = $this->browserInfo(t3lib_div::getIndpEnv('HTTP_USER_AGENT'));
+ list($key, $value) = explode('=', $string, 2);
+ $key = trim($key);
+ if (stristr(',browser,version,system,useragent,', ",$key,")) {
+ $browserInfo = $this->browserInfo(t3lib_div::getIndpEnv('HTTP_USER_AGENT'));
}
- $browserInfo = $this->browserInfoArray;
- $string = trim($string);
- $string = substr($string,1,strlen($string)-2);
- $parts = explode('][',$string);
- foreach ($parts as $val) {
- $pcs = explode('=',$val,2);
- $switchKey = trim($pcs[0]);
- switch($switchKey) {
+ $value = trim($value);
+ switch ($key) {
case 'browser':
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
while(list(,$test)=each($values)) {
if (strstr($browserInfo['browser'].$browserInfo['version'],trim($test))) {
return true;
@@ -118,10 +164,10 @@
}
break;
case 'version':
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
while(list(,$test)=each($values)) {
$test = trim($test);
- if ($test) {
+ if (strlen($test)) {
if (strcspn($test,'=<>')==0) {
switch(substr($test,0,1)) {
case '=':
@@ -141,38 +187,38 @@
}
break;
case 'system':
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
while(list(,$test)=each($values)) {
$test = trim($test);
- if ($test) {
+ if (strlen($test)) {
if (strpos(' '.$browserInfo['system'],$test)==1) {return true;}
}
}
break;
case 'device':
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
if (!isset($this->deviceInfo)) {
$this->deviceInfo = $this->whichDevice(t3lib_div::getIndpEnv('HTTP_USER_AGENT'));
}
while(list(,$test)=each($values)) {
$test = trim($test);
- if ($test) {
+ if (strlen($test)) {
if ($this->deviceInfo==$test) {return true;}
}
}
break;
case 'useragent':
- $test = trim($pcs[1]);
- if ($test) {
+ $test = trim($value);
+ if (strlen($test)) {
return $this->matchWild($browserInfo['useragent'],$test);
}
break;
case 'language':
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
while(list(,$test)=each($values)) {
$test = trim($test);
- if ($test) {
- if (ereg('^\*.+\*$',$test)) {
+ if (strlen($test)) {
+ if (preg_match('/^\*.+\*$/',$test)) {
$allLanguages = split('[,;]',t3lib_div::getIndpEnv('HTTP_ACCEPT_LANGUAGE'));
if (in_array(substr($test,1,-1), $allLanguages)) {return true;}
} else {
@@ -182,10 +228,10 @@
}
break;
case 'IP':
- if (t3lib_div::cmpIP(t3lib_div::getIndpEnv('REMOTE_ADDR'), $pcs[1])) {return true;}
+ if (t3lib_div::cmpIP(t3lib_div::getIndpEnv('REMOTE_ADDR'), $value)) {return true;}
break;
case 'hostname':
- if (t3lib_div::cmpFQDN(t3lib_div::getIndpEnv('REMOTE_ADDR'), $pcs[1])) {return true;}
+ if (t3lib_div::cmpFQDN(t3lib_div::getIndpEnv('REMOTE_ADDR'), $value)) {return true;}
break;
// hour, minute, dayofweek, dayofmonth, month
case 'hour':
@@ -194,7 +240,7 @@
case 'dayofmonth':
case 'month':
$theEvalTime = $GLOBALS['SIM_EXEC_TIME']; // In order to simulate time properly in templates.
- switch($switchKey) {
+ switch($key) {
case 'hour': $theTestValue = date('H',$theEvalTime); break;
case 'minute': $theTestValue = date('i',$theEvalTime); break;
case 'dayofweek': $theTestValue = date('w',$theEvalTime); break;
@@ -203,22 +249,22 @@
}
$theTestValue = intval($theTestValue);
// comp
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
reset($values);
while(list(,$test)=each($values)) {
$test = trim($test);
if (t3lib_div::testInt($test)) {$test='='.$test;}
- if ($test) {
+ if (strlen($test)) {
if ($this->testNumber($test,$theTestValue)) {return true;}
}
}
break;
case 'usergroup':
if ($GLOBALS['TSFE']->gr_list!='0,-1') { // '0,-1' is the default usergroups when not logged in!
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
while(list(,$test)=each($values)) {
$test = trim($test);
- if ($test) {
+ if (strlen($test)) {
if ($test=='*' || t3lib_div::inList($GLOBALS['TSFE']->gr_list,$test)) {return true;}
}
}
@@ -226,20 +272,20 @@
break;
case 'loginUser':
if ($GLOBALS['TSFE']->loginUser) {
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
while(list(,$test)=each($values)) {
$test = trim($test);
- if ($test) {
+ if (strlen($test)) {
if ($test=='*' || !strcmp($GLOBALS['TSFE']->fe_user->user['uid'],$test)) {return true;}
}
}
}
break;
case 'globalVar':
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
while(list(,$test)=each($values)) {
$test = trim($test);
- if ($test) {
+ if (strlen($test)) {
$point = strcspn($test,'=<>');
$theVarName = substr($test,0,$point);
$nv = $this->getGP_ENV_TSFE(trim($theVarName));
@@ -250,10 +296,10 @@
}
break;
case 'globalString':
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
while(list(,$test)=each($values)) {
$test = trim($test);
- if ($test) {
+ if (strlen($test)) {
$point = strcspn($test,'=');
$theVarName = substr($test,0,$point);
$nv = $this->getGP_ENV_TSFE(trim($theVarName));
@@ -264,7 +310,7 @@
}
break;
case 'treeLevel':
- $values = explode(',',$pcs[1]);
+ $values = explode(',',$value);
$theRootLine = is_array($GLOBALS['TSFE']->tmpl->rootLine) ? $GLOBALS['TSFE']->tmpl->rootLine : $this->altRootLine;
$theRLC = count($theRootLine)-1;
while(list(,$test)=each($values)) {
@@ -274,8 +320,8 @@
break;
case 'PIDupinRootline':
case 'PIDinRootline':
- $values = explode(',',$pcs[1]);
- if (($switchKey=='PIDinRootline') || (!in_array($GLOBALS['TSFE']->id,$values))) {
+ $values = explode(',',$value);
+ if (($key=='PIDinRootline') || (!in_array($GLOBALS['TSFE']->id,$values))) {
$theRootLine = is_array($GLOBALS['TSFE']->tmpl->rootLine) ? $GLOBALS['TSFE']->tmpl->rootLine : $this->altRootLine;
reset($values);
while(list(,$test)=each($values)) {
@@ -288,10 +334,10 @@
}
break;
case 'compatVersion':
- { return t3lib_div::compat_version($pcs[1]); }
+ { return t3lib_div::compat_version($value); }
break;
case 'userFunc':
- $values = split('\(|\)',$pcs[1]);
+ $values = split('\(|\)',$value);
$funcName=trim($values[0]);
$funcValue = t3lib_div::trimExplode(',',$values[1]);
$pre = $GLOBALS['TSFE']->TYPO3_CONF_VARS['FE']['userFuncClassPrefix'];
@@ -307,7 +353,9 @@
}
break;
}
- }
+
+
+ return false;
}
/**
@@ -330,6 +378,8 @@
if (trim(substr($test,1))==$value) return true;
break;
}
+
+ return false;
}
/**
@@ -347,6 +397,8 @@
if (preg_match($regex, $haystack, $res)) return true;
}
+
+ return false;
}
/**
@@ -358,6 +410,24 @@
* @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=296&cHash=a8ae66c7d6
*/
function whichDevice($useragent) {
+ foreach($this->hookObjectsArr as $hookObj) {
+ if (method_exists($hookObj, 'whichDevice')) {
+ $result = $hookObj->whichDevice($useragent);
+ if (strlen($result)) {
+ return $result;
+ }
+ }
+ }
+
+ // #XXX deprecated, see above
+ if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['devices_class'])) {
+ foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['devices_class'] as $_classRef) {
+ $_procObj = &t3lib_div::getUserObj($_classRef);
+ return $_procObj->whichDevice_ext($useragent);
+ }
+ }
+ //
+
$agent=strtolower(trim($useragent));
// pda
if( strstr($agent, 'avantgo')) {
@@ -397,19 +467,11 @@
return 'robot';
}
- // Hook for extending device recognition capabilities:
- if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['devices_class'])) {
- foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['devices_class'] as $_classRef) {
- $_procObj = &t3lib_div::getUserObj($_classRef);
- return $_procObj->whichDevice_ext($useragent);
- }
- }
-
}
/**
* Generates an array with abstracted browser information
- * In the function match() this method is called and the result stored in $this->browserInfoArray
+ * This method is used in the function match() in this class
*
* @param string The useragent string, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
* @return array Contains keys "browser", "version", "system"
@@ -417,6 +479,15 @@
* @see match()
*/
function browserInfo($useragent) {
+ foreach($this->hookObjectsArr as $hookObj) {
+ if (method_exists($hookObj, 'browserInfo')) {
+ $result = $hookObj->browserInfo($useragent);
+ if (strlen($result)) {
+ return $result;
+ }
+ }
+ }
+
$useragent = trim($useragent);
$browserInfo=Array();
$browserInfo['useragent']=$useragent;
@@ -521,7 +592,7 @@
* @return double Returns double value, eg. "7.32"
*/
function browserInfo_version($tmp) {
- return doubleval(ereg_replace('^[^0-9]*','',$tmp));
+ return doubleval(preg_replace('/^[^0-9]*/','',$tmp));
}
/**
More information about the TYPO3-team-core
mailing list