index.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2008 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 ***************************************************************/
00027 /**
00028  * Module: Workspace manager
00029  *
00030  * $Id: index.php 4433 2008-11-07 04:13:12Z flyguide $
00031  *
00032  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00033  * @author  Dmitry Dulepov <typo3@accio.lv>
00034  */
00035 /**
00036  * [CLASS/FUNCTION INDEX of SCRIPT]
00037  *
00038  *
00039  *
00040  *  101: class SC_mod_user_ws_index extends t3lib_SCbase
00041  *
00042  *              SECTION: Standard module initialization
00043  *  128:     function menuConfig()
00044  *  175:     function init()
00045  *  233:     function main()
00046  *  280:     function printContent()
00047  *
00048  *              SECTION: Module content: Publish
00049  *  310:     function moduleContent_publish()
00050  *  411:     function displayVersionDetails($details)
00051  *  420:     function displayWorkspaceOverview()
00052  *
00053  *              SECTION: Module content: Workspace list
00054  *  461:     function moduleContent_workspaceList()
00055  *  476:     function workspaceList_displayUserWorkspaceList()
00056  *  553:     function workspaceList_getUserWorkspaceList()
00057  *  592:     function workspaceList_formatWorkspaceData(&$wksp)
00058  *  634:     function workspaceList_getWebMountPoints(&$wksp)
00059  *  683:     function workspaceList_getFileMountPoints(&$wksp)
00060  *  736:     function workspaceList_displayUserWorkspaceListHeader()
00061  *  756:     function workspaceList_getUserList(&$wksp)
00062  *  783:     function workspaceList_getUserListForSysWorkspace(&$wksp)
00063  *  810:     function workspaceList_getUserListWithAccess(&$list, $access)
00064  *  883:     function workspaceList_displayIcons($currentWorkspace, &$wksp)
00065  *  931:     function workspaceList_hasEditAccess(&$wksp)
00066  *  943:     function workspaceList_createFakeWorkspaceRecord($uid)
00067  *
00068  * TOTAL FUNCTIONS: 20
00069  * (This index is automatically created/updated by the extension "extdeveval")
00070  *
00071  */
00072 
00073     // Initialize module:
00074 unset($MCONF);
00075 require ('conf.php');
00076 require ($BACK_PATH.'init.php');
00077 require ($BACK_PATH.'template.php');
00078 $BE_USER->modAccess($MCONF,1);
00079 
00080     // Include libraries of various kinds used inside:
00081 $LANG->includeLLFile('EXT:lang/locallang_mod_user_ws.xml');
00082 $LANG->includeLLFile('EXT:lang/locallang_misc.xml');
00083 require_once(PATH_t3lib.'class.t3lib_scbase.php');
00084 require_once(PATH_typo3.'mod/user/ws/class.wslib.php');
00085 require_once(PATH_typo3.'mod/user/ws/class.wslib_gui.php');
00086 require_once(PATH_t3lib.'class.t3lib_diff.php');
00087 require_once(PATH_t3lib.'class.t3lib_pagetree.php');
00088 require_once(PATH_t3lib.'class.t3lib_tcemain.php');
00089 
00090 
00091 
00092 
00093 /**
00094  * Module: Workspace manager
00095  *
00096  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00097  * @package TYPO3
00098  * @subpackage core
00099  */
00100 class SC_mod_user_ws_index extends t3lib_SCbase {
00101 
00102         // Default variables for backend modules
00103     var $MCONF = array();               // Module configuration
00104     var $MOD_MENU = array();            // Module menu items
00105     var $MOD_SETTINGS = array();        // Module session settings
00106 
00107     /**
00108      * Document Template Object
00109      *
00110      * @var noDoc
00111      */
00112     var $doc;
00113     var $content;                       // Accumulated content
00114 
00115 
00116         // Internal:
00117     var $publishAccess = FALSE;
00118     var $be_user_Array = array();
00119     var $be_user_Array_full = array();  // not blinded, used by workspace listing
00120 
00121 
00122     /*********************************
00123      *
00124      * Standard module initialization
00125      *
00126      *********************************/
00127 
00128     /**
00129      * Initialize menu configuration
00130      *
00131      * @return  void
00132      */
00133     function menuConfig()   {
00134         global  $LANG;
00135 
00136             // Menu items:
00137         $this->MOD_MENU = array(
00138             'function' => array(
00139                 'publish' => $LANG->getLL('menuitem_review'),
00140                 'workspaces' => $LANG->getLL('menuitem_workspaces'),
00141             ),
00142             'filter' => array(
00143                 1 => $LANG->getLL('filter_drafts'),
00144                 2 => $LANG->getLL('filter_archive'),
00145                 0 => $LANG->getLL('filter_all'),
00146             ),
00147             'display' => array(
00148                 0 => '['.$LANG->getLL('shortcut_onlineWS').']',
00149                 -98 => $LANG->getLL('label_offlineWSes'),
00150                 -99 => $LANG->getLL('label_allWSes'),
00151                 -1 => '['.$LANG->getLL('shortcut_offlineWS').']'
00152             ),
00153             'diff' => array(
00154                 0 => $LANG->getLL('diff_no_diff'),
00155                 1 => $LANG->getLL('diff_show_inline'),
00156                 2 => $LANG->getLL('diff_show_popup'),
00157             ),
00158             'expandSubElements' => '',
00159         );
00160 
00161             // Add workspaces:
00162         if ($GLOBALS['BE_USER']->workspace===0) {   // Spend time on this only in online workspace because it might take time:
00163             $workspaces = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,title,adminusers,members,reviewers','sys_workspace','pid=0'.t3lib_BEfunc::deleteClause('sys_workspace'),'','title');
00164             foreach($workspaces as $rec)    {
00165                 if ($GLOBALS['BE_USER']->checkWorkspace($rec))  {
00166                     $this->MOD_MENU['display'][$rec['uid']] = '['.$rec['uid'].'] '.$rec['title'];
00167                 }
00168             }
00169         }
00170 
00171             // CLEANSE SETTINGS
00172         $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name'], 'ses');
00173     }
00174 
00175     /**
00176      * Executes action for selected elements, if any is sent:
00177      */
00178     function execute()  {
00179         $post = t3lib_div::_POST();
00180 
00181 #       debug($post);
00182 
00183         if ($post['_with_selected_do']) {
00184             if (is_array($post['items']) && count($post['items']))  {
00185                 $cmdArray = array();
00186 
00187                 foreach($post['items'] as $item => $v)  {
00188                     list($table,$uid) = explode(':',$item,2);
00189 
00190                     if ($GLOBALS['TCA'][$table] && t3lib_div::testInt($uid))    {
00191                         switch($post['_with_selected_do'])  {
00192                             case "stage_-1":
00193                                 $cmdArray[$table][$uid]['version']['action'] = 'setStage';
00194                                 $cmdArray[$table][$uid]['version']['stageId'] = -1;
00195                             break;
00196                             case "stage_0":
00197                                 $cmdArray[$table][$uid]['version']['action'] = 'setStage';
00198                                 $cmdArray[$table][$uid]['version']['stageId'] = 0;
00199                             break;
00200                             case "stage_1":
00201                                 $cmdArray[$table][$uid]['version']['action'] = 'setStage';
00202                                 $cmdArray[$table][$uid]['version']['stageId'] = 1;
00203                             break;
00204                             case "stage_10":
00205                                 $cmdArray[$table][$uid]['version']['action'] = 'setStage';
00206                                 $cmdArray[$table][$uid]['version']['stageId'] = 10;
00207                             break;
00208                             case "publish":
00209                                 if ($onlineRec = t3lib_BEfunc::getLiveVersionOfRecord($table,$uid,'uid'))   {
00210                                     $cmdArray[$table][$onlineRec['uid']]['version']['action'] = 'swap';
00211                                     $cmdArray[$table][$onlineRec['uid']]['version']['swapWith'] = $uid;
00212                                 }
00213                             break;
00214                             case "swap":
00215                             if ($onlineRec = t3lib_BEfunc::getLiveVersionOfRecord($table,$uid,'uid'))   {
00216                                 $cmdArray[$table][$onlineRec['uid']]['version']['action'] = 'swap';
00217                                 $cmdArray[$table][$onlineRec['uid']]['version']['swapWith'] = $uid;
00218                                 $cmdArray[$table][$onlineRec['uid']]['version']['swapIntoWS'] = 1;
00219                             }
00220                             break;
00221                             case "release":
00222                                 $cmdArray[$table][$uid]['version']['action'] = 'clearWSID';
00223                             break;
00224                             case "flush":
00225                                 $cmdArray[$table][$uid]['version']['action'] = 'flush';
00226                             break;
00227                         }
00228                     }
00229                 }
00230 
00231         #       debug($cmdArray);
00232 
00233                 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
00234                 $tce->stripslashes_values = 0;
00235                 $tce->start(array(), $cmdArray);
00236                 $tce->process_cmdmap();
00237             }
00238         }
00239     }
00240 
00241     /**
00242      * Standard init function of a module.
00243      *
00244      * @return  void
00245      */
00246     function init() {
00247         global $BACK_PATH, $BE_USER;
00248 
00249             // Setting module configuration:
00250         $this->MCONF = $GLOBALS['MCONF'];
00251 
00252             // Initialize Document Template object:
00253         $this->doc = t3lib_div::makeInstance('template');
00254         $this->doc->backPath = $BACK_PATH;
00255         $this->doc->setModuleTemplate('templates/ws.html');
00256 
00257             // JavaScript
00258         $plusIcon = t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/ol/plusbullet.gif', 'width="18" height="16"', 1);
00259         $minusIcon = t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/ol/minusbullet.gif', 'width="18" height="16"', 1);
00260         $this->doc->JScode = $this->doc->wrapScriptTags('
00261             script_ended = 0;
00262             function jumpToUrl(URL) {   //
00263                 window.location.href = URL;
00264             }
00265 
00266             function expandCollapse(rowNumber)  {   //
00267                 elementId = \'wl_\' + rowNumber;
00268                 element = document.getElementById(elementId);
00269                 image = document.getElementById(elementId + \'i\');
00270                 if (element.style)  {
00271                     if (element.style.display == \'none\')  {
00272                         element.style.display = \'\';
00273                         image.src = \'' . $minusIcon . '\';
00274                     } else {
00275                         element.style.display = \'none\';
00276                         image.src = \'' . $plusIcon . '\';
00277                     }
00278                 }
00279             }
00280         ');
00281         $this->doc->form = '<form action="index.php" method="post" name="pageform">';
00282 
00283             // Setting up the context sensitive menu:
00284         $this->doc->getContextMenuCode();
00285 
00286             // Add JS for dynamic tabs:
00287         $this->doc->JScode.= $this->doc->getDynTabMenuJScode();
00288 
00289             // Setting publish access permission for workspace:
00290         $this->publishAccess = $BE_USER->workspacePublishAccess($BE_USER->workspace);
00291 
00292             // Parent initialization:
00293         parent::init();
00294     }
00295 
00296     /**
00297      * Main function for Workspace Manager module.
00298      *
00299      * @return  void
00300      */
00301     function main() {
00302         global $LANG, $BE_USER, $BACK_PATH;
00303 
00304         // See if we need to switch workspace
00305         $changeWorkspace = t3lib_div::_GET('changeWorkspace');
00306         if ($changeWorkspace != '') {
00307             $BE_USER->setWorkspace($changeWorkspace);
00308             $this->content .= $this->doc->wrapScriptTags('top.location.href="' . $BACK_PATH . t3lib_BEfunc::getBackendScript() . '";');
00309         } else {
00310                 // Starting page:
00311             $this->content.=$this->doc->header($LANG->getLL('title'));
00312             $this->content.=$this->doc->spacer(5);
00313 
00314             // Get usernames and groupnames
00315             $be_group_Array = t3lib_BEfunc::getListGroupNames('title,uid');
00316             $groupArray = array_keys($be_group_Array);
00317             // Need 'admin' field for t3lib_iconWorks::getIconImage()
00318             $this->be_user_Array_full = $this->be_user_Array = t3lib_BEfunc::getUserNames('username,usergroup,usergroup_cached_list,uid,admin,workspace_perms');
00319             if (!$GLOBALS['BE_USER']->isAdmin()) {
00320                 $this->be_user_Array = t3lib_BEfunc::blindUserNames($this->be_user_Array,$groupArray,1);
00321             }
00322 
00323             // Build top menu:
00324             $menuItems = array();
00325             $menuItems[] = array(
00326                 'label' => $LANG->getLL('menuitem_review'),
00327                 'content' => $this->moduleContent_publish()
00328             );
00329             $menuItems[] = array(
00330                 'label' => $LANG->getLL('menuitem_workspaces'),
00331                 'content' => $this->moduleContent_workspaceList()
00332             );
00333 
00334                 // Add hidden fields and create tabs:
00335             $content = $this->doc->getDynTabMenu($menuItems,'user_ws');
00336             $this->content.=$this->doc->section('',$content,0,1);
00337 
00338                 // Setting up the buttons and markers for docheader
00339             $docHeaderButtons = $this->getButtons();
00340             // $markers['CSH'] = $docHeaderButtons['csh'];
00341 
00342         }
00343         $markers['CONTENT'] = $this->content;
00344 
00345             // Build the <body> for the module
00346         $this->content = $this->doc->startPage($LANG->getLL('title'));
00347         $this->content.= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
00348         $this->content.= $this->doc->endPage();
00349         $this->content = $this->doc->insertStylesAndJS($this->content);
00350 
00351     }
00352 
00353     /**
00354      * Print module content. Called as last thing in the global scope.
00355      *
00356      * @return  void
00357      */
00358     function printContent() {
00359         echo $this->content;
00360     }
00361 
00362     /**
00363      * Create the panel of buttons for submitting the form or otherwise perform operations.
00364      *
00365      * @return  array   all available buttons as an assoc. array
00366      */
00367     protected function getButtons() {
00368         global $LANG, $BACK_PATH;
00369 
00370         $buttons = array(
00371             'new_record' => '',
00372         );
00373 
00374         $newWkspUrl = 'workspaceforms.php?action=new';
00375 
00376             // workspace creation link
00377         if ($GLOBALS['BE_USER']->isAdmin() || 0 != ($GLOBALS['BE_USER']->groupData['workspace_perms'] & 4)) {
00378             $buttons['new_record'] = '<a href="' . $newWkspUrl . '">' .
00379                         '<img ' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/new_el.gif') . ' alt="' . $LANG->getLL('img_title_create_new_workspace') . '" id="ver-wl-new-workspace-icon" />' .
00380                         '</a>';
00381         }
00382         return $buttons;
00383     }
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395     /*********************************
00396      *
00397      * Module content: Publish
00398      *
00399      *********************************/
00400 
00401     /**
00402      * Rendering the content for the publish and review panel in the workspace manager
00403      *
00404      * @return  string      HTML content
00405      */
00406     function moduleContent_publish()    {
00407         global  $LANG;
00408 
00409             // Initialize:
00410         $content = '';
00411         $details = t3lib_div::_GP('details');
00412 
00413             // Create additional menus:
00414         $menu = '';
00415         if ($GLOBALS['BE_USER']->workspace===0) {
00416             $menu.= t3lib_BEfunc::getFuncMenu(0,'SET[filter]',$this->MOD_SETTINGS['filter'],$this->MOD_MENU['filter']);
00417             $menu.= t3lib_BEfunc::getFuncMenu(0,'SET[display]',$this->MOD_SETTINGS['display'],$this->MOD_MENU['display']);
00418         }
00419         $menu.= t3lib_BEfunc::getFuncMenu(0,'SET[diff]',$this->MOD_SETTINGS['diff'],$this->MOD_MENU['diff']);
00420         if ($GLOBALS['BE_USER']->workspace!==0) {
00421             $menu.= t3lib_BEfunc::getFuncCheck(0,'SET[expandSubElements]',$this->MOD_SETTINGS['expandSubElements'],'','','id="checkExpandSubElements"').' <label for="checkExpandSubElements">'.$LANG->getLL('label_showsubelements').'</label> ';
00422         }
00423 
00424             // Create header:
00425         $title = '';
00426         $description = '';
00427         switch($GLOBALS['BE_USER']->workspace)  {
00428             case 0:
00429                 $title = t3lib_iconWorks::getIconImage('sys_workspace', array(), $this->doc->backPath, ' align="top"').'['.$LANG->getLL('shortcut_onlineWS').']';
00430                 $description = $LANG->getLL('workspace_description_live');
00431             break;
00432             case -1:
00433                 $title = t3lib_iconWorks::getIconImage('sys_workspace', array(), $this->doc->backPath, ' align="top"').'['.$LANG->getLL('shortcut_offlineWS').']';
00434                 $description = $LANG->getLL('workspace_description_draft');
00435             break;
00436             case -99:
00437                 $title = $this->doc->icons(3).'[' . $LANG->getLL('shortcut_noWSfound') . ']';
00438                 $description = $LANG->getLL('workspace_description_no_access');
00439             break;
00440             default:
00441                 $title = t3lib_iconWorks::getIconImage('sys_workspace', $GLOBALS['BE_USER']->workspaceRec, $this->doc->backPath, ' align="top"').
00442                             '['.$GLOBALS['BE_USER']->workspace.'] '.t3lib_BEfunc::getRecordTitle('sys_workspace',$GLOBALS['BE_USER']->workspaceRec,TRUE);
00443                 $description = ($GLOBALS['BE_USER']->workspaceRec['description'] ? htmlspecialchars($GLOBALS['BE_USER']->workspaceRec['description']) : '<em>[' . $LANG->getLL('shortcut_noWSfound') . ']</em>');
00444             break;
00445         }
00446 
00447             // Buttons for publish / swap:
00448         $actionLinks = '';
00449         if ($GLOBALS['BE_USER']->workspace!==0) {
00450             if ($this->publishAccess)   {
00451                 $confirmation = $LANG->JScharCode($LANG->getLL(($GLOBALS['BE_USER']->workspaceRec['publish_access'] & 1) ? 'submit_publish_workspace_confirmation_1' :  'submit_publish_workspace_confirmation_2'));
00452                 $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"/>';
00453                 if ($GLOBALS['BE_USER']->workspaceSwapAccess()) {
00454                     $confirmation = $LANG->JScharCode($LANG->getLL(($GLOBALS['BE_USER']->workspaceRec['publish_access'] & 1) ? 'submit_swap_workspace_confirmation_1' :  'submit_swap_workspace_confirmation_2'));
00455                     $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 ;" />';
00456                 }
00457             } else {
00458                 $actionLinks.= $this->doc->icons(1) . $LANG->getLL('no_publish_permission');
00459             }
00460 
00461                 // Preview of workspace link
00462             if (t3lib_div::_POST('_previewLink'))   {
00463                 $ttlHours = intval($GLOBALS['BE_USER']->getTSConfigVal('options.workspaces.previewLinkTTLHours'));
00464                 $ttlHours = ($ttlHours ? $ttlHours : 24*2);
00465                 $previewUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL').'index.php?ADMCMD_prev='.t3lib_BEfunc::compilePreviewKeyword('', $GLOBALS['BE_USER']->user['uid'],60*60*$ttlHours,$GLOBALS['BE_USER']->workspace).'&id='.intval($GLOBALS['BE_USER']->workspaceRec['db_mountpoints']);
00466                 $actionLinks.=  '<br/>Any user can browse the workspace frontend using this link for the next '.$ttlHours.' hours (does not require backend login):<br/><br/><a target="_blank" href="'.htmlspecialchars($previewUrl).'">'.$previewUrl.'</a>';
00467             } else {
00468                 $actionLinks.= '<input type="submit" name="_previewLink" value="Generate Workspace Preview Link" />';
00469             }
00470         }
00471 
00472         $wsAccess = $GLOBALS['BE_USER']->checkWorkspace($GLOBALS['BE_USER']->workspaceRec);
00473 
00474             // Add header to content variable:
00475         $content = '
00476         <table border="0" cellpadding="1" cellspacing="1" class="lrPadding" style="border: 1px solid black;">
00477             <tr>
00478                 <td class="bgColor2" nowrap="nowrap"><b>' . $LANG->getLL('label_workspace') . '</b>&nbsp;</td>
00479                 <td class="bgColor4" nowrap="nowrap">'.$title.'</td>
00480             </tr>
00481             <tr>
00482                 <td class="bgColor2" nowrap="nowrap"><b>' . $LANG->getLL('label_description') . '</b>&nbsp;</td>
00483                 <td class="bgColor4">'.$description.'</td>
00484             </tr>'.($GLOBALS['BE_USER']->workspace!=-99 && !$details ? '
00485             <tr>
00486                 <td class="bgColor2" nowrap="nowrap"><b>' . $LANG->getLL('label_options') . '</b>&nbsp;</td>
00487                 <td class="bgColor4">'.$menu.$actionLinks.'</td>
00488             </tr>
00489             <tr>
00490                 <td class="bgColor2" nowrap="nowrap"><b>' . $LANG->getLL('label_status') . '</b>&nbsp;</td>
00491                 <td class="bgColor4">'.$LANG->getLL('label_access_level').' ' . $GLOBALS['LANG']->getLL('workspace_list_access_' . $wsAccess['_ACCESS']) . '</td>
00492             </tr>' : '').'
00493         </table>
00494         <br/>
00495         ';
00496 
00497             // Add publishing and review overview:
00498         if ($GLOBALS['BE_USER']->workspace!=-99)    {
00499             if ($details)   {
00500                 $content.= $this->displayVersionDetails($details);
00501             } else {
00502                 $content.= $this->displayWorkspaceOverview();
00503             }
00504             $content.='<br/>';
00505         }
00506 
00507             // Return content:
00508         return $content;
00509     }
00510 
00511     /**
00512      * Display details for a single version from workspace
00513      *
00514      * @param   string      Version identification, made of table and uid
00515      * @return  string      HTML string
00516      */
00517     function displayVersionDetails($details)    {
00518         return 'TODO: Show details for version "'.$details.'"<hr/><a href="index.php">BACK</a>';
00519     }
00520 
00521     /**
00522      * Rendering the overview of versions in the current workspace
00523      *
00524      * @return  string      HTML (table)
00525      */
00526     function displayWorkspaceOverview() {
00527 
00528             // Initialize Workspace ID and filter-value:
00529         if ($GLOBALS['BE_USER']->workspace===0) {
00530             $wsid = $this->MOD_SETTINGS['display'];     // Set wsid to the value from the menu (displaying content of other workspaces)
00531             $filter = $this->MOD_SETTINGS['filter'];
00532         } else {
00533             $wsid = $GLOBALS['BE_USER']->workspace;
00534             $filter = 0;
00535         }
00536 
00537             // Instantiate workspace GUI library and generate workspace overview
00538         $wslibGuiObj = t3lib_div::makeInstance('wslib_gui');
00539         $wslibGuiObj->diff = $this->MOD_SETTINGS['diff'];
00540         $wslibGuiObj->expandSubElements = $this->MOD_SETTINGS['expandSubElements'];
00541         $wslibGuiObj->alwaysDisplayHeader = true;
00542         return $wslibGuiObj->getWorkspaceOverview($this->doc, $wsid, $filter);
00543     }
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557     /********************************
00558      *
00559      * Module content: Workspace list
00560      *
00561      ********************************/
00562 
00563     /**
00564      * Rendering of the workspace list
00565      *
00566      * @return  string      HTML
00567      */
00568     function moduleContent_workspaceList()  {
00569         // Original Kasper's TODO: Workspace listing
00570         //
00571         //  - 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.
00572         //  - SWITCHING: Switching between available workspaces is done by a button shown for each in the list
00573         //  - 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)
00574         //  - 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!).
00575         return $this->workspaceList_displayUserWorkspaceList();
00576     }
00577 
00578     /**
00579      * Generates HTML to display a list of workspaces.
00580      *
00581      * @return  string      Generated HTML code
00582      */
00583     function workspaceList_displayUserWorkspaceList()   {
00584         global  $BACK_PATH, $LANG;
00585 
00586             // table header
00587         $content = $this->workspaceList_displayUserWorkspaceListHeader();
00588 
00589             // get & walk workspace list generating content
00590         $wkspList = $this->workspaceList_getUserWorkspaceList();
00591         $rowNum = 1;
00592         foreach ($wkspList as $wksp)    {
00593             $currentWksp = ($GLOBALS['BE_USER']->workspace == $wksp['uid']);
00594 
00595             // Each workspace data occupies two rows:
00596             // (1) Folding + Icons + Title + Description
00597             // (2) Information about workspace (initially hidden)
00598 
00599             $cssClass = ($currentWksp ? 'bgColor3' : 'bgColor4');
00600                 // Start first row
00601             $content .= '<tr class="' . $cssClass . '">';
00602 
00603                 // row #1, column #1: expand icon
00604             $content .= '<td>' .
00605                         '<a href="javascript:expandCollapse(' . $rowNum . ')">' .
00606                         '<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') . '" />' .
00607                         '</a></td>';
00608 
00609                 // row #1, column #2: icon panel
00610             $content .= '<td nowrap="nowrap">'; // Mozilla Firefox will attempt wrap due to `width="1"` on topmost column
00611             $content .= $this->workspaceList_displayIcons($currentWksp, $wksp);
00612             $content .= '</td>';
00613 
00614                 // row #1, column #3: current workspace indicator
00615             $content .= '<td nowrap="nowrap" style="text-align: center">';  // Mozilla Firefox will attempt wrap due to `width="1"` on topmost column
00616             $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') . '" />');
00617             $content .= '</td>';
00618 
00619                 // row #1, column #4 and 5: title and description
00620             $content .= '<td nowrap="nowrap">' . $wksp['title'] . '</td>' .
00621                         '<td>' . nl2br($wksp['description']) . '</td>';
00622             $content .= '</tr>';
00623 
00624                 // row #2, column #1 and #2
00625             $content .= '<tr id="wl_' . $rowNum . '" class="bgColor" style="display: none">';
00626             $content .= '<td colspan="2" style="border-right: none;">&nbsp;</td>';
00627 
00628                 // row #2, column #3, #4 and #4
00629             $content .= '<td colspan="3" style="border-left: none;">' .
00630                         $this->workspaceList_formatWorkspaceData($wksp) .
00631                         '</td>';
00632 
00633             $content .= '</tr>';
00634             $rowNum++;
00635         }
00636         $content .= '</table>';
00637 
00638         return $content;
00639     }
00640 
00641 
00642 
00643 
00644 
00645     /**
00646      * Retrieves a list of workspaces where user has access.
00647      *
00648      * @return  array       A list of workspaces available to the current BE user
00649      */
00650     function workspaceList_getUserWorkspaceList()   {
00651 
00652             // Get list of all workspaces. Note: system workspaces will be always displayed before custom ones!
00653         $workspaces = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*','sys_workspace','pid=0'.t3lib_BEfunc::deleteClause('sys_workspace'),'','title');
00654         $availableWorkspaces = array();
00655 
00656             // Live
00657         $wksp = $this->workspaceList_createFakeWorkspaceRecord(0);
00658         $wksp = $GLOBALS['BE_USER']->checkWorkspace($wksp);
00659         if (false !== $wksp) {
00660             $availableWorkspaces[] = $wksp;
00661         }
00662 
00663             // Draft
00664         $wksp = $this->workspaceList_createFakeWorkspaceRecord(-1);
00665         $wksp = $GLOBALS['BE_USER']->checkWorkspace($wksp);
00666         if (false !== $wksp) {
00667             $availableWorkspaces[] = $wksp;
00668         }
00669 
00670             // Custom
00671         foreach($workspaces as $rec)    {
00672                 // see if user can access this workspace in any way
00673             if (false !== ($result = $GLOBALS['BE_USER']->checkWorkspace($rec)))    {
00674                 $availableWorkspaces[] = $result;   // `$result` contains `$rec` plus access type through '_ACCESS' key
00675             }
00676         }
00677         return $availableWorkspaces;
00678     }
00679 
00680     /**
00681      * Create inner information panel for workspace list. This panel is
00682      * initially hidden and becomes visible when user click on the expand
00683      * icon on the very left of workspace list against the workspace he
00684      * wants to explore.
00685      *
00686      * @param   array       Workspace information
00687      * @return  string      Formatted workspace information
00688      */
00689     function workspaceList_formatWorkspaceData(&$wksp)  {
00690         global $LANG;
00691 
00692         $content = '<table cellspacing="1" cellpadding="1" width="100%" class="ver-wl-details-table">' .
00693                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_file_mountpoints') . '</b></td>' .
00694                 '<td class="ver-wl-details">' . $this->workspaceList_getFileMountPoints($wksp) . '</td></tr>' .
00695                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_db_mountpoints') . '</b></td>' .
00696                 '<td class="ver-wl-details">' . $this->workspaceList_getWebMountPoints($wksp) . '</td></tr>';
00697         if ($wksp['uid'] > 0) {
00698             // Displaying information below makes sence only for custom workspaces
00699             $content .=
00700                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_frozen') . '</b></td>' .
00701                 '<td class="ver-wl-details">' . $LANG->getLL($wksp['freeze'] ? 'workspace_list_label_frozen_yes' : 'workspace_list_label_frozen_no') . '</td></tr>' .
00702                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_publish_date') . '</b></td>' .
00703                 '<td class="ver-wl-details">' . ($wksp['publish_time'] == 0 ? '&nbsp;&ndash;' : t3lib_BEfunc::datetime($wksp['publish_time'])) . '</td></tr>' .
00704                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_unpublish_date') . '</b></td>' .
00705                 '<td class="ver-wl-details">' . ($wksp['unpublish_time'] == 0 ? '&nbsp;&ndash;' : t3lib_BEfunc::datetime($wksp['unpublish_time'])) . '</td></tr>' .
00706                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_your_access') . '</b></td>' .
00707                 '<td class="ver-wl-details">' . $LANG->getLL('workspace_list_access_' . $wksp['_ACCESS']) . '</td></tr>' .
00708                 '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_workspace_users') . '</b></td>' .
00709                 '<td class="ver-wl-details">' . $this->workspaceList_getUserList($wksp) . '</td></tr>';
00710         }
00711         else if ($GLOBALS['BE_USER']->isAdmin()) {
00712             // show users for draft/live workspace only to admin users
00713             $content .= '<tr><td class="ver-wl-details-label"><b>' . $LANG->getLL('workspace_list_label_workspace_users') . '</b></td>' .
00714                 '<td class="ver-wl-details">' . $this->workspaceList_getUserList($wksp) . '</td></tr>';
00715         }
00716         $content .= '</table>';
00717 
00718         return $content;
00719     }
00720 
00721 
00722 
00723 
00724 
00725     /**
00726      * Retrieves and formats database mount points lists.
00727      *
00728      * @param   array       &$wksp  Workspace record
00729      * @return  string      Generated HTML
00730      */
00731     function workspaceList_getWebMountPoints(&$wksp)    {
00732         if ($wksp['uid'] <= 0) {
00733             // system workspaces
00734             return $GLOBALS['LANG']->getLL($wksp['uid'] == 0 ? 'workspace_list_db_mount_point_live' : 'workspace_list_db_mount_point_draft');
00735         }
00736 
00737         // here only if obtaining mount points for custom workspaces
00738 
00739         // Warning: all fields needed for t3lib_iconWorks::getIconImage()!
00740         $MPs = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'pages', 'deleted=0 AND uid IN (' . $GLOBALS['TYPO3_DB']->cleanIntList($wksp['db_mountpoints']) . ')', '', 'title');
00741         $content_array = array();
00742         if (count($MPs) > 0)    {
00743             $isAdmin = $GLOBALS['BE_USER']->isAdmin();
00744             if (!$isAdmin) {
00745                 // We need to fetch user's mount point list (including MPS mounted from groups).
00746                 // This list must not be affects by current user's workspace. It means we cannot use
00747                 // $BE_USER->isInWebMount() to check mount points.
00748                 $userMPs = explode(',', $GLOBALS['BE_USER']->dataLists['webmount_list']); // includes group data if necessary!
00749             }
00750             foreach ($MPs as $mp)   {
00751                 if (!$isAdmin && !in_array($mp['uid'], $userMPs)) {
00752                     // Show warning icon
00753                     $title = $GLOBALS['LANG']->getLL('workspace_list_mount_point_inaccessible');
00754                     $str = '<img ' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/icon_warning.gif', 'width="18" height="16"') .
00755                             ' alt="' . $title . '" title="' . $title . '" align="absmiddle" />';
00756                     $classAttr = 'class="ver-wl-mp-inacessible" ';
00757                 }
00758                 else {
00759                     // normal icon
00760                     $str = t3lib_iconWorks::getIconImage('pages', $mp, $GLOBALS['BACK_PATH'], ' align="absmiddle"');
00761                     $classAttr = '';
00762                 }
00763                 // Will show UID on hover. Just convinient to user.
00764                 $content_array[] = $str . '<span ' . $classAttr . 'title="UID: ' . $mp['uid'] . '">' . $mp['title'] . '</span>';
00765             }
00766         }
00767         if (count($content_array) > 0) {
00768             return implode('<br />', $content_array);
00769         }
00770         // no mount points
00771         return $GLOBALS['LANG']->getLL('workspace_list_db_mount_point_custom');
00772     }
00773 
00774     /**
00775      * Retrieves and formats file mount points lists.
00776      *
00777      * @param   array       &$wksp  Workspace record
00778      * @return  string      Generated HTML
00779      */
00780     function workspaceList_getFileMountPoints(&$wksp)   {
00781         if ($wksp['uid'] == -1) {
00782             // draft workspace - none!
00783             return $GLOBALS['LANG']->getLL('workspace_list_file_mount_point_draft');
00784         }
00785         else if ($wksp['uid'] == 0) {
00786             // live workspace
00787             return $GLOBALS['LANG']->getLL('workspace_list_file_mount_point_live');
00788         }
00789 
00790         // Here if displaying information for custom workspace
00791 
00792         // Warning: all fields needed for t3lib_iconWorks::getIconImage()!
00793         $MPs = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_filemounts', 'deleted=0 AND hidden=0 AND uid IN (' . $GLOBALS['TYPO3_DB']->cleanIntList($wksp['file_mountpoints']) . ')', '', 'title');
00794         if (count($MPs) != 0)   {
00795             // Has mount points
00796             $isAdmin = $GLOBALS['BE_USER']->isAdmin();
00797             if (!$isAdmin) {
00798                 // We need to fetch user's mount point list (including MPS mounted from groups).
00799                 // This list must not be affects by current user's workspace. It means we cannot use
00800                 // $BE_USER->isInWebMount() to check mount points.
00801                 $userMPs = explode(',', $GLOBALS['BE_USER']->dataLists['filemount_list']); // includes group data if necessary!
00802             }
00803             foreach ($MPs as $mp)   {
00804                 if (!$isAdmin && !in_array($mp['uid'], $userMPs)) {
00805                     // Show warning icon
00806                     $title = $GLOBALS['LANG']->getLL('workspace_list_mount_point_inaccessible');
00807                     $str = '<img ' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/icon_warning.gif', 'width="18" height="16"') .
00808                             ' alt="' . $title . '" title="' . $title . '" align="absmiddle" />';
00809                     $classAttr = 'class="ver-wl-mp-inacessible" ';
00810                 }
00811                 else {
00812                     // normal icon
00813                     $str = t3lib_iconWorks::getIconImage('sys_filemounts', $mp, $GLOBALS['BACK_PATH'], ' align="absmiddle"');
00814                     $classAttr = '';
00815                 }
00816                 // Will show UID on hover. Just convinient to user.
00817                 $content_array[] = $str . '<span ' . $classAttr . 'title="UID: ' . $mp['uid'] . '">' . $mp['title'] . '</span>';
00818             }
00819         }
00820         if (count($content_array) > 0) {
00821             return implode('<br />', $content_array);
00822         }
00823         // No file mount points
00824         return $GLOBALS['LANG']->getLL('workspace_list_file_mount_point_custom');
00825     }
00826 
00827     /**
00828      * Creates a header for the workspace list table. This function only makes
00829      * <code>workspaceList_displayUserWorkspaceList()</code> smaller.
00830      *
00831      * @return  string      Generated content
00832      */
00833     function workspaceList_displayUserWorkspaceListHeader() {
00834         global  $LANG;
00835         // TODO CSH lables?
00836         return '<table border="0" cellpadding="0" cellspacing="1" class="lrPadding workspace-overview ver-wl-table">
00837             <tr class="bgColor5 tableheader">
00838                 <td width="1">&nbsp;</td>
00839                 <td width="1">&nbsp;</td>
00840                 <td nowrap="nowrap">' . $LANG->getLL('workspace_list_label_current_workspace') . '</td>
00841                 <td nowrap="nowrap">' . $LANG->getLL('workspace_list_label_workspace_title') . '</td>
00842                 <td nowrap="nowrap">' . $LANG->getLL('workspace_list_label_workspace_description') . '</td>
00843             </tr>';
00844     }
00845 
00846 
00847     /**
00848      * Generates a list of <code>&lt;option&gt;</code> tags with user names.
00849      *
00850      * @param   array       Workspace record
00851      * @return  string      Generated content
00852      */
00853     function workspaceList_getUserList(&$wksp) {
00854         global  $LANG;
00855 
00856         if ($wksp['uid'] > 0) {
00857             // custom workspaces
00858             $content = $this->workspaceList_getUserListWithAccess($wksp['adminusers'], $LANG->getLL('workspace_list_label_owners')); // owners
00859             $content .= $this->workspaceList_getUserListWithAccess($wksp['members'], $LANG->getLL('workspace_list_label_members')); // members
00860             $content .= $this->workspaceList_getUserListWithAccess($wksp['reviewers'], $LANG->getLL('workspace_list_label_reviewers')); // reviewers
00861             if ($content != '') {
00862                 $content = '<table cellpadding="0" cellspacing="1" width="100%" class="lrPadding workspace-overview">' . $content . '</table>';
00863             } else {
00864                 $content = $LANG->getLL($wksp['uid'] > 0 ? 'workspace_list_access_admins_only' : 'workspace_list_access_anyone');
00865             }
00866         }
00867         else {
00868             // live and draft workspace
00869             $content = $this->workspaceList_getUserListForSysWorkspace($wksp);
00870         }
00871         return $content;
00872     }
00873 
00874     /**
00875      * Generates a list of user names that has access to the system workspace.
00876      *
00877      * @param   array       &$wksp  Workspace record
00878      * @return  string      Generated content
00879      */
00880     function workspaceList_getUserListForSysWorkspace(&$wksp) {
00881         $option = ($wksp['uid'] == 0 ? 1 : 2);
00882         $content_array = array();
00883         foreach ($this->be_user_Array_full as $uid => $user) {
00884             if ($user['admin'] != 0 || 0 != ($user['workspace_perms'] & $option)) {
00885                 if ($uid == $GLOBALS['BE_USER']->user['uid']) {
00886                     // highlight current user
00887                     $tag0 = '<span class="ver-wl-current-user">';
00888                     $tag1 = '</span>';
00889                 }
00890                 else {
00891                     $tag0 = $tag1 = '';
00892                 }
00893                 $content_array[] = $this->doc->wrapClickMenuOnIcon(t3lib_iconWorks::getIconImage('be_users', $uid, $GLOBALS['BACK_PATH'], ' align="middle" alt="UID: ' . $uid . '"'), 'be_users', $uid, 2).
00894                     $tag0 . $user['username'] . $tag1;
00895             }
00896         }
00897         return implode('<br />', $content_array);
00898     }
00899 
00900     /**
00901      * Generates a list of user names that has access to the workspace.
00902      *
00903      * @param   array       A list of user IDs separated by comma
00904      * @param   string      Access string
00905      * @return  string      Generated content
00906      */
00907     function workspaceList_getUserListWithAccess(&$list, $access)   {
00908         $content_array = array();
00909         if ($list != '')    {
00910             $userIDs = explode(',', $list);
00911 
00912                 // get user names and sort
00913             $regExp = '/^(be_[^_]+)_(\d+)$/';
00914             $groups = false;
00915             foreach ($userIDs as $userUID)  {
00916                 $id = $userUID;
00917 
00918                 if (preg_match($regExp, $userUID)) {
00919                     $table = preg_replace($regExp, '\1', $userUID);
00920                     $id = intval(preg_replace($regExp, '\2', $userUID));
00921                     if ($table == 'be_users') {
00922                         // user
00923                         $icon = $GLOBALS['TCA']['be_users']['typeicons'][$this->be_user_Array[$id]['admin']];
00924                         if ($id == $GLOBALS['BE_USER']->user['uid']) {
00925                             // highlight current user
00926                             $tag0 = '<span class="ver-wl-current-user">';
00927                             $tag1 = '</span>';
00928                         }
00929                         else {
00930                             $tag0 = $tag1 = '';
00931                         }
00932                         $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) .
00933                                             $tag0 . $this->be_user_Array_full[$id]['username'] . $tag1;
00934                     }
00935                     else {
00936                         // group
00937                         if (false === $groups) {
00938                             $groups = t3lib_BEfunc::getGroupNames();
00939                         }
00940                         $content_array[] = $this->doc->wrapClickMenuOnIcon(t3lib_iconWorks::getIconImage($table, $groups[$id], $GLOBALS['BACK_PATH'], ' align="middle" alt="UID: ' . $id . '"'), $table, $id, 2) .
00941                                             $groups[$id]['title'];
00942                     }
00943                 }
00944                 else {
00945                     // user id
00946                     if ($userUID == $GLOBALS['BE_USER']->user['uid']) {
00947                         // highlight current user
00948                         $tag0 = '<span class="ver-wl-current-user">';
00949                         $tag1 = '</span>';
00950                     }
00951                     else {
00952                         $tag0 = $tag1 = '';
00953                     }
00954                     $content_array[] = t3lib_iconWorks::getIconImage('be_users', $this->be_user_Array[$id], $GLOBALS['BACK_PATH'], ' align="middle" alt="UID: ' . $id . '"') .
00955                                         $tag0 . $this->be_user_Array_full[$userUID]['username'] . $tag1;
00956                 }
00957             }
00958             sort($content_array);
00959         }
00960         else {
00961             $content_array[] = '&nbsp;&ndash;';
00962         }
00963 
00964         $content = '<tr><td class="ver-wl-details-label ver-wl-details-user-list-label">';
00965         // TODO CSH lable explaining access here?
00966         $content .= '<b>' . $access . '</b></td>';
00967         $content .= '<td class="ver-wl-details">' . implode('<br />', $content_array) . '</td></tr>';
00968         return $content;
00969     }
00970 
00971 
00972 
00973     /**
00974      * Creates a list of icons for workspace.
00975      *
00976      * @param   boolean     <code>true</code> if current workspace
00977      * @param   array       Workspace record
00978      * @return  string      Generated content
00979      */
00980     function workspaceList_displayIcons($currentWorkspace, &$wksp)  {
00981         global  $BACK_PATH, $LANG;
00982 
00983         $content = '';
00984             // `edit workspace` button
00985         if ($this->workspaceList_hasEditAccess($wksp))  {
00986                 // User can modify workspace parameters, display corresponding link and icon
00987             $editUrl = 'workspaceforms.php?action=edit&amp;wkspId=' . $wksp['uid'];
00988 
00989             $content .= '<a href="' . $editUrl . '" />' .
00990                     '<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" />' .
00991                     '</a>';
00992         } else {
00993                 // User can NOT modify workspace parameters, display space
00994                 // Get only withdth and height from skinning API
00995             $content .= '<img src="clear.gif" ' .
00996                     t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/edit2.gif', 'width="11" height="12"', 2) .
00997                     ' border="0" alt="" hspace="1" align="middle" />';
00998         }
00999             // `switch workspace` button
01000         if (!$currentWorkspace) {
01001                 // Workspace switching button
01002             $content .= '<a href="' .
01003                     t3lib_div::getIndpEnv('SCRIPT_NAME') .
01004                     '?changeWorkspace=' . $wksp['uid'] . '"/>' .
01005                     '<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" />' .
01006                     '</a>';
01007         } else {
01008                 // Current workspace: empty space instead of workspace switching button
01009                 //
01010                 // Here get only width and height from skinning API
01011             $content .= '<img src="clear.gif" ' .
01012                     t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/switch.png', 'width="18" height="16"', 2) .
01013                     ' border="0" alt="" hspace="1" align="middle" alt="" />';
01014         }
01015         return $content;
01016     }
01017 
01018     /**
01019      * Checks if user has edit access to workspace. Access is granted if
01020      * workspace is custom and user is admin or the the owner of the workspace.
01021      * This function assumes that <code>$wksp</code> were passed through
01022      * <code>$GLOBALS['BE_USER']->checkWorkspace()</code> function to obtain
01023      * <code>_ACCESS</code> attribute of the workspace.
01024      *
01025      * @param   array       Workspace record
01026      * @return  boolean     <code>true</code> if user can modify workspace parameters
01027      */
01028     function workspaceList_hasEditAccess(&$wksp)    {
01029         $access = &$wksp['_ACCESS'];
01030         return ($wksp['uid'] > 0 && ($access == 'admin' || $access == 'owner'));
01031     }
01032 
01033     /**
01034      * Creates a fake workspace record for system workspaces. Record contains
01035      * all fields found in <code>sys_workspaces</code>.
01036      *
01037      * @param   integer     System workspace ID. Currently <code>0</code> and <code>-1</code> are accepted.
01038      * @return  array       Generated record (see <code>sys_workspaces</code> for structure)
01039      */
01040     function workspaceList_createFakeWorkspaceRecord($uid)  {
01041         global  $BE_USER, $LANG;
01042 
01043         $record = array(
01044             'uid' => $uid,
01045             'pid' => 0,             // always 0!
01046             'tstamp' => 0,          // does not really matter