diff -ruN TYPO3core_orig_cvs/t3lib/class.t3lib_tcemain.php TYPO3core_testing/t3lib/class.t3lib_tcemain.php
--- TYPO3core_orig_cvs/t3lib/class.t3lib_tcemain.php	2005-11-23 16:57:13.000000000 +0100
+++ TYPO3core_testing/t3lib/class.t3lib_tcemain.php	2005-12-06 22:30:51.000000000 +0100
@@ -2065,7 +2065,7 @@
 			$modifyAccessList = $this->checkModifyAccessList($table);
 			if (!$modifyAccessList)	{
 				$this->log($table,$id,2,0,1,"Attempt to modify table '%s' without permission",1,array($table));
-			}
+			}	// FIXME: $id not set here (Comment added by Sebastian Kurfuerst)

 				// Check basic permissions and circumstances:
 			if (isset($TCA[$table]) && !$this->tableReadOnly($table) && is_array($this->cmdmap[$table]) && $modifyAccessList)	{
@@ -2130,6 +2130,9 @@
 							case 'delete':
 								$this->deleteAction($table, $id);
 							break;
+							case 'undelete':
+								$this->undeleteRecord($table, $id);
+							break;
 						}

 						foreach($hookObjectsArr as $hookObj) {
@@ -2993,7 +2996,18 @@
 	}

 	/**
-	 * Deleting a record
+	 * Undeleting a record
+	 *
+	 * @param	string		Table name
+	 * @param	integer		Record UID
+	 * @return	void
+	 */
+	function undeleteRecord($table,$uid)	{
+		$this->deleteRecord($table,$uid,TRUE,FALSE,TRUE);
+	}
+
+	/**
+	 * Deleting/Undeleting a record
 	 * This function may not be used to delete pages-records unless the underlying records are already deleted
 	 * Deletes a record regardless of versioning state (live of offline, doesn't matter, the uid decides)
 	 * If both $noRecordCheck and $forceHardDelete are set it could even delete a "deleted"-flagged record!
@@ -3002,9 +3016,10 @@
 	 * @param	integer		Record UID
 	 * @param	boolean		Flag: If $noRecordCheck is set, then the function does not check permission to delete record
 	 * @param	boolean		If TRUE, the "deleted" flag is ignored if applicable for record and the record is deleted COMPLETELY!
+	 * @param	boolean		If TRUE, the "deleted" flag is set to 0 again and thus, the item is undeleted.
 	 * @return	void
 	 */
