Documentation TYPO3 par Ameos

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 and icon:
00615                                                                         $rec_off = t3lib_BEfunc::getRecord($table,$rec['uid']);
00616                                                                         $icon = t3lib_iconWorks::getIconImage($table, $rec_off, $this->doc->backPath, ' align="top" title="'.t3lib_BEfunc::getRecordIconAltText($rec_off,$table).'"');
00617                                                                         $icon = $this->doc->wrapClickMenuOnIcon($icon, $table, $rec_off['uid'], 2, '', '+edit,view,info,delete');
00618 
00619                                                                                 // Prepare diff-code:
00620                                                                         if ($this->MOD_SETTINGS['diff'])        {
00621                                                                                 $diffCode = '';
00622                                                                                 list($diffHTML,$diffPct) = $this->createDiffView($table, $rec_off, $rec_on);
00623                                                                                 if ($rec_on['t3ver_state']==1)  {       // New record:
00624                                                                                         $diffCode.= $this->doc->icons(1).$LANG->getLL('label_newrecord').'<br/>';
00625                                                                                         $diffCode.= $diffHTML;
00626                                                                                 } elseif ($rec_off['t3ver_state']==2)   {
00627                                                                                         $diffCode.= $this->doc->icons(2).'Deleted element<br/>';
00628                                                                                         $diffCode.= $this->doc->icons(2).$LANG->getLL('label_deletedrecord').'<br/>';
00629                                                                                 } else {
00630                                                                                         $diffCode.= ($diffPct<0 ? 'N/A' : ($diffPct ? $diffPct.'% change:' : ''));
00631                                                                                         $diffCode.= ($diffPct<0 ? $LANG->getLL('label_notapplicable') : ($diffPct ? sprintf($LANG->getLL('label_percentchange'), $diffPct) : ''));
00632                                                                                         $diffCode.= $diffHTML;
00633                                                                                 }
00634 
00635                                                                         } else $diffCode = '';
00636 
00637                                                                                 // Prepare swap-mode values:
00638                                                                         if ($table==='pages' && $rec_off['t3ver_swapmode']!=-1) {
00639                                                                                 if ($rec_off['t3ver_swapmode']>0)       {
00640                                                                                         $vType = 'branch';      // Do not translate!
00641                                                                                 } else {
00642                                                                                         $vType = 'page';        // Do not translate!
00643                                                                                 }
00644                                                                         } else {
00645                                                                                 $vType = 'element';     // Do not translate!
00646                                                                         }
00647 
00648                                                                         switch($vType) {
00649                                                                                 case 'element':
00650                                                                                         $swapLabel = ' ['.$LANG->getLL('label_element').']';
00651                                                                                         $swapClass = 'ver-element';     // Do not translate!
00652                                                                                         $warnAboutVersions_nonPages = $warnAboutVersions_page;  // Setting this if sub elements are found with a page+content (must be rendered prior to this of course!)
00653                                                                                 break;
00654                                                                                 case 'page':
00655                                                                                         $swapLabel = ' ['.$LANG->getLL('label_page').']';
00656                                                                                         $swapClass = 'ver-page';        // Do not translate!
00657                                                                                         $warnAboutVersions_page = !$this->showWorkspaceCol;             // This value is true only if multiple workspaces are shown and we need the opposite here.
00658                                                                                 break;
00659                                                                                 case 'branch':
00660                                                                                         $swapLabel = ' ['.$LANG->getLL('label_branch').']';     
00661                                                                                         $swapClass = 'ver-branch';      // Do not translate!
00662                                                                                         $warnAboutVersions_next = !$this->showWorkspaceCol;             // This value is true only if multiple workspaces are shown and we need the opposite here.
00663                                                                                 break;
00664                                                                         }
00665 
00666                                                                                 // Modify main cell based on first version shown:
00667                                                                         $subElements = array();
00668                                                                         if ($table==='pages' && $rec_off['t3ver_swapmode']!=-1 && $mainCell)    {       // For "Page" and "Branch" swap modes where $mainCell is still carrying content (only first version)
00669                                                                                 $subElements['on'] = $this->subElements($rec_on['uid'], $rec_off['t3ver_swapmode']);
00670                                                                                 $subElements['off'] = $this->subElements($rec_off['uid'],$rec_off['t3ver_swapmode'],$rec_on['uid']);
00671                                                                         }
00672                                                                         $mainCell = str_replace('###SUB_ELEMENTS###', $subElements['on'], $mainCell);
00673 
00674                                                                                 // Create version element:
00675                                                                         $versionsInOtherWS = $this->versionsInOtherWS($table, $rec_on['uid']);
00676                                                                         $versionsInOtherWSWarning = $versionsInOtherWS && $GLOBALS['BE_USER']->workspace!==0 ? '<br/>'.$this->doc->icons(2).$LANG->getLL('label_otherversions').' '.$versionsInOtherWS : '';
00677                                                                         $multipleWarning = (!$mainCell && $GLOBALS['BE_USER']->workspace!==0? '<br/>'.$this->doc->icons(3).'<b>'.$LANG->getLL('label_multipleversions').'</b>' : '');
00678                                                                         $verWarning = $warnAboutVersions || ($warnAboutVersions_nonPages && $GLOBALS['TCA'][$table]['ctrl']['versioning_followPages'])? '<br/>'.$this->doc->icons(3).'<b>'.$LANG->getLL('label_nestedversions').'</b>' : '';
00679                                                                         $verElement = $icon.
00680                                                                                 '<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'))).'">'.
00681                                                                                 t3lib_BEfunc::getRecordTitle($table,$rec_off,TRUE).
00682                                                                                 '</a>'.
00683                                                                                 $versionsInOtherWSWarning.
00684                                                                                 $multipleWarning.
00685                                                                                 $verWarning;
00686                                                                         if ($diffCode)  {
00687                                                                                 $verElement = '
00688                                                                                 <table border="0" cellpadding="0" cellspacing="0" class="ver-verElement">
00689                                                                                         <tr>
00690                                                                                                 <td nowrap="nowrap" width="180">'.$verElement.'&nbsp;&nbsp;</td>
00691                                                                                                 <td class="c-diffCell">'.$diffCode.'</td>
00692                                                                                         </tr>
00693                                                                                 </table>';
00694                                                                         }
00695 
00696                                                                                 // Create version cell:
00697                                                                         $verCell = '
00698                                                                                         <td align="center">'.$this->formatVerId($rec_off['t3ver_id']).'</td>
00699                                                                                         <td nowrap="nowrap">'.
00700                                                                                                 $verElement.
00701                                                                                                 $subElements['off'].
00702                                                                                                 '</td>';
00703 
00704                                                                                 // Compile table row:
00705                                                                         $tableRows[] = '
00706                                                                                 <tr class="bgColor4">
00707                                                                                         '.$mainCell.$verCell.'
00708                                                                                         <td nowrap="nowrap">'.$this->showStageChangeLog($table,$rec_off['uid'],$this->displayWorkspaceOverview_stageCmd($table,$rec_off)).'</td>
00709                                                                                         <td nowrap="nowrap" class="'.$swapClass.'">'.
00710                                                                                                 $this->displayWorkspaceOverview_commandLinks($table,$rec_on,$rec_off,$vType).
00711                                                                                                 htmlspecialchars($swapLabel).
00712                                                                                                 '</td>
00713                                                                                         <td nowrap="nowrap">'.htmlspecialchars($this->formatCount($rec_off['t3ver_count'])).'</td>'.            // Lifecycle
00714                                                                                                 ($this->showWorkspaceCol ? '
00715                                                                                         <td nowrap="nowrap">'.htmlspecialchars($this->formatWorkspace($rec_off['t3ver_wsid'])).'</td>' : '').'
00716                                                                                 </tr>';
00717 
00718                                                                                 // Reset the main cell:
00719                                                                         $mainCell = '';
00720                                                                 }
00721                                                         }
00722                                                 }
00723                                         }
00724                                                 // Call recursively for sub-rows:
00725                                         $tableRows = $this->displayWorkspaceOverview_list($pArray[$k.'.'], $tableRows, $c+1, $warnAboutVersions_next);
00726                                 }
00727                         }
00728                 }
00729                 return $tableRows;
00730         }
00731 
00740         function displayWorkspaceOverview_pageTreeIconTitle($pageUid, $title, $indentCount)     {
00741                 $pRec = t3lib_BEfunc::getRecord('pages',$pageUid);
00742                 return '<img src="clear.gif" width="1" height="1" hspace="'.($indentCount * $this->pageTreeIndent).'" align="top" alt="" />'.   // Indenting page tree
00743                                         t3lib_iconWorks::getIconImage('pages',$pRec,$this->doc->backPath,' align="top" title="'.t3lib_BEfunc::getRecordIconAltText($pRec,'pages').'"').
00744                                         htmlspecialchars(t3lib_div::fixed_lgd_cs($title,$this->pageTreeIndent_titleLgd)).
00745                                         '&nbsp;&nbsp;';
00746         }
00747 
00755         function displayWorkspaceOverview_stageCmd($table,&$rec_off)    {
00756                 global $LANG;
00757 
00758                 switch((int)$rec_off['t3ver_stage'])    {
00759                         case 0:
00760                                 $sId = 1;
00761                                 $sLabel = $LANG->getLL('stage_editing');
00762                                 $color = '#666666';     // TODO Use CSS?
00763                                 $label = $LANG->getLL('label_commentforreviewer');
00764                                 $titleAttrib = $LANG->getLL('label_sendtoreview');
00765                         break;
00766                         case 1:
00767                                 $sId = 10;
00768                                 $sLabel = $LANG->getLL('label_review');
00769                                 $color = '#6666cc';     // TODO Use CSS?
00770                                 $label = $LANG->getLL('label_commentforpublisher');
00771                                 $titleAttrib = $LANG->getLL('label_approveforpublishing');
00772                         break;
00773                         case 10:
00774                                 $sLabel = $LANG->getLL('label_publish');
00775                                 $color = '#66cc66';     // TODO Use CSS?
00776                         break;
00777                         case -1:
00778                                 $sLabel = $this->doc->icons(2).$LANG->getLL('label_rejected');
00779                                 $sId = 0;
00780                                 $color = '#ff0000';     // TODO Use CSS?
00781                                 $label = $LANG->getLL('stage_label_user_comment');
00782                                 $titleAttrib = $LANG->getLL('label_resetstage');
00783                         break;
00784                         default:
00785                                 $sLabel = $LANG->getLL('label_undefined');
00786                                 $sId = 0;
00787                                 $color = '';
00788                         break;
00789                 }
00790 #debug($sId);
00791 
00792                 $raiseOk = !$GLOBALS['BE_USER']->workspaceCannotEditOfflineVersion($table,$rec_off);
00793 
00794                 if ($raiseOk && $rec_off['t3ver_stage']!=-1)    {
00795                         $onClick = 'var commentTxt=window.prompt("'.$LANG->getLL('explain_reject').'","");
00796                                                         if (commentTxt!=null) {window.location.href="'.$this->doc->issueCommand(
00797                                                         '&cmd['.$table.']['.$rec_off['uid'].'][version][action]=setStage'.
00798                                                         '&cmd['.$table.']['.$rec_off['uid'].'][version][stageId]=-1'
00799                                                         ).'&cmd['.$table.']['.$rec_off['uid'].'][version][comment]="+escape(commentTxt);}'.
00800                                                         ' return false;';
00801                                 // Reject:
00802                         $actionLinks.=
00803                                 '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
00804                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/down.gif','width="14" height="14"').' alt="" align="top" title="'.$LANG->getLL('label_reject').'" />'.
00805                                 '</a>';
00806                 } else {
00807                                 // Reject:
00808                         $actionLinks.=
00809                                 '<img src="'.$this->doc->backPath.'gfx/clear.gif" width="14" height="14" alt="" align="top" title="" />';
00810                 }
00811 
00812                 // TODO Use CSS?
00813                 $actionLinks.= '<span style="background-color: '.$color.'; color: white;">'.$sLabel.'</span>';
00814 
00815                         // Raise
00816                 if ($raiseOk)   {
00817                         $onClick = 'var commentTxt=window.prompt("'.$label.'","");
00818                                                         if (commentTxt!=null) {window.location.href="'.$this->doc->issueCommand(
00819                                                         '&cmd['.$table.']['.$rec_off['uid'].'][version][action]=setStage'.
00820                                                         '&cmd['.$table.']['.$rec_off['uid'].'][version][stageId]='.$sId
00821                                                         ).'&cmd['.$table.']['.$rec_off['uid'].'][version][comment]="+escape(commentTxt);}'.
00822                                                         ' return false;';
00823                         if ($rec_off['t3ver_stage']!=10)        {
00824                                 $actionLinks.=
00825                                         '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.
00826                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/up.gif','width="14" height="14"').' alt="" align="top" title="'.htmlspecialchars($titleAttrib).'" />'.
00827                                         '</a>';
00828 
00829                                 $this->stageIndex[$sId][$table][] = $rec_off['uid'];
00830                         }
00831                 }
00832 
00833                 return $actionLinks;
00834         }
00835 
00845         function displayWorkspaceOverview_commandLinks($table,&$rec_on,&$rec_off,$vType)        {
00846                 global  $LANG;
00847 
00848                 if ($this->publishAccess && (!($GLOBALS['BE_USER']->workspaceRec['publish_access']&1) || (int)$rec_off['t3ver_stage']===10))    {
00849                         $actionLinks =
00850                                 '<a href="'.htmlspecialchars($this->doc->issueCommand(
00851                                                 '&cmd['.$table.']['.$rec_on['uid'].'][version][action]=swap'.
00852                                                 '&cmd['.$table.']['.$rec_on['uid'].'][version][swapWith]='.$rec_off['uid']
00853                                                 )).'">'.
00854                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/insert1.gif','width="14" height="14"').' alt="" align="top" title="' . $LANG->getLL('img_title_publish') . '" />'.
00855                                 '</a>';
00856                         if ($GLOBALS['BE_USER']->workspaceSwapAccess() && (int)$rec_on['t3ver_state']!==1 && (int)$rec_off['t3ver_state']!==2)  {
00857                                 $actionLinks.=
00858                                         '<a href="'.htmlspecialchars($this->doc->issueCommand(
00859                                                         '&cmd['.$table.']['.$rec_on['uid'].'][version][action]=swap'.
00860                                                         '&cmd['.$table.']['.$rec_on['uid'].'][version][swapWith]='.$rec_off['uid'].
00861                                                         '&cmd['.$table.']['.$rec_on['uid'].'][version][swapIntoWS]=1'
00862                                                         )).'">'.
00863                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/swap.png','width="14" height="14"').' alt="" align="top" title="' . $LANG->getLL('img_title_swap') . '" />'.
00864                                         '</a>';
00865                         }
00866                 }
00867 
00868                 if (!$GLOBALS['BE_USER']->workspaceCannotEditOfflineVersion($table,$rec_off))   {
00869 
00870                         if ($GLOBALS['BE_USER']->workspace!==0) {
00871                                         // Release
00872                                 $confirm = $LANG->JScharCode($LANG->getLL('remove_from_ws_confirmation'));
00873                                 $actionLinks.=
00874                                         '<a href="'.htmlspecialchars($this->doc->issueCommand('&cmd['.$table.']['.$rec_off['uid'].'][version][action]=clearWSID')).'" onclick="return confirm(' . $confirm . ');">'.
00875                                         '<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') . '" />'.
00876                                         '</a>';
00877                         }
00878 
00879                                 // Edit
00880                         if ($table==='pages' && $vType!=='element')     {
00881                                 $tempUid = ($vType==='branch' || $GLOBALS['BE_USER']->workspace===0 ? $rec_off['uid'] : $rec_on['uid']);
00882                                 $actionLinks.=
00883                                         '<a href="#" onclick="top.loadEditId('.$tempUid.');top.goToModule(\''.$this->pageModule.'\'); return false;">'.
00884                                         '<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="" />'.
00885                                         '</a>';
00886                         } else {
00887                                 $params = '&edit['.$table.']['.$rec_off['uid'].']=edit';
00888                                 $actionLinks.=
00889                                         '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->doc->backPath)).'">'.
00890                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/edit2.gif','width="12" height="12"').' title="' . $LANG->getLL('img_title_edit_element') . '" alt="" />'.
00891                                         '</a>';
00892                         }
00893                 }
00894 
00895                         // History/Log
00896                 $actionLinks.=
00897                         '<a href="'.htmlspecialchars($this->doc->backPath.'show_rechis.php?element='.rawurlencode($table.':'.$rec_off['uid']).'&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'">'.
00898                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/history2.gif','width="13" height="12"').' title="' . $LANG->getLL('img_title_show_log') . '" alt="" />'.
00899                         '</a>';
00900 
00901                         // View
00902                 if ($table==='pages')   {
00903                         $tempUid = ($vType==='branch' || $GLOBALS['BE_USER']->workspace===0 ? $rec_off['uid'] : $rec_on['uid']);
00904                         $actionLinks.=
00905                                 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($tempUid,$this->doc->backPath,t3lib_BEfunc::BEgetRootLine($tempUid))).'">'.
00906                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/zoom.gif','width="12" height="12"').' title="" alt="" />'.
00907                                 '</a>';
00908                 }
00909 
00910                 return $actionLinks;
00911         }
00912 
00921         function displayWorkspaceOverview_commandLinksSub($table,$rec,$origId)  {
00922                 global $LANG;
00923 
00924                 $uid = $rec['uid'];
00925                 if ($origId || $GLOBALS['BE_USER']->workspace===0)      {
00926                         if (!$GLOBALS['BE_USER']->workspaceCannotEditRecord($table,$rec))       {
00927                                         // Edit
00928                                 if ($table==='pages')   {
00929                                         $actionLinks.=
00930                                                 '<a href="#" onclick="top.loadEditId('.$uid.');top.goToModule(\''.$this->pageModule.'\'); return false;">'.
00931                                                 '<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="" />'.
00932                                                 '</a>';
00933                                 } else {
00934                                         $params = '&edit['.$table.']['.$uid.']=edit';
00935                                         $actionLinks.=
00936                                                 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick($params,$this->doc->backPath)).'">'.
00937                                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/edit2.gif','width="12" height="12"').' title="' . $LANG->getLL('img_title_edit_element') . '" alt="" />'.
00938                                                 '</a>';
00939                                 }
00940                         }
00941 
00942                                 // History/Log
00943                         $actionLinks.=
00944                                 '<a href="'.htmlspecialchars($this->doc->backPath.'show_rechis.php?element='.rawurlencode($table.':'.$uid).'&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))).'">'.
00945                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/history2.gif','width="13" height="12"').' title="' . $LANG->getLL('img_title_show_log') . '" alt="" />'.
00946                                 '</a>';
00947                 }
00948 
00949                         // View
00950                 if ($table==='pages')   {
00951                         $actionLinks.=
00952                                 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($uid,$this->doc->backPath,t3lib_BEfunc::BEgetRootLine($uid))).'">'.
00953                                 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/zoom.gif','width="12" height="12"').' title="" alt="" />'.
00954                                 '</a>';
00955                 }
00956 
00957                 return $actionLinks;
00958         }
00959 
00971         function displayWorkspaceOverview_setInPageArray(&$pArray,$rlArr,$table,$row)   {
00972 
00973                         // Initialize:
00974                 ksort($rlArr);
00975                 reset($rlArr);
00976                 if (!$rlArr[0]['uid'])          array_shift($rlArr);
00977 
00978                         // Get and remove first element in root line:
00979                 $cEl = current($rlArr);
00980                 $pUid = $cEl['t3ver_oid'] ? $cEl['t3ver_oid'] : $cEl['uid'];            // Done to pile up "false versions" in the right branch...
00981 
00982                 $pArray[$pUid] = $cEl['title'];
00983                 array_shift($rlArr);
00984                 
00985                 
00986                         // If there are elements left in the root line, call this function recursively (to build $pArray in depth)
00987                 if (count($rlArr))      {
00988                         if (!isset($pArray[$pUid.'.'])) $pArray[$pUid.'.'] = array();
00989                         $this->displayWorkspaceOverview_setInPageArray($pArray[$pUid.'.'],$rlArr,$table,$row);
00990                 } else {        // If this was the last element, set the value:
00991                         $pArray[$pUid.'_'][$table][$row['t3ver_oid']][] = $row;
00992                 }
00993         }
00994 
01003         function subElements($uid,$treeLevel,$origId=0) {
01004                 global $TCA, $LANG;
01005 
01006                 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:
01007                         return '<br/>
01008                                         <img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/ol/joinbottom.gif','width="18" height="16"').' align="top" alt="" title="" />'.
01009                                         ($origId ?
01010                                                 '<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'))).'">'.
01011                                                 '<span class="typo3-dimmed"><em>['.$LANG->getLL('label_subelementsdetails').']</em><span></a>' :
01012                                                 '<span class="typo3-dimmed"><em>['.$LANG->getLL('label_subelements').']</em><span>');
01013                 } else {        // For an offline workspace, show sub elements:
01014 
01015                         $tCell = array();
01016 
01017                                 // Find records that follow pages when swapping versions:
01018                         $recList = array();
01019                         foreach($TCA as $tN => $tCfg)   {
01020                                 if ($tN!='pages' && ($treeLevel>0 || $TCA[$tN]['ctrl']['versioning_followPages']))      {
01021                                         $this->subElements_getNonPageRecords($tN, $uid, $recList);
01022                                 }
01023                         }
01024 
01025                                 // Render records collected above:
01026                         $elCount = count($recList)-1;
01027                         foreach($recList as $c => $comb)        {
01028                                 list($tN,$rec) = $comb;
01029 
01030                                 $this->subElements_renderItem(
01031                                         $tCell,
01032                                         $tN,
01033                                         $uid,
01034                                         $rec,
01035                                         $origId,
01036                                         $c==$elCount && $treeLevel==0 ? 1 : 0,          // If true, will show bottom-join icon.
01037                                         ''
01038                                 );
01039                         }
01040 
01041                                 // For branch, dive into the subtree:
01042                         if ($treeLevel>0) {
01043 
01044                                         // Drawing tree:
01045                                 $tree = t3lib_div::makeInstance('t3lib_pageTree');
01046                                 $tree->init('AND '.$GLOBALS['BE_USER']->getPagePermsClause(1));
01047                                 $tree->makeHTML = 2;            // 2=Also rendering depth-data into the result array
01048                                 $tree->getTree($uid, 99, '');
01049 
01050                                         // Traverse page tree:
01051                                 foreach($tree->tree as $data)   {
01052 
01053                                                 // Render page in table cell:
01054                                         $this->subElements_renderItem(
01055                                                 $tCell,
01056                                                 'pages',
01057                                                 $uid,
01058                                                 t3lib_BEfunc::getRecord('pages',$data['row']['uid']),   // Needs all fields, at least more than what is given in $data['row']...
01059                                                 $origId,
01060                                                 2,              // 2=the join icon and icon for the record is not rendered for pages (where all is in $data['HTML']
01061                                                 $data['HTML']
01062                                         );
01063 
01064                                                 // Find all records from page and collect in $recList:
01065                                         $recList = array();
01066                                         foreach($TCA as $tN => $tCfg)   {
01067                                                 if ($tN!=='pages')      {
01068                                                         $this->subElements_getNonPageRecords($tN, $data['row']['uid'], $recList);
01069                                                 }
01070                                         }
01071 
01072                                                 // Render records collected above:
01073                                         $elCount = count($recList)-1;
01074                                         foreach($recList as $c => $comb)        {
01075                                                 list($tN,$rec) = $comb;
01076 
01077                                                 $this->subElements_renderItem(
01078                                                         $tCell,
01079                                                         $tN,
01080                                                         $uid,
01081                                                         $rec,
01082                                                         $origId,
01083                                                         $c==$elCount?1:0,       // If true, will show bottom-join icon.
01084                                                         $data['HTML_depthData']
01085                                                 );
01086                                         }
01087                                 }
01088                         }
01089 
01090                         return '
01091                                         <!-- Sub-element tree for versions -->
01092                                         <table border="0" cellpadding="0" cellspacing="1" class="ver-subtree">
01093                                                 '.implode('',$tCell).'
01094                                         </table>';
01095                 }
01096         }
01097 
01106         function subElements_getNonPageRecords($tN, $uid, &$recList)    {
01107                 global $TCA;
01108 
01109                 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01110                         '*',
01111                         $tN,
01112                         'pid='.intval($uid).
01113                                 ($TCA[$tN]['ctrl']['versioningWS'] ? ' AND t3ver_state=0' : '').
01114                                 t3lib_BEfunc::deleteClause($tN),
01115                         '',
01116                         $TCA[$tN]['ctrl']['sortby'] ? $TCA[$tN]['ctrl']['sortby'] : $GLOBALS['TYPO3_DB']->stripOrderBy($TCA[$tN]['ctrl']['default_sortby'])
01117                 );
01118 
01119                 foreach($records as $rec)       {
01120                         $recList[] = array($tN,$rec);
01121                 }
01122         }
01123 
01136         function subElements_renderItem(&$tCell,$tN,$uid,$rec,$origId,$iconMode,$HTMLdata)      {
01137                 global $TCA;
01138 
01139                         // Initialize:
01140                 $origUidFields = $TCA[$tN]['ctrl']['origUid'];
01141                 $diffCode = '';
01142 
01143                 if ($origUidFields)     {       // If there is a field for this table with original uids we will use that to connect records:
01144                         if (!$origId)   {       // In case we are displaying the online originals:
01145                                 $this->targets['orig_'.$uid.'_'.$tN.'_'.$rec['uid']] = $rec;    // Build up target array (important that
01146                                 $tdParams =  ' id="orig_'.$uid.'_'.$tN.'_'.$rec['uid'].'" class="typo3-ver"';           // Setting ID of the table row
01147                         } else {        // Version branch:
01148                                 if ($this->targets['orig_'.$origId.'_'.$tN.'_'.$rec[$origUidFields]])   {       // If there IS a corresponding original record...:
01149 
01150                                                 // Prepare Table row parameters:
01151                                         $tdParams =  ' onmouseover="hlSubelements(\''.$origId.'_'.$tN.'_'.$rec[$origUidFields].'\', \''.$uid.'_'.$tN.'_'.$rec[$origUidFields].'\', 1, '.($this->MOD_SETTINGS['diff']==2?1:0).');"'.
01152                                                                 ' onmouseout="hlSubelements(\''.$origId.'_'.$tN.'_'.$rec[$origUidFields].'\', \''.$uid.'_'.$tN.'_'.$rec[$origUidFields].'\', 0, '.($this->MOD_SETTINGS['diff']==2?1:0).');"'.
01153                                                                 ' id="ver_'.$uid.'_'.$tN.'_'.$rec[$origUidFields].'" class="typo3-ver"';
01154 
01155                                                 // Create diff view:
01156                                         if ($this->MOD_SETTINGS['diff'])        {
01157                                                 list($diffHTML,$diffPct) = $this->createDiffView($tN, $rec, $this->targets['orig_'.$origId.'_'.$tN.'_'.$rec[$origUidFields]]);
01158 
01159                                                 if ($this->MOD_SETTINGS['diff']==2)     {
01160                                                         $diffCode =
01161                                                                 ($diffPct ? '<span class="nobr">'.$diffPct.'% change</span>' : '-').
01162                                                                 '<div style="visibility: hidden; position: absolute;" id="diff_'.$uid.'_'.$tN.'_'.$rec[$origUidFields].'" class="diffLayer">'.
01163                                                                 $diffHTML.
01164                                                                 '</div>';
01165                                                 } else {
01166                                                         $diffCode =
01167                                                                 ($diffPct<0 ? 'N/A' : ($diffPct ? $diffPct.'% change:' : '')).
01168                                                                 $diffHTML;
01169                                                 }
01170                                         }
01171 
01172                                                 // Unsetting the target fields allows us to mark all originals without a version in the subtree (see ->markupNewOriginals())
01173                                         unset($this->targets['orig_'.$origId.'_'.$tN.'_'.$rec[$origUidFields]]);
01174                                 } else {        // No original record, so must be new:
01175                                         $tdParams =  ' class="typo3-ver-new"';
01176                                 }
01177                         }
01178                 } else {        // If no original uid column is supported for this table we are forced NOT to display any diff or highlighting.
01179                         $tdParams = ' class="typo3-ver-noComp"';
01180                 }
01181 
01182                         // Compile the cell:
01183                 $tCell[] = '
01184                                                 <tr'.$tdParams.'>
01185                                                         <td class="iconTitle">'.
01186                                                                 $HTMLdata.
01187                                                                 ($iconMode < 2 ?
01188                                                                         '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/ol/join'.($iconMode ? 'bottom' : '').'.gif','width="18" height="16"').' alt="" />'.
01189                                                                         t3lib_iconWorks::getIconImage($tN, $rec, $this->doc->backPath,'') : '').
01190                                                                 t3lib_BEfunc::getRecordTitle($tN, $rec, TRUE).
01191                                                         '</td>
01192                                                         <td class="cmdCell">'.
01193                                                                 $this->displayWorkspaceOverview_commandLinksSub($tN,$rec,$origId).
01194                                                         '</td>'.($origId ? '<td class="diffCell">'.
01195                                                                 $diffCode.
01196                                                         '</td>':'').'
01197                                                 </tr>';
01198         }
01199 
01205         function markupNewOriginals()   {
01206 
01207                 if (count($this->targets))      {
01208                         $scriptCode = '';
01209                         foreach($this->targets as $key => $rec) {
01210                                 $scriptCode.='
01211                                         document.getElementById(\''.$key.'\').attributes.getNamedItem("class").nodeValue = \'typo3-ver-new\';
01212                                 ';
01213                         }
01214 
01215                         return $this->doc->wrapScriptTags($scriptCode);
01216                 }
01217         }
01218 
01227         function createDiffView($table, $diff_1_record, $diff_2_record) {
01228                 global $TCA, $LANG;
01229 
01230                         // Initialize:
01231                 $pctChange = 'N/A';
01232 
01233                         // Check that records are arrays:
01234                 if (is_array($diff_1_record) && is_array($diff_2_record))       {
01235 
01236                                 // Load full table description and initialize diff-object:
01237                         t3lib_div::loadTCA($table);
01238                         $t3lib_diff_Obj = t3lib_div::makeInstance('t3lib_diff');
01239 
01240                                 // Add header row:
01241                         $tRows = array();
01242                         $tRows[] = '
01243                                 <tr class="bgColor5 tableheader">
01244                                         <td>' . $LANG->getLL('diffview_label_field_name') . '</td>
01245                                         <td width="98%" nowrap="nowrap">' . $LANG->getLL('diffview_label_colored_diff_view') . '</td>
01246                                 </tr>
01247                         ';
01248 
01249                                 // Initialize variables to pick up string lengths in:
01250                         $allStrLen = 0;
01251                         $diffStrLen = 0;
01252 
01253                                 // Traversing the first record and process all fields which are editable:
01254                         foreach($diff_1_record as $fN => $fV)   {
01255                                 if ($TCA[$table]['columns'][$fN] && $TCA[$table]['columns'][$fN]['config']['type']!='passthrough' && !t3lib_div::inList('t3ver_label',$fN))     {
01256 
01257                                                 // Check if it is files:
01258                                         $isFiles = FALSE;
01259                                         if (strcmp(trim($diff_1_record[$fN]),trim($diff_2_record[$fN])) &&
01260                                                         $TCA[$table]['columns'][$fN]['config']['type']=='group' &&
01261                                                         $TCA[$table]['columns'][$fN]['config']['internal_type']=='file')        {
01262 
01263                                                         // Initialize:
01264                                                 $uploadFolder = $TCA[$table]['columns'][$fN]['config']['uploadfolder'];
01265                                                 $files1 = array_flip(t3lib_div::trimExplode(',', $diff_1_record[$fN],1));
01266                                                 $files2 = array_flip(t3lib_div::trimExplode(',', $diff_2_record[$fN],1));
01267 
01268                                                         // Traverse filenames and read their md5 sum:
01269                                                 foreach($files1 as $filename => $tmp)   {
01270                                                         $files1[$filename] = @is_file(PATH_site.$uploadFolder.'/'.$filename) ? md5(t3lib_div::getUrl(PATH_site.$uploadFolder.'/'.$filename)) : $filename;
01271                                                 }
01272                                                 foreach($files2 as $filename => $tmp)   {
01273                                                         $files2[$filename] = @is_file(PATH_site.$uploadFolder.'/'.$filename) ? md5(t3lib_div::getUrl(PATH_site.$uploadFolder.'/'.$filename)) : $filename;
01274                                                 }
01275 
01276                                                         // Implode MD5 sums and set flag:
01277                                                 $diff_1_record[$fN] = implode(' ',$files1);
01278                                                 $diff_2_record[$fN] = implode(' ',$files2);
01279                                                 $isFiles = TRUE;
01280                                         }
01281 
01282                                                 // If there is a change of value:
01283                                         if (strcmp(trim($diff_1_record[$fN]),trim($diff_2_record[$fN])))        {
01284 
01285 
01286                                                         // Get the best visual presentation of the value and present that:
01287                                                 $val1 = t3lib_BEfunc::getProcessedValue($table,$fN,$diff_2_record[$fN],0,1);
01288                                                 $val2 = t3lib_BEfunc::getProcessedValue($table,$fN,$diff_1_record[$fN],0,1);
01289 
01290                                                         // Make diff result and record string lenghts:
01291                                                 $diffres = $t3lib_diff_Obj->makeDiffDisplay($val1,$val2,$isFiles?'div':'span');
01292                                                 $diffStrLen+= $t3lib_diff_Obj->differenceLgd;
01293                                                 $allStrLen+= strlen($val1.$val2);
01294 
01295                                                         // If the compared values were files, substituted MD5 hashes:
01296                                                 if ($isFiles)   {
01297                                                         $allFiles = array_merge($files1,$files2);
01298                                                         foreach($allFiles as $filename => $token)       {
01299                                                                 if (strlen($token)==32 && strstr($diffres,$token))      {
01300                                                                         $filename =
01301                                                                                 t3lib_BEfunc::thumbCode(array($fN=>$filename),$table,$fN,$this->doc->backPath).
01302                                                                                 $filename;
01303                                                                         $diffres = str_replace($token,$filename,$diffres);
01304                                                                 }
01305                                                         }
01306                                                 }
01307 
01308                                                         // Add table row with result:
01309                                                 $tRows[] = '
01310                                                         <tr class="bgColor4">
01311                                                                 <td>'.htmlspecialchars($GLOBALS['LANG']->sL(t3lib_BEfunc::getItemLabel($table,$fN))).'</td>
01312                                                                 <td width="98%">'.$diffres.'</td>
01313                                                         </tr>
01314                                                 ';
01315                                         } else {
01316                                                         // Add string lengths even if value matched - in this was the change percentage is not high if only a single field is changed:
01317                                                 $allStrLen+=strlen($diff_1_record[$fN].$diff_2_record[$fN]);
01318                                         }
01319                                 }
01320                         }
01321 
01322                                 // Calculate final change percentage:
01323                         $pctChange = $allStrLen ? ceil($diffStrLen*100/$allStrLen) : -1;
01324 
01325                                 // Create visual representation of result:
01326                         if (count($tRows)>1)    {
01327                                 $content.= '<table border="0" cellpadding="1" cellspacing="1" class="diffTable">'.implode('',$tRows).'</table>';
01328                         } else {
01329                                 $content.= '<span class="nobr">'.$this->doc->icons(1).$LANG->getLL('diffview_complete_match').'</span>';
01330                         }
01331                 } else $content.= $this->doc->icons(3).$LANG->getLL('diffview_cannot_find_records');
01332 
01333                         // Return value:
01334                 return array($content,$pctChange);
01335         }
01336 
01337 
01338 
01339 
01340 
01341 
01342 
01343 
01344 
01345 
01346 
01347 
01348         /********************************
01349          *
01350          * Module content: Workspace list
01351          *
01352          ********************************/
01353 
01359         function moduleContent_workspaceList()  {
01360                 // Original Kasper's TODO: Workspace listing
01361                 //
01362                 //      - LISTING: Shows list of available workspaces for user. Used can see title, description, publication time, freeze-state, db-mount, member users/groups etc. Current workspace is indicated.
01363                 //      - SWITCHING: Switching between available workspaces is done by a button shown for each in the list
01364                 //      - ADMIN: Administrator of a workspace can click an edit-button linking to a form where he can edit the workspace. Users and groups should be selected based on some filtering so he cannot select groups he is not a member off himself (or some other rule... like for permission display with blinded users/groups)
01365                 //      - CREATE: If allowed, the user can create a new workspace which brings up a form where he can enter basic data. This is saved by a local instance of tcemain with forced admin-rights (creation in pid=0!).
01366                 return $this->workspaceList_displayUserWorkspaceList();
01367         }
01368 
01374         function workspaceList_displayUserWorkspaceList()       {
01375                 global  $BACK_PATH, $LANG;
01376 
01377                         // table header
01378                 $content = $this->workspaceList_displayUserWorkspaceListHeader();
01379 
01380                         // get & walk workspace list generating content
01381                 $wkspList = $this->workspaceList_getUserWorkspaceList();
01382                 $rowNum = 1;
01383                 foreach ($wkspList as $wksp)    {
01384                         $currentWksp = ($GLOBALS['BE_USER']->workspace == $wksp['uid']);
01385 
01386                         // Each workspace data occupies two rows:
01387                         // (1) Folding + Icons + Title + Description
01388                         // (2) Information about workspace (initially hidden)
01389 
01390                         $cssClass = ($currentWksp ? 'bgColor3' : 'bgColor4');
01391                                 // Start first row
01392                         $content .= '<tr class="' . $cssClass . '">';
01393 
01394                                 // row #1, column #1: expand icon
01395                         $content .= '<td>' .
01396                                                 '<a href="javascript:expandCollapse(' . $rowNum . ')">' .
01397                                                 '<img ' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/ol/plusbullet.gif', 'width="18" height="16"') . ' id="wl_' . $rowNum . 'i" border="0" hspace="1" alt="' . $LANG->getLL('img_title_show_more') . '" />' .
01398                                                 '</a></td>';
01399 
01400                                 // row #1, column #2: icon panel
01401                         $content .= '<td nowrap="nowrap">';     // Mozilla Firefox will attempt wrap due to `width="1"` on topmost column
01402                         $content .= $this->workspaceList_displayIcons($currentWksp, $wksp);
01403                         $content .= '</td>';
01404 
01405                                 // row #1, column #3: current workspace indicator
01406                         $content .= '<td nowrap="nowrap" style="text-align: center">';  // Mozilla Firefox will attempt wrap due to `width="1"` on topmost column
01407                         $content .= (!$currentWksp ? '&nbsp;' : '<img ' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/icon_ok.gif', 'width="18" height="16"') . ' id="wl_' . $rowNum . 'i" border="0" hspace="1" alt="' . $LANG->getLL('img_title_current_workspace') . '" />');
01408                         $content .= '</td>';
01409 
01410                                 // row #1, column #4 and 5: title and description
01411                         $content .= '<td nowrap="nowrap">' . $wksp['title'] . '</td>' .
01412                                                 '<td>' . nl2br($wksp['description']) . '</td>';
01413                         $content .= '</tr>';
01414 
01415                                 // row #2, column #1 and #2
01416                         $content .= '<tr id="wl_' . $rowNum . '" class="bgColor" style="display: none">';
01417                         $content .= '<td colspan="2" style="border-right: none;">&nbsp;</td>';
01418 
01419                                 // row #2, column #3, #4 and #4
01420                         $content .= '<td colspan="3" style="border-left: none;">' .
01421                                                 $this->workspaceList_formatWorkspaceData($wksp) .
01422                                                 '</td>';
01423 
01424                         $content .= '</tr>';
01425                         $rowNum++;
01426                 }
01427                 $content .= '</table>';
01428 
01429                 $newWkspUrl = 'workspaceforms.php?action=new';
01430 
01431                         // workspace creation link
01432                 if ($GLOBALS['BE_USER']->isAdmin() || 0 != ($GLOBALS['BE_USER']->groupData['workspace_perms'] & 4))     {
01433                         $content .= '<br /><a href="' . $newWkspUrl . '">' .
01434                                                 '<img ' .
01435                                                 t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/new_el.gif', 'width="11" height="12"') .
01436                                                 ' alt="' . $LANG->getLL('img_title_create_new_workspace'). '" id="ver-wl-new-workspace-icon" />' .
01437                                                 $LANG->getLL('link_text_create_new_workspace') . '</a>';
01438                 }
01439                 return $content;
01440         }
01441 
01442 
01443 
01444 
01445 
01451         function workspaceList_getUserWorkspaceList()   {
01452                         // Get BE users if necessary
01453                 if (!is_array($this->be_user_Array))    {
01454                         $this->be_user_Array = t3lib_BEfunc::getUserNames();
01455                 }
01456                         // Get list of all workspaces. Note: system workspaces will be always displayed before custom ones!
01457                 $workspaces = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*','sys_workspace','pid=0'.t3lib_BEfunc::deleteClause('sys_workspace'),'','title');
01458                 $availableWorkspaces = array();
01459 
01460                         // Live
01461                 $wksp = $this->workspaceList_createFakeWorkspaceRecord(0);
01462                 $wksp = $GLOBALS['BE_USER']->checkWorkspace($wksp);
01463                 if (false !== $wksp) {
01464                         $availableWorkspaces[] = $wksp;
01465                 }
01466 
01467                         // Draft
01468                 $wksp = $this->workspaceList_createFakeWorkspaceRecord(-1);
01469                 $wksp = $GLOBALS['BE_USER']->checkWorkspace($wksp);
01470                 if (false !== $wksp) {
01471                         $availableWorkspaces[] = $wksp;
01472                 }
01473 
01474                         // Custom
01475                 foreach($workspaces as $rec)    {
01476                                 // see if user can access this workspace in any way
01477                         if (false !== ($result = $GLOBALS['BE_USER']->checkWorkspace($rec)))    {
01478                                 $availableWorkspaces[] = $result;       // `$result` contains `$rec` plus access type through '_ACCESS' key
01479                         }
01480                 }
01481                 return $availableWorkspaces;
01482         }
01483 
01493         function workspaceList_formatWorkspaceData(&$wksp)      {
01494                 global $LANG;
01495 
01496                 $content = '<table cellspacing="1" cellpadding="1" width="100%" class="ver-wl-details-table">' .
01497                                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_file_mountpoints') . '</b></td>' .
01498                                 '<td class="ver-wl-details">' . $this->workspaceList_getFileMountPoints($wksp) . '</td></tr>' .
01499                                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_db_mountpoints') . '</b></td>' .
01500                                 '<td class="ver-wl-details">' . $this->workspaceList_getWebMountPoints($wksp) . '</td></tr>';
01501                 if ($wksp['uid'] > 0) {
01502                         // Displaying information below makes sence only for custom workspaces
01503                         $content .=
01504                                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_frozen') . '</b></td>' .
01505                                 '<td class="ver-wl-details">' . $LANG->getLL($wksp['freeze'] ? 'workspace_list_label_frozen_yes' : 'workspace_list_label_frozen_no') . '</td></tr>' .
01506                                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_publish_date') . '</b></td>' .
01507                                 '<td class="ver-wl-details">' . ($wksp['publish_time'] == 0 ? '&nbsp;&ndash;' : t3lib_BEfunc::datetime($wksp['publish_time'])) . '</td></tr>' .
01508                                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_unpublish_date') . '</b></td>' .
01509                                 '<td class="ver-wl-details">' . ($wksp['unpublish_time'] == 0 ? '&nbsp;&ndash;' : t3lib_BEfunc::datetime($wksp['unpublish_time'])) . '</td></tr>' .
01510                                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_your_access') . '</b></td>' .
01511                                 '<td class="ver-wl-details">' . $LANG->getLL('workspace_list_access_' . $wksp['_ACCESS']) . '</td></tr>' .
01512                                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_workspace_users') . '</b></td>' .
01513                                 '<td class="ver-wl-details">' . $this->workspaceList_getUserList($wksp) . '</td></tr>';
01514                 }
01515                 else if ($GLOBALS['BE_USER']->isAdmin()) {
01516                         // show users for draft/live workspace only to admin users
01517                         $content .=     '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_workspace_users') . '</b></td>' .
01518                                 '<td class="ver-wl-details">' . $this->workspaceList_getUserList($wksp) . '</td></tr>';
01519                 }
01520                 $content .= '</table>';
01521 
01522                 return $content;
01523         }
01524 
01525 
01526 
01527 
01528 
01535         function workspaceList_getWebMountPoints(&$wksp)        {
01536                 if ($wksp['uid'] <= 0) {
01537                         // system workspaces
01538                         return $GLOBALS['LANG']->getLL($wksp['uid'] == 0 ? 'workspace_list_db_mount_point_live' : 'workspace_list_db_mount_point_draft');
01539                 }
01540 
01541                 // here only if obtaining mount points for custom workspaces
01542 
01543                 // Warning: all fields needed for t3lib_iconWorks::getIconImage()!
01544                 $MPs = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'pages', 'deleted=0 AND uid IN (' . $GLOBALS['TYPO3_DB']->cleanIntList($wksp['db_mountpoints']) . ')', '', 'title');
01545                 $content_array = array();
01546                 if (count($MPs) > 0)    {
01547                         $isAdmin = $GLOBALS['BE_USER']->isAdmin();
01548                         if (!$isAdmin) {
01549                                 // We need to fetch user's mount point list (including MPS mounted from groups).
01550                                 // This list must not be affects by current user's workspace. It means we cannot use
01551                                 // $BE_USER->isInWebMount() to check mount points.
01552                                 $userMPs = explode(',', $GLOBALS['BE_USER']->dataLists['webmount_list']); // includes group data if necessary!
01553                         }
01554                         foreach ($MPs as $mp)   {
01555                                 if (!$isAdmin && !in_array($mp['uid'], $userMPs)) {
01556                                         // Show warning icon
01557                                         $title = $GLOBALS['LANG']->getLL('workspace_list_mount_point_inaccessible');
01558                                         $str = '<img ' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/icon_warning.gif', 'width="18" height="16"') .
01559                                                         ' alt="' . $title . '" title="' . $title . '" align="absmiddle" />';
01560                                         $classAttr = 'class="ver-wl-mp-inacessible" ';
01561                                 }
01562                                 else {
01563                                         // normal icon
01564                                         $str = t3lib_iconWorks::getIconImage('pages', $mp, $GLOBALS['BACK_PATH'], ' align="absmiddle"');
01565                                         $classAttr = '';
01566                                 }
01567                                 // Will show UID on hover. Just convinient to user.
01568                                 $content_array[] = $str . '<span ' . $classAttr . 'title="UID: ' . $mp['uid'] . '">' . $mp['title'] . '</span>';
01569                         }
01570                 }
01571                 if (count($content_array) > 0) {
01572                         return implode('<br />', $content_array);
01573                 }
01574                 // no mount points
01575                 return $GLOBALS['LANG']->getLL('workspace_list_db_mount_point_custom');
01576         }
01577 
01584         function workspaceList_getFileMountPoints(&$wksp)       {
01585                 if ($wksp['uid'] == -1) {
01586                         // draft workspace - none!
01587                         return $GLOBALS['LANG']->getLL('workspace_list_file_mount_point_draft');
01588                 }
01589                 else if ($wksp['uid'] == 0) {
01590                         // live workspace
01591                         return $GLOBALS['LANG']->getLL('workspace_list_file_mount_point_live');
01592                 }
01593 
01594                 // Here if displaying information for custom workspace
01595 
01596                 // Warning: all fields needed for t3lib_iconWorks::getIconImage()!
01597                 $MPs = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_filemounts', 'deleted=0 AND hidden=0 AND uid IN (' . $GLOBALS['TYPO3_DB']->cleanIntList($wksp['file_mountpoints']) . ')', '', 'title');
01598                 if (count($MPs) != 0)   {
01599                         // Has mount points
01600                         $isAdmin = $GLOBALS['BE_USER']->isAdmin();
01601                         if (!$isAdmin) {
01602                                 // We need to fetch user's mount point list (including MPS mounted from groups).
01603                                 // This list must not be affects by current user's workspace. It means we cannot use
01604                                 // $BE_USER->isInWebMount() to check mount points.
01605                                 $userMPs = explode(',', $GLOBALS['BE_USER']->dataLists['filemount_list']); // includes group data if necessary!
01606                         }
01607                         foreach ($MPs as $mp)   {
01608                                 if (!$isAdmin && !in_array($mp['uid'], $userMPs)) {
01609                                         // Show warning icon
01610                                         $title = $GLOBALS['LANG']->getLL('workspace_list_mount_point_inaccessible');
01611                                         $str = '<img ' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/icon_warning.gif', 'width="18" height="16"') .
01612                                                         ' alt="' . $title . '" title="' . $title . '" align="absmiddle" />';
01613                                         $classAttr = 'class="ver-wl-mp-inacessible" ';
01614                                 }
01615                                 else {
01616                                         // normal icon
01617                                         $str = t3lib_iconWorks::getIconImage('sys_filemounts', $mp, $GLOBALS['BACK_PATH'], ' align="absmiddle"');
01618                                         $classAttr = '';
01619                                 }
01620                                 // Will show UID on hover. Just convinient to user.
01621                                 $content_array[] = $str . '<span ' . $classAttr . 'title="UID: ' . $mp['uid'] . '">' . $mp['title'] . '</span>';
01622                         }
01623                 }
01624                 if (count($content_array) > 0) {
01625                         return implode('<br />', $content_array);
01626                 }
01627                 // No file mount points
01628                 return $GLOBALS['LANG']->getLL('workspace_list_file_mount_point_custom');
01629         }
01630 
01637         function workspaceList_displayUserWorkspaceListHeader() {
01638                 global  $LANG;
01639                 // TODO CSH lables?
01640                 return '<table border="0" cellpadding="0" cellspacing="1" class="lrPadding workspace-overview ver-wl-table">
01641                         <tr class="bgColor5 tableheader">
01642                                 <td width="1">&nbsp;</td>
01643                                 <td width="1">&nbsp;</td>
01644                                 <td nowrap="nowrap">' . $LANG->getLL('workspace_list_label_current_workspace') . '</td>
01645                                 <td nowrap="nowrap">' . $LANG->getLL('workspace_list_label_workspace_title') . '</td>
01646                                 <td nowrap="nowrap">' . $LANG->getLL('workspace_list_label_workspace_description') . '</td>
01647                         </tr>';
01648         }
01649 
01650 
01657         function workspaceList_getUserList(&$wksp) {
01658                 global  $LANG;
01659 
01660                 if ($wksp['uid'] > 0) {
01661                         // custom workspaces
01662                         $content = $this->workspaceList_getUserListWithAccess($wksp['adminusers'], $LANG->getLL('workspace_list_label_owners')); // owners
01663                         $content .= $this->workspaceList_getUserListWithAccess($wksp['members'], $LANG->getLL('workspace_list_label_members')); // members
01664                         $content .= $this->workspaceList_getUserListWithAccess($wksp['reviewers'], $LANG->getLL('workspace_list_label_reviewers')); // reviewers
01665                         if ($content != '')     {
01666                                 $content = '<table cellpadding="0" cellspacing="1" width="100%" class="lrPadding workspace-overview">' . $content . '</table>';
01667                         } else {
01668                                 $content = $LANG->getLL($wksp['uid'] > 0 ? 'workspace_list_access_admins_only' : 'workspace_list_access_anyone');
01669                         }
01670                 }
01671                 else {
01672                         // live and draft workspace
01673                         $content = $this->workspaceList_getUserListForSysWorkspace($wksp);
01674                 }
01675                 return $content;
01676         }
01677 
01684         function workspaceList_getUserListForSysWorkspace(&$wksp) {
01685                 $option = ($wksp['uid'] == 0 ? 1 : 2);
01686                 $content_array = array();
01687                 foreach ($this->be_user_Array_full as $uid => $user) {
01688                         if ($user['admin'] != 0 || 0 != ($user['workspace_perms'] & $option)) {
01689                                 if ($uid == $GLOBALS['BE_USER']->user['uid']) {
01690                                         // highlight current user
01691                                         $tag0 = '<span class="ver-wl-current-user">';
01692                                         $tag1 = '</span>';
01693                                 }
01694                                 else {
01695                                         $tag0 = $tag1 = '';
01696                                 }
01697                                 $content_array[] = $this->doc->wrapClickMenuOnIcon(t3lib_iconWorks::getIconImage('be_users', $uid, $GLOBALS['BACK_PATH'], ' align="middle" alt="UID: ' . $uid . '"'), 'be_users', $uid, 2).
01698                                         $tag0 . $user['username'] . $tag1;
01699                         }
01700                 }
01701                 return implode('<br />', $content_array);
01702         }
01703 
01711         function workspaceList_getUserListWithAccess(&$list, $access)   {
01712                 $content_array = array();
01713                 if ($list != '')        {
01714                         $userIDs = explode(',', $list);
01715 
01716                                 // get user names and sort
01717                         $regExp = '/^(be_[^_]+)_(\d+)$/';
01718                         $groups = false;
01719                         foreach ($userIDs as $userUID)  {
01720                                 $id = $userUID;
01721 
01722                                 if (preg_match($regExp, $userUID)) {
01723                                         $table = preg_replace($regExp, '\1', $userUID);
01724                                         $id = intval(preg_replace($regExp, '\2', $userUID));
01725                                         if ($table == 'be_users') {
01726                                                 // user
01727                                                 $icon = $GLOBALS['TCA']['be_users']['typeicons'][$this->be_user_Array[$id]['admin']];
01728                                                 if ($id == $GLOBALS['BE_USER']->user['uid']) {
01729                                                         // highlight current user
01730                                                         $tag0 = '<span class="ver-wl-current-user">';
01731                                                         $tag1 = '</span>';
01732                                                 }
01733                                                 else {
01734                                                         $tag0 = $tag1 = '';
01735                                                 }
01736                                                 $content_array[] = $this->doc->wrapClickMenuOnIcon(t3lib_iconWorks::getIconImage($table, $this->be_user_Array[$id], $GLOBALS['BACK_PATH'], ' align="middle" alt="UID: ' . $id . '"'), $table, $id, 2) .
01737                                                                                         $tag0 . $this->be_user_Array_full[$id]['username'] . $tag1;
01738                                         }
01739                                         else {
01740                                                 // group
01741                                                 if (false === $groups) {
01742                                                         $groups = t3lib_BEfunc::getGroupNames();
01743                                                 }
01744                                                 $content_array[] = $this->doc->wrapClickMenuOnIcon(t3lib_iconWorks::getIconImage($table, $groups[$id], $GLOBALS['BACK_PATH'], ' align="middle" alt="UID: ' . $id . '"'), $table, $id, 2) .
01745                                                                                         $groups[$id]['title'];
01746                                         }
01747                                 }
01748                                 else {
01749                                         // user id
01750                                         if ($userUID == $GLOBALS['BE_USER']->user['uid']) {
01751                                                 // highlight current user
01752                                                 $tag0 = '<span class="ver-wl-current-user">';
01753                                                 $tag1 = '</span>';
01754                                         }
01755                                         else {
01756                                                 $tag0 = $tag1 = '';
01757                                         }
01758                                         $content_array[] = t3lib_iconWorks::getIconImage('be_users', $this->be_user_Array[$id], $GLOBALS['BACK_PATH'], ' align="middle" alt="UID: ' . $id . '"') .
01759                                                                                 $tag0 . $this->be_user_Array_full[$userUID]['username'] . $tag1;
01760                                 }
01761                         }
01762                         sort($content_array);
01763                 }
01764                 else {
01765                         $content_array[] = '&nbsp;&ndash;';
01766                 }
01767 
01768                 $content = '<tr><td class="ver-wl-details-label ver-wl-details-user-list-label">';
01769                 // TODO CSH lable explaining access here?
01770                 $content .= '<b>' . $access . '</b></td>';
01771                 $content .= '<td class="ver-wl-details">' . implode('<br />', $content_array) . '</td></tr>';
01772                 return $content;
01773         }
01774 
01775 
01776 
01784         function workspaceList_displayIcons($currentWorkspace, &$wksp)  {
01785                 global  $BACK_PATH, $LANG;
01786 
01787                 $content = '';
01788                         // `edit workspace` button
01789                 if ($this->workspaceList_hasEditAccess($wksp))  {
01790                                 // User can modify workspace parameters, display corresponding link and icon
01791                         $editUrl = 'workspaceforms.php?action=edit&amp;wkspId=' . $wksp['uid'];
01792 
01793                         $content .= '<a href="' . $editUrl . '" />' .
01794                                         '<img ' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/edit2.gif', 'width="11" height="12"') . ' border="0" alt="' . $LANG->getLL('workspace_list_icon_title_edit_workspace') . '" align="middle" hspace="1" />' .
01795                                         '</a>';
01796                 } else {
01797                                 // User can NOT modify workspace parameters, display space
01798                                 // Get only withdth and height from skinning API
01799                         $content .= '<img src="clear.gif" ' .
01800                                         t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/edit2.gif', 'width="11" height="12"', 2) .
01801                                         ' border="0" alt="" hspace="1" align="middle" />';
01802                 }
01803                         // `switch workspace` button
01804                 if (!$currentWorkspace) {
01805                                 // Workspace switching button
01806                         $content .= '<a href="' .
01807                                         t3lib_div::getIndpEnv('SCRIPT_NAME') .
01808                                         '?changeWorkspace=' . $wksp['uid'] . '"/>' .
01809                                         '<img ' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/switch.gif', 'width="11" height="10"') . ' border="0" alt="' . $LANG->getLL('workspace_list_icon_title_switch_workspace') . '" align="middle" hspace="1" />' .
01810                                         '</a>';
01811                 } else {
01812                                 // Current workspace: empty space instead of workspace switching button
01813                                 //
01814                                 // Here get only width and height from skinning API
01815                         $content .= '<img src="clear.gif" ' .
01816                                         t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/switch.png', 'width="18" height="16"', 2) .
01817                                         ' border="0" alt="" hspace="1" align="middle" alt="" />';
01818                 }
01819                 return $content;
01820         }
01821 
01832         function workspaceList_hasEditAccess(&$wksp)    {
01833                 $access = &$wksp['_ACCESS'];
01834                 return ($wksp['uid'] > 0 && ($access == 'admin' || $access == 'owner'));
01835         }
01836 
01844         function workspaceList_createFakeWorkspaceRecord($uid)  {
01845                 global  $BE_USER, $LANG;
01846 
01847                 $record = array(
01848                         'uid' => $uid,
01849                         'pid' => 0,                             // always 0!
01850                         'tstamp' => 0,                  // does not really matter
01851                         'deleted' => 0,
01852                         'title' => ($uid == 0 ? '['.$LANG->getLL('shortcut_onlineWS').']' : '['.$LANG->getLL('shortcut_offlineWS').']'),
01853                         'description' => ($uid == 0 ? $LANG->getLL('shortcut_onlineWS') : $LANG->getLL('shortcut_offlineWS')),  
01854                         'adminusers' => '',
01855                         'members' => '',
01856                         'reviewers' => '',
01857                         'db_mountpoints' => '',         // TODO get mount points from user profile
01858                         'file_mountpoints' => '',       // TODO get mount points from user profile for live workspace only (uid == 0)
01859                         'publish_time' => 0,
01860                         'unpublish_time' => 0,
01861                         'freeze' => 0,
01862                         'live_edit' => ($uid == 0),
01863                         'vtypes' => 0,
01864                         'disable_autocreate' => 0,
01865                         'swap_modes' => 0,
01866                         'publish_access' => 0,
01867                         'stagechg_notification' => 0
01868                 );
01869                 return $record;
01870         }
01871 
01872 
01873 
01874 
01875 
01876 
01877 
01878 
01879 
01880 
01881 
01882 
01883 
01884 
01885 
01886 
01887 
01888 
01889 
01890 
01891 
01892 
01893 
01894 
01895         /**************************************
01896          *
01897          * Helper functions
01898          *
01899          *************************************/
01900 
01907         function formatVerId($verId)    {
01908                 return '1.'.$verId;
01909         }
01910 
01917         function formatWorkspace($wsid) {
01918 
01919                         // Render, if not cached:
01920                 if (!isset($this->formatWorkspace_cache[$wsid]))        {
01921                         switch($wsid)   {
01922                                 case -1:
01923                                         $this->formatWorkspace_cache[$wsid] = '[Draft]';
01924                                 break;
01925                                 case 0:
01926                                         $this->formatWorkspace_cache[$wsid] = '';       // Does not output anything for ONLINE because it might confuse people to think that the elemnet IS online which is not the case - only that it exists as an offline version in the online workspace...
01927                                 break;
01928                                 default:
01929                                         list($titleRec) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('title','sys_workspace','uid='.intval($wsid).t3lib_BEfunc::deleteClause('sys_workspace'));
01930                                         $this->formatWorkspace_cache[$wsid] = '['.$wsid.'] '.$titleRec['title'];
01931                                 break;
01932                         }
01933                 }
01934 
01935                 return $this->formatWorkspace_cache[$wsid];
01936         }
01937 
01944         function formatCount($count)    {
01945                 global  $LANG;
01946 
01947                         // Render, if not cached:
01948                 if (!isset($this->formatCount_cache[$count]))   {
01949                         switch($count)  {
01950                                 case 0:
01951                                         $this->formatCount_cache[$count] = $LANG->getLL('workspace_list_publishing_count_draft');
01952                                 break;
01953                                 case 1:
01954                                         $this->formatCount_cache[$count] = $LANG->getLL('workspace_list_publishing_count_archive');
01955                                 break;
01956                                 default:
01957                                         $this->formatCount_cache[$count] = sprintf($LANG->getLL('workspace_list_publishing_count'), $count);
01958                                 break;
01959                         }
01960                 }
01961 
01962                 return $this->formatCount_cache[$count];
01963         }
01964 
01972         function versionsInOtherWS($table,$uid) {
01973 
01974                         // Check for duplicates:
01975                         // Select all versions of record NOT in this workspace:
01976                 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01977                         't3ver_wsid',
01978                         $table,
01979                         'pid=-1
01980                                 AND t3ver_oid='.intval($uid).'
01981                                 AND t3ver_wsid!='.intval($GLOBALS['BE_USER']->workspace).'
01982                                 AND (t3ver_wsid=-1 OR t3ver_wsid>0)'.
01983                                 t3lib_BEfunc::deleteClause($table),
01984                         '',
01985                         't3ver_wsid',
01986                         '',
01987                         't3ver_wsid'
01988                 );
01989                 if (count($rows))       {
01990                         return implode(',',array_keys($rows));
01991                 }
01992         }
01993 
02002         function showStageChangeLog($table,$id,$stageCommands)  {
02003                 global  $LANG;
02004 
02005                 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
02006                         'log_data,tstamp,userid',
02007                         'sys_log',
02008                         'action=6 and details_nr=30
02009                                 AND tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_log').'
02010                                 AND recuid='.intval($id)
02011                 );
02012 
02013                 $entry = array();
02014                 foreach($rows as $dat)  {
02015                         $data = unserialize($dat['log_data']);
02016                         $username = $this->be_user_Array[$dat['userid']] ? $this->be_user_Array[$dat['userid']]['username'] : '['.$dat['userid'].']';
02017 
02018                         switch($data['stage'])  {
02019                                 case 1:
02020                                         $text = $LANG->getLL('stage_sent_to_review');
02021                                 break;
02022                                 case 10:
02023                                         $text = $LANG->getLL('stage_approved_for_publish');
02024                                 break;
02025                                 case -1:
02026                                         $text = $LANG->getLL('stage_rejected');
02027                                 break;
02028                                 case 0:
02029                                         $text = $LANG->getLL('stage_reset_to_editing');
02030                                 break;
02031                                 default:
02032                                         $text = $LANG->getLL('stage_undefined');
02033                                 break;
02034                         }
02035                         $text = t3lib_BEfunc::datetime($dat['tstamp']).': ' . sprintf($text, $username);
02036                         $text.= ($data['comment']?'<br/>' . $LANG->getLL('stage_label_user_comment'). ' <em>'.$data['comment'].'</em>':'');
02037 
02038                         $entry[] = $text;
02039                 }
02040 
02041                 return count($entry) ? '<span onmouseover="document.getElementById(\'log_'.$table.$id.'\').style.visibility = \'visible\';" onmouseout="document.getElementById(\'log_'.$table.$id.'\').style.visibility = \'hidden\';">'.$stageCommands.' ('.count($entry).')</span>'.
02042                                 '<div class="logLayer" style="visibility: hidden; position: absolute;" id="log_'.$table.$id.'">'.implode('<hr/>',$entry).'</div>' : $stageCommands;
02043         }
02044 
02045 
02046 
02047 
02048 
02049 
02050 
02051 }
02052 
02053 // Include extension?
02054 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/user/ws/index.php'])     {
02055         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/user/ws/index.php']);
02056 }
02057 
02058 
02059 
02060 
02061 
02062 
02063 
02064 
02065 
02066 // Make instance:
02067 $SOBE = t3lib_div::makeInstance('SC_mod_user_ws_index');
02068 $SOBE->init();
02069 $SOBE->main();
02070 $SOBE->printContent();
02071 ?>


Généré par TYPO3 Ameos avec  doxygen 1.4.6