00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00079
00080 unset($MCONF);
00081 require ('conf.php');
00082 require ($BACK_PATH.'init.php');
00083 require ($BACK_PATH.'template.php');
00084 $LANG->includeLLFile('EXT:version/locallang.xml');
00085 require_once (PATH_t3lib.'class.t3lib_scbase.php');
00086
00087
00088 require_once(PATH_t3lib.'class.t3lib_diff.php');
00089 require_once(PATH_typo3.'mod/user/ws/class.wslib.php');
00090 require_once(PATH_t3lib.'class.t3lib_pagetree.php');
00091 require_once(PATH_t3lib.'class.t3lib_tcemain.php');
00092
00093
00094
00102 class tx_version_cm1 extends t3lib_SCbase {
00103
00104
00105 var $MCONF = array();
00106 var $MOD_MENU = array();
00107 var $MOD_SETTINGS = array();
00108 var $doc;
00109 var $content;
00110
00111
00112
00113 var $showWorkspaceCol = 0;
00114 var $formatWorkspace_cache = array();
00115 var $formatCount_cache = array();
00116 var $targets = array();
00117 var $pageModule = '';
00118 var $publishAccess = FALSE;
00119 var $be_user_Array = array();
00120 var $stageIndex = array();
00121 var $recIndex = array();
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00139 function menuConfig() {
00140
00141
00142 $this->MOD_MENU = array(
00143 'filter' => array(
00144 1 => 'Drafts',
00145 2 => 'Archive',
00146 0 => 'All',
00147 ),
00148 'display' => array(
00149 0 => '[Live workspace]',
00150 -98 => 'Draft Workspaces',
00151 -99 => 'All',
00152 -1 => '[Default Draft]'
00153 ),
00154 'diff' => ''
00155 );
00156
00157
00158 if ($GLOBALS['BE_USER']->workspace===0) {
00159 $workspaces = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,title,adminusers,members,reviewers','sys_workspace','pid=0'.t3lib_BEfunc::deleteClause('sys_workspace'),'','title');
00160 foreach($workspaces as $rec) {
00161 if ($GLOBALS['BE_USER']->checkWorkspace($rec)) {
00162 $this->MOD_MENU['display'][$rec['uid']] = '['.$rec['uid'].'] '.$rec['title'];
00163 }
00164 }
00165 }
00166
00167
00168 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name'], 'ses');
00169 }
00170
00176 function main() {
00177 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00178
00179
00180 $this->MCONF = $GLOBALS['MCONF'];
00181
00182 $this->REQUEST_URI = str_replace('&sendToReview=1','',t3lib_div::getIndpEnv('REQUEST_URI'));
00183
00184
00185 $this->doc = t3lib_div::makeInstance('mediumDoc');
00186 $this->doc->backPath = $BACK_PATH;
00187 $this->doc->form='<form action="" method="post">';
00188
00189
00190 $this->doc->inDocStylesArray[$GLOBALS['MCONF']['name']] = '
00191 .version-diff-1 { background-color: green; }
00192 .version-diff-2 { background-color: red; }
00193 ';
00194
00195
00196 $CMparts = $this->doc->getContextMenuCode();
00197 $this->doc->JScode.= $CMparts[0];
00198 $this->doc->bodyTagAdditions = $CMparts[1];
00199 $this->doc->postCode.= $CMparts[2];
00200
00201
00202 $this->id = intval(t3lib_div::_GP('id'));
00203 if (!$this->id) {
00204 $this->uid = intval(t3lib_div::_GP('uid'));
00205 $this->table = t3lib_div::_GP('table');
00206 } else {
00207 $this->uid = $this->id;
00208 $this->table = 'pages';
00209 }
00210 $this->details = t3lib_div::_GP('details');
00211 $this->diffOnly = t3lib_div::_GP('diffOnly');
00212
00213
00214 $this->MOD_SETTINGS['expandSubElements'] = TRUE;
00215 $this->MOD_SETTINGS['diff'] = $this->details || $this->MOD_SETTINGS['diff']?1:0;
00216
00217
00218 $record = t3lib_BEfunc::getRecord($this->table,$this->uid);
00219 if ($record['pid']==-1) {
00220 $record = t3lib_BEfunc::getRecord($this->table,$record['t3ver_oid']);
00221 }
00222 $pidValue = $this->table==='pages' ? $this->uid : $record['pid'];
00223
00224
00225 if (is_array($record) && $TCA[$this->table]['ctrl']['versioningWS']) {
00226 $this->uid = $record['uid'];
00227
00228
00229
00230 $this->pageinfo = t3lib_BEfunc::readPageAccess($pidValue,$this->perms_clause);
00231 $access = is_array($this->pageinfo) ? 1 : 0;
00232
00233 if (($pidValue && $access) || ($BE_USER->user['admin'] && !$pidValue)) {
00234
00235
00236 $this->doc->JScode.= '
00237 <script language="javascript" type="text/javascript">
00238 script_ended = 0;
00239 function jumpToUrl(URL) {
00240 window.location.href = URL;
00241 }
00242
00243 function hlSubelements(origId, verId, over, diffLayer) {
00244 if (over) {
00245 document.getElementById(\'orig_\'+origId).attributes.getNamedItem("class").nodeValue = \'typo3-ver-hl\';
00246 document.getElementById(\'ver_\'+verId).attributes.getNamedItem("class").nodeValue = \'typo3-ver-hl\';
00247 if (diffLayer) {
00248 document.getElementById(\'diff_\'+verId).style.visibility = \'visible\';
00249 }
00250 } else {
00251 document.getElementById(\'orig_\'+origId).attributes.getNamedItem("class").nodeValue = \'typo3-ver\';
00252 document.getElementById(\'ver_\'+verId).attributes.getNamedItem("class").nodeValue = \'typo3-ver\';
00253 if (diffLayer) {
00254 document.getElementById(\'diff_\'+verId).style.visibility = \'hidden\';
00255 }
00256 }
00257 }
00258 </script>
00259 ';
00260
00261
00262 $newPageModule = trim($BE_USER->getTSConfigVal('options.overridePageModule'));
00263 $this->pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
00264
00265
00266 $this->publishAccess = $BE_USER->workspacePublishAccess($BE_USER->workspace);
00267
00268
00269 $headerSection = $this->doc->getHeader('pages',$this->pageinfo,$this->pageinfo['_thePath']).'<br/>'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.path').': '.t3lib_div::fixed_lgd_pre($this->pageinfo['_thePath'],50);
00270
00271 $this->content.=$this->doc->startPage($LANG->getLL('title'));
00272 $this->content.=$this->doc->header($LANG->getLL('title'));
00273 $this->content.=$this->doc->spacer(5);
00274 $this->content.=$this->doc->section('',$headerSection);
00275 $this->content.=$this->doc->divider(5);
00276
00277
00278 if ($this->id) {
00279 $this->workspaceMgm();
00280 } else {
00281 $this->versioningMgm();
00282 }
00283
00284
00285 if ($BE_USER->mayMakeShortcut()) {
00286 $this->content.=$this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('id',implode(',',array_keys($this->MOD_MENU)),$this->MCONF['name']));
00287 }
00288 }
00289
00290 $this->content.=$this->doc->spacer(10);
00291 } else {
00292
00293 $this->content.=$this->doc->startPage($LANG->getLL('title'));
00294 $this->content.=$this->doc->section($LANG->getLL('clickAPage_header'),$LANG->getLL('clickAPage_content'),0,1);
00295 }
00296 }
00297
00303 function printContent() {
00304
00305 $this->content.=$this->doc->endPage();
00306 echo $this->content;
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00329 function versioningMgm() {
00330 global $TCA;
00331
00332
00333 $diff_1 = t3lib_div::_POST('diff_1');
00334 $diff_2 = t3lib_div::_POST('diff_2');
00335 if (t3lib_div::_POST('do_diff')) {
00336 $content='';
00337 $content.='<h3>DIFFING:</h3>';
00338 if ($diff_1 && $diff_2) {
00339 $diff_1_record = t3lib_BEfunc::getRecord($this->table, $diff_1);
00340 $diff_2_record = t3lib_BEfunc::getRecord($this->table, $diff_2);
00341
00342 if (is_array($diff_1_record) && is_array($diff_2_record)) {
00343 t3lib_div::loadTCA($this->table);
00344 $t3lib_diff_Obj = t3lib_div::makeInstance('t3lib_diff');
00345
00346 $tRows=array();
00347 $tRows[] = '
00348 <tr class="bgColor5 tableheader">
00349 <td>Fieldname:</td>
00350 <td width="98%">Colored diff-view:</td>
00351 </tr>
00352 ';
00353 foreach($diff_1_record as $fN => $fV) {
00354 if ($TCA[$this->table]['columns'][$fN] && $TCA[$this->table]['columns'][$fN]['config']['type']!='passthrough' && !t3lib_div::inList('t3ver_label',$fN)) {
00355 if (strcmp($diff_1_record[$fN],$diff_2_record[$fN])) {
00356
00357 $diffres = $t3lib_diff_Obj->makeDiffDisplay(
00358 t3lib_BEfunc::getProcessedValue($this->table,$fN,$diff_2_record[$fN],0,1),
00359 t3lib_BEfunc::getProcessedValue($this->table,$fN,$diff_1_record[$fN],0,1)
00360 );
00361
00362 $tRows[] = '
00363 <tr class="bgColor4">
00364 <td>'.$fN.'</td>
00365 <td width="98%">'.$diffres.'</td>
00366 </tr>
00367 ';
00368 }
00369 }
00370 }
00371
00372 if (count($tRows)>1) {
00373 $content.='<table border="0" cellpadding="1" cellspacing="1" width="100%">'.implode('',$tRows).'</table><br/><br/>';
00374 } else {
00375 $content.='Records matches completely on all editable fields!';
00376 }
00377 } else $content.='ERROR: Records could strangely not be found!';
00378 } else {
00379 $content.='ERROR: You didn\'t select two sources for diffing!';
00380 }
00381 }
00382
00383
00384 $record = t3lib_BEfunc::getRecord($this->table,$this->uid);
00385 $recordIcon = t3lib_iconWorks::getIconImage($this->table,$record,$this->doc->backPath,'class="absmiddle"');
00386 $recTitle = t3lib_BEfunc::getRecordTitle($this->table,$record,TRUE);
00387
00388
00389 $content.='
00390 '.$recordIcon.$recTitle.'
00391 <form name="theform" action="'.str_replace('&sendToReview=1','',$this->REQUEST_URI).'" method="post">
00392 <table border="0" cellspacing="1" cellpadding="1">';
00393 $content.='
00394 <tr class="bgColor5 tableheader">
00395 <td> </td>
00396 <td> </td>
00397 <td>Title</td>
00398 <td>UID</td>
00399 <td title="t3ver_oid - Reference to live version UID">oid</td>
00400 <td title="t3ver_id - Version number, incremental integer">id</td>
00401 <td title="t3ver_wsid - Workspace ID. There can be only one version of an element per ID (except ID zero).">wsid</td>
00402 <td title="t3ver_state - Special states of a version: 1=Placeholder for "New". 2=Marked deleted.">state</td>
00403 <td title="t3ver_stage - Publishing stage: Editing (0), review (1), publish (10), rejected (-1).">stage</td>
00404 <td title="t3ver_count - Life cycle counter. Incremented each time element is unpublished.">count</td>
00405 <td>pid</td>
00406 <td>t3ver_label</td>
00407 <td colspan="2"><input type="submit" name="do_diff" value="Diff" /></td>
00408 </tr>';
00409
00410 $versions = t3lib_BEfunc::selectVersionsOfRecord($this->table, $this->uid, '*', $GLOBALS['BE_USER']->workspace);
00411 foreach($versions as $row) {
00412 $adminLinks = $this->adminLinks($this->table,$row);
00413
00414 $content.='
00415 <tr class="'.($row['uid']!=$this->uid ? 'bgColor4' : 'bgColor2 tableheader').'">
00416 <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').'">'.
00417 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/insert1.gif','width="14" height="14"').' alt="" title="SWAP with current" />'.
00418 '</a>'
00419
00420
00421
00422
00423
00424
00425 : '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/blinkarrow_left.gif','width="5" height="9"').' alt="" title="CURRENT ONLINE VERSION!"/>').'</td>
00426 <td nowrap="nowrap">'.$adminLinks.'</td>
00427 <td nowrap="nowrap">'.t3lib_BEfunc::getRecordTitle($this->table,$row,TRUE).'</td>
00428 <td>'.$row['uid'].'</td>
00429 <td>'.$row['t3ver_oid'].'</td>
00430 <td>'.$row['t3ver_id'].'</td>
00431 <td>'.$row['t3ver_wsid'].'</td>
00432 <td>'.$row['t3ver_state'].'</td>
00433 <td>'.$row['t3ver_stage'].'</td>
00434 <td>'.$row['t3ver_count'].'</td>
00435 <td>'.$row['pid'].'</td>
00436 <td nowrap="nowrap"><a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick('&edit['.$this->table.']['.$row['uid'].']=edit&columnsOnly=t3ver_label',$this->doc->backPath)).'"><img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/edit2.gif','width="11" height="12"').' alt="" title="Edit"/></a>'.htmlspecialchars($row['t3ver_label']).'</td>
00437 <td class="version-diff-1"><input type="radio" name="diff_1" value="'.$row['uid'].'"'.($diff_1==$row['uid'] ? ' checked="checked"':'').'/></td>
00438 <td class="version-diff-2"><input type="radio" name="diff_2" value="'.$row['uid'].'"'.($diff_2==$row['uid'] ? ' checked="checked"':'').'/></td>
00439 </tr>';
00440
00441
00442 if ($this->table == 'pages' && $row['uid']!=$this->uid) {
00443 $sub = $this->pageSubContent($row['uid']);
00444
00445 if ($sub) {
00446 $content.='
00447 <tr>
00448 <td></td>
00449 <td></td>
00450 <td colspan="10">'.$sub.'</td>
00451 <td colspan="2"></td>
00452 </tr>';
00453 }
00454 }
00455 }
00456 $content.='</table></form>';
00457
00458 $this->content.=$this->doc->section('',$content,0,1);
00459
00460
00461
00462 $content='
00463
00464 <form action="'.$this->doc->backPath.'tce_db.php" method="post">
00465 Label: <input type="text" name="cmd['.$this->table.']['.$this->uid.'][version][label]" /><br/>
00466 '.($this->table == 'pages' ? '<select name="cmd['.$this->table.']['.$this->uid.'][version][treeLevels]">
00467 '.($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(0) ? '<option value="0">Page: Page + content</option>' : '').'
00468 '.($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(1) ? '<option value="100">Branch: All subpages</option>' : '').'
00469 '.($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(-1) ? '<option value="-1">Element: Just record</option>' : '').'
00470 </select>' : '').'
00471 <br/><input type="hidden" name="cmd['.$this->table.']['.$this->uid.'][version][action]" value="new" />
00472 <input type="hidden" name="prErr" value="1" />
00473 <input type="hidden" name="redirect" value="'.htmlspecialchars($this->REQUEST_URI).'" />
00474 <input type="submit" name="_" value="Create new version" />
00475
00476 </form>
00477
00478 ';
00479
00480 $this->content.=$this->doc->spacer(15);
00481 $this->content.=$this->doc->section('Create new version',$content,0,1);
00482
00483 }
00484
00492 function pageSubContent($pid,$c=0) {
00493 global $TCA;
00494
00495 $tableNames = t3lib_div::removeArrayEntryByValue(array_keys($TCA),'pages');
00496 $tableNames[] = 'pages';
00497
00498 foreach($tableNames as $tN) {
00499
00500 #if ($TCA[$tN]['ctrl']['versioning_followPages'] || $tN=='pages') {
00501 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $tN, 'pid='.intval($pid).t3lib_BEfunc::deleteClause($tN), '', ($TCA[$tN]['ctrl']['sortby'] ? $TCA[$tN]['ctrl']['sortby'] : ''));
00502
00503 if ($GLOBALS['TYPO3_DB']->sql_num_rows($mres)) {
00504 $content.='
00505 <tr>
00506 <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>
00507 </tr>';
00508 while ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
00509 $ownVer = $this->lookForOwnVersions($tN,$subrow['uid']);
00510 $content.='
00511 <tr>
00512 <td>'.$this->adminLinks($tN,$subrow).'</td>
00513 <td>'.$subrow['uid'].'</td>
00514 '.($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>').'
00515 <td width="98%">'.t3lib_BEfunc::getRecordTitle($tN,$subrow,TRUE).'</td>
00516 </tr>';
00517
00518 if ($tN == 'pages' && $c<100) {
00519 $sub = $this->pageSubContent($subrow['uid'],$c+1);
00520
00521 if ($sub) {
00522 $content.='
00523 <tr>
00524 <td></td>
00525 <td></td>
00526 <td></td>
00527 <td width="98%">'.$sub.'</td>
00528 </tr>';
00529 }
00530 }
00531 }
00532 }
00533 #}
00534 }
00535
00536 return $content ? '<table border="1" cellpadding="1" cellspacing="0" width="100%">'.$content.'</table>' : '';
00537 }
00538
00546 function lookForOwnVersions($table,$uid) {
00547 global $TCA;
00548
00549 $versions = t3lib_BEfunc::selectVersionsOfRecord($table, $uid, 'uid');
00550 if (is_array($versions)) {
00551 return count($versions);
00552 }
00553 return FALSE;
00554 }
00555
00563 function adminLinks($table,$row) {
00564 global $BE_USER;
00565
00566
00567 $adminLink = '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::editOnClick('&edit['.$table.']['.$row['uid'].']=edit',$this->doc->backPath)).'">'.
00568 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/edit2.gif','width="11" height="12"').' alt="" title="Edit"/>'.
00569 '</a>';
00570
00571
00572 $adminLink.= '<a href="'.htmlspecialchars($this->doc->issueCommand('&cmd['.$table.']['.$row['uid'].'][delete]=1')).'">'.
00573 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/garbage.gif','width="11" height="12"').' alt="" title="Delete"/>'.
00574 '</a>';
00575
00576
00577
00578 if ($table == 'pages') {
00579
00580
00581 $newPageModule = trim($BE_USER->getTSConfigVal('options.overridePageModule'));
00582 $pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
00583
00584
00585 $a_wl = $BE_USER->check('modules','web_list');
00586 $a_wp = t3lib_extMgm::isLoaded('cms') && $BE_USER->check('modules',$pageModule);
00587
00588 $adminLink.='<a href="#" onclick="top.loadEditId('.$row['uid'].');top.goToModule(\''.$pageModule.'\'); return false;">'.
00589 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,t3lib_extMgm::extRelPath('cms').'layout/layout.gif','width="14" height="12"').' title="" alt="" />'.
00590 '</a>';
00591 $adminLink.='<a href="#" onclick="top.loadEditId('.$row['uid'].');top.goToModule(\'web_list\'); return false;">'.
00592 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'mod/web/list/list.gif','width="14" height="12"').' title="" alt="" />'.
00593 '</a>';
00594
00595
00596 $adminLink.='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($row['uid'],$this->doc->backPath,t3lib_BEfunc::BEgetRootLine($row['uid']))).'">'.
00597 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/zoom.gif','width="12" height="12"').' title="" alt="" />'.
00598 '</a>';
00599 } else {
00600 if ($row['pid']==-1) {
00601 $getVars = '&ADMCMD_vPrev['.rawurlencode($table.':'.$row['t3ver_oid']).']='.$row['uid'];
00602
00603
00604 $adminLink.='<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($row['_REAL_PID'],$this->doc->backPath,t3lib_BEfunc::BEgetRootLine($row['_REAL_PID']),'','',$getVars)).'">'.
00605 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/zoom.gif','width="12" height="12"').' title="" alt="" />'.
00606 '</a>';
00607 }
00608 }
00609
00610 return $adminLink;
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00635 function workspaceMgm() {
00636
00637 $menu = '';
00638 if ($GLOBALS['BE_USER']->workspace===0) {
00639 $menu.= t3lib_BEfunc::getFuncMenu($this->id,'SET[filter]',$this->MOD_SETTINGS['filter'],$this->MOD_MENU['filter']);
00640 $menu.= t3lib_BEfunc::getFuncMenu($this->id,'SET[display]',$this->MOD_SETTINGS['display'],$this->MOD_MENU['display']);
00641 }
00642 if (!$this->details && $GLOBALS['BE_USER']->workspace && !$this->diffOnly) {
00643 $menu.= t3lib_BEfunc::getFuncCheck($this->id,'SET[diff]',$this->MOD_SETTINGS['diff'],'','','id="checkDiff"').' <label for="checkDiff">Show difference view</label>';
00644 }
00645
00646 if ($menu) {
00647 $this->content.=$this->doc->section('',$menu,0,1);
00648 }
00649
00650
00651 $errors = $this->publishAction();
00652
00653
00654 $WSoverview = $this->displayWorkspaceOverview();
00655
00656
00657 $actionLinks = '<br/>';
00658 if ($GLOBALS['BE_USER']->workspace!==0) {
00659 if ($this->publishAccess) {
00660 $actionLinks.= '<input type="submit" name="_publish" value="Publish page" onclick="return confirm(\'Are you sure you want to publish all content '.($GLOBALS['BE_USER']->workspaceRec['publish_access']&1 ? 'in "Publish" stage ':'').'from this page?\');"/>';
00661 if ($GLOBALS['BE_USER']->workspaceSwapAccess()) {
00662 $actionLinks.= '<input type="submit" name="_swap" value="Swap page" onclick="return confirm(\'Are you sure you want to publish (swap) all content '.($GLOBALS['BE_USER']->workspaceRec['publish_access']&1 ? 'in "Publish" stage ':'').'from this page?\');" />';
00663 }
00664 } else {
00665 $actionLinks.= $this->doc->icons(1).'You are not permitted to publish from this workspace';
00666 }
00667 }
00668 $actionLinks.= '<input type="submit" name="_" value="Refresh" />';
00669 $actionLinks.= '<input type="submit" name="_previewLink" value="Preview Link" />';
00670 $actionLinks.= $this->displayWorkspaceOverview_allStageCmd();
00671
00672 if ($actionLinks || count($errors)) {
00673 $this->content.= $this->doc->section('',$actionLinks.(count($errors) ? '<h3>Errors:</h3><br/>'.implode('<br/>',$errors).'<hr/>' : ''),0,1);
00674 }
00675
00676 if (t3lib_div::_POST('_previewLink')) {
00677 $params = 'id='.$this->id.'&ADMCMD_view=1&ADMCMD_editIcons=1&ADMCMD_previewWS='.$GLOBALS['BE_USER']->workspace;
00678 $previewUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL').'index.php?ADMCMD_prev='.t3lib_BEfunc::compilePreviewKeyword($params, $GLOBALS['BE_USER']->user['uid']);
00679
00680 $this->content.= $this->doc->section('Preview Url:','You can preview this page from the workspace using this link for the next 48 hours (does not require backend login):<br/><br/><a target="_blank" href="'.htmlspecialchars($previewUrl).'">'.$previewUrl.'</a>',0,1);
00681 }
00682
00683
00684 $this->content.= $this->doc->spacer(15);
00685 $this->content.= $this->doc->section($this->details ? 'Details for version' : 'Workspace management', $WSoverview,0,1);
00686
00687 }
00688
00695 function displayWorkspaceOverview() {
00696
00697
00698 $this->showWorkspaceCol = $GLOBALS['BE_USER']->workspace===0 && $this->MOD_SETTINGS['display']<=-98;
00699
00700
00701 $be_group_Array = t3lib_BEfunc::getListGroupNames('title,uid');
00702 $groupArray = array_keys($be_group_Array);
00703 $this->be_user_Array = t3lib_BEfunc::getUserNames();
00704 if (!$GLOBALS['BE_USER']->isAdmin()) $this->be_user_Array = t3lib_BEfunc::blindUserNames($this->be_user_Array,$groupArray,1);
00705
00706
00707 if ($GLOBALS['BE_USER']->workspace===0) {
00708 $wsid = $this->details ? -99 : $this->MOD_SETTINGS['display'];
00709 $filter = $this->details ? 0 : $this->MOD_SETTINGS['filter'];
00710 } else {
00711 $wsid = $GLOBALS['BE_USER']->workspace;
00712 $filter = 0;
00713 }
00714
00715
00716 $wslibObj = t3lib_div::makeInstance('wslib');
00717
00718
00719 $versions = $wslibObj->selectVersionsInWorkspace($wsid, $filter, -99, $this->uid);
00720
00721
00722 $pArray = array();
00723 foreach($versions as $table => $records) {
00724 foreach($records as $rec) {
00725 $pageIdField = $table==='pages' ? 't3ver_oid' : 'realpid';
00726 $this->displayWorkspaceOverview_setInPageArray(
00727 $pArray,
00728 $table,
00729 $rec
00730 );
00731 }
00732 }
00733
00734
00735 $tableRows = array();
00736 if (count($pArray)) {
00737 $tableRows[] = '
00738 <tr class="bgColor5 tableheader">
00739 '.($this->diffOnly?'':'<td nowrap="nowrap" colspan="2">Live Version:</td>').'
00740 <td nowrap="nowrap" colspan="2">Draft Versions:</td>
00741 <td nowrap="nowrap"'.($this->diffOnly?' colspan="2"':' colspan="4"').'>Controls:</td>
00742 </tr>';
00743
00744
00745 $tableRows = array_merge($tableRows, $this->displayWorkspaceOverview_list($pArray));
00746
00747 $table = '<table border="0" cellpadding="0" cellspacing="1" class="lrPadding workspace-overview">'.implode('',$tableRows).'</table>';
00748 } else $table = '';
00749
00750 $linkBack = t3lib_div::_GP('returnUrl') ? '<a href="'.htmlspecialchars(t3lib_div::_GP('returnUrl')).'" class="typo3-goBack"><img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/goback.gif','width="14" height="14"').' alt="" />Click here to go back</a><br/><br/>' : '';
00751 $resetDiffOnly = $this->diffOnly ? '<a href="index.php?id='.intval($this->id).'" class="typo3-goBack">Show all information</a><br/><br/>' : '';
00752
00753 $versionSelector = $GLOBALS['BE_USER']->workspace ? $this->doc->getVersionSelector($this->id) : '';
00754
00755 return $versionSelector.$linkBack.$resetDiffOnly.$table.$this->markupNewOriginals();
00756 }
00757
00765 function displayWorkspaceOverview_list($pArray) {
00766 global $TCA;
00767
00768
00769 $warnAboutVersions_nonPages = FALSE;
00770 $warnAboutVersions_page = FALSE;
00771 if (is_array($pArray)) {
00772 foreach($pArray as $table => $oidArray) {
00773 foreach($oidArray as $oid => $recs) {
00774
00775
00776 $rec_on = t3lib_BEfunc::getRecord($table,$oid);
00777 $icon = t3lib_iconWorks::getIconImage($table, $rec_on, $this->doc->backPath,' align="top" title="'.t3lib_BEfunc::getRecordIconAltText($rec_on,$table).'"');
00778 if ($GLOBALS['BE_USER']->workspace===0) {
00779 $icon = $this->doc->wrapClickMenuOnIcon($icon, $table, $rec_on['uid'], 1, '', '+edit,view,info,delete');
00780 }
00781
00782
00783
00784 $verLinkUrl = $TCA[$table]['ctrl']['versioningWS'];
00785 $origElement = $icon.
00786 ($verLinkUrl ? '<a href="'.htmlspecialchars('index.php?table='.$table.'&uid='.$rec_on['uid']).'">' : '').
00787 t3lib_BEfunc::getRecordTitle($table,$rec_on,TRUE).
00788 ($verLinkUrl ? '</a>' : '');
00789 $mainCell_rowSpan = count($recs)>1 ? ' rowspan="'.count($recs).'"' : '';
00790 $mainCell = '
00791 <td align="center"'.$mainCell_rowSpan.'>'.$this->formatVerId($rec_on['t3ver_id']).'</td>
00792 <td nowrap="nowrap"'.$mainCell_rowSpan.'>'.
00793 $origElement.
00794 '###SUB_ELEMENTS###'.
00795 '</td>';
00796
00797
00798
00799 foreach($recs as $rec) {
00800
00801
00802 $rec_off = t3lib_BEfunc::getRecord($table,$rec['uid']);
00803
00804
00805 if ($table==='pages' && $rec_off['t3ver_swapmode']!=-1) {
00806 if ($rec_off['t3ver_swapmode']>0) {
00807 $vType = 'branch';
00808 } else {
00809 $vType = 'page';
00810 }
00811 } else {
00812 $vType = 'element';
00813 }
00814
00815
00816 $icon = t3lib_iconWorks::getIconImage($table, $rec_off, $this->doc->backPath, ' align="top" title="'.t3lib_BEfunc::getRecordIconAltText($rec_off,$table).'"');
00817 $tempUid = ($table != 'pages' || $vType==='branch' || $GLOBALS['BE_USER']->workspace===0 ? $rec_off['uid'] : $rec_on['uid']);
00818 $icon = $this->doc->wrapClickMenuOnIcon($icon, $table, $tempUid, 1, '', '+edit,' . ($table == 'pages' ? 'view,info,' : '') . 'delete');
00819
00820
00821 if ($this->MOD_SETTINGS['diff'] || $this->diffOnly) {
00822 $diffCode = '';
00823 list($diffHTML,$diffPct) = $this->createDiffView($table, $rec_off, $rec_on);
00824 if ($rec_on['t3ver_state']==1) {
00825 $diffCode.= $this->doc->icons(1).'New element<br/>';
00826 $diffCode.= $diffHTML;
00827 } elseif ($rec_off['t3ver_state']==2) {
00828 $diffCode.= $this->doc->icons(2).'Deleted element<br/>';
00829 } else {
00830 $diffCode.= ($diffPct<0 ? 'N/A' : ($diffPct ? $diffPct.'% change:' : ''));
00831 $diffCode.= $diffHTML;
00832 }
00833 } else $diffCode = '';
00834
00835 switch($vType) {
00836 case 'element':
00837 $swapLabel = ' [Element]';
00838 $swapClass = 'ver-element';
00839 $warnAboutVersions_nonPages = $warnAboutVersions_page;
00840 break;
00841 case 'page':
00842 $swapLabel = ' [Page]';
00843 $swapClass = 'ver-page';
00844 $warnAboutVersions_page = !$this->showWorkspaceCol;
00845 break;
00846 case 'branch':
00847 $swapLabel = ' [Branch]';
00848 $swapClass = 'ver-branch';
00849 break;
00850 }
00851
00852
00853 $subElements = array();
00854 if ($table==='pages' && $rec_off['t3ver_swapmode']!=-1 && $mainCell) {
00855 $subElements['on'] = $this->subElements($rec_on['uid'], $rec_off['t3ver_swapmode']);
00856 $subElements['off'] = $this->subElements($rec_off['uid'],$rec_off['t3ver_swapmode'],$rec_on['uid']);
00857 }
00858 $mainCell = str_replace('###SUB_ELEMENTS###', $subElements['on'], $mainCell);
00859
00860
00861 $versionsInOtherWS = $this->versionsInOtherWS($table, $rec_on['uid']);
00862 $versionsInOtherWSWarning = $versionsInOtherWS && $GLOBALS['BE_USER']->workspace!==0 ? '<br/>'.$this->doc->icons(2).'Other version(s) in workspace '.$versionsInOtherWS : '';
00863 $multipleWarning = (!$mainCell && $GLOBALS['BE_USER']->workspace!==0? '<br/>'.$this->doc->icons(3).'<b>Multiple versions in same workspace!</b>' : '');
00864 $verWarning = $warnAboutVersions || ($warnAboutVersions_nonPages && $GLOBALS['TCA'][$table]['ctrl']['versioning_followPages'])? '<br/>'.$this->doc->icons(3).'<b>Version inside version!</b>' : '';
00865 $verElement = $icon.
00866 (!$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)).'">' : '').
00867 t3lib_BEfunc::getRecordTitle($table,$rec_off,TRUE).
00868 (!$this->details ? '</a>' : '').
00869 $versionsInOtherWSWarning.
00870 $multipleWarning.
00871 $verWarning;
00872
00873 $ctrlTable = '
00874 <td nowrap="nowrap">'.$this->showStageChangeLog($table,$rec_off['uid'],$this->displayWorkspaceOverview_stageCmd($table,$rec_off)).'</td>
00875 <td nowrap="nowrap" class="'.$swapClass.'">'.
00876 $this->displayWorkspaceOverview_commandLinks($table,$rec_on,$rec_off,$vType).
00877 htmlspecialchars($swapLabel).
00878 ' </td>
00879 '.(!$this->diffOnly?'<td nowrap="nowrap"><b>Lifecycle:</b> '.htmlspecialchars($this->formatCount($rec_off['t3ver_count'])).'</td>'.
00880 ($this->showWorkspaceCol ? '
00881 <td nowrap="nowrap"> <b>Workspace:</b> '.htmlspecialchars($this->formatWorkspace($rec_off['t3ver_wsid'])).'</td>' : ''):'');
00882
00883 if ($diffCode) {
00884 $verElement = $verElement.'
00885 <br/><b>Difference to live element:</b>
00886 <table border="0" cellpadding="0" cellspacing="0" class="ver-verElement">
00887 <tr>
00888 <td class="c-diffCell">'.$diffCode.'</td>
00889 </tr>
00890 </table>';
00891 }
00892
00893
00894
00895 $verCell = '
00896 <td align="center">'.$this->formatVerId($rec_off['t3ver_id']).'</td>
00897 <td nowrap="nowrap">'.
00898 $verElement.
00899 $subElements['off'].
00900 '</td>
00901 ';
00902
00903
00904 $tableRows[] = '
00905 <tr class="bgColor4">
00906 '.
00907 ($this->diffOnly?'':$mainCell).
00908 $verCell.
00909 $ctrlTable.
00910 '
00911 </tr>';
00912
00913
00914 $mainCell = '';
00915
00916 }
00917 }
00918 }
00919 }
00920
00921 return $tableRows;
00922 }
00923
00933 function displayWorkspaceOverview_setInPageArray(&$pArray,$table,$row) {
00934 if (!$this->details || $this->details==$table.':'.$row['uid']) {
00935 $pArray[$table][$row['t3ver_oid']][] = $row;
00936 }
00937 }
00938
00946 function displayWorkspaceOverview_allStageCmd() {
00947
00948 $table = t3lib_div::_GP('table');
00949 if ($table && $table!='pages') {
00950 $uid = t3lib_div::_GP('uid');
00951 if ($rec_off = t3lib_BEfunc::getRecordWSOL($table,$uid)) {
00952 $uid = $rec_off['_ORIG_uid'];
00953 }
00954 } else $table = '';
00955
00956 if ($table) {
00957 if ($uid && $this->recIndex[$table][$uid]) {
00958 $sId = $this->recIndex[$table][$uid];
00959 switch($sId) {
00960 case 1:
00961 $label = 'Comment for Reviewer:';
00962 break;
00963 case 10:
00964 $label = 'Comment for Publisher:';
00965 break;
00966 }
00967 } else $sId = 0;
00968 } else {
00969 if (count($this->stageIndex[1])) {
00970 $sId = 1;
00971 $color = '#666666';
00972 $label = 'Sending %s item(s) to review. Comment for Reviewer:';
00973 $titleAttrib = 'Send all to Review';
00974 } elseif(count($this->stageIndex[10])) {
00975 $sId = 10;
00976 $color = '#6666cc';
00977 $label = 'Approving %s item(s) to publishing. Comment for Publisher:';
00978 $titleAttrib = 'Approve all for Publishing';
00979 } else {
00980 $sId = 0;
00981 }
00982 }
00983
00984 if ($sId>0) {
00985 $issueCmd = '';
00986 $itemCount = 0;
00987
00988 if ($table && $uid && $this->recIndex[$table][$uid]) {
00989 $issueCmd.='&cmd['.$table.']['.$uid.'][version][action]=setStage';
00990 $issueCmd.='&cmd['.$table.']['.$uid.'][version][stageId]='.$this->recIndex[$table][$uid];
00991 } else {
00992 foreach($this->stageIndex[$sId] as $table => $uidArray) {
00993 $issueCmd.='&cmd['.$table.']['.implode(',',$uidArray).'][version][action]=setStage';
00994 $issueCmd.='&cmd['.$table.']['.implode(',',$uidArray).'][version][stageId]='.$sId;
00995 $itemCount+=count($uidArray);
00996 }
00997 }
00998
00999 $onClick = 'var commentTxt=window.prompt("'.sprintf($label,$itemCount).'","");
01000 if (commentTxt!=null) {window.location.href="'.$this->doc->issueCommand($issueCmd,$this->REQUEST_URI).'&generalComment="+escape(commentTxt);}';
01001
01002 if (t3lib_div::_GP('sendToReview')) {
01003 $onClick.= ' else {window.location.href = "'.$this->REQUEST_URI.'"}';
01004 $actionLinks.=
01005 $this->doc->wrapScriptTags($onClick);
01006 } else {
01007 $onClick.= ' return false;';
01008 $actionLinks.=
01009 '<input type="submit" name="_" value="'.htmlspecialchars($titleAttrib).'" onclick="'.htmlspecialchars($onClick).'" />';
01010 }
01011 } elseif (t3lib_div::_GP('sendToReview')) {
01012 $onClick = 'window.location.href = "'.$this->REQUEST_URI.'";';
01013 $actionLinks.=
01014 $this->doc->wrapScriptTags($onClick);
01015 } else $actionLinks = '';
01016
01017 return $actionLinks;
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01037 function formatVerId($verId) {
01038 return '1.'.$verId;
01039 }
01040
01047 function formatWorkspace($wsid) {
01048
01049
01050 if (!isset($this->formatWorkspace_cache[$wsid])) {
01051 switch($wsid) {
01052 case -1:
01053 $this->formatWorkspace_cache[$wsid] = '[Offline]';
01054 break;
01055 case 0:
01056 $this->formatWorkspace_cache[$wsid] = '';
01057 break;
01058 default:
01059 list($titleRec) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('title','sys_workspace','uid='.intval($wsid).t3lib_BEfunc::deleteClause('sys_workspace'));
01060 $this->formatWorkspace_cache[$wsid] = '['.$wsid.'] '.$titleRec['title'];
01061 break;
01062 }
01063 }
01064
01065 return $this->formatWorkspace_cache[$wsid];
01066 }
01067
01074 function formatCount($count) {
01075
01076
01077 if (!isset($this->formatCount_cache[$count])) {
01078 switch($count) {
01079 case 0:
01080 $this->formatCount_cache[$count] = 'Draft';
01081 break;
01082 case 1:
01083 $this->formatCount_cache[$count] = 'Archive';
01084 break;
01085 default:
01086 $this->formatCount_cache[$count] = 'Published '.$count.' times';
01087 break;
01088 }
01089 }
01090
01091 return $this->formatCount_cache[$count];
01092 }
01093
01101 function versionsInOtherWS($table,$uid) {
01102
01103
01104
01105 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01106 't3ver_wsid',
01107 $table,
01108 'pid=-1
01109 AND t3ver_oid='.intval($uid).'
01110 AND t3ver_wsid!='.intval($GLOBALS['BE_USER']->workspace).'
01111 AND (t3ver_wsid=-1 OR t3ver_wsid>0)'.
01112 t3lib_BEfunc::deleteClause($table),
01113 '',
01114 't3ver_wsid',
01115 '',
01116 't3ver_wsid'
01117 );
01118 if (count($rows)) {
01119 return implode(',',array_keys($rows));
01120 }
01121 }
01122
01131 function showStageChangeLog($table,$id,$stageCommands) {
01132 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
01133 'log_data,tstamp,userid',
01134 'sys_log',
01135 'action=6 and details_nr=30
01136 AND tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_log').'
01137 AND recuid='.intval($id)
01138 );
01139
01140 $entry = array();
01141 foreach($rows as $dat) {
01142 $data = unserialize($dat['log_data']);
01143 $username = $this->be_user_Array[$dat['userid']] ? $this->be_user_Array[$dat['userid']]['username'] : '['.$dat['userid'].']';
01144
01145 switch($data['stage']) {
01146 case 1:
01147 $text = 'sent element to "Review"';
01148 break;
01149 case 10:
01150 $text = 'approved for "Publish"';
01151 break;
01152 case -1:
01153 $text = 'rejected element!';
01154 break;
01155 case 0:
01156 $text = 'reset to "Editing"';
01157 break;
01158 default:
01159 $text = '[undefined]';
01160 break;
01161 }
01162 $text = t3lib_BEfunc::dateTime($dat['tstamp']).': "'.$username.'" '.$text;
01163 $text.= ($data['comment']?'<br/>User Comment: <em>'.htmlspecialchars($data['comment']).'</em>':'');
01164
01165 $entry[] = $text;
01166 }
01167
01168 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>'.
01169 '<div class="logLayer" style="visibility: hidden; position: absolute;" id="log_'.$table.$id.'">'.implode('<hr/>',array_reverse($entry)).'</div>' : $stageCommands;
01170 }
01171
01180 function subElements($uid,$treeLevel,$origId=0) {
01181 global $TCA;
01182
01183 if (!$this->details && ($GLOBALS['BE_USER']->workspace===0 || !$this->MOD_SETTINGS['expandSubElements'])) {
01184 return '<br/>
01185 <img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/ol/joinbottom.gif','width="18" height="16"').' align="top" alt="" title="" />'.