-	function deleteRecord($table,$uid, $noRecordCheck=FALSE, $forceHardDelete=FALSE)	{
+	function deleteRecord($table,$uid, $noRecordCheck=FALSE, $forceHardDelete=FALSE,$undeleteRecord=FALSE)	{
 		global $TCA;

 		$uid = intval($uid);
@@ -3014,12 +3029,13 @@

 				$deleteRow = $TCA[$table]['ctrl']['delete'];
 				if ($deleteRow && !$forceHardDelete)	{
+					$value = $undeleteRecord ? 0 : 1;
 					$updateFields = array(
-						$deleteRow => 1
+						$deleteRow => $value
 					);

 						// If the table is sorted, then the sorting number is set very high
-					if ($TCA[$table]['ctrl']['sortby'])	{
+					if ($TCA[$table]['ctrl']['sortby'] && !$undeleteRecord)	{
 						$updateFields[$TCA[$table]['ctrl']['sortby']] = 1000000000;
 					}

@@ -3043,10 +3059,11 @@
 					$GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'uid='.intval($uid));
 				}

+				$state = $undeleteRecord ? 1 : 3;
 				if (!$GLOBALS['TYPO3_DB']->sql_error())	{
-					$this->log($table,$uid,3,0,0,'');
+					$this->log($table,$uid,$state,0,0,'');
 				} else {
-					$this->log($table,$uid,3,0,100,$GLOBALS['TYPO3_DB']->sql_error());
+					$this->log($table,$uid,$state,0,100,$GLOBALS['TYPO3_DB']->sql_error());
 				}

 			} else $this->log($table,$uid,3,0,1,'Attempt to delete record without delete-permissions');

diff -ruN TYPO3core_orig_cvs/typo3/class.show_rechis_new.inc TYPO3core_testing/typo3/class.show_rechis_new.inc
--- TYPO3core_orig_cvs/typo3/class.show_rechis_new.inc	1970-01-01 01:00:00.000000000 +0100
+++ TYPO3core_testing/typo3/class.show_rechis_new.inc	2005-12-06 22:46:32.000000000 +0100
@@ -0,0 +1,656 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Class for the record history display script (show_rechis.php)
+ *
+ * $Id: class.show_rechis.inc,v 1.17 2005/11/02 22:51:52 typo3 Exp $
+ * XHTML Compliant
+ *
+ * @author	Sebastian Kurfuerst <sebastian@garbage-group.de>
+ */
+
+
+/**
+ * Class for the record history display script (show_rechis.php)
+ *
+ * @author	Sebastian Kurfuerst <sebastian@garbage-group.de>
+ * @package TYPO3
+ * @subpackage core
+ */
+
+class recordHistory {
+		// External, static:
+	var $maxSteps=20;		// Maximum number of sys_history steps to show.
+	// TODO: NEEDS TO BE IMPLEMENTED
+	var $displayDiff=1;		// display diff or not (0-no diff, 1-inline, 2-popup)
+	// TODO: $displayDiff=2
+	var $showSubElements=1;		// on a pages table - show sub elements as well.
+	var $showInsertDelete=1;		// show inserts and deletes as well
+		// Internal, GPvars
+	var $element;			// Element reference, syntax [tablename]:[uid]
+	var $returnUrl;
+	var $changeLog;
+	var $lastSyslogId;		// syslog ID which is not shown anymore
+	/**
+	 * Constructor for the class
+	 *
+	 * @return	void
+	 */
+	function recordHistory()	{
+
+			// GPvars:
+		#$this->sh_uid = t3lib_div::_GP('sh_uid');
+		$this->element = t3lib_div::_GP('element');
+		$this->returnUrl = t3lib_div::_GP('returnUrl');
+		$this->lastSyslogId = t3lib_div::_GP('diff');
+		$this->rollbackFields = t3lib_div::_GP('rollbackFields');
+		/*$this->saveState = t3lib_div::_GP('saveState');
+
+		$this->revert = t3lib_div::_GP('revert');
+		$this->sumUp = t3lib_div::_GP('sumUp');
+		$this->doReturn = t3lib_div::_GP('doReturn');*/
+	}
+
+	/**
+	 * Main function for the listing of history.
+	 * It detects incoming variables like element reference, history element uid etc. and renders the correct screen.
+	 *
+	 * @return	void
+	 */
+	function main()	{
+		$content = '';
+		$this->resolveElement();	// FIXME: RESOLVE ELEMENT MIGHT NEED TO BE CALLED MORE OFTEN
+		$this->createChangeLog();
+		if ($this->rollbackFields)	{
+			$completeDiff = $this->createMultipleDiff();
+			$this->performRollback($completeDiff);
+
+		}
+		if ($this->lastSyslogId)	{
+			$completeDiff = $this->createMultipleDiff();
+			$content .= $this->displayMultipleDiff($completeDiff);
+		}
+		if ($this->element)	{
+			$content .= $this->displayHistory();
+		}
+		return $content;
+	}
+
+	/*******************************
+	 *
+	 * database actions - rollback
+	 *
+	 *******************************/
+	/**
+	 * perform rollback
+	 *
+	 * @param	array		diff array to rollback
+	 * @return	void
+	 * @access	private
+	 */
+	function performRollback($diff)	{
+		if (!$this->rollbackFields)	{
+			return 0;
+		}
+			// PROCESS INSERTS AND DELETES
+			// rewrite inserts and deletes
+		$cmdmapArray = array();
+		if ($diff['insertsDeletes'])	{
+			foreach ($diff['insertsDeletes'] as $key => $action)	{
+				$elParts = explode(':',$key);
+				if ($action == 1)	{	// inserted records should be deleted
+					$cmdmapArray[$elParts[0]][$elParts[1]]['delete'] = 1;
+						// when the record is deleted, the contents of the record do not need to be updated
+					unset($diff['oldData'][$key]);
+					unset($diff['newData'][$key]);
+				} else {	// deleted records should be inserted again
+					$cmdmapArray[$elParts[0]][$elParts[1]]['undelete'] = 1;
+				}
+			}
+		}
+			// Writes the data:
+		if ($cmdmapArray)	{
+			$tce = t3lib_div::makeInstance('t3lib_TCEmain');
+			$tce->stripslashes_values=0;
+			$tce->debug=0;
+			$tce->dontProcessTransformations=1;
+			$tce->start(array(),$cmdmapArray);
+			$tce->process_cmdmap();
+			unset($tce);
+		}
+
+			// PROCESS CHANGES
+			// create an array for process_datamap
+		$diff_modified = array();
+		foreach ($diff['oldData'] as $key => $value)	{
+			$splitKey = explode(':',$key);
+			$diff_modified[$splitKey[0]][$splitKey[1]] = $value;
+		}
+
+		$rollbackData = explode(':',$this->rollbackFields);
+
+		switch (count($rollbackData))	{
+			case 1:	// TODO: ALL / ONE TABLE => IMPLEMENT!!!!!! currently only "ALL"
+				$data = $diff_modified;
+				break;
+			case 2:	// one record
+				$data[$rollbackData[0]][$rollbackData[1]] = $diff_modified[$rollbackData[0]][$rollbackData[1]];
+				break;
+			case 3:	// one field in one record
+				$data[$rollbackData[0]][$rollbackData[1]][$rollbackData[2]] = $diff_modified[$rollbackData[0]][$rollbackData[1]][$rollbackData[2]];
+				break;
+		}
+			// Removing fields:
+		$data = $this->removeFilefields($rollbackData[0],$data);
+
+			// Writes the data:
+		$tce = t3lib_div::makeInstance('t3lib_TCEmain');
+		$tce->stripslashes_values=0;
+		$tce->debug=0;
+		$tce->dontProcessTransformations=1;
+		$tce->start($data,array());
+		$tce->process_datamap();
+		unset($tce);
+
+			// return to normal operation
+		$this->lastSyslogId = FALSE;
+		$this->rollbackFields = FALSE;
+		$this->createChangeLog();
+	}
+
+	/*******************************
+	 *
+	 * Display functions
+	 *
+	 *******************************/
+
+	/**
+	 * Displays the history states of an element
+	 * Shows the full change Log:
+	 *
+	 * @return	string		HTML for list, wrapped in a table.
+	 */
+	function displayHistory()	{
+		global $LANG;
+		global $SOBE;
+		global $TCA;
+		$changeLog = $this->changeLog;
+		$lines=array();
+			//$darkerBgColor_interM = '#cccccc';
+			// TODO: Table header
+					// Initialize:
+/*				$lines[] = '<tr class="bgColor5 c-head">
+						<td>'.$LANG->getLL('fieldName',1).':</td>
+						<td>'.$LANG->getLL('difference',1).':</td>
+						<td>&nbsp;</td>
+					</tr>';
+*/
+			// TODO: Maybe user/groupname blinding necessary
+		#$be_group_Array=t3lib_BEfunc::getListGroupNames('title,uid');
+		#$groupArray=array_keys($be_group_Array);
+
+		$be_user_array = t3lib_BEfunc::getUserNames();
+		#if (!$GLOBALS['BE_USER']->isAdmin())		$be_user_Array = t3lib_BEfunc::blindUserNames($be_user_Array,$groupArray,1);
+
+			// Traverse changelog array:
+		if (!$changeLog)	{
+			return 0;
+		}
+		$i = 0;
+		foreach ($changeLog as $sysLogUid => $entry)	{
+				// stop after maxSteps
+			if ($i > $this->maxSteps && $this->maxSteps)	{
+				break;
+			}
+			$i++;
+				// get user name
+			$userName = ($entry['user']?$be_user_array[$entry['user']]['username']:$LANG->getLL('externalChange',1));
+
+				// build up single line
+			$singleLine = array();
+			$image = '<img'.t3lib_iconWorks::skinImg('','gfx/pilright_n.gif').' align="top" alt="" />';
+
+			$singleLine[] = '<span style="position:relative;top:-10px">'.$this->linkPage($image,array('diff' => $sysLogUid)).'</span>';
+			$singleLine[] = htmlspecialchars(t3lib_BEfunc::datetime($entry['tstamp']));	// add time
+			$singleLine[] = htmlspecialchars(t3lib_BEfunc::calcAge(time()-$entry['tstamp'],$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')));	// add age
+			$singleLine[] = htmlspecialchars($userName);
+			$singleLine[] = htmlspecialchars($entry['tablename'].':'.$entry['recuid']);
+
+			if ($entry['action'])	{	// insert or delete of element
+				$singleLine[] = '<strong>'.htmlspecialchars($LANG->getLL($entry['action'],1)).'</strong>';
+			} else {
+				if (!$this->displayDiff)	{	// display field names
+					// re-write field names with labels
+				$tmpFieldList = explode(',',$entry['fieldlist']);
+				foreach ($tmpFieldList as $key => $value)	{
+					$tmpFieldList[$key] = str_replace(':','',$LANG->sl(t3lib_BEfunc::getItemLabel($entry['tablename'],$value),1));	// FIXME: Ugly hack for removing the :
+				}
+				$singleLine[] = htmlspecialchars(implode(',',$tmpFieldList));
+				} else {	// display diff
+					$diff = $this->renderDiff($entry,$entry['tablename']);
+					$singleLine[] = $diff;
+				}
+			}
+
+				// put line together
+			$lines[] = '
+				<tr class="bgColor4-20">
+					<td>'.implode('</td><td>',$singleLine).'</td>
+				</tr>';
+		}
+
+			// Finally, put it all together:
+		$theCode = '
+			<!--
+				History (list):
+			-->
+			<table border="0" cellpadding="2" cellspacing="2" id="typo3-history">
+				'.implode('',$lines).'
+			</table>';
+
+			// Add message about the difference view.
+		$theCode .= '<br /><img'.t3lib_iconWorks::skinImg('','gfx/icon_note.gif','width="18" height="16"').' align="top" alt="" />'.$LANG->getLL('differenceMsg').'<br /><br />';
+
+			// Add CSH:
+			// TODO: FIX CSH
+		$theCode .= t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'history_'.($this->sumUp ? 'sum' : 'log'), $GLOBALS['BACK_PATH'],'');
+
+			// Add the whole content as a module section:
+		return $SOBE->doc->section($LANG->getLL('changes'),$theCode,0,1);
+	}
+
+
+
+	/**
+	 * Displays a diff over multiple fields including rollback links
+	 *
+	 * @param	array		difference array
+	 * @return	string		HTML output
+	 */
+	function displayMultipleDiff($diff)	{
+		global $SOBE, $LANG;
+		$content = '';
+			// create diffs for all changed records
+		$arrayKeys = array_merge(array_keys($diff['newData']),array_keys($diff['insertsDeletes']));
+
+		foreach ($arrayKeys as $key)	{
+			$record = '';
+			$elParts = explode(':',$key);
+			if ($diff['insertsDeletes'][$key] == 1)	{	// insert
+				$record .= $LANG->getLL('insert',1);
+				$record .= '<br/>';
+			} elseif ($diff['insertsDeletes'][$key] == -1)	{
+				$record .= $LANG->getLL('delete',1);
+				$record .= '<br/>';
+			}
+				// build up temporary diff array
+			if ($diff['newData'][$key])	{
+				$tmpArr['newRecord'] = $diff['newData'][$key];
+				$tmpArr['oldRecord'] = $diff['oldData'][$key];
+				$record .= $this->renderDiff($tmpArr, $elParts[0],$elParts[1]);
+			}
+
+			$titleLine = $key.$this->createRollbackLink($key);
+
+			$content .= $SOBE->doc->section($titleLine,$record,0,0,0,1);
+
+		}
+		$titleLine = $LANG->getLL('mergedDifferences',1) . $this->createRollbackLink('ALL');
+		return $SOBE->doc->section($titleLine,$content,0,1,0,1);
+	}
+
+
+
+	/**
+	 * Renders HTML table-rows with the comparison information of an sys_history entry record
+	 *
+	 * @param	array		sys_history entry record.
+	 * @param	string		The table name
+	 * @param	integer		If set to UID of record, display rollback links
+	 * @return	string		HTML table
+	 * @access private
+	 */
+	function renderDiff($entry,$table,$rollbackUid=0)	{
+		global $SOBE, $LANG, $TCA;
+		$lines=array();
+ 		if (is_array($entry['newRecord']))	{
+
+			$t3lib_diff_Obj = t3lib_div::makeInstance('t3lib_diff');
+
+			$fieldsToDisplay = array_keys($entry['newRecord']);
+			foreach($fieldsToDisplay as $fN)	{
+				t3lib_div::loadTCA($table);
+				if (is_array($TCA[$table]['columns'][$fN]) && $TCA[$table]['columns'][$fN]['config']['type']!='passthrough')	{
+
+						// Create diff-result:
+					$diffres = $t3lib_diff_Obj->makeDiffDisplay(
+						t3lib_BEfunc::getProcessedValue($table,$fN,$entry['oldRecord'][$fN],0,1),
+						t3lib_BEfunc::getProcessedValue($table,$fN,$entry['newRecord'][$fN],0,1)
+					);
+					$lines[]='
+						<tr class="bgColor4">
+							<td><em>'.$LANG->sl(t3lib_BEfunc::getItemLabel($table,$fN),1).($rollbackUid?$this->createRollbackLink($table.':'.$rollbackUid.':'.$fN):'').'</em></td>
+							<td>'.nl2br($diffres).'</td>
+						</tr>';
+				}
+			}
+		}
+		if ($lines)	{
+			$content = '<table border="0" cellpadding="2" cellspacing="2" id="typo3-history-item">
+					'.implode('',$lines).'
+				</table>';
+			return $content;
+		}
+		return NULL;	// error fallback
+	}
+	/*******************************
+	 *
+	 * build up history
+	 *
+	 *******************************/
+	/**
+	 * Creates a diff between the current version of the records and the selected version
+	 *
+	 * @return	array		diff for many elements
+	 */
+	function createMultipleDiff()	{
+		$insertsDeletes = array();
+		$newArr = array();
+		$differences = array();
+		if (!$this->changeLog)	{
+			return 0;
+		}
+		$i = array();
+		foreach ($this->changeLog as $key => $value)	{
+			$field = $value['tablename'].':'.$value['recuid'];
+			if ($value['action'])	{
+				if (!$insertsDeletes[$field])	{
+					$insertsDeletes[$field] = 0;
+				}
+				if ($value['action'] == 'insert')	{
+					$insertsDeletes[$field]++;
+				} else {
+					$insertsDeletes[$field]--;
+				}
+				if ($insertsDeletes[$field] == 0)	{
+					unset($insertsDeletes[$field]);
+				}
+			} else {
+				if ($i[$field] == 0)	{
+					$newArr[$field] = $value['newRecord'];
+				}
+				$i[$field]++;
+				$differences[$field] = array_merge($differences[$field],$value['oldRecord']);
+			}
+		}
+		return array(
+			'newData' => $newArr,
+			'oldData' => $differences,
+			'insertsDeletes' => $insertsDeletes
+		);
+	}
+
+	/**
+	 * Creates change log including sub-elements
+	 *
+	 */
+	function createChangeLog()	{
+		global $TCA;
+		$elParts = explode(':',$this->element);
+		$changeLog = $this->getHistoryData($elParts[0],$elParts[1]);
+
+			// get history of tables of this page and merge it into changelog
+		if ($elParts[0] == 'pages' && $this->showSubElements)	{
+			foreach ($TCA as $tablename => $value)	{
+				$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid',$tablename,'pid='.intval($elParts[1]));	// check if there are records on the page
+				while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
+					if ($newChangeLog = $this->getHistoryData($tablename, $row['uid']))	{	// if there is history data available, merge it into changelog
+						foreach ($newChangeLog as $key => $value)	{
+							$changeLog[$key] = $value;
+						}
+					}
+				}
+			}
+		}
+		if(!$changeLog)	{
+			return 0;
+		}
+
+		krsort($changeLog);
+		$this->changeLog = $changeLog;
+	}
+
+
+
+	/**
+	 * Gets history and delete/insert data from sys_log and sys_history
+	 *
+	 * @param	string		DB table name
+	 * @param	integer		UID of record
+	 * @return	array		history data of the record
+	 */
+	function getHistoryData($table,$uid)	{
+		global $TCA;
+
+			// If table is found in $TCA:
+		if ($TCA[$table])	{
+				// Selecting the $this->maxSteps most recent states:
+			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+						'sys_history.*,sys_log.userid',
+						'sys_history,sys_log',
+						'sys_history.sys_log_uid=sys_log.uid
+							AND sys_history.tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table, 'sys_history').'
+							AND sys_history.recuid='.intval($uid),
+						'',
+						'sys_log.uid DESC',
+						$this->maxSteps
+					);
+
+				// Traversing the result, building up changesArray / changeLog:
+			$changesArray=array();	// used temporarily to track intermedia changes
+			$changeLog=array();
+			while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
+					// only history until a certain syslog ID needed
+				if ($row['sys_log_uid'] <= $this->lastSyslogId && $this->lastSyslogId)	{
+					continue;
+				}
+				$hisDat = unserialize($row['history_data']);
+				if (is_array($hisDat['newRecord']) && is_array($hisDat['oldRecord']))	{
+
+						// If intermedia changes:
+					$intermediaChanges = $this->cmp($changesArray,$hisDat['newRecord']);
+					if (count($intermediaChanges) && !$row['snapshot'])	{	// QUESTION: WHAT DOES SNAPSHOT DO?
+						$changeLog[]=$intermediaChanges;
+						// FIXME: ARRAY INDEX MIGHT HAVE AN ERROR!!!!!
+					}
+
+						// Add hisDat to the changeLog
+						// TODO: Possible to overload it with $row?
+					$hisDat['uid']=$row['uid'];
+					$hisDat['tstamp']=$row['tstamp'];
+					$hisDat['user']=$row['userid'];
+					$hisDat['snapshot']=$row['snapshot'];
+					$hisDat['fieldlist']=$row['fieldlist'];
+					$hisDat['tablename']=$row['tablename'];
+					$hisDat['recuid']=$row['recuid'];
+
+					$changeLog[$row['sys_log_uid']]=$hisDat;
+
+						// Update change array
+						// This is used to detect if any intermedia changes have been made.
+					$changesArray = array_merge($changesArray,$hisDat['oldRecord']);
+				} else {
+					debug('ERROR: [getHistoryData]');
+					return 0;	// error fallback
+				}
+			}
+				// SELECT INSERTS/DELETES
+			if ($this->showInsertDelete)	{
+					// Select most recent inserts and deletes
+					// TODO: action 1 or 3
+				$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+						'uid,userid,action,tstamp',
+						'sys_log',
+						'type=1
+							AND action!=2
+							AND tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table, 'sys_log').'
+							AND recuid='.intval($uid),
+						'',
+						'uid DESC',
+						$this->maxSteps
+					);
+				while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
+					if ($row['uid'] <= $this->lastSyslogId && $this->lastSyslogId)	{
+					continue;
+				}
+					$hisDat = array();
+					switch ($row['action'])	{
+						case 1:	// Insert
+							$hisDat['action'] = 'insert';
+							break;
+						case 3:	// Delete
+							$hisDat['action'] = 'delete';
+							break;
+					}
+					$hisDat['tstamp']=$row['tstamp'];
+					$hisDat['user']=$row['userid'];
+					$hisDat['tablename'] = $table;
+					$hisDat['recuid'] = $uid;
+					$changeLog[$row['uid']] = $hisDat;
+				}
+			}
+			return $changeLog;
+		}
+		return 0;	// error fallback
+	}
+
+
+	/*******************************
+	 *
+	 * Various helper functions
+	 *
+	 *******************************/
+	/**
+	 * creates a link for the rollback
+	 *
+	 * @param	sting		parameter which is set to rollbackFields
+	 * @return	string		HTML output
+	 */
+	function createRollbackLink($key)	{
+		 global $LANG;
+		 return $this->linkPage('<img '.t3lib_iconWorks::skinImg('','gfx/history2.gif','width="13" height="12"').' title="'.$LANG->getLL('rollback',1).'" alt="" />',array('rollbackFields'=>$key));
+	 }
+	/**
+	 * Creates a link to the same page.
+	 *
+	 * @param	string		String to wrap in <a> tags (must be htmlspecialchars()'ed prior to calling function)
+	 * @param	array		Array of key/value pairs to override the default values with.
+	 * @param	string		Possible anchor value.
+	 * @return	string		Link.
+	 * @access private
+	 */
+	function linkPage($str,$inparams=array(),$anchor='')	{
+
+			// Setting default values based on GET parameters:
+		//$params['sh_uid']=$this->sh_uid;
+		//$params['sumUp']=$this->sumUp;
+		$params['element']=$this->element;
+		$params['returnUrl']=$this->returnUrl;
+		$params['diff']=$this->lastSyslogId;
+			// Mergin overriding values:
+		$params = array_merge($params,$inparams);
+
+			// Make the link:
+		$Ahref = 'show_rechis.php?'.t3lib_div::implodeArrayForUrl('',$params).($anchor?'#'.$anchor:'');
+		$link = '<a href="'.htmlspecialchars($Ahref).'">'.$str.'</a>';
+
+			// Return link:
+		return $link;
+	}
+
+	/**
+	 * Will traverse the field names in $dataArray and look in $TCA if the fields are of types which cannot be handled by the sys_history (that is currently group types with internal_type set to "file")
+	 *
+	 * @param	string		Table name
+	 * @param	array		The data array
+	 * @return	array		The modified data array
+	 * @access private
+	 */
+	function removeFilefields($table,$dataArray)	{
+		global $TCA;
+
+		if ($TCA[$table])	{
+			t3lib_div::loadTCA($table);
+
+			foreach($TCA[$table]['columns'] as $field => $config)	{
+				if ($config['config']['type']=='group' && $config['config']['internal_type']=='file')	{
+					unset($dataArray[$field]);
+				}
+			}
+		}
+		return $dataArray;
+	}
+
+
+	/**
+	 * Compares the old record with the changed fields.
+	 *
+	 * @param	array		Record with field/value pairs (what has changed)
+	 * @param	array		Record with field/value pairs
+	 * @return	array		Comparison result.
+	 * @access private
+	 */
+	function cmp($newRecord,$oldRecord)	{
+			// Initialize:
+		$changes=array();
+
+			// Traverse $oldRecord
+		foreach($oldRecord as $fN => $fV)	{
+			if (isset($newRecord[$fN]) && strcmp($fV,$newRecord[$fN]))	{
+				$changes['oldRecord'][$fN]=$newRecord[$fN];
+				$changes['newRecord'][$fN]=$fV;
+			}
+		}
+		return $changes;
+	}
+	/**
+	 * Convert input element reference to workspace version if any.
+	 *
+	 * @return	void
+	 */
+	function resolveElement()	{
+		$parts = explode(':',$this->element);
+
+		if (isset($GLOBALS['TCA'][$parts[0]]))	{
+			if ($workspaceVersion = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, $parts[0], $parts[1], 'uid'))	{
+				$parts[1] = $workspaceVersion['uid'];
+				$this->element = implode(':', $parts);
+			}
+		}
+	}
+}
+?>
\ Kein Zeilenumbruch am Dateiende.
Dateien TYPO3core_orig_cvs/typo3/.class.show_rechis_new.inc.marks und TYPO3core_testing/typo3/.class.show_rechis_new.inc.marks sind verschieden.
diff -ruN TYPO3core_orig_cvs/typo3/show_rechis.php TYPO3core_testing/typo3/show_rechis.php
--- TYPO3core_orig_cvs/typo3/show_rechis.php	2005-10-21 10:06:59.000000000 +0200
+++ TYPO3core_testing/typo3/show_rechis.php	2005-12-04 14:13:32.000000000 +0100
@@ -55,7 +55,7 @@
 require_once (PATH_t3lib.'class.t3lib_diff.php');
 require_once (PATH_t3lib.'class.t3lib_tcemain.php');
 $LANG->includeLLFile('EXT:lang/locallang_show_rechis.xml');
