/**
     * Creates the control panel for a single record in the listing.
     *
     * @param	string		The table
     * @param	array		The record for which to make the control panel.
     * @return	string		HTML table with the control panel (unless disabled)
     */
    function makeControl($table, $row)
    {
        global $TCA, $LANG, $BACK_PATH;
        // Return blank, if disabled:
        #		if ($this->dontShowClipControlPanels)	return '';
        // Initialize:
        t3lib_div::loadTCA($table);
        $cells = array();
        $shEl = $this->showElements;
        // If the listed table is 'pages' we have to request the permission settings for each page:
        if ($table == 'pages') {
            $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages', $row['uid']));
        }
        // This expresses the edit permissions for this particular element:
        $permsEdit = $table == 'pages' && $localCalcPerms & 2 || $table != 'pages' && $this->calcPerms & 16;
        // "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id)
        if ($permsEdit && in_array('editRec', $shEl)) {
            $params = '&edit[' . $table . '][' . $row['uid'] . ']=edit';
            $icon = '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/edit2' . (!$TCA[$table]['ctrl']['readOnly'] ? '' : '_d') . '.gif', 'width="11" height="12"') . ' title="' . $LANG->getLL('edit', 1) . '" alt="" />';
            $cells[] = $this->wrapEditLink($icon, $params);
        }
        // If the extended control panel is enabled OR if we are seeing a single table:
        if ($GLOBALS['SOBE']->MOD_SETTINGS['bigControlPanel'] || $this->table) {
            // "Info": (All records)
            if (in_array('infoRec', $shEl)) {
                $cells[] = '<a href="#" onclick="' . htmlspecialchars('top.launchView(\'' . $table . '\', \'' . $row['uid'] . '\'); return false;') . '">' . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/zoom2.gif', 'width="12" height="12"') . ' title="' . $LANG->getLL('showInfo', 1) . '" alt="" />' . '</a>';
            }
            // If the table is NOT a read-only table, then show these links:
            if (!$TCA[$table]['ctrl']['readOnly']) {
                // "Revert" link (history/undo)
                if (in_array('revertRec', $shEl)) {
                    $cells[] = '<a href="#" onclick="' . htmlspecialchars('return jumpExt(\'' . $this->backPath . 'show_rechis.php?element=' . rawurlencode($table . ':' . $row['uid']) . '\',\'#latest\');') . '">' . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/history2.gif', 'width="13" height="12"') . ' title="' . $LANG->getLL('history', 1) . '" alt="" />' . '</a>';
                }
                // Versioning:
                if (t3lib_extMgm::isLoaded('version')) {
                    $vers = t3lib_BEfunc::selectVersionsOfRecord($table, $row['uid'], $fields = 'uid');
                    if (is_array($vers)) {
                        // If table can be versionized.
                        if (count($vers) > 1) {
                            $st = 'background-color: #FFFF00; font-weight: bold;';
                            $lab = count($vers) - 1;
                        } else {
                            $st = 'background-color: #9999cc; font-weight: bold;';
                            $lab = 'V';
                        }
                        $cells[] = '<a href="' . htmlspecialchars($this->backPath . t3lib_extMgm::extRelPath('version')) . 'cm1/index.php?table=' . rawurlencode($table) . '&uid=' . rawurlencode($row['uid']) . '" class="typo3-ctrl-versioning" style="' . htmlspecialchars($st) . '">' . $lab . '</a>';
                    }
                }
                // "Edit Perms" link:
                if ($table == 'pages' && in_array('permsRec', $shEl) && $GLOBALS['BE_USER']->check('modules', 'web_perm')) {
                    $cells[] = '<a href="' . htmlspecialchars($this->backPath . 'mod/web/perm/index.php?id=' . $row['uid'] . '&return_id=' . $row['uid'] . '&edit=1') . '">' . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/perm.gif', 'width="7" height="12"') . ' title="' . $LANG->getLL('permissions', 1) . '" alt="" />' . '</a>';
                }
                // "Up/Down" links
                if ($permsEdit && $TCA[$table]['ctrl']['sortby'] && !$this->sortField && in_array('sortRec', $shEl)) {
                    //
                    if (isset($this->currentTable['prev'][$row['uid']])) {
                        // Up
                        $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prev'][$row['uid']];
                        $cells[] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '">' . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/button_up.gif', 'width="11" height="10"') . ' title="' . $LANG->getLL('moveUp', 1) . '" alt="" />' . '</a>';
                    } else {
                        $cells[] = '<img src="clear.gif" ' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/button_up.gif', 'width="11" height="10"', 2) . ' alt="" />';
                    }
                    if ($this->currentTable['next'][$row['uid']]) {
                        // Down
                        $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['next'][$row['uid']];
                        $cells[] = '<a href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '">' . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/button_down.gif', 'width="11" height="10"') . ' title="' . $LANG->getLL('moveDown', 1) . '" alt="" />' . '</a>';
                    } else {
                        $cells[] = '<img src="clear.gif" ' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/button_down.gif', 'width="11" height="10"', 2) . ' alt="" />';
                    }
                }
                // "Hide/Unhide" links:
                $hiddenField = $TCA[$table]['ctrl']['enablecolumns']['disabled'];
                if ($permsEdit && $hiddenField && $TCA[$table]['columns'][$hiddenField] && in_array('unHideRec', $shEl) && (!$TCA[$table]['columns'][$hiddenField]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $table . ':' . $hiddenField))) {
                    if ($row[$hiddenField]) {
                        $params = '&data[' . $table . '][' . $row['uid'] . '][' . $hiddenField . ']=0';
                        $cells[] = '<a title="' . $LANG->getLL('unHide' . ($table == 'pages' ? 'Page' : ''), 1) . '" href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '">' . t3lib_iconWorks::getSpriteIcon('actions-edit-unhide') . '</a>';
                    } else {
                        $params = '&data[' . $table . '][' . $row['uid'] . '][' . $hiddenField . ']=1';
                        $cells[] = '<a title="' . $LANG->getLL('hide' . ($table == 'pages' ? 'Page' : ''), 1) . '" href="#" onclick="' . htmlspecialchars('return jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');') . '">' . t3lib_iconWorks::getSpriteIcon('actions-edit-hide') . '</a>';
                    }
                }
                // "Delete" link:
                //				if ( ($table=='pages' && ($localCalcPerms&4)) || ($table!='pages' && ($this->calcPerms&16)) && in_array('delRec',$shEl) )	{
                //					$params='&cmd['.$table.']['.$row['uid'].'][delete]=1';
                //					$title = $row['title'].' ('.$row['file_name'].')';
                //
                //					$cells[]='<a href="#" onclick="if (confirm('.$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.delete'),$title)).')) {jumpToUrl(\''.$GLOBALS['SOBE']->doc->issueCommand($params,-1).'\');} return false;"><img src="'.$this->backPath.'gfx/delete_record.gif" width="12" height="12" border="0" align="top" title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:cm.delete',1).'" /></a>';
                //				}
                // ToDo: weird: quickDelete = true means that there is a confirmation message
                // Todo: quickDelete=true is hardcoded
                $quickDelete = true;
                // "Delete" with confirmation (default)
                if ($quickDelete and $table == 'pages' && $localCalcPerms & 4 || $table != 'pages' && $this->calcPerms & 16 && in_array('delRec', $shEl)) {
                    $params = '&cmd[tx_dam_cat][' . $row['uid'] . '][delete]=1';
                    $title = $row['title'] . ' (' . $row['file_name'] . ')';
                    $onClick = 'if (confirm(' . $GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.delete'), $title)) . ')) {jumpToUrl(\'' . $GLOBALS['SOBE']->doc->issueCommand($params, -1) . '\');} return false;';
                    $cells[] = '<a title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:cm.delete', 1) . '" href="#" onclick="' . $onClick . '">' . t3lib_iconWorks::getSpriteIcon('actions-edit-delete') . '</a>';
                }
                // Todo: Quick delete. Works but without redirect back to the overview.
                if (!$quickDelete and $table == 'pages' && $localCalcPerms & 4 || $table != 'pages' && $this->calcPerms & 16 && in_array('delRec', $shEl)) {
                    $cmd = 'tx_dam_cmd_filedelete';
                    $script = $BACK_PATH . PATH_txdam_rel . 'mod_cmd/index.php?CMD=' . $cmd . '&vC=' . $GLOBALS['BE_USER']->veriCode() . '&id=' . rawurlencode($row['uid']) . '&returnUrl=' . t3lib_div::getIndpEnv('TYPO3_REQUEST_URL');
                    $cells[] = '<a href="' . htmlspecialchars($script) . '">' . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/delete_record.gif', 'width="12" height="12"') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:cm.delete', 1) . '" alt="" />' . '</a>';
                }
            }
        }
        // If the record is edit-locked	by another user, we will show a little warning sign:
        if ($lockInfo = t3lib_BEfunc::isRecordLocked($table, $row['uid'])) {
            $cells[] = '<a href="#" onclick="' . htmlspecialchars('alert(' . $LANG->JScharCode($lockInfo['msg']) . ');return false;') . '">' . '<img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/recordlock_warning3.gif', 'width="17" height="12"') . ' title="' . htmlspecialchars($lockInfo['msg']) . '" alt="" />' . '</a>';
        }
        // Compile items into a DIV-element:
        return '
											<!-- CONTROL PANEL: ' . $table . ':' . $row['uid'] . ' -->
											<div class="typo3-DBctrl">' . implode('', $cells) . '</div>';
    }
