[TYPO3-core] RFC: fix feature request #568

Wolfgang Klinger wolfgang at stufenlos.net
Thu Jan 19 13:04:56 CET 2006


 *hiya!*

 On Thu, 19 Jan 2006, Bernhard Kraft wrote the following:
> Please send again such a easier to read patch and I will look on it, test this one (send a new
> one with indendting respected if you changed something in between) and send you my opinion.
 
 done, attached, sorry didn't know that

> Fine with that if also (string)"0" should return true for that (is not everywhere
> the case in T3. i.e. if you check a TS value it might have also been set to (string)"0" which
> means "false". i.e: "stdWrap.insertData = 0" )

 not the case here IMHO,
 and I know that 0 is treated as false :-)

> You have 't3lib/class.t3lib_matchcondition.php' definig the file in which the hook
> is found and "devices_class" as the name of the hook.
> in t3lib_tcemain.php you have "t3lib/class.t3lib_tcemain.php" as file name and
> "preProcessDatamapClass" as hook name for example.

 I want one "hook class" for this, not three for every method,
 I think that's cleaner?

> If I understand you correct you would like to have only ONE ['matchConditionClass'] array
> for the whole class ?? Or am I misunderstanding something ?

 right, something wrong with that (I don't know)?

> If you provide a backwards compatible version I would be fine with it. And let's remove the
> backwards compatibility let's say in 4.2.0 or so

 ok

> The hookObjectsArr in the mentioned example are always local variables !

 but I'll use it in more than one place in this class...

> Stay with the coding guidelines and simply do a "return" or "break" after the
> first valid hook-object (or the first one which returned a valid value).

 ..and that's the question: valid object or valid value? Is that
 something that's handled for each hook seperately? I would (in this
 case) choose to return only if the return value contains something
 (strlen check).

> Using only a simple variable instead of an array would bring up other questions
> why the standard is not kept in this place.

 true though...


 bye
 Wolfgang

-------------- next part --------------
--- TYPO3core/t3lib/class.t3lib_matchcondition.php	2006-01-16 08:24:33.000000000 +0100
+++ TYPO3core_testing/t3lib/class.t3lib_matchcondition.php	2006-01-18 20:07:39.000000000 +0100
@@ -80,6 +80,44 @@
 
 	var $altRootLine=array();
 
+	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 +126,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 +146,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 +169,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 +210,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 +222,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 +231,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 +254,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 +278,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 +292,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 +302,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 +316,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 +335,9 @@
 					}
 				break;
 			}
-		}
+		
+
+		return false;
 	}
 
 	/**
@@ -330,6 +360,8 @@
 				if (trim(substr($test,1))==$value)	return true;
 			break;
 		}
+
+		return false;
 	}
 
 	/**
@@ -347,6 +379,8 @@
 
 			if (preg_match($regex, $haystack, $res)) return true;
 		}
+
+		return false;
 	}
 
 	/**
@@ -358,6 +392,14 @@
 	 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=296&cHash=a8ae66c7d6
 	 */
 	function whichDevice($useragent)	{
+			// 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);
+			}
+		}
+
 		$agent=strtolower(trim($useragent));
 			// pda
 		if(	strstr($agent, 'avantgo'))	{
@@ -397,19 +439,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 +451,14 @@
 	 * @see match()
 	 */
 	function browserInfo($useragent)	{
+			// Hook for extending useragent recognition capabilities:
+		if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['browserinfo_class']))	{
+			foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['browserinfo_class'] as $_classRef)	{
+				$_procObj = &t3lib_div::getUserObj($_classRef);
+				return $_procObj->browserInfo_ext($useragent);
+			}
+		}
+
 		$useragent = trim($useragent);
 		$browserInfo=Array();
 		$browserInfo['useragent']=$useragent;
@@ -521,7 +563,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