-require_once ('class.show_rechis.inc');
+require_once ('class.show_rechis_new.inc');



@@ -109,7 +109,7 @@
 		$historyObj = t3lib_div::makeInstance('recordHistory');

 			// Get content:
-		$this->content.= $historyObj->main();
+		$this->content .= $historyObj->main();

 			// Return link:
 		if ($historyObj->returnUrl)	{
diff -ruN TYPO3core_orig_cvs/typo3/sysext/lang/locallang_show_rechis.xml TYPO3core_testing/typo3/sysext/lang/locallang_show_rechis.xml
--- TYPO3core_orig_cvs/typo3/sysext/lang/locallang_show_rechis.xml	2005-10-21 10:06:59.000000000 +0200
+++ TYPO3core_testing/typo3/sysext/lang/locallang_show_rechis.xml	2005-12-06 16:18:58.000000000 +0100
@@ -16,7 +16,7 @@
 			<label index="time">Time</label>
 			<label index="user">User</label>
 			<label index="changeCount">Changes since time</label>
-			<label index="changes">Changes to the record</label>
+			<label index="changes">Change history</label>
 			<label index="return">Return</label>
 			<label index="returnLink">Click here to go back</label>
 			<label index="revertField">Restore old value of this field</label>
@@ -35,6 +35,10 @@
 			<label index="currentValue">Current value</label>
 			<label index="differenceMsg">In the Difference column the &lt;span class=&quot;diff-g&quot;&gt;green colored text&lt;/span&gt; are new changes and the &lt;span class=&quot;diff-r&quot;&gt;red colored text&lt;/span&gt; are the old values which were removed.</label>
 			<label index="difference">Difference</label>
+			<label index="insert">Record was inserted</label>
+			<label index="delete">Record was deleted</label>
+			<label index="rollback">Rollback changes</label>
+			<label index="mergedDifferences">Merged differences to the current version</label>
 		</languageKey>
 		<languageKey index="dk">EXT:csh_dk/lang/dk.locallang_show_rechis.xml</languageKey>
 		<languageKey index="de">EXT:csh_de/lang/de.locallang_show_rechis.xml</languageKey>
