Index: t3lib/class.t3lib_befunc.php
===================================================================
--- t3lib/class.t3lib_befunc.php	(Revision 2438)
+++ t3lib/class.t3lib_befunc.php	(Arbeitskopie)
@@ -172,6 +172,7 @@
  */
 
 require_once (PATH_t3lib.'class.t3lib_loaddbgroup.php');
+require_once (PATH_t3lib.'class.t3lib_matchcondition.php');
 
 
 /**
@@ -1189,16 +1190,23 @@
 
 			// Parsing the user TS (or getting from cache)
 		$userTS = implode($TSdataArray,chr(10).'[GLOBAL]'.chr(10));
-		$hash = md5('pageTS:'.$userTS);
+		$hash = md5('pageTS:'.$id.':'.$userTS);
 		$cachedContent = t3lib_BEfunc::getHash($hash,0);
 		$TSconfig = array();
 		if (isset($cachedContent))	{
 			$TSconfig = unserialize($cachedContent);
 		} else {
+			$matchObj = t3lib_div::makeInstance('t3lib_matchCondition');
+			$matchObj->backendPage = $id;
 			$parseObj = t3lib_div::makeInstance('t3lib_TSparser');
-			$parseObj->parse($userTS);
+			$parseObj->parse($userTS, $matchObj);
 			$TSconfig = $parseObj->setup;
-			t3lib_BEfunc::storeHash($hash,serialize($TSconfig),'PAGES_TSconfig');
+				// Don't store to cache if conditions were found:
+				// @TODO: Optimize this part and adjust e.g. to FE disposal
+			if (!count($parseObj->sections)) {
+					// @TODO: Set 'PAGES_TSconfig_<uid>' for later removal of old data/cleanup
+				t3lib_BEfunc::storeHash($hash,serialize($TSconfig),'PAGES_TSconfig');
+			}
 		}
 
 			// get User TSconfig overlay
Index: t3lib/class.t3lib_matchcondition.php
===================================================================
--- t3lib/class.t3lib_matchcondition.php	(Revision 2438)
+++ t3lib/class.t3lib_matchcondition.php	(Arbeitskopie)
@@ -83,6 +83,8 @@
 
 	var $altRootLine=array();
 	var $hookObjectsArr = array();
+	var $backendMode = false;
+	var $backendPage = null;
 
 	/**
 	 * Constructor for this class
@@ -92,6 +94,10 @@
 	function __construct()	{
 		global $TYPO3_CONF_VARS;
 
+			// Enable the hybrid mode if used in TYPO3 backend:
+		if (defined('TYPO3_MODE') && TYPO3_MODE=='BE') {
+			$this->backendMode = true;
+		}
 		// Usage (ext_localconf.php):
 		// $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_matchcondition.php']['matchConditionClass'][] =
 		// 'EXT:my_ext/class.browserinfo.php:MyBrowserInfoClass';
@@ -278,23 +284,24 @@
 				}
 			break;
 			case 'usergroup':
-				if ($GLOBALS['TSFE']->gr_list!='0,-1')	{		// '0,-1' is the default usergroups when not logged in!
+				$groupList = $this->getGroupList();
+				if ($groupList!='0,-1')	{		// '0,-1' is the default usergroups when not logged in!
 					$values = explode(',',$value);
 					while(list(,$test)=each($values))	{
 						$test = trim($test);
 						if (strlen($test)) {
-							if ($test=='*' || t3lib_div::inList($GLOBALS['TSFE']->gr_list,$test))	{return true;}
+							if ($test=='*' || t3lib_div::inList($groupList,$test))	{return true;}
 						}
 					}
 				}
 			break;
 			case 'loginUser':
-				if ($GLOBALS['TSFE']->loginUser)	{
+				if ($this->isUserLoggedIn())	{
 					$values = explode(',',$value);
 					while(list(,$test)=each($values))	{
 						$test = trim($test);
 						if (strlen($test)) {
-							if ($test=='*' || !strcmp($GLOBALS['TSFE']->fe_user->user['uid'],$test))	{return true;}
+							if ($test=='*' || !strcmp($this->getUserId(),$test))	{return true;}
 						}
 					}
 				}
@@ -329,7 +336,8 @@
 			break;
 			case 'treeLevel':
 				$values = explode(',',$value);
-				$theRootLine = is_array($GLOBALS['TSFE']->tmpl->rootLine) ? $GLOBALS['TSFE']->tmpl->rootLine : $this->altRootLine;
+				$rootLine = $this->getRootline();
+				$theRootLine = is_array($rootLine) ? $rootLine : $this->altRootLine;
 				$theRLC = count($theRootLine)-1;
 				while(list(,$test)=each($values))	{
 					$test = trim($test);
@@ -339,8 +347,10 @@
 			case 'PIDupinRootline':
 			case 'PIDinRootline':
 				$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;
+				$pageId = $this->getPageId();
+				$rootLine = $this->getRootline();
+				if (($key=='PIDinRootline') || !in_array($pageId, $values) || $this->isNewPageWithPid($pageId)) {
+					$theRootLine = is_array($rootLine) ? $rootLine : $this->altRootLine;
 					reset($values);
 					while(list(,$test)=each($values))	{
 						$test = trim($test);
@@ -356,17 +366,17 @@
 			break;
 			case 'userFunc':
 				$values = split('\(|\)',$value);
-				$funcName=trim($values[0]);
-				$funcValue = t3lib_div::trimExplode(',',$values[1]);
-				$pre = $GLOBALS['TSFE']->TYPO3_CONF_VARS['FE']['userFuncClassPrefix'];
+				$funcName = trim($values[0]);
+				$funcValues = t3lib_div::trimExplode(',',$values[1]);
+				$pre = $this->getUserFuncClassPrefix();
 				if ($pre &&
 					!t3lib_div::isFirstPartOfStr(trim($funcName),$pre) &&
 					!t3lib_div::isFirstPartOfStr(trim($funcName),'tx_')
 				)	{
-					if (is_object($GLOBALS['TT']))	$GLOBALS['TT']->setTSlogMessage('Match condition: Function "'.$funcName.'" was not prepended with "'.$pre.'"',3);
+					$this->setLogMessage('Match condition: Function "'.$funcName.'" was not prepended with "'.$pre.'"');
 					return false;
 				}
-				if (function_exists($funcName) && call_user_func($funcName, $funcValue[0]))	{
+				if (function_exists($funcName) && call_user_func_array($funcName, $funcValues))	{
 					return true;
 				}
 			break;
@@ -698,6 +708,155 @@
 		}
 		return $val;
 	}
+
+	/**
+	 * Hybrid FE/BE: Get the usergroup list of the current user.
+	 *
+	 * @return	string		The usergroup list of the current user
+	 */
+	function getGroupList() {
+		if (!$this->backendMode) {
+			$groupList = $GLOBALS['TSFE']->gr_list;
+		} else {
+			$groupList = $GLOBALS['BE_USER']->groupList;
+		}
+		return $groupList;
+	}
+
+	/**
+	 * Hybrid FE/BE: Get the id of the current page.
+	 *
+	 * @return	integer		The id of the current page
+	 */
+	function getPageId() {
+		if (!$this->backendMode) {
+			$pageId = $GLOBALS['TSFE']->id;
+		} else {
+			if ($this->backendPage != null) {
+				$pageId = $this->backendPage;
+			} else {
+				$pageId = intval(t3lib_div::_GP('id'));
+			}
+		}
+		return $pageId;
+	}
+
+	/**
+	 * Determine if record of table 'pages' with the given $pid is currently created in TCEforms.
+	 * This information is required for conditions in BE an PIDupinRootline.
+	 * 
+	 * @param	integer		$pid: The pid the check for as parent page
+	 * @return	boolean		true if the is currently a new page record being edited with $pid as uid of the parent page
+	 */
+	function isNewPageWithPid($pid) {
+		if (isset($GLOBALS['SOBE']) && is_object($GLOBALS['SOBE']) && is_a($GLOBALS['SOBE'], 'SC_alt_doc')) {
+			$pid = intval($pid);
+			$elementsData = $GLOBALS['SOBE']->elementsData;
+			$data = $GLOBALS['SOBE']->data;
+				// If editing a new page record:
+			if (is_array($elementsData)) {
+				foreach ($elementsData as $element) {
+					if ($element['cmd'] == 'new' && $element['table'] == 'pages') {
+						if ($element['pid'] < 0) {
+							$pageRecord = t3lib_BEfunc::getRecord('pages', abs($element['pid']), 'pid');
+							$element['pid'] = $pageRecord['pid'];
+						}
+						if ($element['pid'] == $pid) {
+							return true;
+						}
+					}
+				}
+				// If saving a new page record:
+			} elseif (is_array($data) && isset($data['pages']) && is_array($data['pages'])) {
+				foreach ($data['pages'] as $uid => $fields) {
+					if (substr($uid, 0, 3) == 'NEW' && $fields['pid'] == $pid) {
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Hybrid FE/BE: Get the rootline for the current page.
+	 *
+	 * @return	array		The rootline for the current page.
+	 */
+	function getRootline() {
+		if (!$this->backendMode) {
+			$rootline = $GLOBALS['TSFE']->tmpl->rootLine;
+		} else {
+			$pageId = $this->getPageId();
+			$rootline = t3lib_BEfunc::BEgetRootLine($pageId, '', true);
+		}
+		return $rootline;
+	}
+
+	/**
+	 * Hybrid FE/BE: Get prefix for user functions (normally 'user_').
+	 *
+	 * @return	string		The prefix for user functions (normally 'user_').
+	 */
+	function getUserFuncClassPrefix() {
+		if (!$this->backendMode) {
+			$userFuncClassPrefix = $GLOBALS['TSFE']->TYPO3_CONF_VARS['FE']['userFuncClassPrefix'];
+		} else {
+			$userFuncClassPrefix = 'user_';
+		}
+		return $userFuncClassPrefix;
+	}
+
+	/**
+	 * Hybrid FE/BE: Get the id of the current user.
+	 *
+	 * @return	integer		The id of the current user
+	 */
+	function getUserId() {
+		if (!$this->backendMode) {
+			$userId = $GLOBALS['TSFE']->fe_user->user['uid'];
+		} else {
+			$userId = $GLOBALS['BE_USER']->user['uid'];
+		}
+		return $userId;
+	}
+
+	/**
+	 * Hybrid FE/BE: Determines if a user is logged in.
+	 *
+	 * @return	boolean		Determines if a user is logged in
+	 */
+	function isUserLoggedIn() {
+		$userLoggedIn = false;
+		if (!$this->backendMode) {
+			if ($GLOBALS['TSFE']->loginUser) {
+				$userLoggedIn = true;
+			}
+		} else {
+			if ($this->getUserId()) {
+				$userLoggedIn = true;
+			}
+		}
+		return $userLoggedIn;
+	}
+
+	/**
+	 * Hybrid FE/BE: Set/write a log message.
+	 *
+	 * @param	string		$message: The log message to set/write
+	 * @return	void
+	 */
+	function setLogMessage($message) {
+		if (!$this->backendMode) {
+			if (is_object($GLOBALS['TT'])) {
+				$GLOBALS['TT']->setTSlogMessage($message,3);
+			}
+		} else {
+			if (is_object($GLOBALS['BE_USER'])) {
+				$GLOBALS['BE_USER']->writelog(3, 0, 1, 0, $message, array());
+			}
+		}
+	}
 }
 
 
