2 /***************************************************************
5 * (c) 2004-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
27 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
30 * [CLASS/FUNCTION INDEX of SCRIPT]
34 * 102: class tx_version_cm1 extends t3lib_SCbase
36 * SECTION: Standard module initialization
37 * 138: function menuConfig()
38 * 175: function main()
39 * 236: function jumpToUrl(URL)
40 * 296: function printContent()
42 * SECTION: Versioning management
43 * 322: function versioningMgm()
44 * 485: function pageSubContent($pid,$c=0)
45 * 539: function lookForOwnVersions($table,$uid)
46 * 556: function adminLinks($table,$row)
48 * SECTION: Workspace management
49 * 628: function workspaceMgm()
50 * 688: function displayWorkspaceOverview()
51 * 758: function displayWorkspaceOverview_list($pArray)
52 * 923: function displayWorkspaceOverview_setInPageArray(&$pArray,$table,$row)
53 * 936: function displayWorkspaceOverview_allStageCmd()
55 * SECTION: Helper functions (REDUNDANT FROM user/ws/index.php - someone could refactor this...)
56 * 986: function formatVerId($verId)
57 * 996: function formatWorkspace($wsid)
58 * 1023: function formatCount($count)
59 * 1050: function versionsInOtherWS($table,$uid)
60 * 1080: function showStageChangeLog($table,$id,$stageCommands)
61 * 1129: function subElements($uid,$treeLevel,$origId=0)
62 * 1232: function subElements_getNonPageRecords($tN, $uid, &$recList)
63 * 1262: function subElements_renderItem(&$tCell,$tN,$uid,$rec,$origId,$iconMode,$HTMLdata)
64 * 1331: function markupNewOriginals()
65 * 1353: function createDiffView($table, $diff_1_record, $diff_2_record)
66 * 1470: function displayWorkspaceOverview_stageCmd($table,&$rec_off)
67 * 1557: function displayWorkspaceOverview_commandLinks($table,&$rec_on,&$rec_off,$vType)
68 * 1627: function displayWorkspaceOverview_commandLinksSub($table,$rec,$origId)
71 * 1683: function publishAction()
74 * (This index is automatically created/updated by the extension "extdeveval")
79 // DEFAULT initialization of a module [BEGIN]
82 require ($BACK_PATH.'init.php');
83 require ($BACK_PATH.'template.php');
84 $LANG->includeLLFile('EXT:version/locallang.xml');
85 // DEFAULT initialization of a module [END]
87 require_once(PATH_typo3
.'mod/user/ws/class.wslib.php');
92 * Versioning module, including workspace management
94 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
98 class tx_version_cm1
extends t3lib_SCbase
{
100 // Default variables for backend modules
101 var $MCONF = array(); // Module configuration
102 var $MOD_MENU = array(); // Module menu items
103 var $MOD_SETTINGS = array(); // Module session settings
106 * document template object
111 var $content; // Accumulated content
115 var $showWorkspaceCol = 0;
116 var $formatWorkspace_cache = array();
117 var $formatCount_cache = array();
118 var $targets = array(); // Accumulation of online targets.
119 var $pageModule = ''; // Name of page module
120 var $publishAccess = FALSE;
121 var $be_user_Array = array();
122 var $stageIndex = array();
123 var $recIndex = array();
130 /*********************************
132 * Standard module initialization
134 *********************************/
137 * Initialize menu configuration
141 function menuConfig() {
144 $this->MOD_MENU
= array(
146 1 => $GLOBALS['LANG']->getLL('filter_drafts'),
147 2 => $GLOBALS['LANG']->getLL('filter_archive'),
148 0 => $GLOBALS['LANG']->getLL('filter_all'),
151 0 => $GLOBALS['LANG']->getLL('liveWorkspace'),
152 -98 => $GLOBALS['LANG']->getLL('draftWorkspaces'),
153 -99 => $GLOBALS['LANG']->getLL('filter_all'),
154 -1 => $GLOBALS['LANG']->getLL('defaultDraft')
160 if ($GLOBALS['BE_USER']->workspace
===0) { // Spend time on this only in online workspace because it might take time:
161 $workspaces = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,title,adminusers,members,reviewers','sys_workspace','pid=0'.t3lib_BEfunc
::deleteClause('sys_workspace'),'','title');
162 foreach($workspaces as $rec) {
163 if ($GLOBALS['BE_USER']->checkWorkspace($rec)) {
164 $this->MOD_MENU
['display'][$rec['uid']] = '['.$rec['uid'].'] '.$rec['title'];
170 $this->MOD_SETTINGS
= t3lib_BEfunc
::getModuleData($this->MOD_MENU
, t3lib_div
::_GP('SET'), $this->MCONF
['name'], 'ses');
174 * Main function of the module. Write the content to $this->content
179 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
189 // Setting module configuration:
190 $this->MCONF
= $GLOBALS['MCONF'];
192 $this->REQUEST_URI
= str_replace('&sendToReview=1','',t3lib_div
::getIndpEnv('REQUEST_URI'));
195 $this->doc
= t3lib_div
::makeInstance('template');
196 $this->doc
->backPath
= $BACK_PATH;
197 $this->doc
->setModuleTemplate('templates/version.html');
200 $this->doc
->inDocStylesArray
[$GLOBALS['MCONF']['name']] = '
201 .version-diff-1 { background-color: green; }
202 .version-diff-2 { background-color: red; }
205 // Setting up the context sensitive menu:
206 $this->doc
->getContextMenuCode();
208 // Getting input data:
209 $this->id
= intval(t3lib_div
::_GP('id')); // Page id. If set, indicates activation from Web>Versioning module
211 $this->uid
= intval(t3lib_div
::_GP('uid')); // Record uid. Goes with table name to indicate specific record
212 $this->table
= t3lib_div
::_GP('table'); // Record table. Goes with uid to indicate specific record
214 $this->uid
= $this->id
;
215 $this->table
= 'pages';
217 $this->details
= t3lib_div
::_GP('details'); // Page id. If set, indicates activation from Web>Versioning module
218 $this->diffOnly
= t3lib_div
::_GP('diffOnly'); // Flag. If set, shows only the offline version and with diff-view
220 // Force this setting:
221 $this->MOD_SETTINGS
['expandSubElements'] = TRUE;
222 $this->MOD_SETTINGS
['diff'] = $this->details ||
$this->MOD_SETTINGS
['diff']?
1:0;
224 // Reading the record:
225 $record = t3lib_BEfunc
::getRecord($this->table
,$this->uid
);
226 if ($record['pid']==-1) {
227 $record = t3lib_BEfunc
::getRecord($this->table
,$record['t3ver_oid']);
230 $this->recordFound
= is_array($record);
232 $pidValue = $this->table
==='pages' ?
$this->uid
: $record['pid'];
234 // Checking access etc.
235 if ($this->recordFound
&& $TCA[$this->table
]['ctrl']['versioningWS']) {
236 $this->doc
->form
='<form action="" method="post">';
237 $this->uid
= $record['uid']; // Might have changed if new live record was found!
240 // The page will show only if there is a valid page and if this page may be viewed by the user
241 $this->pageinfo
= t3lib_BEfunc
::readPageAccess($pidValue,$this->perms_clause
);
242 $access = is_array($this->pageinfo
) ?
1 : 0;
244 if (($pidValue && $access) ||
($BE_USER->user
['admin'] && !$pidValue)) {
247 $this->doc
->JScode
.= '
248 <script language="javascript" type="text/javascript">
250 function jumpToUrl(URL) {
251 window.location.href = URL;
254 function hlSubelements(origId, verId, over, diffLayer) { //
256 document.getElementById(\'orig_\'+origId).attributes.getNamedItem("class").nodeValue = \'typo3-ver-hl\';
257 document.getElementById(\'ver_\'+verId).attributes.getNamedItem("class").nodeValue = \'typo3-ver-hl\';
259 document.getElementById(\'diff_\'+verId).style.visibility = \'visible\';
262 document.getElementById(\'orig_\'+origId).attributes.getNamedItem("class").nodeValue = \'typo3-ver\';
263 document.getElementById(\'ver_\'+verId).attributes.getNamedItem("class").nodeValue = \'typo3-ver\';
265 document.getElementById(\'diff_\'+verId).style.visibility = \'hidden\';
272 // If another page module was specified, replace the default Page module with the new one
273 $newPageModule = trim($BE_USER->getTSConfigVal('options.overridePageModule'));
274 $this->pageModule
= t3lib_BEfunc
::isModuleSetInTBE_MODULES($newPageModule) ?
$newPageModule : 'web_layout';
276 // Setting publish access permission for workspace:
277 $this->publishAccess
= $BE_USER->workspacePublishAccess($BE_USER->workspace
);
281 $this->workspaceMgm();
283 $this->versioningMgm();
287 $this->content
.=$this->doc
->spacer(10);
289 // Setting up the buttons and markers for docheader
290 $docHeaderButtons = $this->getButtons();
291 $markers['CSH'] = $docHeaderButtons['csh'];
292 $markers['FUNC_MENU'] = t3lib_BEfunc
::getFuncMenu($this->id
, 'SET[function]', $this->MOD_SETTINGS
['function'], $this->MOD_MENU
['function']);
293 $markers['WS_MENU'] = $this->workspaceMenu();
294 $markers['CONTENT'] = $this->content
;
296 // If no access or id value, create empty document
297 $this->content
= $this->doc
->section($LANG->getLL('clickAPage_header'), $LANG->getLL('clickAPage_content'), 0, 1);
299 // Setting up the buttons and markers for docheader
300 $docHeaderButtons = $this->getButtons();
301 $markers['CONTENT'] = $this->content
;
303 // Build the <body> for the module
304 $this->content
= $this->doc
->startPage($LANG->getLL('title'));
305 $this->content
.= $this->doc
->moduleBody($this->pageinfo
, $docHeaderButtons, $markers);
306 $this->content
.= $this->doc
->endPage();
307 $this->content
= $this->doc
->insertStylesAndJS($this->content
);
311 * Outputs accumulated module content to browser.
315 function printContent() {
320 * Create the panel of buttons for submitting the form or otherwise perform operations.
322 * @return array all available buttons as an assoc. array
324 protected function getButtons() {
325 global $TCA, $LANG, $BACK_PATH, $BE_USER;
334 //$buttons['csh'] = t3lib_BEfunc::cshItem('_MOD_web_txversionM1', '', $GLOBALS['BACK_PATH']);
336 if ($this->recordFound
&& $TCA[$this->table
]['ctrl']['versioningWS']) {
338 $buttons['view'] = '<a href="#" onclick="' . htmlspecialchars(t3lib_BEfunc
::viewOnClick($this->pageinfo
['uid'], $BACK_PATH, t3lib_BEfunc
::BEgetRootLine($this->pageinfo
['uid']))) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showPage', TRUE) . '">' .
339 t3lib_iconWorks
::getSpriteIcon('actions-document-view') .
343 if ($BE_USER->mayMakeShortcut()) {
344 $buttons['shortcut'] = $this->doc
->makeShortcutIcon('id, edit_record, pointer, new_unique_uid, search_field, search_levels, showLimit', implode(',', array_keys($this->MOD_MENU
)), $this->MCONF
['name']);
347 // If access to Web>List for user, then link to that module.
348 if ($BE_USER->check('modules','web_list')) {
349 $href = $BACK_PATH . 'db_list.php?id=' . $this->pageinfo
['uid'] . '&returnUrl=' . rawurlencode(t3lib_div
::getIndpEnv('REQUEST_URI'));
350 $buttons['record_list'] = '<a href="' . htmlspecialchars($href) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showList', TRUE) . '">' .
351 t3lib_iconWorks
::getSpriteIcon('actions-system-list-open') .
365 /******************************
367 * Versioning management
369 ******************************/
372 * Management of versions for record
376 function versioningMgm() {
380 $diff_1 = t3lib_div
::_POST('diff_1');
381 $diff_2 = t3lib_div
::_POST('diff_2');
382 if (t3lib_div
::_POST('do_diff')) {
384 $content.='<h3>' . $GLOBALS['LANG']->getLL('diffing') . ':</h3>';
385 if ($diff_1 && $diff_2) {
386 $diff_1_record = t3lib_BEfunc
::getRecord($this->table
, $diff_1);
387 $diff_2_record = t3lib_BEfunc
::getRecord($this->table
, $diff_2);
389 if (is_array($diff_1_record) && is_array($diff_2_record)) {
390 t3lib_div
::loadTCA($this->table
);
391 $t3lib_diff_Obj = t3lib_div
::makeInstance('t3lib_diff');
395 <tr class="bgColor5 tableheader">
396 <td>' . $GLOBALS['LANG']->getLL('fieldname') . '</td>
397 <td width="98%">' . $GLOBALS['LANG']->getLL('coloredDiffView') . ':</td>
400 foreach($diff_1_record as $fN => $fV) {
401 if ($TCA[$this->table
]['columns'][$fN] && $TCA[$this->table
]['columns'][$fN]['config']['type']!='passthrough' && !t3lib_div
::inList('t3ver_label',$fN)) {
402 if (strcmp($diff_1_record[$fN],$diff_2_record[$fN])) {
404 $diffres = $t3lib_diff_Obj->makeDiffDisplay(
405 t3lib_BEfunc
::getProcessedValue($this->table
,$fN,$diff_2_record[$fN],0,1),
406 t3lib_BEfunc
::getProcessedValue($this->table
,$fN,$diff_1_record[$fN],0,1)
410 <tr class="bgColor4">
412 <td width="98%">'.$diffres.'</td>
419 if (count($tRows)>1) {
420 $content .= '<table border="0" cellpadding="1" cellspacing="1" width="100%">' . implode('', $tRows) . '</table><br /><br />';
422 $content .= $GLOBALS['LANG']->getLL('recordsMatchesCompletely');
424 } else $content .= $GLOBALS['LANG']->getLL('errorRecordsNotFound');
426 $content .= $GLOBALS['LANG']->getLL('errorDiffSources');
431 $record = t3lib_BEfunc
::getRecord($this->table
,$this->uid
);
432 $recordIcon = t3lib_iconWorks
::getIconImage($this->table
,$record,$this->doc
->backPath
,'class="absmiddle"');
433 $recTitle = t3lib_BEfunc
::getRecordTitle($this->table
,$record,TRUE);
437 '.$recordIcon.$recTitle.'
438 <form name="theform" action="'.str_replace('&sendToReview=1','',$this->REQUEST_URI
).'" method="post">
439 <table border="0" cellspacing="1" cellpadding="1">';
441 <tr class="bgColor5 tableheader">
444 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_title') . '">' . $GLOBALS['LANG']->getLL('tblHeader_title') . '</td>
445 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_uid') . '">' . $GLOBALS['LANG']->getLL('tblHeader_uid') . '</td>
446 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_oid') . '">' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_oid') . '</td>
447 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_id') . '">' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_id') . '</td>
448 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_wsid') . '">' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_wsid') . '</td>
449 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_state') . '">' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_state') . '</td>
450 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_stage') . '">' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_stage') . '</td>
451 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_count') . '">' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_count') . '</td>
452 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_pid') . '">' . $GLOBALS['LANG']->getLL('tblHeader_pid') . '</td>
453 <td title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_label') . '">' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_label') . '</td>
454 <td colspan="2"><input type="submit" name="do_diff" value="' . $GLOBALS['LANG']->getLL('diff') . '" /></td>
457 $versions = t3lib_BEfunc
::selectVersionsOfRecord($this->table
, $this->uid
, '*', $GLOBALS['BE_USER']->workspace
);
458 foreach($versions as $row) {
459 $adminLinks = $this->adminLinks($this->table
,$row);
462 <tr class="' . ($row['uid'] != $this->uid ?
'bgColor4' : 'bgColor2 tableheader') . '">
463 <td>'.($row['uid']!=$this->uid ?
'<a href="'.$this->doc
->issueCommand('&cmd['.$this->table
.']['.$this->uid
.'][version][swapWith]='.$row['uid'].'&cmd['.$this->table
.']['.$this->uid
.'][version][action]=swap').'" title="' . $GLOBALS['LANG']->getLL('swapWithCurrent', TRUE) . '">'.
464 t3lib_iconWorks
::getSpriteIcon('apps-version-swap-versions') .
466 $this->table == 'pages' ?
467 '<a href="'.$this->doc->issueCommand('&cmd['.$this->table.']['.$this->uid.'][version][action]=swap&cmd['.$this->table.']['.$this->uid.'][version][swapWith]='.$row['uid'].'&cmd['.$this->table.']['.$this->uid.'][version][swapContent]=1').'">'.
468 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/insert2.gif','width="14" height="14"').' alt="" title="Publish page AND content!" />'.
470 '<a href="'.$this->doc->issueCommand('&cmd['.$this->table.']['.$this->uid.'][version][action]=swap&cmd['.$this->table.']['.$this->uid.'][version][swapWith]='.$row['uid'].'&cmd['.$this->table.']['.$this->uid.'][version][swapContent]=ALL').'">'.
471 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/insert4.gif','width="14" height="14"').' alt="" title="Publish page AND content! - AND ALL SUBPAGES!" />'.
472 '</a>' : '') */ : t3lib_iconWorks
::getSpriteIcon('status-status-current', array('title' => $GLOBALS['LANG']->getLL('currentOnlineVersion', TRUE)))) . '</td>
473 <td nowrap="nowrap">'.$adminLinks.'</td>
474 <td nowrap="nowrap">'.t3lib_BEfunc
::getRecordTitle($this->table
,$row,TRUE).'</td>
475 <td>'.$row['uid'].'</td>
476 <td>'.$row['t3ver_oid'].'</td>
477 <td>'.$row['t3ver_id'].'</td>
478 <td>'.$row['t3ver_wsid'].'</td>
479 <td>'.$row['t3ver_state'].'</td>
480 <td>'.$row['t3ver_stage'].'</td>
481 <td>'.$row['t3ver_count'].'</td>
482 <td>'.$row['pid'].'</td>
483 <td nowrap="nowrap"><a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc
::editOnClick('&edit['.$this->table
.']['.$row['uid'].']=edit&columnsOnly=t3ver_label',$this->doc
->backPath
)).'" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:cm.edit', TRUE) . '">' .
484 t3lib_iconWorks
::getSpriteIcon('actions-document-open') .
485 '</a>' . htmlspecialchars($row['t3ver_label']) . '</td>
486 <td class="version-diff-1"><input type="radio" name="diff_1" value="'.$row['uid'].'"'.($diff_1==$row['uid'] ?
' checked="checked"':'').'/></td>
487 <td class="version-diff-2"><input type="radio" name="diff_2" value="'.$row['uid'].'"'.($diff_2==$row['uid'] ?
' checked="checked"':'').'/></td>
490 // Show sub-content if the table is pages AND it is not the online branch (because that will mostly render the WHOLE tree below - not smart;)
491 if ($this->table
== 'pages' && $row['uid']!=$this->uid
) {
492 $sub = $this->pageSubContent($row['uid']);
499 <td colspan="10">'.$sub.'</td>
500 <td colspan="2"></td>
505 $content.='</table></form>';
507 $this->content
.=$this->doc
->section('',$content,0,1);
513 <form action="'.$this->doc
->backPath
.'tce_db.php" method="post">
514 ' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_label') . ': <input type="text" name="cmd[' . $this->table
. '][' . $this->uid
. '][version][label]" /><br />
515 '.($this->table
== 'pages' ?
'<select name="cmd['.$this->table
.']['.$this->uid
.'][version][treeLevels]">
516 '.($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(0) ?
'<option value="0">' . $GLOBALS['LANG']->getLL('cmdPid0') . '</option>' : '').'
517 '.($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(1) ?
'<option value="100">' . $GLOBALS['LANG']->getLL('cmdPid100') . '</option>' : '').'
518 '.($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(-1) ?
'<option value="-1">' . $GLOBALS['LANG']->getLL('cmdPid1') . '</option>' : '').'
520 <br /><input type="hidden" name="cmd[' . $this->table
. '][' . $this->uid
. '][version][action]" value="new" />
521 <input type="hidden" name="prErr" value="1" />
522 <input type="hidden" name="redirect" value="'.htmlspecialchars($this->REQUEST_URI
).'" />
523 <input type="submit" name="_" value="' . $GLOBALS['LANG']->getLL('createNewVersion') . '" />
529 $this->content
.=$this->doc
->spacer(15);
530 $this->content
.=$this->doc
->section($GLOBALS['LANG']->getLL('createNewVersion'), $content,0,1);
535 * Recursively look for children for page version with $pid
537 * @param integer UID of page record for which to look up sub-elements following that version
538 * @param integer Counter, do not set (limits to 100 levels)
539 * @return string Table with content if any
541 function pageSubContent($pid,$c=0) {
544 $tableNames = t3lib_div
::removeArrayEntryByValue(array_keys($TCA),'pages');
545 $tableNames[] = 'pages';
547 foreach($tableNames as $tN) {
548 // Basically list ALL tables - not only those being copied might be found!
549 #if ($TCA[$tN]['ctrl']['versioning_followPages'] || $tN=='pages') {
550 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $tN, 'pid='.intval($pid).t3lib_BEfunc
::deleteClause($tN), '', ($TCA[$tN]['ctrl']['sortby'] ?
$TCA[$tN]['ctrl']['sortby'] : ''));
552 if ($GLOBALS['TYPO3_DB']->sql_num_rows($mres)) {
555 <td colspan="4" class="'.($TCA[$tN]['ctrl']['versioning_followPages'] ?
'bgColor6' : ($tN=='pages' ?
'bgColor5' : 'bgColor-10')).'"'.(!$TCA[$tN]['ctrl']['versioning_followPages'] && $tN!='pages' ?
' style="color: #666666; font-style:italic;"':'').'>'.$tN.'</td>
557 while ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
558 $ownVer = $this->lookForOwnVersions($tN,$subrow['uid']);
561 <td>'.$this->adminLinks($tN,$subrow).'</td>
562 <td>'.$subrow['uid'].'</td>
563 '.($ownVer>1 ?
'<td style="font-weight: bold; background-color: yellow;"><a href="index.php?table='.rawurlencode($tN).'&uid='.$subrow['uid'].'">'.($ownVer-1).'</a></td>' : '<td></td>').'
564 <td width="98%">'.t3lib_BEfunc
::getRecordTitle($tN,$subrow,TRUE).'</td>
567 if ($tN == 'pages' && $c<100) {
568 $sub = $this->pageSubContent($subrow['uid'],$c+
1);
576 <td width="98%">'.$sub.'</td>
585 return $content ?
'<table border="1" cellpadding="1" cellspacing="0" width="100%">'.$content.'</table>' : '';
589 * Look for number of versions of a record
591 * @param string Table name
592 * @param integer Record uid
593 * @return integer Number of versions for record, false if none.
595 function lookForOwnVersions($table,$uid) {
598 $versions = t3lib_BEfunc
::selectVersionsOfRecord($table, $uid, 'uid');
599 if (is_array($versions)) {
600 return count($versions);
606 * Administrative links for a table / record
608 * @param string Table name
609 * @param array Record for which administrative links are generated.
610 * @return string HTML link tags.
612 function adminLinks($table,$row) {
616 $adminLink = '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc
::editOnClick('&edit['.$table.']['.$row['uid'].']=edit',$this->doc
->backPath
)).'" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:cm.edit', TRUE) . '">'.
617 t3lib_iconWorks
::getSpriteIcon('actions-document-open') .
621 $adminLink.= '<a href="'.htmlspecialchars($this->doc
->issueCommand('&cmd['.$table.']['.$row['uid'].'][delete]=1')).'" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.delete', TRUE) . '">' .
622 t3lib_iconWorks
::getSpriteIcon('actions-edit-delete') .
627 if ($table == 'pages') {
629 // If another page module was specified, replace the default Page module with the new one
630 $newPageModule = trim($BE_USER->getTSConfigVal('options.overridePageModule'));
631 $pageModule = t3lib_BEfunc
::isModuleSetInTBE_MODULES($newPageModule) ?
$newPageModule : 'web_layout';
633 // Perform some acccess checks:
634 $a_wl = $BE_USER->check('modules','web_list');
635 $a_wp = t3lib_extMgm
::isLoaded('cms') && $BE_USER->check('modules',$pageModule);
637 $adminLink.='<a href="#" onclick="top.loadEditId('.$row['uid'].');top.goToModule(\''.$pageModule.'\'); return false;">'.
638 t3lib_iconWorks
::getSpriteIcon('apps-version-page-open') .
640 $adminLink.='<a href="#" onclick="top.loadEditId('.$row['uid'].');top.goToModule(\'web_list\'); return false;">'.
641 t3lib_iconWorks
::getSpriteIcon('actions-system-list-open') .
644 // "View page" icon is added:
645 $adminLink.='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc
::viewOnClick($row['uid'],$this->doc
->backPath
,t3lib_BEfunc
::BEgetRootLine($row['uid']))).'">'.
646 t3lib_iconWorks
::getSpriteIcon('actions-document-view') .
649 if ($row['pid']==-1) {
650 $getVars = '&ADMCMD_vPrev['.rawurlencode($table.':'.$row['t3ver_oid']).']='.$row['uid'];
652 // "View page" icon is added:
653 $adminLink.='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc
::viewOnClick($row['_REAL_PID'],$this->doc
->backPath
,t3lib_BEfunc
::BEgetRootLine($row['_REAL_PID']),'','',$getVars)).'">'.
654 t3lib_iconWorks
::getSpriteIcon('actions-document-view') .
672 /******************************
674 * Workspace management
676 ******************************/
679 * Management of workspace for page ID
680 * Called when $this->id is set.
684 function workspaceMgm() {
686 // Perform workspace publishing action if buttons are pressed:
687 $errors = $this->publishAction();
689 // Generate workspace overview:
690 $WSoverview = $this->displayWorkspaceOverview();
692 // Buttons for publish / swap:
693 $actionLinks = '<br />';
694 if ($GLOBALS['BE_USER']->workspace
!==0) {
695 if ($this->publishAccess
) {
696 $actionLinks.= '<input type="submit" name="_publish" value="' . $GLOBALS['LANG']->getLL('publishPage') . '" onclick="return confirm(\'' . sprintf($GLOBALS['LANG']->getLL('publishPageQuestion'), $GLOBALS['BE_USER']->workspaceRec
['publish_access'] & 1 ?
$GLOBALS['LANG']->getLL('publishPageQuestionStage') : '') . '\');"/>';
697 if ($GLOBALS['BE_USER']->workspaceSwapAccess()) {
698 $actionLinks.= '<input type="submit" name="_swap" value="' . $GLOBALS['LANG']->getLL('swapPage') . '" onclick="return confirm(\'' . sprintf($GLOBALS['LANG']->getLL('swapPageQuestion'), $GLOBALS['BE_USER']->workspaceRec
['publish_access'] & 1 ?
$GLOBALS['LANG']->getLL('publishPageQuestionStage') : '') . '\');" />';
701 $actionLinks.= $this->doc
->icons(1) . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xml:no_publish_permission');
705 $actionLinks.= '<input type="submit" name="_" value="' . $GLOBALS['LANG']->getLL('refresh') . '" />';
706 $actionLinks.= '<input type="submit" name="_previewLink" value="' . $GLOBALS['LANG']->getLL('previewLink') . '" />';
707 $actionLinks.= '<input type="checkbox" class="checkbox" name="_previewLink_wholeWorkspace" id="_previewLink_wholeWorkspace" value="1" /><label for="_previewLink_wholeWorkspace">' . $GLOBALS['LANG']->getLL('allowPreviewOfWholeWorkspace') . '</label>';
708 $actionLinks.= $this->displayWorkspaceOverview_allStageCmd();
710 if ($actionLinks ||
count($errors)) {
711 $this->content
.= $this->doc
->section('', $actionLinks . (count($errors) ?
'<h3>' . $GLOABLS['LANG']->getLL('errors') . '</h3><br />' . implode('<br />', $errors) . '<hr />' : ''), 0, 1);
714 if (t3lib_div
::_POST('_previewLink')) {
715 $ttlHours = intval($GLOBALS['BE_USER']->getTSConfigVal('options.workspaces.previewLinkTTLHours'));
716 $ttlHours = ($ttlHours ?
$ttlHours : 24*2);
718 if (t3lib_div
::_POST('_previewLink_wholeWorkspace')) {
719 $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($this->id
);
721 $params = 'id='.$this->id
.'&ADMCMD_previewWS='.$GLOBALS['BE_USER']->workspace
;
722 $previewUrl = t3lib_div
::getIndpEnv('TYPO3_SITE_URL').'index.php?ADMCMD_prev='.t3lib_BEfunc
::compilePreviewKeyword($params, $GLOBALS['BE_USER']->user
['uid'],60*60*$ttlHours);
724 $this->content
.= $this->doc
->section($GLOBALS['LANG']->getLL('previewUrl'), sprintf($GLOBALS['LANG']->getLL('previewInstruction'), $ttlHours) . '<br /><br /><a target="_blank" href="' . htmlspecialchars($previewUrl) . '">' . $previewUrl . '</a>', 0, 1);
727 // Output overview content:
728 $this->content
.= $this->doc
->spacer(15);
729 $this->content
.= $this->doc
->section($this->details ?
$GLOBALS['LANG']->getLL('versionDetails') : $GLOBALS['LANG']->getLL('wsManagement'), $WSoverview,0,1);
733 function workspaceMenu() {
736 if ($GLOBALS['BE_USER']->workspace
===0) {
737 $menu.= t3lib_BEfunc
::getFuncMenu($this->id
,'SET[filter]',$this->MOD_SETTINGS
['filter'],$this->MOD_MENU
['filter']);
738 $menu.= t3lib_BEfunc
::getFuncMenu($this->id
,'SET[display]',$this->MOD_SETTINGS
['display'],$this->MOD_MENU
['display']);
740 if (!$this->details
&& $GLOBALS['BE_USER']->workspace
&& !$this->diffOnly
) {
741 $menu.= t3lib_BEfunc
::getFuncCheck($this->id
,'SET[diff]',$this->MOD_SETTINGS
['diff'],'','','id="checkDiff"').' <label for="checkDiff">' . $GLOBALS['LANG']->getLL('showDiffView') . '</label>';
751 * Rendering the overview of versions in the current workspace
753 * @return string HTML (table)
754 * @see typo3/mod/user/ws/index.php for sister function!
756 function displayWorkspaceOverview() {
758 // Initialize variables:
759 $this->showWorkspaceCol
= $GLOBALS['BE_USER']->workspace
===0 && $this->MOD_SETTINGS
['display']<=-98;
761 // Get usernames and groupnames
762 $be_group_Array = t3lib_BEfunc
::getListGroupNames('title,uid');
763 $groupArray = array_keys($be_group_Array);
764 $this->be_user_Array
= t3lib_BEfunc
::getUserNames();
765 if (!$GLOBALS['BE_USER']->isAdmin()) $this->be_user_Array
= t3lib_BEfunc
::blindUserNames($this->be_user_Array
,$groupArray,1);
767 // Initialize Workspace ID and filter-value:
768 if ($GLOBALS['BE_USER']->workspace
===0) {
769 $wsid = $this->details ?
-99 : $this->MOD_SETTINGS
['display']; // Set wsid to the value from the menu (displaying content of other workspaces)
770 $filter = $this->details ?
0 : $this->MOD_SETTINGS
['filter'];
772 $wsid = $GLOBALS['BE_USER']->workspace
;
776 // Initialize workspace object and request all pending versions:
777 $wslibObj = t3lib_div
::makeInstance('wslib');
779 // Selecting ALL versions belonging to the workspace:
780 $versions = $wslibObj->selectVersionsInWorkspace($wsid, $filter, -99, $this->uid
); // $this->uid is the page id of LIVE record.
782 // Traverse versions and build page-display array:
784 foreach($versions as $table => $records) {
785 foreach($records as $rec) {
786 $pageIdField = $table==='pages' ?
't3ver_oid' : 'realpid';
787 $this->displayWorkspaceOverview_setInPageArray(
795 // Make header of overview:
796 $tableRows = array();
797 if (count($pArray)) {
799 <tr class="bgColor5 tableheader">
800 '.($this->diffOnly?
'':'<td nowrap="nowrap" colspan="2">' . $GLOBALS['LANG']->getLL('liveVersion') . '</td>').'
801 <td nowrap="nowrap" colspan="2">' . $GLOBALS['LANG']->getLL('wsVersions') . '</td>
802 <td nowrap="nowrap"'.($this->diffOnly?
' colspan="2"':' colspan="4"').'>' . $GLOBALS['LANG']->getLL('controls') . '</td>
805 // Add lines from overview:
806 $tableRows = array_merge($tableRows, $this->displayWorkspaceOverview_list($pArray));
808 $table = '<table border="0" cellpadding="0" cellspacing="1" class="lrPadding workspace-overview">'.implode('',$tableRows).'</table>';
811 $linkBack = t3lib_div
::_GP('returnUrl') ?
'<a href="' . htmlspecialchars(t3lib_div
::_GP('returnUrl')) . '" class="typo3-goBack">' .
812 t3lib_iconWorks
::getSpriteIcon('actions-go-back') . $GLOBALS['LANG']->getLL('goBack', TRUE) .
813 '</a><br /><br />' : '';
814 $resetDiffOnly = $this->diffOnly ?
'<a href="index.php?id=' . intval($this->id
) . '" class="typo3-goBack">' . $GLOBALS['LANG']->getLL('showAllInformation') . '</a><br /><br />' : '';
816 $versionSelector = $GLOBALS['BE_USER']->workspace ?
$this->doc
->getVersionSelector($this->id
) : '';
818 return $versionSelector.$linkBack.$resetDiffOnly.$table.$this->markupNewOriginals();
822 * Rendering the content for the publish / review overview:
823 * (Made for internal recursive calling)
825 * @param array Storage of the elements to display (see displayWorkspaceOverview() / displayWorkspaceOverview_setInPageArray())
826 * @return array Table rows, see displayWorkspaceOverview()
828 function displayWorkspaceOverview_list($pArray) {
831 // If there ARE elements on this level, print them:
832 $warnAboutVersions_nonPages = FALSE;
833 $warnAboutVersions_page = FALSE;
834 if (is_array($pArray)) {
835 foreach($pArray as $table => $oidArray) {
836 foreach($oidArray as $oid => $recs) {
838 // Get CURRENT online record and icon based on "t3ver_oid":
839 $rec_on = t3lib_BEfunc
::getRecord($table,$oid);
840 $icon = t3lib_iconWorks
::getIconImage($table, $rec_on, $this->doc
->backPath
,' align="top" title="'.t3lib_BEfunc
::getRecordIconAltText($rec_on,$table).'"');
841 if ($GLOBALS['BE_USER']->workspace
===0) { // Only edit online records if in ONLINE workspace:
842 $icon = $this->doc
->wrapClickMenuOnIcon($icon, $table, $rec_on['uid'], 1, '', '+edit,view,info,delete');
845 // Online version display:
846 // Create the main cells which will span over the number of versions there is.
847 $verLinkUrl = $TCA[$table]['ctrl']['versioningWS'];
848 $origElement = $icon.
849 ($verLinkUrl ?
'<a href="'.htmlspecialchars('index.php?table='.$table.'&uid='.$rec_on['uid']).'">' : '').
850 t3lib_BEfunc
::getRecordTitle($table,$rec_on,TRUE).
851 ($verLinkUrl ?
'</a>' : '');
852 $mainCell_rowSpan = count($recs)>1 ?
' rowspan="'.count($recs).'"' : '';
854 <td align="center"'.$mainCell_rowSpan.'>'.$this->formatVerId($rec_on['t3ver_id']).'</td>
855 <td nowrap="nowrap"'.$mainCell_rowSpan.'>'.
857 '###SUB_ELEMENTS###'. // For substitution with sub-elements, if any.
860 // Offline versions display:
861 // Traverse the versions of the element
862 foreach($recs as $rec) {
864 // Get the offline version record and icon:
865 $rec_off = t3lib_BEfunc
::getRecord($table,$rec['uid']);
867 // Prepare swap-mode values:
868 if ($table==='pages' && $rec_off['t3ver_swapmode']!=-1) {
869 if ($rec_off['t3ver_swapmode']>0) {
879 $icon = t3lib_iconWorks
::getIconImage($table, $rec_off, $this->doc
->backPath
, ' align="top" title="'.t3lib_BEfunc
::getRecordIconAltText($rec_off,$table).'"');
880 $tempUid = ($table != 'pages' ||
$vType==='branch' ||
$GLOBALS['BE_USER']->workspace
===0 ?
$rec_off['uid'] : $rec_on['uid']);
881 $icon = $this->doc
->wrapClickMenuOnIcon($icon, $table, $tempUid, 1, '', '+edit,' . ($table == 'pages' ?
'view,info,' : '') . 'delete');
883 // Prepare diff-code:
884 if ($this->MOD_SETTINGS
['diff'] ||
$this->diffOnly
) {
886 list($diffHTML,$diffPct) = $this->createDiffView($table, $rec_off, $rec_on);
887 if ($rec_on['t3ver_state']==1) { // New record:
888 $diffCode.= $this->doc
->icons(1) . $GLOBALS['LANG']->getLL('newElement') . '<br />';
889 $diffCode.= $diffHTML;
890 } elseif ($rec_off['t3ver_state']==2) {
891 $diffCode.= $this->doc
->icons(2) . $GLOBALS['LANG']->getLL('deletedElement') . '<br />';
892 } elseif ($rec_on['t3ver_state']==3) {
893 $diffCode.= $this->doc
->icons(1) . $GLOBALS['LANG']->getLL('moveToPlaceholder') . '<br />';
894 } elseif ($rec_off['t3ver_state']==4) {
895 $diffCode.= $this->doc
->icons(1) . $GLOBALS['LANG']->getLL('moveToPointer') . '<br />';
897 $diffCode.= ($diffPct<0 ?
$GLOBALS['LANG']->getLL('notAvailable') : ($diffPct ?
$diffPct . '% ' . $GLOBALS['LANG']->getLL('change') : ''));
898 $diffCode.= $diffHTML;
900 } else $diffCode = '';
904 $swapLabel = $GLOBALS['LANG']->getLL('element');
905 $swapClass = 'ver-element';
906 $warnAboutVersions_nonPages = $warnAboutVersions_page; // Setting this if sub elements are found with a page+content (must be rendered prior to this of course!)
909 $swapLabel = $GLOBALS['LANG']->getLL('page');
910 $swapClass = 'ver-page';
911 $warnAboutVersions_page = !$this->showWorkspaceCol
; // This value is true only if multiple workspaces are shown and we need the opposite here.
914 $swapLabel = $GLOBALS['LANG']->getLL('branch');
915 $swapClass = 'ver-branch';
919 // Modify main cell based on first version shown:
920 $subElements = array();
921 if ($table==='pages' && $rec_off['t3ver_swapmode']!=-1 && $mainCell) { // For "Page" and "Branch" swap modes where $mainCell is still carrying content (only first version)
922 $subElements['on'] = $this->subElements($rec_on['uid'], $rec_off['t3ver_swapmode']);
923 $subElements['off'] = $this->subElements($rec_off['uid'],$rec_off['t3ver_swapmode'],$rec_on['uid']);
925 $mainCell = str_replace('###SUB_ELEMENTS###', $subElements['on'], $mainCell);
927 // Create version element:
928 $versionsInOtherWS = $this->versionsInOtherWS($table, $rec_on['uid']);
929 $versionsInOtherWSWarning = $versionsInOtherWS && $GLOBALS['BE_USER']->workspace
!== 0 ?
'<br />' . $this->doc
->icons(2) . $GLOBALS['LANG']->getLL('otherVersions') . $versionsInOtherWS : '';
930 $multipleWarning = (!$mainCell && $GLOBALS['BE_USER']->workspace
!== 0 ?
'<br />' . $this->doc
->icons(3) . '<b>' . $GLOBALS['LANG']->getLL('multipleVersions') . '</b>' : '');
931 $verWarning = $warnAboutVersions ||
($warnAboutVersions_nonPages && $GLOBALS['TCA'][$table]['ctrl']['versioning_followPages']) ?
'<br />' . $this->doc
->icons(3) . '<b>' . $GLOBALS['LANG']->getLL('versionInVersion') . '</b>' : '';
933 (!$this->details ?
'<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($this->REQUEST_URI
)).'">' : '').
934 t3lib_BEfunc
::getRecordTitle($table,$rec_off,TRUE).
935 (!$this->details ?
'</a>' : '').
936 $versionsInOtherWSWarning.
941 <td nowrap="nowrap">'.$this->showStageChangeLog($table,$rec_off['uid'],$this->displayWorkspaceOverview_stageCmd($table,$rec_off)).'</td>
942 <td nowrap="nowrap" class="'.$swapClass.'">'.
943 $this->displayWorkspaceOverview_commandLinks($table,$rec_on,$rec_off,$vType).
944 htmlspecialchars($swapLabel).
946 '.(!$this->diffOnly?
'<td nowrap="nowrap"><b>' . $GLOBALS['LANG']->getLL('lifecycle') . ':</b> '.htmlspecialchars($this->formatCount($rec_off['t3ver_count'])).'</td>'. // Lifecycle
947 ($this->showWorkspaceCol ?
'
948 <td nowrap="nowrap"> <b>' . $GLOBALS['LANG']->getLL('workspace') . ':</b> '.htmlspecialchars($this->formatWorkspace($rec_off['t3ver_wsid'])).'</td>' : ''):'');
951 $verElement = $verElement.'
952 <br /><b>' . $GLOBALS['LANG']->getLL('diffToLiveElement') . '</b>
953 <table border="0" cellpadding="0" cellspacing="0" class="ver-verElement">
955 <td class="c-diffCell">'.$diffCode.'</td>
961 // Create version cell:
963 <td align="center">'.$this->formatVerId($rec_off['t3ver_id']).'</td>
964 <td nowrap="nowrap">'.
970 // Compile table row:
972 <tr class="bgColor4">
974 ($this->diffOnly?
'':$mainCell).
980 // Reset the main cell:
992 * Building up of the $pArray
995 * @param array Array that is built up with the page tree structure
996 * @param string Table name
997 * @param array Table row
998 * @return void $pArray is passed by reference and modified internally
1000 function displayWorkspaceOverview_setInPageArray(&$pArray,$table,$row) {
1001 if (!$this->details ||
$this->details
==$table.':'.$row['uid']) {
1002 $pArray[$table][$row['t3ver_oid']][] = $row;
1007 * Links to stage change of a version
1009 * @param string Table name
1010 * @param array Offline record (version)
1011 * @return string HTML content, mainly link tags and images.
1013 function displayWorkspaceOverview_allStageCmd() {
1015 $table = t3lib_div
::_GP('table');
1016 if ($table && $table!='pages') {
1017 $uid = t3lib_div
::_GP('uid');
1018 if ($rec_off = t3lib_BEfunc
::getRecordWSOL($table,$uid)) {
1019 $uid = $rec_off['_ORIG_uid'];
1024 if ($uid && $this->recIndex
[$table][$uid]) {
1025 $sId = $this->recIndex
[$table][$uid];
1028 $label = $GLOBALS['LANG']->getLL('commentForReviewer');
1031 $label = $GLOBALS['LANG']->getLL('commentForPublisher');
1036 if (count($this->stageIndex
[1])) { // Review:
1039 $label = $GLOBALS['LANG']->getLL('sendItemsToReview') . $GLOBALS['LANG']->getLL('commentForReviewer');
1040 $titleAttrib = $GLOBALS['LANG']->getLL('sendAllToReview');
1041 } elseif(count($this->stageIndex
[10])) { // Publish:
1044 $label = $GLOBALS['LANG']->getLL('approveToPublish') . $GLOBALS['LANG']->getLL('commentForPublisher');
1045 $titleAttrib = $GLOBALS['LANG']->getLL('approveAllToPublish');
1055 if ($table && $uid && $this->recIndex
[$table][$uid]) {
1056 $issueCmd.='&cmd['.$table.']['.$uid.'][version][action]=setStage';
1057 $issueCmd.='&cmd['.$table.']['.$uid.'][version][stageId]='.$this->recIndex
[$table][$uid];
1059 foreach($this->stageIndex
[$sId] as $table => $uidArray) {
1060 $issueCmd.='&cmd['.$table.']['.implode(',',$uidArray).'][version][action]=setStage';
1061 $issueCmd.='&cmd['.$table.']['.implode(',',$uidArray).'][version][stageId]='.$sId;
1062 $itemCount+
=count($uidArray);
1066 $onClick = 'var commentTxt=window.prompt("'.sprintf($label,$itemCount).'","");
1067 if (commentTxt!=null) {window.location.href="'.$this->doc
->issueCommand($issueCmd,$this->REQUEST_URI
).'&generalComment="+escape(commentTxt);}';
1069 if (t3lib_div
::_GP('sendToReview')) {
1070 $onClick.= ' else {window.location.href = "'.$this->REQUEST_URI
.'"}';
1072 $this->doc
->wrapScriptTags($onClick);
1074 $onClick.= ' return false;';
1076 '<input type="submit" name="_" value="'.htmlspecialchars($titleAttrib).'" onclick="'.htmlspecialchars($onClick).'" />';
1078 } elseif (t3lib_div
::_GP('sendToReview')) {
1079 $onClick = 'window.location.href = "'.$this->REQUEST_URI
.'";';
1081 $this->doc
->wrapScriptTags($onClick);
1082 } else $actionLinks = '';
1084 return $actionLinks;
1092 /**************************************
1094 * Helper functions (REDUNDANT FROM user/ws/index.php - someone could refactor this...)
1096 *************************************/
1099 * Formatting the version number for HTML output
1101 * @param integer Version number
1102 * @return string Version number for output
1104 function formatVerId($verId) {
1109 * Formatting workspace ID into a visual label
1111 * @param integer Workspace ID
1112 * @return string Workspace title
1114 function formatWorkspace($wsid) {
1116 // Render, if not cached:
1117 if (!isset($this->formatWorkspace_cache
[$wsid])) {
1120 $this->formatWorkspace_cache
[$wsid] = $GLOBALS['LANG']->getLL('offline');
1123 $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...
1126 list($titleRec) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('title','sys_workspace','uid='.intval($wsid).t3lib_BEfunc
::deleteClause('sys_workspace'));
1127 $this->formatWorkspace_cache
[$wsid] = '['.$wsid.'] '.$titleRec['title'];
1132 return $this->formatWorkspace_cache
[$wsid];
1136 * Format publishing count for version (lifecycle state)
1138 * @param integer t3ver_count value (number of times it has been online)
1139 * @return string String translation of count.
1141 function formatCount($count) {
1143 // Render, if not cached:
1144 if (!isset($this->formatCount_cache
[$count])) {
1147 $this->formatCount_cache
[$count] = $GLOBALS['LANG']->getLL('draft');
1150 $this->formatCount_cache
[$count] = $GLOBALS['LANG']->getLL('archive');
1153 $this->formatCount_cache
[$count] = sprintf($GLOBALS['LANG']->getLL('publishedXTimes'), $count);
1158 return $this->formatCount_cache
[$count];
1162 * Looking for versions of a record in other workspaces than the current
1164 * @param string Table name
1165 * @param integer Record uid
1166 * @return string List of other workspace IDs
1168 function versionsInOtherWS($table,$uid) {
1170 // Check for duplicates:
1171 // Select all versions of record NOT in this workspace:
1172 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1176 AND t3ver_oid='.intval($uid).'
1177 AND t3ver_wsid!='.intval($GLOBALS['BE_USER']->workspace
).'
1178 AND (t3ver_wsid=-1 OR t3ver_wsid>0)'.
1179 t3lib_BEfunc
::deleteClause($table),
1186 return implode(',',array_keys($rows));
1191 * Looks up stage changes for version and displays a formatted view on mouseover.
1193 * @param string Table name
1194 * @param integer Record ID
1195 * @param string HTML string to wrap the mouseover around (should be stage change links)
1196 * @return string HTML code.
1198 function showStageChangeLog($table,$id,$stageCommands) {
1199 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1200 'log_data,tstamp,userid',
1202 'action=6 and details_nr=30
1203 AND tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_log').'
1204 AND recuid='.intval($id)
1208 foreach($rows as $dat) {
1209 $data = unserialize($dat['log_data']);
1210 $username = $this->be_user_Array
[$dat['userid']] ?
$this->be_user_Array
[$dat['userid']]['username'] : '['.$dat['userid'].']';
1212 switch($data['stage']) {
1214 $text = $GLOBALS['LANG']->getLL('stage.sentToReview');
1217 $text = $GLOBALS['LANG']->getLL('stage.approvedForPublish');
1220 $text = $GLOBALS['LANG']->getLL('stage.rejectedElement');
1223 $text = $GLOBALS['LANG']->getLL('stage.resetToEdit');
1226 $text = $GLOBALS['LANG']->getLL('stage.undefined');
1229 $text = t3lib_BEfunc
::dateTime($dat['tstamp']).': "'.$username.'" '.$text;
1230 $text.= ($data['comment'] ?
'<br />' . $GLOBALS['LANG']->getLL('userComment') . ': <em>' . htmlspecialchars($data['comment']) . '</em>' : '');
1235 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>'.
1236 '<div class="logLayer" style="visibility: hidden; position: absolute;" id="log_'.$table.$id.'">'.implode('<hr/>',array_reverse($entry)).'</div>' : $stageCommands;
1240 * Creates display of sub elements of a page when the swap mode is either "Page" or "Branch" (0 / ALL)
1242 * @param integer Page uid (for either online or offline version, but it MUST have swapmode/treeLevel set to >0 (not -1 indicating element versioning)
1243 * @param integer The treeLevel value, >0 indicates "branch" while 0 means page+content. (-1 would have meant element versioning, but that should never happen for a call to this function!)
1244 * @param integer For offline versions; This is t3ver_oid, the original ID of the online page.
1245 * @return string HTML content.
1247 function subElements($uid,$treeLevel,$origId=0) {
1250 if (!$this->details
&& ($GLOBALS['BE_USER']->workspace
===0 ||
!$this->MOD_SETTINGS
['expandSubElements'])) { // In online workspace we have a reduced view because otherwise it will bloat the listing:
1252 <img'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/ol/joinbottom.gif','width="18" height="16"').' align="top" alt="" title="" />'.
1254 '<a href="'.htmlspecialchars($this->doc
->backPath
.t3lib_extMgm
::extRelPath('version').'cm1/index.php?id='.$uid.'&details='.rawurlencode('pages:'.$uid).'&returnUrl='.rawurlencode($this->REQUEST_URI
)).'">'.
1255 '<span class="typo3-dimmed"><em>' . $GLOBALS['LANG']->getLL('subElementsClick') . '</em><span></a>' :
1256 '<span class="typo3-dimmed"><em>' . $GLOBALS['LANG']->getLL('subElements') . '</em><span>');
1257 } else { // For an offline workspace, show sub elements:
1261 // Find records that follow pages when swapping versions:
1263 foreach($TCA as $tN => $tCfg) {
1264 if ($tN!='pages' && ($treeLevel>0 ||
$TCA[$tN]['ctrl']['versioning_followPages'])) {
1265 $this->subElements_getNonPageRecords($tN, $uid, $recList);
1269 // Render records collected above:
1270 $elCount = count($recList)-1;
1271 foreach($recList as $c => $comb) {
1272 list($tN,$rec) = $comb;
1274 $this->subElements_renderItem(
1280 $c==$elCount && $treeLevel==0 ?
1 : 0, // If true, will show bottom-join icon.
1285 // For branch, dive into the subtree:
1289 $tree = t3lib_div
::makeInstance('t3lib_pageTree');
1290 $tree->init('AND '.$GLOBALS['BE_USER']->getPagePermsClause(1));
1291 $tree->makeHTML
= 2; // 2=Also rendering depth-data into the result array
1292 $tree->getTree($uid, 99, '');
1294 // Traverse page tree:
1295 foreach($tree->tree
as $data) {
1297 // Render page in table cell:
1298 $this->subElements_renderItem(
1302 t3lib_BEfunc
::getRecord('pages',$data['row']['uid']), // Needs all fields, at least more than what is given in $data['row']...
1304 2, // 2=the join icon and icon for the record is not rendered for pages (where all is in $data['HTML']
1308 // Find all records from page and collect in $recList:
1310 foreach($TCA as $tN => $tCfg) {
1311 if ($tN!=='pages') {
1312 $this->subElements_getNonPageRecords($tN, $data['row']['uid'], $recList);
1316 // Render records collected above:
1317 $elCount = count($recList)-1;
1318 foreach($recList as $c => $comb) {
1319 list($tN,$rec) = $comb;
1321 $this->subElements_renderItem(
1327 $c==$elCount?
1:0, // If true, will show bottom-join icon.
1328 $data['HTML_depthData']
1335 <!-- Sub-element tree for versions -->
1336 <table border="0" cellpadding="0" cellspacing="1" class="ver-subtree">
1337 '.implode('',$tCell).'
1343 * Select records from a table and add them to recList
1345 * @param string Table name (from TCA)
1346 * @param integer PID to select records from
1347 * @param array Array where records are accumulated, passed by reference
1350 function subElements_getNonPageRecords($tN, $uid, &$recList) {
1353 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1356 'pid='.intval($uid).
1357 ($TCA[$tN]['ctrl']['versioningWS'] ?
' AND t3ver_state=0' : '').
1358 t3lib_BEfunc
::deleteClause($tN),
1360 $TCA[$tN]['ctrl']['sortby'] ?
$TCA[$tN]['ctrl']['sortby'] : $GLOBALS['TYPO3_DB']->stripOrderBy($TCA[$tN]['ctrl']['default_sortby'])
1363 foreach($records as $rec) {
1364 $recList[] = array($tN,$rec);
1369 * Render a single item in a subelement list into a table row:
1371 * @param array Table rows, passed by reference
1372 * @param string Table name
1373 * @param integer Page uid for which the subelements are selected/shown
1374 * @param array Row of element in list
1375 * @param integer The uid of the online version of $uid. If zero it means we are drawing a row for the online version itself while a value means we are drawing display for an offline version.
1376 * @param integer Mode of icon display: 0=not the last, 1= is the last in list (make joinbottom icon then), 2=do not shown icons are all (for pages from the page tree already rendered)
1377 * @param string Prefix HTML data (icons for tree rendering)
1378 * @return void (Content accumulated in $tCell!)
1380 function subElements_renderItem(&$tCell,$tN,$uid,$rec,$origId,$iconMode,$HTMLdata) {
1384 $origUidFields = $TCA[$tN]['ctrl']['origUid'];
1387 if ($origUidFields) { // If there is a field for this table with original uids we will use that to connect records:
1388 if (!$origId) { // In case we are displaying the online originals:
1389 $this->targets
['orig_'.$uid.'_'.$tN.'_'.$rec['uid']] = $rec; // Build up target array (important that
1390 $tdParams = ' id="orig_'.$uid.'_'.$tN.'_'.$rec['uid'].'" class="typo3-ver"'; // Setting ID of the table row
1391 } else { // Version branch:
1392 if ($this->targets
['orig_'.$origId.'_'.$tN.'_'.$rec[$origUidFields]]) { // If there IS a corresponding original record...:
1394 // Prepare Table row parameters:
1395 $tdParams = ' onmouseover="hlSubelements(\''.$origId.'_'.$tN.'_'.$rec[$origUidFields].'\', \''.$uid.'_'.$tN.'_'.$rec[$origUidFields].'\', 1, '.($this->MOD_SETTINGS
['diff']==2?
1:0).');"'.
1396 ' onmouseout="hlSubelements(\''.$origId.'_'.$tN.'_'.$rec[$origUidFields].'\', \''.$uid.'_'.$tN.'_'.$rec[$origUidFields].'\', 0, '.($this->MOD_SETTINGS
['diff']==2?
1:0).');"'.
1397 ' id="ver_'.$uid.'_'.$tN.'_'.$rec[$origUidFields].'" class="typo3-ver"';
1399 // Create diff view:
1400 if ($this->MOD_SETTINGS
['diff']) {
1401 list($diffHTML,$diffPct) = $this->createDiffView($tN, $rec, $this->targets
['orig_'.$origId.'_'.$tN.'_'.$rec[$origUidFields]]);
1403 if ($this->MOD_SETTINGS
['diff']==2) {
1405 ($diffPct ?
'<span class="nobr">'.$diffPct.'% change</span>' : '-').
1406 '<div style="visibility: hidden; position: absolute;" id="diff_'.$uid.'_'.$tN.'_'.$rec[$origUidFields].'" class="diffLayer">'.
1411 ($diffPct<0 ?
$GLOBALS['LANG']->getLL('notAvailable') : ($diffPct ?
$diffPct . '% ' . $GLOBALS['LANG']->getLL('change') : '')).
1416 // Unsetting the target fields allows us to mark all originals without a version in the subtree (see ->markupNewOriginals())
1417 unset($this->targets
['orig_'.$origId.'_'.$tN.'_'.$rec[$origUidFields]]);
1418 } else { // No original record, so must be new:
1419 $tdParams = ' class="typo3-ver-new"';
1422 } else { // If no original uid column is supported for this table we are forced NOT to display any diff or highlighting.
1423 $tdParams = ' class="typo3-ver-noComp"';
1426 // Compile the cell:
1429 <td class="iconTitle">'.
1432 '<img'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/ol/join'.($iconMode ?
'bottom' : '').'.gif','width="18" height="16"').' alt="" />'.
1433 t3lib_iconWorks
::getIconImage($tN, $rec, $this->doc
->backPath
,'') : '').
1434 t3lib_BEfunc
::getRecordTitle($tN, $rec, TRUE).
1436 <td class="cmdCell">'.
1437 $this->displayWorkspaceOverview_commandLinksSub($tN,$rec,$origId).
1438 '</td>'.($origId ?
'<td class="diffCell">'.
1445 * JavaScript code to mark up new records that are online (in sub element lists)
1447 * @return string HTML javascript section
1449 function markupNewOriginals() {
1451 if (count($this->targets
)) {
1453 foreach($this->targets
as $key => $rec) {
1455 document.getElementById(\''.$key.'\').attributes.getNamedItem("class").nodeValue = \'typo3-ver-new\';
1459 return $this->doc
->wrapScriptTags($scriptCode);
1464 * Create visual difference view of two records. Using t3lib_diff library
1466 * @param string Table name
1467 * @param array New version record (green)
1468 * @param array Old version record (red)
1469 * @return array Array with two keys (0/1) with HTML content / percentage integer (if -1, then it means N/A) indicating amount of change
1471 function createDiffView($table, $diff_1_record, $diff_2_record) {
1477 // Check that records are arrays:
1478 if (is_array($diff_1_record) && is_array($diff_2_record)) {
1480 // Load full table description and initialize diff-object:
1481 t3lib_div
::loadTCA($table);
1482 $t3lib_diff_Obj = t3lib_div
::makeInstance('t3lib_diff');
1487 <tr class="bgColor5 tableheader">
1488 <td>' . $GLOBALS['LANG']->getLL('fieldname') . ':</td>
1489 <td width="98%" nowrap="nowrap">' . $GLOBALS['LANG']->getLL('coloredDiffView') . ':</td>
1493 // Initialize variables to pick up string lengths in:
1497 // Traversing the first record and process all fields which are editable:
1498 foreach($diff_1_record as $fN => $fV) {
1499 if ($TCA[$table]['columns'][$fN] && $TCA[$table]['columns'][$fN]['config']['type']!='passthrough' && !t3lib_div
::inList('t3ver_label',$fN)) {
1501 // Check if it is files:
1503 if (strcmp(trim($diff_1_record[$fN]),trim($diff_2_record[$fN])) &&
1504 $TCA[$table]['columns'][$fN]['config']['type']=='group' &&
1505 $TCA[$table]['columns'][$fN]['config']['internal_type']=='file') {
1508 $uploadFolder = $TCA[$table]['columns'][$fN]['config']['uploadfolder'];
1509 $files1 = array_flip(t3lib_div
::trimExplode(',', $diff_1_record[$fN],1));
1510 $files2 = array_flip(t3lib_div
::trimExplode(',', $diff_2_record[$fN],1));
1512 // Traverse filenames and read their md5 sum:
1513 foreach($files1 as $filename => $tmp) {
1514 $files1[$filename] = @is_file
(PATH_site
.$uploadFolder.'/'.$filename) ?
md5(t3lib_div
::getUrl(PATH_site
.$uploadFolder.'/'.$filename)) : $filename;
1516 foreach($files2 as $filename => $tmp) {
1517 $files2[$filename] = @is_file
(PATH_site
.$uploadFolder.'/'.$filename) ?
md5(t3lib_div
::getUrl(PATH_site
.$uploadFolder.'/'.$filename)) : $filename;
1520 // Implode MD5 sums and set flag:
1521 $diff_1_record[$fN] = implode(' ',$files1);
1522 $diff_2_record[$fN] = implode(' ',$files2);
1526 // If there is a change of value:
1527 if (strcmp(trim($diff_1_record[$fN]),trim($diff_2_record[$fN]))) {
1530 // Get the best visual presentation of the value and present that:
1531 $val1 = t3lib_BEfunc
::getProcessedValue($table,$fN,$diff_2_record[$fN],0,1);
1532 $val2 = t3lib_BEfunc
::getProcessedValue($table,$fN,$diff_1_record[$fN],0,1);
1534 // Make diff result and record string lenghts:
1535 $diffres = $t3lib_diff_Obj->makeDiffDisplay($val1,$val2,$isFiles?
'div':'span');
1536 $diffStrLen+
= $t3lib_diff_Obj->differenceLgd
;
1537 $allStrLen+
= strlen($val1.$val2);
1539 // If the compared values were files, substituted MD5 hashes:
1541 $allFiles = array_merge($files1,$files2);
1542 foreach($allFiles as $filename => $token) {
1543 if (strlen($token)==32 && strstr($diffres,$token)) {
1545 t3lib_BEfunc
::thumbCode(array($fN=>$filename),$table,$fN,$this->doc
->backPath
).
1547 $diffres = str_replace($token,$filename,$diffres);
1552 // Add table row with result:
1554 <tr class="bgColor4">
1555 <td>'.htmlspecialchars($GLOBALS['LANG']->sL(t3lib_BEfunc
::getItemLabel($table,$fN))).'</td>
1556 <td width="98%">'.$diffres.'</td>
1560 // Add string lengths even if value matched - in this was the change percentage is not high if only a single field is changed:
1561 $allStrLen+
=strlen($diff_1_record[$fN].$diff_2_record[$fN]);
1566 // Calculate final change percentage:
1567 $pctChange = $allStrLen ?
ceil($diffStrLen*100/$allStrLen) : -1;
1569 // Create visual representation of result:
1570 if (count($tRows)>1) {
1571 $content.= '<table border="0" cellpadding="1" cellspacing="1" class="diffTable">'.implode('',$tRows).'</table>';
1573 $content.= '<span class="nobr">'.$this->doc
->icons(1) . $GLOBALS['LANG']->getLL('completeMatch') . '</span>';
1575 } else $content.= $this->doc
->icons(3) . $GLOBALS['LANG']->getLL('errorRecordsNotFound');
1578 return array($content,$pctChange);
1582 * Links to stage change of a version
1584 * @param string Table name
1585 * @param array Offline record (version)
1586 * @return string HTML content, mainly link tags and images.
1588 function displayWorkspaceOverview_stageCmd($table,&$rec_off) {
1589 #debug($rec_off['t3ver_stage']);
1590 switch((int)$rec_off['t3ver_stage']) {
1593 $sLabel = $GLOBALS['LANG']->getLL('editing');
1595 $label = $GLOBALS['LANG']->getLL('commentForReviewer');
1596 $titleAttrib = $GLOBALS['LANG']->getLL('sendToReview');
1600 $sLabel = $GLOBALS['LANG']->getLL('review');
1602 $label = $GLOBALS['LANG']->getLL('commentForPublisher');
1603 $titleAttrib = $GLOBALS['LANG']->getLL('approveForPublishing');
1606 $sLabel = $GLOBALS['LANG']->getLL('publish');
1610 $sLabel = $this->doc
->icons(2) . $GLOBALS['LANG']->getLL('rejected');
1613 $label = $GLOBALS['LANG']->getLL('comment');
1614 $titleAttrib = $GLOBALS['LANG']->getLL('resetStage');
1617 $sLabel = $GLOBALS['LANG']->getLL('undefined');
1624 $raiseOk = !$GLOBALS['BE_USER']->workspaceCannotEditOfflineVersion($table,$rec_off);
1626 if ($raiseOk && $rec_off['t3ver_stage']!=-1) {
1627 $onClick = 'var commentTxt=window.prompt("' . $GLOBALS['LANG']->getLL('rejectExplain') . '","");
1628 if (commentTxt!=null) {window.location.href="'.$this->doc
->issueCommand(
1629 '&cmd['.$table.']['.$rec_off['uid'].'][version][action]=setStage'.
1630 '&cmd['.$table.']['.$rec_off['uid'].'][version][stageId]=-1'
1631 ).'&cmd['.$table.']['.$rec_off['uid'].'][version][comment]="+escape(commentTxt);}'.
1635 '<a href="#" onclick="'.htmlspecialchars($onClick).'" title="' . $GLOBALS['LANG']->getLL('reject', TRUE) . '">'.
1636 t3lib_iconWorks
::getSpriteIcon('actions-move-down') .
1641 '<img src="'.$this->doc
->backPath
.'gfx/clear.gif" width="14" height="14" alt="" align="top" title="" />';
1644 $actionLinks.= '<span style="background-color: '.$color.'; color: white;">'.$sLabel.'</span>';
1648 $onClick = 'var commentTxt=window.prompt("'.$label.'","");
1649 if (commentTxt!=null) {window.location.href="'.$this->doc
->issueCommand(
1650 '&cmd['.$table.']['.$rec_off['uid'].'][version][action]=setStage'.
1651 '&cmd['.$table.']['.$rec_off['uid'].'][version][stageId]='.$sId
1652 ).'&cmd['.$table.']['.$rec_off['uid'].'][version][comment]="+escape(commentTxt);}'.
1654 if ($rec_off['t3ver_stage']!=10) {
1656 '<a href="#" onclick="'.htmlspecialchars($onClick).'" title="' . htmlspecialchars($titleAttrib) . '">' .
1657 t3lib_iconWorks
::getSpriteIcon('actions-move-up') .
1660 $this->stageIndex
[$sId][$table][] = $rec_off['uid'];
1661 $this->recIndex
[$table][$rec_off['uid']] = $sId;
1664 return $actionLinks;
1668 * Links to publishing etc of a version
1670 * @param string Table name
1671 * @param array Online record
1672 * @param array Offline record (version)
1673 * @param string Swap type, "branch", "page" or "element"
1674 * @return string HTML content, mainly link tags and images.
1676 function displayWorkspaceOverview_commandLinks($table,&$rec_on,&$rec_off,$vType) {
1677 if ($this->publishAccess
&& (!($GLOBALS['BE_USER']->workspaceRec
['publish_access']&1) ||
(int)$rec_off['t3ver_stage']===10)) {
1679 '<a href="'.htmlspecialchars($this->doc
->issueCommand(
1680 '&cmd['.$table.']['.$rec_on['uid'].'][version][action]=swap'.
1681 '&cmd['.$table.']['.$rec_on['uid'].'][version][swapWith]='.$rec_off['uid']
1682 )).'" title="' . $GLOBALS['LANG']->getLL('publish', TRUE) . '">'.
1683 t3lib_iconWorks
::getSpriteIcon('apps-version-swap-versions') .
1685 if ($GLOBALS['BE_USER']->workspaceSwapAccess()) {
1687 '<a href="'.htmlspecialchars($this->doc
->issueCommand(
1688 '&cmd['.$table.']['.$rec_on['uid'].'][version][action]=swap'.
1689 '&cmd['.$table.']['.$rec_on['uid'].'][version][swapWith]='.$rec_off['uid'].
1690 '&cmd['.$table.']['.$rec_on['uid'].'][version][swapIntoWS]=1'
1691 )).'" title="' . $GLOBALS['LANG']->getLL('swap', TRUE) . '">'.
1692 t3lib_iconWorks
::getSpriteIcon('apps-version-swap-workspace') .
1697 if (!$GLOBALS['BE_USER']->workspaceCannotEditOfflineVersion($table,$rec_off)) {
1700 '<a href="'.htmlspecialchars($this->doc
->issueCommand('&cmd['.$table.']['.$rec_off['uid'].'][version][action]=clearWSID')).'" onclick="return confirm(\'' . $GLOBALS['LANG']->getLL('removeFromWorkspace', TRUE) . '?\');" title="' . $GLOBALS['LANG']->getLL('removeFromWorkspace', TRUE) . '">'.
1701 t3lib_iconWorks
::getSpriteIcon('apps-version-document-remove') .
1705 if ($table==='pages' && $vType!=='element') {
1706 $tempUid = ($vType==='branch' ||
$GLOBALS['BE_USER']->workspace
===0 ?
$rec_off['uid'] : $rec_on['uid']);
1708 '<a href="#" onclick="top.loadEditId('.$tempUid.');top.goToModule(\''.$this->pageModule
.'\'); return false;" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xml:img_title_edit_page', TRUE) . '">'.
1709 t3lib_iconWorks
::getSpriteIcon('apps-version-page-open') .
1712 $params = '&edit['.$table.']['.$rec_off['uid'].']=edit';
1714 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc
::editOnClick($params,$this->doc
->backPath
)).'" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xml:img_title_edit_element', TRUE). '">'.
1715 t3lib_iconWorks
::getSpriteIcon('actions-document-open') .
1722 '<a href="'.htmlspecialchars($this->doc
->backPath
.'show_rechis.php?element='.rawurlencode($table.':'.$rec_off['uid']).'&returnUrl='.rawurlencode($this->REQUEST_URI
)).'" title="' . $GLOBALS['LANG']->getLL('showLog', TRUE) . '">'.
1723 t3lib_iconWorks
::getSpriteIcon('actions-document-history-open') .
1727 if ($table==='pages') {
1728 $tempUid = ($vType==='branch' ||
$GLOBALS['BE_USER']->workspace
===0 ?
$rec_off['uid'] : $rec_on['uid']);
1730 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc
::viewOnClick($tempUid,$this->doc
->backPath
,t3lib_BEfunc
::BEgetRootLine($tempUid))).'">'.
1731 t3lib_iconWorks
::getSpriteIcon('actions-document-view') .
1735 return $actionLinks;
1739 * Links to publishing etc of a version
1741 * @param string Table name
1742 * @param array Record
1743 * @param integer The uid of the online version of $uid. If zero it means we are drawing a row for the online version itself while a value means we are drawing display for an offline version.
1744 * @return string HTML content, mainly link tags and images.
1746 function displayWorkspaceOverview_commandLinksSub($table,$rec,$origId) {
1748 if ($origId ||
$GLOBALS['BE_USER']->workspace
===0) {
1749 if (!$GLOBALS['BE_USER']->workspaceCannotEditRecord($table,$rec)) {
1751 if ($table==='pages') {
1753 '<a href="#" onclick="top.loadEditId('.$uid.');top.goToModule(\''.$this->pageModule
.'\'); return false;" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xml:img_title_edit_page', TRUE) . '">'.
1754 t3lib_iconWorks
::getSpriteIcon('apps-version-page-open') .
1757 $params = '&edit['.$table.']['.$uid.']=edit';
1759 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc
::editOnClick($params,$this->doc
->backPath
)).'" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_user_ws.xml:img_title_edit_element', TRUE) . '">'.
1760 t3lib_iconWorks
::getSpriteIcon('actions-document-open') .
1767 '<a href="'.htmlspecialchars($this->doc
->backPath
.'show_rechis.php?element='.rawurlencode($table.':'.$uid).'&returnUrl='.rawurlencode($this->REQUEST_URI
)).'" title="' . $GLOBALS['LANG']->getLL('showLog', TRUE) . '">'.
1768 t3lib_iconWorks
::getSpriteIcon('actions-document-history-open') .
1773 if ($table==='pages') {
1775 '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc
::viewOnClick($uid,$this->doc
->backPath
,t3lib_BEfunc
::BEgetRootLine($uid))).'">'.
1776 t3lib_iconWorks
::getSpriteIcon('actions-document-view') .
1780 return $actionLinks;
1791 /**********************************
1795 **********************************/
1798 * Will publish workspace if buttons are pressed
1802 function publishAction() {
1804 // If "Publish" or "Swap" buttons are pressed:
1805 if (t3lib_div
::_POST('_publish') || t3lib_div
::_POST('_swap')) {
1807 if ($this->table
==='pages') { // Making sure ->uid is a page ID!
1808 // Initialize workspace object and request all pending versions:
1809 $wslibObj = t3lib_div
::makeInstance('wslib');
1810 $cmd = $wslibObj->getCmdArrayForPublishWS($GLOBALS['BE_USER']->workspace
, t3lib_div
::_POST('_swap'),$this->uid
);
1812 // Execute the commands:
1813 $tce = t3lib_div
::makeInstance('t3lib_TCEmain');
1814 $tce->stripslashes_values
= 0;
1815 $tce->start(array(), $cmd);
1816 $tce->process_cmdmap();
1818 t3lib_BEfunc
::setUpdateSignal('updatePageTree');
1820 return $tce->errorLog
;
1828 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['ext/version/cm1/index.php']) {
1829 include_once($TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['ext/version/cm1/index.php']);
1836 $SOBE = t3lib_div
::makeInstance('tx_version_cm1');
1841 $SOBE->printContent();