Example #2
0
 /**
  * Look for number of versions of a record
  *
  * @param	string		Table name
  * @param	integer		Record uid
  * @return	integer		Number of versions for record, false if none.
  */
 function lookForOwnVersions($table, $uid)
 {
     global $TCA;
     $versions = t3lib_BEfunc::selectVersionsOfRecord($table, $uid, 'uid');
     if (is_array($versions)) {
         return count($versions);
     }
     return FALSE;
 }
    /**
     * Creates the version selector for the page id inputted.
     * Requires the core version management extension, "version" to be loaded.
     *
     * @param	integer		Page id to create selector for.
     * @param	boolean		If set, there will be no button for swapping page.
     * @return	void
     */
    function getVersionSelector($id, $noAction = FALSE)
    {
        if ($id > 0) {
            if (t3lib_extMgm::isLoaded('version') && $GLOBALS['BE_USER']->workspace == 0) {
                // Get Current page record:
                $curPage = t3lib_BEfunc::getRecord('pages', $id);
                // If the selected page is not online, find the right ID
                $onlineId = $curPage['pid'] == -1 ? $curPage['t3ver_oid'] : $id;
                // Select all versions of online version:
                $versions = t3lib_BEfunc::selectVersionsOfRecord('pages', $onlineId, 'uid,pid,t3ver_label,t3ver_oid,t3ver_wsid,t3ver_id');
                // If more than one was found...:
                if (count($versions) > 1) {
                    $selectorLabel = '<strong>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.label', TRUE) . '</strong>';
                    // Create selector box entries:
                    $opt = array();
                    foreach ($versions as $vRow) {
                        if ($vRow['uid'] == $onlineId) {
                            //Live version
                            $label = '[' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.live', TRUE) . ']';
                        } else {
                            $label = $vRow['t3ver_label'] . ' (' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionId', TRUE) . ' ' . $vRow['t3ver_id'] . ($vRow['t3ver_wsid'] != 0 ? ' ' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:workspaceId', TRUE) . ' ' . $vRow['t3ver_wsid'] : '') . ')';
                        }
                        $opt[] = '<option value="' . htmlspecialchars(t3lib_div::linkThisScript(array('id' => $vRow['uid']))) . '"' . ($id == $vRow['uid'] ? ' selected="selected"' : '') . '>' . htmlspecialchars($label) . '</option>';
                    }
                    // Add management link:
                    $management = '<input type="button" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.mgm', TRUE) . '" onclick="window.location.href=\'' . htmlspecialchars($this->backPath . t3lib_extMgm::extRelPath('version') . 'cm1/index.php?table=pages&uid=' . $onlineId) . '\';" />';
                    // Create onchange handler:
                    $onChange = "window.location.href=this.options[this.selectedIndex].value;";
                    // Controls:
                    if ($id == $onlineId) {
                        $controls .= '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/blinkarrow_left.gif', 'width="5" height="9"') . ' class="absmiddle" alt="" /> <strong>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.online', TRUE) . '</strong>';
                    } elseif (!$noAction) {
                        $controls .= '<a href="' . $this->issueCommand('&cmd[pages][' . $onlineId . '][version][swapWith]=' . $id . '&cmd[pages][' . $onlineId . '][version][action]=swap', t3lib_div::linkThisScript(array('id' => $onlineId))) . '" class="nobr">' . t3lib_iconWorks::getSpriteIcon('actions-version-swap-version', array('title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.swapPage', TRUE), 'style' => 'margin-left:5px;vertical-align:bottom;')) . '<strong>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.swap', TRUE) . '</strong></a>';
                    }
                    // Write out HTML code:
                    return '

						<!--
							Version selector:
						-->
						<table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
							<tr>
								<td>' . $selectorLabel . '</td>
								<td>
									<select onchange="' . htmlspecialchars($onChange) . '">
										' . implode('', $opt) . '
									</select></td>
								<td>' . $controls . '</td>
								<td>' . $management . '</td>
							</tr>
						</table>
					';
                }
            } elseif ($GLOBALS['BE_USER']->workspace !== 0) {
                // Write out HTML code:
                switch ($GLOBALS['BE_USER']->workspace) {
                    case 0:
                        $wsTitle = $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:live', TRUE);
                        break;
                    case -1:
                        $wsTitle = $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:draft', TRUE);
                        break;
                    default:
                        $wsTitle = $GLOBALS['BE_USER']->workspaceRec['title'];
                        break;
                }
                if (t3lib_BEfunc::isPidInVersionizedBranch($id) == 'branchpoint') {
                    return '

						<!--
							Version selector:
						-->
						<table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
							<tr>
								<td>' . $selectorLabel . '</td>
								<td>Workspace: "' . htmlspecialchars($wsTitle) . '"</td>
								<td><em>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.inBranch', TRUE) . '</em></td>
							</tr>
						</table>
					';
                } else {
                    // Get Current page record:
                    $curPage = t3lib_BEfunc::getRecord('pages', $id);
                    // If the selected page is not online, find the right ID
                    $onlineId = $curPage['pid'] == -1 ? $curPage['t3ver_oid'] : $id;
                    // The version of page:
                    $verPage = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, 'pages', $onlineId);
                    if (!$verPage) {
                        if (!count(t3lib_BEfunc::countVersionsOfRecordsOnPage($GLOBALS['BE_USER']->workspace, $onlineId))) {
                            if ($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(0)) {
                                $onClick = $this->issueCommand('&cmd[pages][' . $onlineId . '][version][action]=new&cmd[pages][' . $onlineId . '][version][treeLevels]=0', t3lib_div::linkThisScript(array('id' => $onlineId)));
                                $onClick = 'window.location.href=\'' . $onClick . '\'; return false;';
                                // Write out HTML code:
                                return '

									<!--
										No version yet, create one?
									-->
									<table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
										<tr>
											<td>' . $selectorLabel . '</td>
											<td>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:workspace', TRUE) . ': "' . htmlspecialchars($wsTitle) . '"</td>
											<td>
												<input type="button" value="New version of page" name="_" onclick="' . htmlspecialchars($onClick) . '" /></td>
										</tr>
									</table>
								';
                            }
                        } elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['elementVersioningOnly'] == FALSE && $GLOBALS['TYPO3_CONF_VARS']['BE']['newPagesVersioningType'] == 0) {
                            // only add this info if old/deprecated newPagesVersioning is allowed
                            return '

								<!--
									Version selector:
								-->
								<table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
									<tr>
										<td>' . $selectorLabel . '</td>
										<td>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:workspace', TRUE) . ': "' . htmlspecialchars($wsTitle) . '"</td>
										<td><em>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.versionsFound', TRUE) . '</em></td>
									</tr>
								</table>
							';
                        }
                    } elseif ($verPage['t3ver_swapmode'] == 0) {
                        $onClick = $this->issueCommand('&cmd[pages][' . $onlineId . '][version][action]=swap&cmd[pages][' . $onlineId . '][version][swapWith]=' . $verPage['uid'], t3lib_div::linkThisScript(array('id' => $onlineId)));
                        $onClick = 'window.location.href=\'' . $onClick . '\'; return false;';
                        // Write out HTML code:
                        return '

							<!--
								Version selector:
							-->
							<table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
								<tr>
									<td>' . $selectorLabel . '</td>
									<td>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:workspace', TRUE) . ': "' . htmlspecialchars($wsTitle) . '"</td>
									<td>
										<input type="button" value="' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.publish', TRUE) . '" onclick="' . htmlspecialchars($onClick) . '" /></td>
								</tr>
							</table>
						';
                    }
                }
            }
        }
    }
 /**
  * Find orphan records
  * VERY CPU and memory intensive since it will look up the whole page tree!
  *
  * @return	array
  */
 function main()
 {
     global $TYPO3_DB;
     // Initialize result array:
     $resultArray = array('message' => $this->cli_help['name'] . LF . LF . $this->cli_help['description'], 'headers' => array('versions' => array('All versions', 'Showing all versions of records found', 0), 'versions_published' => array('All published versions', 'This is all records that has been published and can therefore be removed permanently', 1), 'versions_liveWS' => array('All versions in Live workspace', 'This is all records that are offline versions in the Live workspace. You may wish to flush these if you only use workspaces for versioning since then you might find lots of versions piling up in the live workspace which have simply been disconnected from the workspace before they were published.', 1), 'versions_lost_workspace' => array('Versions outside a workspace', 'Versions that has lost their connection to a workspace in TYPO3.', 3), 'versions_inside_versioned_page' => array('Versions in versions', 'Versions inside an already versioned page. Something that is confusing to users and therefore should not happen but is technically possible.', 2), 'versions_unused_placeholders' => array('Unused placeholder records', 'Placeholder records which are not used anymore by offline versions.', 2), 'versions_move_placeholders_ok' => array('Move placeholders', 'Move-to placeholder records which has good integrity', 0), 'versions_move_placeholders_bad' => array('Move placeholders with bad integrity', 'Move-to placeholder records which has bad integrity', 2), 'versions_move_id_check' => array('Checking if t3ver_move_id is correct', 't3ver_move_id must only be set with online records having t3ver_state=3.', 2)), 'versions' => array());
     $startingPoint = $this->cli_isArg('--pid') ? t3lib_div::intInRange($this->cli_argValue('--pid'), 0) : 0;
     $depth = $this->cli_isArg('--depth') ? t3lib_div::intInRange($this->cli_argValue('--depth'), 0) : 1000;
     $this->genTree($startingPoint, $depth, (int) $this->cli_argValue('--echotree'));
     $resultArray['versions'] = $this->recStats['versions'];
     $resultArray['versions_published'] = $this->recStats['versions_published'];
     $resultArray['versions_liveWS'] = $this->recStats['versions_liveWS'];
     $resultArray['versions_lost_workspace'] = $this->recStats['versions_lost_workspace'];
     $resultArray['versions_inside_versioned_page'] = $this->recStats['versions_inside_versioned_page'];
     // Finding all placeholders with no records attached!
     $resultArray['versions_unused_placeholders'] = array();
     foreach ($GLOBALS['TCA'] as $table => $cfg) {
         if ($cfg['ctrl']['versioningWS']) {
             $placeHolders = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,pid', $table, 't3ver_state=1 AND pid>=0' . t3lib_BEfunc::deleteClause($table));
             foreach ($placeHolders as $phrec) {
                 if (count(t3lib_BEfunc::selectVersionsOfRecord($table, $phrec['uid'], 'uid')) <= 1) {
                     $resultArray['versions_unused_placeholders'][t3lib_div::shortmd5($table . ':' . $phrec['uid'])] = $table . ':' . $phrec['uid'];
                 }
             }
         }
     }
     asort($resultArray['versions_unused_placeholders']);
     // Finding all move placeholders with inconsistencies:
     $resultArray['versions_move_placeholders_ok'] = array();
     $resultArray['versions_move_placeholders_bad'] = array();
     foreach ($GLOBALS['TCA'] as $table => $cfg) {
         if ((int) $cfg['ctrl']['versioningWS'] >= 2) {
             $placeHolders = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,pid,t3ver_move_id,t3ver_wsid,t3ver_state', $table, 't3ver_state=3 AND pid>=0' . t3lib_BEfunc::deleteClause($table));
             foreach ($placeHolders as $phrec) {
                 $shortID = t3lib_div::shortmd5($table . ':' . $phrec['uid']);
                 if ((int) $phrec['t3ver_wsid'] != 0) {
                     $phrecCopy = $phrec;
                     if (t3lib_BEfunc::movePlhOL($table, $phrec)) {
                         if ($wsAlt = t3lib_BEfunc::getWorkspaceVersionOfRecord($phrecCopy['t3ver_wsid'], $table, $phrec['uid'], 'uid,pid,t3ver_state')) {
                             if ($wsAlt['t3ver_state'] != 4) {
                                 $resultArray['versions_move_placeholders_bad'][$shortID] = array($table . ':' . $phrec['uid'], 'State for version was not "4" as it should be!', $phrecCopy);
                             } else {
                                 $resultArray['versions_move_placeholders_ok'][$shortID] = array($table . ':' . $phrec['uid'], 'PLH' => $phrecCopy, 'online' => $phrec, 'PNT' => $wsAlt);
                             }
                         } else {
                             $resultArray['versions_move_placeholders_bad'][$shortID] = array($table . ':' . $phrec['uid'], 'No version was found for online record to be moved. A version must exist.', $phrecCopy);
                         }
                     } else {
                         $resultArray['versions_move_placeholders_bad'][$shortID] = array($table . ':' . $phrec['uid'], 'Did not find online record for "t3ver_move_id" value ' . $phrec['t3ver_move_id'], $phrec);
                     }
                 } else {
                     $resultArray['versions_move_placeholders_bad'][$shortID] = array($table . ':' . $phrec['uid'], 'Placeholder was not assigned a workspace value in t3ver_wsid.', $phrec);
                 }
             }
         }
     }
     ksort($resultArray['versions_move_placeholders_ok']);
     ksort($resultArray['versions_move_placeholders_bad']);
     // Finding move_id_check inconsistencies:
     $resultArray['versions_move_id_check'] = array();
     foreach ($GLOBALS['TCA'] as $table => $cfg) {
         if ((int) $cfg['ctrl']['versioningWS'] >= 2) {
             $placeHolders = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,pid,t3ver_move_id,t3ver_wsid,t3ver_state', $table, 't3ver_move_id!=0' . t3lib_BEfunc::deleteClause($table));
             foreach ($placeHolders as $phrec) {
                 if ((int) $phrec['t3ver_state'] == 3) {
                     if ($phrec['pid'] != -1) {
                         // OK
                     } else {
                         $resultArray['versions_move_id_check'][] = array($table . ':' . $phrec['uid'], 'Record was offline, must not be!', $phrec);
                     }
                 } else {
                     $resultArray['versions_move_id_check'][] = array($table . ':' . $phrec['uid'], 'Record had t3ver_move_id set to "' . $phrec['t3ver_move_id'] . '" while having t3ver_state=' . $phrec['t3ver_state'], $phrec);
                 }
             }
         }
     }
     return $resultArray;
 }
 /**
  * Recursive traversal of page tree:
  *
  * @param	integer		Page root id (must be online, valid page record - or zero for page tree root)
  * @param	integer		Depth
  * @param	integer		Echo Level
  * @param	string		Call back function (from this class or subclass)
  * @param	string		DON'T set from outside, internal. (indicates we are inside a version of a page)
  * @param	integer		DON'T set from outside, internal. (1: Indicates that rootID is a version of a page, 2: ...that it is even a version of a version (which triggers a warning!)
  * @param	string		Internal string that accumulates the path
  * @return	void
  * @access private
  */
 function genTree_traverse($rootID, $depth, $echoLevel = 0, $callBack = '', $versionSwapmode = '', $rootIsVersion = 0, $accumulatedPath = '')
 {
     // Register page:
     $this->recStats['all']['pages'][$rootID] = $rootID;
     $pageRecord = t3lib_BEfunc::getRecordRaw('pages', 'uid=' . intval($rootID), 'deleted,title,t3ver_count,t3ver_wsid');
     $accumulatedPath .= '/' . $pageRecord['title'];
     // Register if page is deleted:
     if ($pageRecord['deleted']) {
         $this->recStats['deleted']['pages'][$rootID] = $rootID;
     }
     // If rootIsVersion is set it means that the input rootID is that of a version of a page. See below where the recursive call is made.
     if ($rootIsVersion) {
         $this->recStats['versions']['pages'][$rootID] = $rootID;
         if ($pageRecord['t3ver_count'] >= 1 && $pageRecord['t3ver_wsid'] == 0) {
             // If it has been published and is in archive now...
             $this->recStats['versions_published']['pages'][$rootID] = $rootID;
         }
         if ($pageRecord['t3ver_wsid'] == 0) {
             // If it has been published and is in archive now...
             $this->recStats['versions_liveWS']['pages'][$rootID] = $rootID;
         }
         if (!isset($this->workspaceIndex[$pageRecord['t3ver_wsid']])) {
             // If it doesn't belong to a workspace...
             $this->recStats['versions_lost_workspace']['pages'][$rootID] = $rootID;
         }
         if ($rootIsVersion == 2) {
             // In case the rootID is a version inside a versioned page
             $this->recStats['versions_inside_versioned_page']['pages'][$rootID] = $rootID;
         }
     }
     if ($echoLevel > 0) {
         echo LF . $accumulatedPath . ' [' . $rootID . ']' . ($pageRecord['deleted'] ? ' (DELETED)' : '') . ($this->recStats['versions_published']['pages'][$rootID] ? ' (PUBLISHED)' : '');
     }
     if ($echoLevel > 1 && $this->recStats['versions_lost_workspace']['pages'][$rootID]) {
         echo LF . '	ERROR! This version belongs to non-existing workspace (' . $pageRecord['t3ver_wsid'] . ')!';
     }
     if ($echoLevel > 1 && $this->recStats['versions_inside_versioned_page']['pages'][$rootID]) {
         echo LF . '	WARNING! This version is inside an already versioned page or branch!';
     }
     // Call back:
     if ($callBack) {
         $this->{$callBack}('pages', $rootID, $echoLevel, $versionSwapmode, $rootIsVersion);
     }
     $pt3 = t3lib_div::milliseconds();
     // Traverse tables of records that belongs to page:
     foreach ($GLOBALS['TCA'] as $tableName => $cfg) {
         if ($tableName != 'pages') {
             // Select all records belonging to page:
             $pt4 = t3lib_div::milliseconds();
             $resSub = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), $tableName, 'pid=' . intval($rootID) . ($this->genTree_traverseDeleted ? '' : t3lib_BEfunc::deleteClause($tableName)));
             $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL']['(ALL)'] += t3lib_div::milliseconds() - $pt4;
             $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL'][$tableName] += t3lib_div::milliseconds() - $pt4;
             $pt5 = t3lib_div::milliseconds();
             $count = $GLOBALS['TYPO3_DB']->sql_num_rows($resSub);
             if ($count) {
                 if ($echoLevel == 2) {
                     echo LF . '	\\-' . $tableName . ' (' . $count . ')';
                 }
             }
             while ($rowSub = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resSub)) {
                 if ($echoLevel == 3) {
                     echo LF . '	\\-' . $tableName . ':' . $rowSub['uid'];
                 }
                 // If the rootID represents an "element" or "page" version type, we must check if the record from this table is allowed to belong to this:
                 if ($versionSwapmode == 'SWAPMODE:-1' || $versionSwapmode == 'SWAPMODE:0' && !$GLOBALS['TCA'][$tableName]['ctrl']['versioning_followPages']) {
                     // This is illegal records under a versioned page - therefore not registered in $this->recStats['all'] so they should be orphaned:
                     $this->recStats['illegal_record_under_versioned_page'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                     if ($echoLevel > 1) {
                         echo LF . '		ERROR! Illegal record (' . $tableName . ':' . $rowSub['uid'] . ') under versioned page!';
                     }
                 } else {
                     $this->recStats['all'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                     // Register deleted:
                     if ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] && $rowSub[$GLOBALS['TCA'][$tableName]['ctrl']['delete']]) {
                         $this->recStats['deleted'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                         if ($echoLevel == 3) {
                             echo ' (DELETED)';
                         }
                     }
                     // Check location of records regarding tree root:
                     if (!$GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] && $rootID == 0) {
                         $this->recStats['misplaced_at_rootlevel'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                         if ($echoLevel > 1) {
                             echo LF . '		ERROR! Misplaced record (' . $tableName . ':' . $rowSub['uid'] . ') on rootlevel!';
                         }
                     }
                     if ($GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] == 1 && $rootID > 0) {
                         $this->recStats['misplaced_inside_tree'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                         if ($echoLevel > 1) {
                             echo LF . '		ERROR! Misplaced record (' . $tableName . ':' . $rowSub['uid'] . ') inside page tree!';
                         }
                     }
                     // Traverse plugins:
                     if ($callBack) {
                         $this->{$callBack}($tableName, $rowSub['uid'], $echoLevel, $versionSwapmode, $rootIsVersion);
                     }
                     // Add any versions of those records:
                     if ($this->genTree_traverseVersions) {
                         $versions = t3lib_BEfunc::selectVersionsOfRecord($tableName, $rowSub['uid'], 'uid,t3ver_wsid,t3ver_count' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), 0, TRUE);
                         if (is_array($versions)) {
                             foreach ($versions as $verRec) {
                                 if (!$verRec['_CURRENT_VERSION']) {
                                     if ($echoLevel == 3) {
                                         echo LF . '		\\-[#OFFLINE VERSION: WS#' . $verRec['t3ver_wsid'] . '/Cnt:' . $verRec['t3ver_count'] . '] ' . $tableName . ':' . $verRec['uid'] . ')';
                                     }
                                     $this->recStats['all'][$tableName][$verRec['uid']] = $verRec['uid'];
                                     // Register deleted:
                                     if ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] && $verRec[$GLOBALS['TCA'][$tableName]['ctrl']['delete']]) {
                                         $this->recStats['deleted'][$tableName][$verRec['uid']] = $verRec['uid'];
                                         if ($echoLevel == 3) {
                                             echo ' (DELETED)';
                                         }
                                     }
                                     // Register version:
                                     $this->recStats['versions'][$tableName][$verRec['uid']] = $verRec['uid'];
                                     if ($verRec['t3ver_count'] >= 1 && $verRec['t3ver_wsid'] == 0) {
                                         // Only register published versions in LIVE workspace (published versions in draft workspaces are allowed)
                                         $this->recStats['versions_published'][$tableName][$verRec['uid']] = $verRec['uid'];
                                         if ($echoLevel == 3) {
                                             echo ' (PUBLISHED)';
                                         }
                                     }
                                     if ($verRec['t3ver_wsid'] == 0) {
                                         $this->recStats['versions_liveWS'][$tableName][$verRec['uid']] = $verRec['uid'];
                                     }
                                     if (!isset($this->workspaceIndex[$verRec['t3ver_wsid']])) {
                                         $this->recStats['versions_lost_workspace'][$tableName][$verRec['uid']] = $verRec['uid'];
                                         if ($echoLevel > 1) {
                                             echo LF . '		ERROR! Version (' . $tableName . ':' . $verRec['uid'] . ') belongs to non-existing workspace (' . $verRec['t3ver_wsid'] . ')!';
                                         }
                                     }
                                     if ($versionSwapmode) {
                                         // In case we are inside a versioned branch, there should not exists versions inside that "branch".
                                         $this->recStats['versions_inside_versioned_page'][$tableName][$verRec['uid']] = $verRec['uid'];
                                         if ($echoLevel > 1) {
                                             echo LF . '		ERROR! This version (' . $tableName . ':' . $verRec['uid'] . ') is inside an already versioned page or branch!';
                                         }
                                     }
                                     // Traverse plugins:
                                     if ($callBack) {
                                         $this->{$callBack}($tableName, $verRec['uid'], $echoLevel, $versionSwapmode, $rootIsVersion);
                                     }
                                 }
                             }
                         }
                         unset($versions);
                     }
                 }
             }
             $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc']['(ALL)'] += t3lib_div::milliseconds() - $pt5;
             $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc'][$tableName] += t3lib_div::milliseconds() - $pt5;
         }
     }
     unset($resSub);
     unset($rowSub);
     $this->performanceStatistics['genTree_traverse():TraverseTables'] += t3lib_div::milliseconds() - $pt3;
     // Find subpages to root ID and traverse (only when rootID is not a version or is a branch-version):
     if (!$versionSwapmode || $versionSwapmode == 'SWAPMODE:1') {
         if ($depth > 0) {
             $depth--;
             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid=' . intval($rootID) . ($this->genTree_traverseDeleted ? '' : t3lib_BEfunc::deleteClause('pages')), '', 'sorting');
             while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
                 $this->genTree_traverse($row['uid'], $depth, $echoLevel, $callBack, $versionSwapmode, 0, $accumulatedPath);
             }
         }
         // Add any versions of pages
         if ($rootID > 0 && $this->genTree_traverseVersions) {
             $versions = t3lib_BEfunc::selectVersionsOfRecord('pages', $rootID, 'uid,t3ver_oid,t3ver_wsid,t3ver_count,t3ver_swapmode', 0, TRUE);
             if (is_array($versions)) {
                 foreach ($versions as $verRec) {
                     if (!$verRec['_CURRENT_VERSION']) {
                         $this->genTree_traverse($verRec['uid'], $depth, $echoLevel, $callBack, 'SWAPMODE:' . t3lib_div::intInRange($verRec['t3ver_swapmode'], -1, 1), $versionSwapmode ? 2 : 1, $accumulatedPath . ' [#OFFLINE VERSION: WS#' . $verRec['t3ver_wsid'] . '/Cnt:' . $verRec['t3ver_count'] . ']');
                     }
                 }
             }
         }
     }
 }
 /**
  * Delete versions for element from any table
  *
  * @param	string		Table name
  * @param	integer		Record UID
  * @param	boolean		If TRUE, the "deleted" flag is ignored if applicable for record and the record is deleted COMPLETELY!
  * @return	void
  */
 function deleteVersionsForRecord($table, $uid, $forceHardDelete)
 {
     $versions = t3lib_BEfunc::selectVersionsOfRecord($table, $uid, 'uid,pid');
     if (is_array($versions)) {
         foreach ($versions as $verRec) {
             if (!$verRec['_CURRENT_VERSION']) {
                 if ($table == 'pages') {
                     $this->deletePages($verRec['uid'], TRUE, $forceHardDelete);
                 } else {
                     $this->deleteRecord($table, $verRec['uid'], TRUE, $forceHardDelete);
                 }
             }
         }
     }
 }