/src/typo3_src-4.1.2/typo3/mod/user/ws/index.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2007 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00092         // Initialize module:
00093 unset($MCONF);
00094 require ('conf.php');
00095 require ($BACK_PATH.'init.php');
00096 require ($BACK_PATH.'template.php');
00097 $BE_USER->modAccess($MCONF,1);
00098 
00099         // Include libraries of various kinds used inside:
00100 $LANG->includeLLFile('EXT:lang/locallang_mod_user_ws.xml');
00101 $LANG->includeLLFile('EXT:lang/locallang_misc.xml');
00102 require_once(PATH_t3lib.'class.t3lib_scbase.php');
00103 require_once(PATH_typo3.'mod/user/ws/class.wslib.php');
00104 require_once(PATH_t3lib.'class.t3lib_diff.php');
00105 require_once(PATH_t3lib.'class.t3lib_pagetree.php');
00106 require_once(PATH_t3lib.'class.t3lib_tcemain.php');
00107 
00108 
00109 
00110 
00118 class SC_mod_user_ws_index extends t3lib_SCbase {
00119 
00120                 // Static:
00121         var $pageTreeIndent = 8;
00122         var $pageTreeIndent_titleLgd = 30;
00123 
00124                 // Default variables for backend modules
00125         var $MCONF = array();                           // Module configuration
00126         var $MOD_MENU = array();                        // Module menu items
00127         var $MOD_SETTINGS = array();            // Module session settings
00128         var $doc;                                                       // Document Template Object
00129         var $content;                                           // Accumulated content
00130 
00131 
00132                 // Internal:
00133         var $showWorkspaceCol = 0;
00134         var $formatWorkspace_cache = array();
00135         var $formatCount_cache = array();
00136         var $targets = array();         // Accumulation of online targets.
00137         var $pageModule = '';
00138         var $publishAccess = FALSE;
00139         var $be_user_Array = array();
00140         var $be_user_Array_full = array();      // not blinded, used by workspace listing
00141         var $stageIndex = array();
00142 
00143 
00144         /*********************************
00145          *
00146          * Standard module initialization
00147          *
00148          *********************************/
00149 
00155         function menuConfig()   {
00156                 global  $LANG;
00157 
00158                         // Menu items:
00159                 $this->MOD_MENU = array(
00160                         'function' => array(
00161                                 'publish' => $LANG->getLL('menuitem_review'),
00162                                 'workspaces' => $LANG->getLL('menuitem_workspaces'),
00163                         ),
00164                         'filter' => array(
00165                                 1 => $LANG->getLL('filter_drafts'),
00166                                 2 => $LANG->getLL('filter_archive'),
00167                                 0 => $LANG->getLL('filter_all'),
00168                         ),
00169                         'display' => array(
00170                                 0 => '['.$LANG->getLL('shortcut_onlineWS').']',
00171                                 -98 => $LANG->getLL('label_offlineWSes'),
00172                                 -99 => $LANG->getLL('label_allWSes'),
00173                                 -1 => '['.$LANG->getLL('shortcut_offlineWS').']'
00174                         ),
00175                         'diff' => array(
00176                                 0 => $LANG->getLL('diff_no_diff'),
00177                                 1 => $LANG->getLL('diff_show_inline'),
00178                                 2 => $LANG->getLL('diff_show_popup'),
00179                         ),
00180                         'expandSubElements' => '',
00181                 );
00182 
00183                         // Add workspaces:
00184                 if ($GLOBALS['BE_USER']->workspace===0) {       // Spend time on this only in online workspace because it might take time:
00185                         $workspaces = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,title,adminusers,members,reviewers','sys_workspace','pid=0'.t3lib_BEfunc::deleteClause('sys_workspace'),'','title');
00186                         foreach($workspaces as $rec)    {
00187                                 if ($GLOBALS['BE_USER']->checkWorkspace($rec))  {
00188                                         $this->MOD_MENU['display'][$rec['uid']] = '['.$rec['uid'].'] '.$rec['title'];
00189                                 }
00190                         }
00191                 }
00192 
00193                         // CLEANSE SETTINGS
00194                 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name'], 'ses');
00195         }
00196 
00202         function init() {
00203                 global $BACK_PATH, $BE_USER;
00204 
00205                         // Setting module configuration:
00206                 $this->MCONF = $GLOBALS['MCONF'];
00207 
00208                         // Initialize Document Template object:
00209                 $this->doc = t3lib_div::makeInstance('noDoc');
00210                 $this->doc->backPath = $BACK_PATH;
00211                 $this->doc->docType = 'xhtml_trans';
00212 
00213                         // JavaScript
00214                 $plusIcon = t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/ol/plusbullet.gif', 'width="18" height="16"', 1);
00215                 $minusIcon = t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/ol/minusbullet.gif', 'width="18" height="16"', 1);
00216                 $this->doc->JScode = $this->doc->wrapScriptTags('
00217                         script_ended = 0;
00218                         function jumpToUrl(URL) {       //
00219                                 window.location.href = URL;
00220                         }
00221 
00222                         function hlSubelements(origId, verId, over, diffLayer)  {       //
00223                                 if (over)       {
00224                                         document.getElementById(\'orig_\'+origId).attributes.getNamedItem("class").nodeValue = \'typo3-ver-hl\';
00225                                         document.getElementById(\'ver_\'+verId).attributes.getNamedItem("class").nodeValue = \'typo3-ver-hl\';
00226                                         if (diffLayer)  {
00227                                                 document.getElementById(\'diff_\'+verId).style.visibility = \'visible\';
00228                                         }
00229                                 } else {
00230                                         document.getElementById(\'orig_\'+origId).attributes.getNamedItem("class").nodeValue = \'typo3-ver\';
00231                                         document.getElementById(\'ver_\'+verId).attributes.getNamedItem("class").nodeValue = \'typo3-ver\';
00232                                         if (diffLayer)  {
00233                                                 document.getElementById(\'diff_\'+verId).style.visibility = \'hidden\';
00234                                         }
00235                                 }
00236                         }
00237 
00238                         function expandCollapse(rowNumber)      {       //
00239                                 elementId = \'wl_\' + rowNumber;
00240                                 element = document.getElementById(elementId);
00241                                 image = document.getElementById(elementId + \'i\');
00242                                 if (element.style)      {
00243                                         if (element.style.display == \'none\')  {
00244                                                 element.style.display = \'\';
00245                                                 image.src = \'' . $minusIcon . '\';
00246                                         } else {
00247                                                 element.style.display = \'none\';
00248                                                 image.src = \'' . $plusIcon . '\';
00249                                         }
00250                                 }
00251                         }
00252                 ');
00253                 $this->doc->form = '<form action="index.php" method="post" name="pageform">';
00254 
00255                         // Setting up the context sensitive menu:
00256                 $CMparts = $this->doc->getContextMenuCode();
00257                 $this->doc->JScode.= $CMparts[0];
00258                 $this->doc->bodyTagAdditions = $CMparts[1];
00259                 $this->doc->postCode.= $CMparts[2];
00260 
00261                         // Add JS for dynamic tabs:
00262                 $this->doc->JScode.= $this->doc->getDynTabMenuJScode();
00263 
00264                         // If another page module was specified, replace the default Page module with the new one
00265                 $newPageModule = trim($BE_USER->getTSConfigVal('options.overridePageModule'));
00266                 $this->pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
00267 
00268                         // Setting publish access permission for workspace:
00269                 $this->publishAccess = $BE_USER->workspacePublishAccess($BE_USER->workspace);
00270 
00271                         // Parent initialization:
00272                 parent::init();
00273         }
00274 
00280         function main() {
00281                 global $LANG, $BE_USER, $BACK_PATH;
00282 
00283                 // See if we need to switch workspace
00284                 $changeWorkspace = t3lib_div::_GET('changeWorkspace');
00285                 if ($changeWorkspace != '') {
00286                         $BE_USER->setWorkspace($changeWorkspace);
00287                         $this->content = $this->doc->startPage($LANG->getLL('title'));
00288                         $this->content .= $this->doc->wrapScriptTags('top.location.href="' . $BACK_PATH . 'alt_main.php";');
00289                 }
00290                 else {
00291                                 // Starting page:
00292                         $this->content.=$this->doc->startPage($LANG->getLL('title'));
00293                         $this->content.=$this->doc->header($LANG->getLL('title'));
00294                         $this->content.=$this->doc->spacer(5);
00295 
00296                                 // Build top menu:
00297                         $menuItems = array();
00298                         $menuItems[] = array(
00299                                 'label' => $LANG->getLL('menuitem_review'),
00300                                 'content' => $this->moduleContent_publish()
00301                         );
00302                         $menuItems[] = array(
00303                                 'label' => $LANG->getLL('menuitem_workspaces'),
00304                                 'content' => $this->moduleContent_workspaceList()
00305                         );
00306 
00307                                 // Add hidden fields and create tabs:
00308                         $content = $this->doc->getDynTabMenu($menuItems,'user_ws');
00309                         $this->content.=$this->doc->section('',$content,0,1);
00310                 }
00311         }
00312 
00318         function printContent() {
00319                 global $SOBE;
00320 
00321                 $this->content.= $this->doc->endPage();
00322                 echo $this->content;
00323         }
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337         /*********************************
00338          *
00339          * Module content: Publish
00340          *
00341          *********************************/
00342 
00348         function moduleContent_publish()        {
00349                 global  $LANG;
00350 
00351                         // Initialize:
00352                 $content = '';
00353                 $details = t3lib_div::_GP('details');
00354 
00355                         // Create additional menus:
00356                 $menu = '';
00357                 if ($GLOBALS['BE_USER']->workspace===0) {
00358                         $menu.= t3lib_BEfunc::getFuncMenu(0,'SET[filter]',$this->MOD_SETTINGS['filter'],$this->MOD_MENU['filter']);
00359                         $menu.= t3lib_BEfunc::getFuncMenu(0,'SET[display]',$this->MOD_SETTINGS['display'],$this->MOD_MENU['display']);
00360                 }
00361                 $menu.= t3lib_BEfunc::getFuncMenu(0,'SET[diff]',$this->MOD_SETTINGS['diff'],$this->MOD_MENU['diff']);
00362                 if ($GLOBALS['BE_USER']->workspace!==0) {
00363                         $menu.= t3lib_BEfunc::getFuncCheck(0,'SET[expandSubElements]',$this->MOD_SETTINGS['expandSubElements'],'','','id="checkExpandSubElements"').' <label for="checkExpandSubElements">'.$LANG->getLL('label_showsubelements').'</label> ';
00364                 }
00365 
00366                         // Create header:
00367                 $title = '';
00368                 $description = '';
00369                 switch($GLOBALS['BE_USER']->workspace)  {
00370                         case 0:
00371                                 $title = t3lib_iconWorks::getIconImage('sys_workspace', array(), $this->doc->backPath, ' align="top"').'['.$LANG->getLL('shortcut_onlineWS').']';
00372                                 $description = $LANG->getLL('workspace_description_live');
00373                         break;
00374                         case -1:
00375                                 $title = t3lib_iconWorks::getIconImage('sys_workspace', array(), $this->doc->backPath, ' align="top"').'['.$LANG->getLL('shortcut_offlineWS').']';
00376                                 $description = $LANG->getLL('workspace_description_draft');
00377                         break;
00378                         case -99:
00379                                 $title = $this->doc->icons(3).'[' . $LANG->getLL('shortcut_noWSfound') . ']';
00380                                 $description = $LANG->getLL('workspace_description_no_access');
00381                         break;
00382                         default:
00383                                 $title = t3lib_iconWorks::getIconImage('sys_workspace', $GLOBALS['BE_USER']->workspaceRec, $this->doc->backPath, ' align="top"').
00384                                                         '['.$GLOBALS['BE_USER']->workspace.'] '.t3lib_BEfunc::getRecordTitle('sys_workspace',$GLOBALS['BE_USER']->workspaceRec,TRUE);
00385                                 $description = ($GLOBALS['BE_USER']->workspaceRec['description'] ? htmlspecialchars($GLOBALS['BE_USER']->workspaceRec['description']) : '<em>[' . $LANG->getLL('shortcut_noWSfound') . ']</em>');
00386                         break;
00387                 }
00388 
00389                         // Buttons for publish / swap:
00390                 $actionLinks = '';
00391                 if ($GLOBALS['BE_USER']->workspace!==0) {
00392                         if ($this->publishAccess)       {
00393                                 $confirmation = $LANG->JScharCode($LANG->getLL(($GLOBALS['BE_USER']->workspaceRec['publish_access'] & 1) ? 'submit_publish_workspace_confirmation_1' :  'submit_publish_workspace_confirmation_2'));
00394                                 $actionLinks.= '<input type="submit" name="_publish" value="' . $LANG->getLL('submit_publish_workspace') . '" onclick="if (confirm(' . $confirmation . ')) window.location.href=\'publish.php?swap=0\';return false"/>';
00395                                 if ($GLOBALS['BE_USER']->workspaceSwapAccess()) {
00396                                         $confirmation = $LANG->JScharCode($LANG->getLL(($GLOBALS['BE_USER']->workspaceRec['publish_access'] & 1) ? 'submit_swap_workspace_confirmation_1' :  'submit_swap_workspace_confirmation_2'));
00397                                         $actionLinks.= '<input type="submit" name="_swap" value="' . $LANG->getLL('submit_swap_workspace') . '" onclick="if (confirm(' . $confirmation . ')) window.location.href=\'publish.php?swap=1\';return false ;" />';
00398                                 }
00399                         } else {
00400                                 $actionLinks.= $this->doc->icons(1) . $LANG->getLL('no_publish_permission');
00401                         }
00402                 }
00403 
00404                 $wsAccess = $GLOBALS['BE_USER']->checkWorkspace($GLOBALS['BE_USER']->workspaceRec);
00405 
00406                         // Add header to content variable:
00407                 $content = '
00408                 <table border="0" cellpadding="1" cellspacing="1" class="lrPadding" style="border: 1px solid black;">
00409                         <tr>
00410                                 <td class="bgColor2" nowrap="nowrap"><b>' . $LANG->getLL('label_workspace') . '</b>&nbsp;</td>
00411                                 <td class="bgColor4" nowrap="nowrap">'.$title.'</td>
00412                         </tr>
00413                         <tr>
00414                                 <td class="bgColor2" nowrap="nowrap"><b>' . $LANG->getLL('label_description') . '</b>&nbsp;</td>
00415                                 <td class="bgColor4">'.$description.'</td>
00416                         </tr>'.($GLOBALS['BE_USER']->workspace!=-99 && !$details ? '
00417                         <tr>
00418                                 <td class="bgColor2" nowrap="nowrap"><b>' . $LANG->getLL('label_options') . '</b>&nbsp;</td>
00419                                 <td class="bgColor4">'.$menu.$actionLinks.'</td>
00420                         </tr>
00421                         <tr>
00422                                 <td class="bgColor2" nowrap="nowrap"><b>' . $LANG->getLL('label_status') . '</b>&nbsp;</td>
00423                                 <td class="bgColor4">'.$LANG->getLL('label_access_level').' ' . $GLOBALS['LANG']->getLL('workspace_list_access_' . $wsAccess['_ACCESS']) . '</td>
00424                         </tr>' : '').'
00425                 </table>
00426                 <br/>
00427                 ';
00428 
00429                         // Add publishing and review overview:
00430                 if ($GLOBALS['BE_USER']->workspace!=-99)        {
00431                         if ($details)   {
00432                                 $content.= $this->displayVersionDetails($details);
00433                         } else {
00434                                 $content.= $this->displayWorkspaceOverview();
00435                         }
00436                         $content.='<br/>';
00437                 }
00438 
00439                         // Return content:
00440                 return $content;
00441         }
00442 
00449         function displayVersionDetails($details)        {
00450                 return 'TODO: Show details for version "'.$details.'"<hr/><a href="index.php">BACK</a>';
00451         }
00452 
00458         function displayWorkspaceOverview()     {
00459                 global  $LANG;
00460 
00461                         // Initialize variables:
00462                 $this->showWorkspaceCol = $GLOBALS['BE_USER']->workspace===0 && $this->MOD_SETTINGS['display']<=-98;
00463 
00464                         // Get usernames and groupnames
00465                 $be_group_Array = t3lib_BEfunc::getListGroupNames('title,uid');
00466                 $groupArray = array_keys($be_group_Array);
00467                         // Need 'admin' field for t3lib_iconWorks::getIconImage()
00468                 $this->be_user_Array_full = $this->be_user_Array = t3lib_BEfunc::getUserNames('username,usergroup,usergroup_cached_list,uid,admin,workspace_perms');
00469                 if (!$GLOBALS['BE_USER']->isAdmin())            $this->be_user_Array = t3lib_BEfunc::blindUserNames($this->be_user_Array,$groupArray,1);
00470 
00471                         // Initialize Workspace ID and filter-value:
00472                 if ($GLOBALS['BE_USER']->workspace===0) {
00473                         $wsid = $this->MOD_SETTINGS['display'];         // Set wsid to the value from the menu (displaying content of other workspaces)
00474                         $filter = $this->MOD_SETTINGS['filter'];
00475                 } else {
00476                         $wsid = $GLOBALS['BE_USER']->workspace;
00477                         $filter = 0;
00478                 }
00479 
00480                         // Initialize workspace object and request all pending versions:
00481                 $wslibObj = t3lib_div::makeInstance('wslib');
00482 
00483                         // Selecting ALL versions belonging to the workspace:
00484                 $versions = $wslibObj->selectVersionsInWorkspace($wsid, $filter);
00485 
00486                         // Traverse versions and build page-display array:
00487                 $pArray = array();
00488                 $wmArray = array();     // is page in web mount?
00489                 $rlArray = array();     // root line of page
00490                 $pagePermsClause = $GLOBALS['BE_USER']->getPagePermsClause(1);
00491                 foreach($versions as $table => $records)        {
00492                         if (is_array($records)) {
00493                                 foreach($records as $rec)       {
00494                                         $pageIdField = $table==='pages' ? 't3ver_oid' : 'realpid';
00495                                         $pageId = $rec[$pageIdField];
00496                                         if (!isset($wmArray[$pageId]))  {
00497                                                 $wmArray[$pageId] = $GLOBALS['BE_USER']->isInWebMount($pageId,$pagePermsClause);
00498                                         }
00499                                         if ($wmArray[$pageId])  {
00500                                                 if (!isset($rlArray[$pageId]))  {
00501                                                         $rlArray[$pageId] = t3lib_BEfunc::BEgetRootLine($pageId, 'AND 1=1');
00502                                                 }
00503                                                 $this->displayWorkspaceOverview_setInPageArray(
00504                                                         $pArray,
00505                                                         $rlArray[$pageId],
00506                                                         $table,
00507                                                         $rec
00508                                                 );
00509                                         }
00510                                 }
00511                         }
00512                 }
00513 
00514                         // Make header of overview:
00515                 $tableRows = array();
00516                 $tableRows[] = '
00517                         <tr class="bgColor5 tableheader">
00518                                 <td nowrap="nowrap" width="100">' . $LANG->getLL('label_pagetree') . '</td>
00519                                 <td nowrap="nowrap" colspan="2">' . $LANG->getLL('label_live_version') . '</td>
00520                                 <td nowrap="nowrap" colspan="2">' . $LANG->getLL('label_draft_versions') . '</td>
00521                                 <td nowrap="nowrap">' . $LANG->getLL('label_stage') . '</td>
00522                                 <td nowrap="nowrap">' . $LANG->getLL('label_publish') . '</td>
00523                                 <td>' . $LANG->getLL('label_lifecycle') . '</td>
00524                                 '.($this->showWorkspaceCol ? '<td>' . $LANG->getLL('label_workspace') . '</td>' : '').'
00525                         </tr>';
00526 
00527                         // Add lines from overview:
00528                 $tableRows = array_merge($tableRows, $this->displayWorkspaceOverview_list($pArray));
00529 
00530                 $table = '<table border="0" cellpadding="0" cellspacing="1" class="lrPadding workspace-overview">'.implode('',$tableRows).'</table>';
00531 
00532                 return $table.$this->markupNewOriginals();
00533         }
00534 
00545         function displayWorkspaceOverview_list($pArray, $tableRows=array(), $c=0, $warnAboutVersions=FALSE)     {
00546                 global $TCA, $LANG;
00547 
00548                         // Initialize:
00549                 $fullColSpan = ($this->showWorkspaceCol?9:8);
00550 
00551                         // Traverse $pArray
00552                 if (is_array($pArray))  {
00553                         foreach($pArray as $k => $v)    {
00554                                 if (t3lib_div::testInt($k))     {
00555 
00556                                                 // If there are elements on this level, output a divider row which just creates a little visual space.
00557                                         if (is_array($pArray[$k.'_']))  {
00558                                                 $tableRows[] = '
00559                                                         <tr>
00560                                                                 <td colspan="'.$fullColSpan.'"><img src="clear.gif" width="1" height="3" alt="" /></td>
00561                                                         </tr>';
00562                                         }
00563 
00564                                                 // Printing a level from the page tree with no additional content:
00565                                                 // If there are NO elements on this level OR if there are NO pages on a level with elements, then show page tree icon and title (otherwise it is shown with the display of the elements)
00566                                         if (!is_array($pArray[$k.'_']) || !is_array($pArray[$k.'_']['pages']))  {
00567                                                 $tableRows[] = '
00568                                                         <tr class="bgColor4-20">
00569                                                                 <td nowrap="nowrap" colspan="'.$fullColSpan.'">'.
00570                                                                         $this->displayWorkspaceOverview_pageTreeIconTitle($k,$pArray[$k],$c).
00571                                                                         '</td>
00572                                                         </tr>';
00573                                         }
00574 
00575                                                 // If there ARE elements on this level, print them:
00576                                         $warnAboutVersions_next = $warnAboutVersions;
00577                                         $warnAboutVersions_nonPages = FALSE;
00578                                         $warnAboutVersions_page = FALSE;
00579                                         if (is_array($pArray[$k.'_']))  {
00580                                                 foreach($pArray[$k.'_'] as $table => $oidArray) {
00581                                                         foreach($oidArray as $oid => $recs)     {
00582 
00583                                                                         // Get CURRENT online record and icon based on "t3ver_oid":
00584                                                                 $rec_on = t3lib_BEfunc::getRecord($table,$oid);
00585                                                                 $icon = t3lib_iconWorks::getIconImage($table, $rec_on, $this->doc->backPath,' align="top" title="'.t3lib_BEfunc::getRecordIconAltText($rec_on,$table).'"');
00586                                                                 if ($GLOBALS['BE_USER']->workspace===0) {       // Only edit online records if in ONLINE workspace:
00587                                                                         $icon = $this->doc->wrapClickMenuOnIcon($icon, $table, $rec_on['uid'], 2, '', '+edit,view,info,delete');
00588                                                                 }
00589 
00590                                                                         // MAIN CELL / Online version display:
00591                                                                         // Create the main cells which will span over the number of versions there is. If the table is "pages" then it will show the page tree icon and title (which was not shown by the code above)
00592                                                                 $verLinkUrl = t3lib_extMgm::isLoaded('version') && $TCA[$table]['ctrl']['versioningWS'];
00593                                                                 $origElement = $icon.
00594                                                                         ($verLinkUrl ? '<a href="'.htmlspecialchars($this->doc->backPath.t3lib_extMgm::extRelPath('version').'cm1/index.php?table='.$table.'&uid='.$rec_on['uid']).'">' : '').
00595                                                                         t3lib_BEfunc::getRecordTitle($table,$rec_on,TRUE).
00596                                                                         ($verLinkUrl ? '</a>' : '');
00597                                                                 $mainCell_rowSpan = count($recs)>1 ? ' rowspan="'.count($recs).'"' : '';
00598                                                                 $mainCell = $table==='pages' ? '
00599                                                                                         <td class="bgColor4-20" nowrap="nowrap"'.$mainCell_rowSpan.'>'.
00600                                                                                         $this->displayWorkspaceOverview_pageTreeIconTitle($k,$pArray[$k],$c).
00601                                                                                         '</td>' : '
00602                                                                                         <td class="bgColor"'.$mainCell_rowSpan.'></td>';
00603                                                                 $mainCell.= '
00604                                                                                         <td align="center"'.$mainCell_rowSpan.'>'.$this->formatVerId($rec_on['t3ver_id']).'</td>
00605                                                                                         <td nowrap="nowrap"'.$mainCell_rowSpan.'>'.
00606                                                                                                 $origElement.
00607                                                                                                 '###SUB_ELEMENTS###'.   // For substitution with sub-elements, if any.
00608                                                                                         '</td>';
00609 
00610                                                                         // Offline versions display:
00611                                                                         // Traverse the versions of the element
00612                                                                 foreach($recs as $rec)  {
00613 
00614                                                                         // Get the offline version record:
00615                                                                         $rec_off = t3lib_BEfunc::getRecord($table,$rec['uid']);
00616 
00617                                                                         // Prepare swap-mode values:
00618                                                                         if ($table==='pages' && $rec_off['t3ver_swapmode']!=-1) {
00619                                                                                 if ($rec_off['t3ver_swapmode']>0)       {
00620                                                                                         $vType = 'branch';      // Do not translate!
00621                                                                                 } else {
00622                                                                                         $vType = 'page';        // Do not translate!
00623                                                                                 }
00624                                                                         } else {
00625                                                                                 $vType = 'element';     // Do not translate!
00626                                                                         }
00627 
00628                                                                         // Get icon:
00629                                                                         $icon = t3lib_iconWorks::getIconImage($table, $rec_off, $this->doc->backPath, ' align="top" title="'.t3lib_BEfunc::getRecordIconAltText($rec_off,$table).'"');
00630                                                                         $tempUid = ($table != 'pages' || $vType==='branch' || $GLOBALS['BE_USER']->workspace == 0 ? $rec_off['uid'] : $rec_on['uid']);
00631                                                                         $icon = $this->doc->wrapClickMenuOnIcon($icon, $table, $tempUid, 2, '', '+edit,' . ($table == 'pages' ? 'view,info,' : '') . 'delete');
00632 
00633                                                                         // Prepare diff-code:
00634                                                                         if ($this->MOD_SETTINGS['diff'])        {
00635                                                                                 $diffCode = '';
00636                                                                                 list($diffHTML,$diffPct) = $this->createDiffView($table, $rec_off, $rec_on);
00637                                                                                 if ($rec_on['t3ver_state']==1)  {       // New record:
00638                                                                                         $diffCode.= $this->doc->icons(1).$LANG->getLL('label_newrecord').'<br/>';
00639                                                                                         $diffCode.= $diffHTML;
00640                                                                                 } elseif ($rec_off['t3ver_state']==2)   {
00641                                                                                         $diffCode.= $this->doc->icons(2).'Deleted element<br/>';
00642                                                                                         $diffCode.= $this->doc->icons(2).$LANG->getLL('label_deletedrecord').'<br/>';
00643                                                                                 } else {
00644                                                                                         $diffCode.= ($diffPct<0 ? 'N/A' : ($diffPct ? $diffPct.'% change:' : ''));
00645                                                                                         $diffCode.= ($diffPct<0 ? $LANG->getLL('label_notapplicable') : ($diffPct ? sprintf($LANG->getLL('label_percentchange'), $diffPct) : ''));
00646                                                                                         $diffCode.= $diffHTML;
00647                                                                                 }
00648 
00649                                                                         } else $diffCode = '';
00650 
00651                                                                         switch($vType) {
00652                                                                                 case 'element':
00653                                                                                         $swapLabel = ' ['.$LANG->getLL('label_element').']';
00654                                                                                         $swapClass = 'ver-element';     // Do not translate!
00655                                                                                         $warnAboutVersions_nonPages = $warnAboutVersions_page;  // Setting this if sub elements are found with a page+content (must be rendered prior to this of course!)
00656                                                                                 break;
00657                                                                                 case 'page':
00658                                                                                         $swapLabel = ' ['.$LANG->getLL('label_page').']';
00659                                                                                         $swapClass = 'ver-page';        // Do not translate!
00660                                                                                         $warnAboutVersions_page = !$this->showWorkspaceCol;             // This value is true only if multiple workspaces are shown and we need the opposite here.
00661                                                                                 break;
00662                                                                                 case 'branch':
00663                                                                                         $swapLabel = ' ['.$LANG->getLL('label_branch').']';     
00664                                                                                         $swapClass = 'ver-branch';      // Do not translate!
00665                                                                                         $warnAboutVersions_next = !$this->showWorkspaceCol;             // This value is true only if multiple workspaces are shown and we need the opposite here.
00666                                                                                 break;
00667                                                                         }
00668 
00669                                                                                 // Modify main cell based on first version shown:
00670                                                                         $subElements = array();
00671                                                                         if ($table==='pages' && $rec_off['t3ver_swapmode']!=-1 && $mainCell)    {       // For "Page" and "Branch" swap modes where $mainCell is still carrying content (only first version)
00672                                                                                 $subElements['on'] = $this->subElements($rec_on['uid'], $rec_off['t3ver_swapmode']);
00673                                                                                 $subElements['off'] = $this->subElements($rec_off['uid'],$rec_off['t3ver_swapmode'],$rec_on['uid']);
00674                                                                         }
00675                                                                         $mainCell = str_replace('###SUB_ELEMENTS###', $subElements['on'], $mainCell);
00676 
00677                                                                                 // Create version element:
00678                                                                         $versionsInOtherWS = $this->versionsInOtherWS($table, $rec_on['uid']);
00679                                                                         $versionsInOtherWSWarning = $versionsInOtherWS && $GLOBALS['BE_USER']->workspace!==0 ? '<br/>'.$this->doc->icons(2).$LANG->getLL('label_otherversions').' '.$versionsInOtherWS : '';
00680                                                                         $multipleWarning = (!$mainCell && $GLOBALS['BE_USER']->workspace!==0? '<br/>'.$this->doc->icons(3).'<b>'.$LANG->getLL('label_multipleversions').'</b>' : '');
00681                                                                         $verWarning = $warnAboutVersions || ($warnAboutVersions_nonPages && $GLOBALS['TCA'][$table]['ctrl']['versioning_followPages'])? '<br/>'.$this->doc->icons(3).'<b>'.$LANG->getLL('label_nestedversions').'</b>' : '';
00682                                                                         $verElement = $icon.
00683                                                                                 '<a href="'.htmlspecialchars($this->doc->backPath.t3lib_extMgm::extRelPath('version').'cm1/index.php?id='.($table==='pages'?$rec_on['uid']:$rec_on['pid']).'&details='.rawurlencode($table.':'.$rec_off['uid']).'&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'">'.
00684                                                                                 t3lib_BEfunc::getRecordTitle($table,$rec_off,TRUE).
00685                                                                                 '</a>'.
00686                                                                                 $versionsInOtherWSWarning.
00687                                                                                 $multipleWarning.
00688                                                                                 $verWarning;
00689                                                                         if ($diffCode)  {
00690                                                                                 $verElement = '
00691                                                                                 <table border="0" cellpadding="0" cellspacing="0" class="ver-verElement">
00692                                                                                         <tr>
00693                                                                                                 <td nowrap="nowrap" width="180">'.$verElement.'&nbsp;&nbsp;</td>
00694                                                                                                 <td class="c-diffCell">'.$diffCode.'</td>
00695                                                                                         </tr>
00696                                                                                 </table>';
00697                                                                         }
00698 
00699                                                                                 // Create version cell:
00700                                                                         $verCell = '
00701                                                                                         <td align="center">'.$this->formatVerId($rec_off['t3ver_id']).'</td>
00702                                                                                         <td nowrap="nowrap">'.
00703                                                                                                 $verElement.
00704                                                                                                 $subElements['off'].
00705                                                                                                 '</td>';
00706 
00707                                                                                 // Compile table row:
00708                                                                         $tableRows[] = '
00709                                                                                 <tr class="bgColor4">
00710                                                                                         '.$mainCell.$verCell.'
00711                                                                                         <td nowrap="nowrap">'.$this->showStageChangeLog($table,$rec_off['uid'],$this->displayWorkspaceOverview_stageCmd($table,$rec_off)).'</td>
00712                                                                                         <td nowrap="nowrap" class="'.$swapClass.'">'.
00713                                                                                                 $this->displayWorkspaceOverview_commandLinks($table,$rec_on,$rec_off,$vType).
00714                                                                                                 htmlspecialchars($swapLabel).
00715                                                                                                 '</td>
00716                                                                                         <td nowrap="nowrap">'.htmlspecialchars($this->formatCount($rec_off['t3ver_count'])).'</td>'.            // Lifecycle
00717                                                                                                 ($this->showWorkspaceCol ? '
00718                                                                                         <td nowrap="nowrap">'.htmlspecialchars($this->formatWorkspace($rec_off['t3ver_wsid'])).'</td>' : '').'
00719                                                                                 </tr>';
00720 
00721                                                                                 // Reset the main cell:
00722                                                                         $mainCell = '';
00723                                                                 }
00724                                                         }
00725                                                 }
00726                                         }
00727                                                 // Call recursively for sub-rows:
00728                                         $tableRows = $this->displayWorkspaceOverview_list($pArray[$k.'.'], $tableRows, $c+1, $warnAboutVersions_next);
00729                                 }
00730                         }
00731                 }
00732                 return $tableRows;
00733         }
00734 
00743         function displayWorkspaceOverview_pageTreeIconTitle($pageUid, $title, $indentCount)     {
00744                 $pRec = t3lib_BEfunc::getRecord('pages',$pageUid);
00745                 return '<img src="clear.gif" width="1" height="1" hspace="'.($indentCount * $this->pageTreeIndent).'" align="top" alt="" />'.   // Indenting page tree
00746                                         t3lib_iconWorks::getIconImage('pages',$pRec,$this->doc->backPath,' align="top" title="'.t3lib_BEfunc::getRecordIconAltText($pRec,'pages').'"').
00747                                         htmlspecialchars(t3lib_div::fixed_lgd_cs($title,$this->pageTreeIndent_titleLgd)).
00748                                         '&nbsp;&nbsp;';
00749         }
00750 
00758         function displayWorkspaceOverview_stageCmd($table,&$rec_off)    {
00759                 global $LANG;
00760 
00761                 switch((int)$rec_off['t3ver_stage'])    {
00762                         case 0:
00763                                 $sId = 1;
00764                                 $sLabel = $LANG->getLL('stage_editing');
00765                                 $color = '#666666';     // TODO Use CSS?
00766                                 $label = $LANG->getLL('label_commentforreviewer');
00767                                 $titleAttrib = $LANG->getLL('label_sendtoreview');
00768                         break;
00769                         case 1:
00770                                 $sId = 10;
00771                                 $sLabel = $LANG->getLL('label_review');
00772                                 $color = '#6666cc';     // TODO Use CSS?
00773                                 $label = $LANG->getLL('label_commentforpublisher');
00774                                 $titleAttrib = $LANG->getLL('label_approveforpublishing');
00775                         break;
00776                         case 10:
00777                                 $sLabel = $LANG->getLL('label_publish');
00778                                 $color = '#66cc66';     // TODO Use CSS?
00779                         break;
00780                         case -1:
00781                                 $sLabel = $this->doc->icons(2).$LANG->getLL('label_rejected');
00782                                 $sId = 0;
00783                                 $color = '#ff0000';     // TODO Use CSS?
00784                                 $label = $LANG->getLL('stage_label_user_comment');
00785                                 $titleAttrib = $LANG->getLL('label_resetstage');
00786                         break;
00787                         default:
00788                                 $sLabel = $LANG->getLL('label_undefined');
00789                                 $sId = 0;
00790                                 $color = '';
00791                         break;
00792                 }
00793 #debug($sId);
00794 
00795                 $raiseOk = !$GLOBALS['BE_USER']->workspaceCannotEditOfflineVersion($table,$rec_off);
00796 
00797                 if ($raiseOk && $rec_off['t3ver_stage']!=-1)    {
00798                         $onClick = 'var commentTxt=window.prompt("'.$LANG->getLL('explain_reject').'","");
00799                                                         if (commentTxt!=null) {window.location.href="'.$this->doc->issueCommand(
00800                                                         '&cmd['.$table.']['.$rec_off['uid'].'][version][action]=setStage'.
00801                                                         '&cmd['.$table.']['.$rec_off['uid'].'][version][stageId]=-1'
00802                                                         ).'&cmd['.$table.']['.$rec_off['uid'].'][version][comment]="+escape(commentTxt);}'.
00803                                                         ' return false;';
00804                                 // Reject:
00805                         $actionLinks.=
00806                                 '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
00807                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/down.gif','width="14" height="14"').' alt="" align="top" title="'.$LANG->getLL('label_reject').'" />'.
00808                                 '</a>';
00809                 } else {
00810                                 // Reject:
00811                         $actionLinks.=
00812                                 '<img src="'.$this->doc->backPath.'gfx/clear.gif" width="14" height="14" alt="" align="top" title="" />';
00813                 }
00814 
00815                 // TODO Use CSS?
00816                 $actionLinks.= '<span style="background-color: '.$color.'; color: white;">'.$sLabel.'</span>';
00817 
00818                         // Raise
00819                 if ($raiseOk)   {
00820                         $onClick = 'var commentTxt=window.prompt("'.$label.'","");
00821                                                         if (commentTxt!=null) {window.location.href="'.$this->doc->issueCommand(
00822                                                         '&cmd['.$table.']['.$rec_off['uid'].'][version][action]=setStage'.
00823                                                         '&cmd['.$table.']['.$rec_off['uid'].'][version][stageId]='.$sId
00824                                                         ).'&cmd['.$table.']['.$rec_off['uid'].'][version][comment]="+escape(commentTxt);}'.
00825                                                         ' return false;';
00826                         if ($rec_off['t3ver_stage']!=10)        {
00827                                 $actionLinks.=
00828                                         '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
00829                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/up.gif','width="14" height="14"').' alt="" align="top" title="'.htmlspecialchars($titleAttrib).'" />'.
00830                                         '</a>';
00831 
00832                                 $this->stageIndex[$sId][$table][] = $rec_off['uid'];
00833                         }
00834                 }
00835 
00836                 return $actionLinks;
00837         }
00838 
00848         function displayWorkspaceOverview_commandLinks($table,&$rec_on,&$rec_off,$vType)        {
00849                 global  $LANG;
00850 
00851                 if ($this->publishAccess && (!($GLOBALS['BE_USER']->workspaceRec['publish_access']&1) || (int)$rec_off['t3ver_stage']===10))    {
00852                         $actionLinks =
00853                                 '<a href="'.htmlspecialchars($this->doc->issueCommand(
00854                                                 '&cmd['.$table.']['.$rec_on['uid'].'][version][action]=swap'.
00855                                                 '&cmd['.$table.']['.$rec_on['uid'].'][version][swapWith]='.$rec_off['uid']
00856                                                 )).'">'.
00857                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/insert1.gif','width="14" height="14"').' alt="" align="top" title="' . $LANG->getLL('img_title_publish') . '" />'.
00858                                 '</a>';
00859                         if ($GLOBALS['BE_USER']->workspaceSwapAccess() && (int)$rec_on['t3ver_state']!==1 && (int)$rec_off['t3ver_state']!==2)  {
00860                                 $actionLinks.=
00861                                         '<a href="'.htmlspecialchars($this->doc->issueCommand(
00862                                                         '&cmd['.$table.']['.$rec_on['uid'].'][version][action]=swap'.
00863                                                         '&cmd['.$table.']['.$rec_on['uid'].'][version][swapWith]='.$rec_off['uid'].
00864                                                         '&cmd['.$table.']['.$rec_on['uid'].'][version][swapIntoWS]=1'
00865                                                         )).'">'.
00866                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/swap.png','width="14" height="14"').' alt="" align="top" title="' . $LANG->getLL('img_title_swap') . '" />'.
00867                                         '</a>';
00868                         }
00869                 }
00870 
00871                 if (!$GLOBALS['BE_USER']->workspaceCannotEditOfflineVersion($table,$rec_off))   {
00872 
00873                         if ($GLOBALS['BE_USER']->workspace!==0) {
00874                                         // Release
00875                                 $confirm = $LANG->JScharCode($LANG->getLL('remove_from_ws_confirmation'));
00876                                 $actionLinks.=
00877                                         '<a href="'.htmlspecialchars($this->doc->issueCommand('&cmd['.$table.']['.$rec_off['uid'].'][version][action]=clearWSID')).'" onclick="return confirm(' . $confirm . ');">'.
00878                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/group_clear.gif','width="14" height="14"').' alt="" align="top" title="' . $LANG->getLL('img_title_remove_from_ws') . '" />'.
00879                                         '</a>';
00880                         }
00881 
00882                                 // Edit
00883                         if ($table==='pages' && $vType!=='element')     {
00884                                 $tempUid = ($vType==='branch' || $GLOBALS['BE_USER']->workspace===0 ? $rec_off['uid'] : $rec_on['uid']);
00885                                 $actionLinks.=
00886                                         '<a href="#" onclick="top.loadEditId('.$tempUid.');top.goToModule(\''.$this->pageModule.'\'); return false;">'.
00887                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,t3lib_extMgm::extRelPath('cms').'layout/layout.gif','width="14" height="12"').' title="' . $LANG->getLL('img_title_edit_page') . '" alt="" />'.
00888                                         '</a>';
00889                         } else {
00890                                 $params = '&edit['.$table.']['.$rec_off['uid'].']=edit';
00891                                 $actionLinks.=
00892                                         '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->doc->backPath)).'">'.
00893                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/edit2.gif','width="12" height="12"').' title="' . $LANG->getLL('img_title_edit_element') . '" alt="" />'.
00894                                         '</a>';
00895                         }
00896                 }
00897 
00898                         // History/Log
00899                 $actionLinks.=
00900                         '<a href="'.htmlspecialchars($this->doc->backPath.'show_rechis.php?element='.rawurlencode($table.':'.$rec_off['uid']).'&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'">'.
00901                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/history2.gif','width="13" height="12"').' title="' . $LANG->getLL('img_title_show_log') . '" alt="" />'.
00902                         '</a>';
00903 
00904                         // View
00905                 if ($table==='pages')   {
00906                         $tempUid = ($vType==='branch' || $GLOBALS['BE_USER']->workspace===0 ? $rec_off['uid'] : $rec_on['uid']);
00907                         $actionLinks.=
00908                                 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($tempUid,$this->doc->backPath,t3lib_BEfunc::BEgetRootLine($tempUid))).'">'.
00909                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/zoom.gif','width="12" height="12"').' title="" alt="" />'.
00910                                 '</a>';
00911                 }
00912 
00913                 return $actionLinks;
00914         }
00915 
00924         function displayWorkspaceOverview_commandLinksSub($table,$rec,$origId)  {
00925                 global $LANG;
00926 
00927                 $uid = $rec['uid'];
00928                 if ($origId || $GLOBALS['BE_USER']->workspace===0)      {
00929                         if (!$GLOBALS['BE_USER']->workspaceCannotEditRecord($table,$rec))       {
00930                                         // Edit
00931                                 if ($table==='pages')   {
00932                                         $actionLinks.=
00933                                                 '<a href="#" onclick="top.loadEditId('.$uid.');top.goToModule(\''.$this->pageModule.'\'); return false;">'.
00934                                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,t3lib_extMgm::extRelPath('cms').'layout/layout.gif','width="14" height="12"').' title="' . $LANG->getLL('img_title_edit_page') . '" alt="" />'.
00935                                                 '</a>';
00936                                 } else {
00937                                         $params = '&edit['.$table.']['.$uid.']=edit';
00938                                         $actionLinks.=
00939                                                 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->doc->backPath)).'">'.
00940                                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/edit2.gif','width="12" height="12"').' title="' . $LANG->getLL('img_title_edit_element') . '" alt="" />'.
00941                                                 '</a>';
00942                                 }
00943                         }
00944 
00945                                 // History/Log
00946                         $actionLinks.=
00947                                 '<a href="'.htmlspecialchars($this->doc->backPath.'show_rechis.php?element='.rawurlencode($table.':'.$uid).'&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'">'.
00948                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/history2.gif','width="13" height="12"').' title="' . $LANG->getLL('img_title_show_log') . '" alt="" />'.
00949                                 '</a>';
00950                 }
00951 
00952                         // View
00953                 if ($table==='pages')   {
00954                         $actionLinks.=
00955                                 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($uid,$this->doc->backPath,t3lib_BEfunc::BEgetRootLine($uid))).'">'.
00956                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/zoom.gif','width="12" height="12"').' title="" alt="" />'.
00957                                 '</a>';
00958                 }
00959 
00960                 return $actionLinks;
00961         }
00962 
00974         function displayWorkspaceOverview_setInPageArray(&$pArray,$rlArr,$table,$row)   {
00975 
00976                         // Initialize:
00977                 ksort($rlArr);
00978                 reset($rlArr);
00979                 if (!$rlArr[0]['uid'])          array_shift($rlArr);
00980 
00981                         // Get and remove first element in root line:
00982                 $cEl = current($rlArr);
00983                 $pUid = $cEl['t3ver_oid'] ? $cEl['t3ver_oid'] : $cEl['uid'];            // Done to pile up "false versions" in the right branch...
00984 
00985                 $pArray[$pUid] = $cEl['title'];
00986                 array_shift($rlArr);
00987                 
00988                 
00989                         // If there are elements left in the root line, call this function recursively (to build $pArray in depth)
00990                 if (count($rlArr))      {
00991                         if (!isset($pArray[$pUid.'.'])) $pArray[$pUid.'.'] = array();
00992                         $this->displayWorkspaceOverview_setInPageArray($pArray[$pUid.'.'],$rlArr,$table,$row);
00993                 } else {        // If this was the last element, set the value:
00994                         $pArray[$pUid.'_'][$table][$row['t3ver_oid']][] = $row;
00995                 }
00996         }
00997 
01006         function subElements($uid,$treeLevel,$origId=0) {
01007                 global $TCA, $LANG;
01008 
01009                 if ($GLOBALS['BE_USER']->workspace===0 || !$this->MOD_SETTINGS['expandSubElements'])    {       // In online workspace we have a reduced view because otherwise it will bloat the listing:
01010                         return '<br/>
01011                                         <img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/ol/joinbottom.gif','width="18" height="16"').' align="top" alt="" title="" />'.
01012                                         ($origId ?
01013                                                 '<a href="'.htmlspecialchars($this->doc->backPath.t3lib_extMgm::extRelPath('version').'cm1/index.php?id='.$uid.'&details='.rawurlencode('pages:'.$uid).'&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'">'.
01014                                                 '<span class="typo3-dimmed"><em>['.$LANG->getLL('label_subelementsdetails').']</em><span></a>' :
01015                                                 '<span class="typo3-dimmed"><em>['.$LANG->getLL('label_subelements').']</em><span>');
01016                 } else {        // For an offline workspace, show sub elements:
01017 
01018                         $tCell = array();
01019 
01020                                 // Find records that follow pages when swapping versions:
01021                         $recList = array();
01022                         foreach($TCA as $tN => $tCfg)   {
01023                                 if ($tN!='pages' && ($treeLevel>0 || $TCA[$tN]['ctrl']['versioning_followPages']))      {
01024                                         $this->subElements_getNonPageRecords($tN, $uid, $recList);
01025                                 }
01026                         }
01027 
01028                                 // Render records collected above:
01029                         $elCount = count($recList)-1;
01030                         foreach($recList as $c => $comb)        {
01031                                 list($tN,$rec) = $comb;
01032 
01033                                 $this->subElements_renderItem(
01034                                         $tCell,
01035                                         $tN,
01036                                         $uid,
01037                                         $rec,
01038                                         $origId,
01039                                         $c==$elCount && $treeLevel==0 ? 1 : 0,          // If true, will show bottom-join icon.
01040                                         ''
01041                                 );
01042                         }
01043 
01044                                 // For branch, dive into the subtree:
01045                         if ($treeLevel>0) {
01046 
01047                                         // Drawing tree:
01048                                 $tree = t3lib_div::makeInstance('t3lib_pageTree');
01049                                 $tree->init('AND '.$GLOBALS['BE_USER']->getPagePermsClause(1));
01050                                 $tree->makeHTML = 2;            // 2=Also rendering depth-data into the result array
01051                                 $tree->getTree($uid, 99, '');
01052 
01053                                         // Traverse page tree:
01054                                 foreach($tree->tree as $data)   {
01055 
01056                                                 // Render page in table cell:
01057                                         $this->subElements_renderItem(
01058                                                 $tCell,
01059                                                 'pages',
01060                                                 $uid,
01061                                                 t3lib_BEfunc::getRecord('pages',$data['row']['uid']),   // Needs all fields, at least more than what is given in $data['row']...
01062                                                 $origId,
01063                                                 2,              // 2=the join icon and icon for the record is not rendered for pages (where all is in $data['HTML']
01064                                                 $data['HTML']
01065                                         );
01066 
01067                                                 // Find all records from page and collect in $recList:
01068                                         $recList = array();
01069                                         foreach($TCA as $tN => $tCfg)   {
01070                                                 if ($tN!=='pages')      {
01071                                                         $this->subElements_getNonPageRecords($tN, $data['row']['uid'], $recList);
01072                                                 }
01073                                         }
01074 
01075                                                 // Render records collected above:
01076                                         $elCount = count($recList)-1;
01077                                         foreach($recList as $c => $comb)        {
01078                                                 list($tN,$rec) = $comb;
01079 
01080                                                 $this->subElements_renderItem(
01081                                                         $tCell,
01082                                                         $tN,
01083                                                         $uid,
01084                                                         $rec,
01085                                                         $origId,
01086                                                         $c==$elCount?1:0,       // If true, will show bottom-join icon.
01087                                                         $data['HTML_depthData']
01088                                                 );
01089                                         }
01090                                 }
01091                         }
01092 
01093                         return '
01094                                         <!-- Sub-element tree for versions -->
01095                                         <table border="0" cellpadding="0" cellspacing="1" class="ver-subtree">
01096                                                 '.implode('',$tCell).'
01097                                         </table>';
01098                 }
01099         }
01100 
01109         function subElements_getNonPageRecords($tN, $uid, &$recList)    {
01110                 global $TCA;
01111 
01112                 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01113                         '*',
01114                         $tN,
01115                         'pid='.intval($uid).
01116                                 ($TCA[$tN]['ctrl']['versioningWS'] ? ' AND t3ver_state=0' : '').
01117                                 t3lib_BEfunc::deleteClause($tN),
01118                         '',
01119                         $TCA[$tN]['ctrl']['sortby'] ? $TCA[$tN]['ctrl']['sortby'] : $GLOBALS['TYPO3_DB']->stripOrderBy($TCA[$tN]['ctrl']['default_sortby'])
01120                 );
01121 
01122                 foreach($records as $rec)       {
01123                         $recList[] = array($tN,$rec);
01124                 }
01125         }
01126 
01139         function subElements_renderItem(&$tCell,$tN,$uid,$rec,$origId,$iconMode,$HTMLdata)      {
01140                 global $TCA;
01141 
01142                         // Initialize:
01143                 $origUidFields = $TCA[$tN]['ctrl']['origUid'];
01144                 $diffCode = '';
01145 
01146                 if ($origUidFields)     {       // If there is a field for this table with original uids we will use that to connect records:
01147                         if (!$origId)   {       // In case we are displaying the online originals:
01148                                 $this->targets['orig_'.$uid.'_'.$tN.'_'.$rec['uid']] = $rec;    // Build up target array (important that
01149                                 $tdParams =  ' id="orig_'.$uid.'_'.$tN.'_'.$rec['uid'].'" class="typo3-ver"';           // Setting ID of the table row
01150                         } else {        // Version branch:
01151                                 if ($this->targets['orig_'.$origId.'_'.$tN.'_'.$rec[$origUidFields]])   {       // If there IS a corresponding original record...:
01152 
01153                                                 // Prepare Table row parameters:
01154                                         $tdParams =  ' onmouseover="hlSubelements(\''.$origId.'_'.$tN.'_'.$rec[$origUidFields].'\', \''.$uid.'_'.$tN.'_'.$rec[$origUidFields].'\', 1, '.($this->MOD_SETTINGS['diff']==2?1:0).');"'.
01155                                                                 ' onmouseout="hlSubelements(\''.$origId.'_'.$tN.'_'.$rec[$origUidFields].'\', \''.$uid.'_'.$tN.'_'.$rec[$origUidFields].'\', 0, '.($this->MOD_SETTINGS['diff']==2?1:0).');"'.
01156                                                                 ' id="ver_'.$uid.'_'.$tN.'_'.$rec[$origUidFields].'" class="typo3-ver"';
01157 
01158                                                 // Create diff view: