|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 /** 00028 * Cleaner module: Versions of records 00029 * User function called from tx_lowlevel_cleaner_core configured in ext_localconf.php 00030 * 00031 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00032 */ 00033 /** 00034 * [CLASS/FUNCTION INDEX of SCRIPT] 00035 * 00036 * 00037 * 00038 * 56: class tx_lowlevel_versions extends tx_lowlevel_cleaner_core 00039 * 63: function tx_lowlevel_versions() 00040 * 88: function main() 00041 * 122: function main_autoFix($resultArray) 00042 * 00043 * TOTAL FUNCTIONS: 3 00044 * (This index is automatically created/updated by the extension "extdeveval") 00045 * 00046 */ 00047 00048 00049 /** 00050 * Looking for versions of records 00051 * 00052 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00053 * @package TYPO3 00054 * @subpackage tx_lowlevel 00055 */ 00056 class tx_lowlevel_versions extends tx_lowlevel_cleaner_core { 00057 00058 /** 00059 * Constructor 00060 * 00061 * @return void 00062 */ 00063 function tx_lowlevel_versions() { 00064 parent::tx_lowlevel_cleaner_core(); 00065 00066 // Setting up help: 00067 $this->cli_options[] = array('--echotree level', 'When "level" is set to 1 or higher you will see the page of the page tree outputted as it is traversed. A value of 2 for "level" will show even more information.'); 00068 $this->cli_options[] = array('--pid id', 'Setting start page in page tree. Default is the page tree root, 0 (zero)'); 00069 $this->cli_options[] = array('--depth int', 'Setting traversal depth. 0 (zero) will only analyse start page (see --pid), 1 will traverse one level of subpages etc.'); 00070 00071 $this->cli_options[] = array('--flush-live', 'If set, not only published versions from Live workspace are flushed, but ALL versions from Live workspace (which are offline of course)'); 00072 00073 $this->cli_help['name'] = 'versions -- To find information about versions and workspaces in the system'; 00074 $this->cli_help['description'] = trim(' 00075 Traversing page tree and finding versions, categorizing them by various properties. 00076 Published versions from the Live workspace are registered. So are all offline versions from Live workspace in general. Further, versions in non-existing workspaces are found. 00077 00078 Automatic Repair: 00079 - Deleting (completely) published versions from LIVE workspace OR _all_ offline versions from Live workspace (toogle by --flush-live) 00080 - Resetting workspace for versions where workspace is deleted. (You might want to run this tool again after this operation to clean out those new elements in the Live workspace) 00081 - Deleting unused placeholders 00082 '); 00083 00084 $this->cli_help['examples'] = ''; 00085 } 00086 00087 /** 00088 * Find orphan records 00089 * VERY CPU and memory intensive since it will look up the whole page tree! 00090 * 00091 * @return array 00092 */ 00093 function main() { 00094 global $TYPO3_DB; 00095 00096 // Initialize result array: 00097 $resultArray = array( 00098 'message' => $this->cli_help['name'].LF.LF.$this->cli_help['description'], 00099 'headers' => array( 00100 'versions' => array('All versions','Showing all versions of records found',0), 00101 'versions_published' => array('All published versions','This is all records that has been published and can therefore be removed permanently',1), 00102 '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), 00103 'versions_lost_workspace' => array('Versions outside a workspace','Versions that has lost their connection to a workspace in TYPO3.',3), 00104 '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), 00105 'versions_unused_placeholders' => array('Unused placeholder records','Placeholder records which are not used anymore by offline versions.',2), 00106 'versions_move_placeholders_ok' => array('Move placeholders','Move-to placeholder records which has good integrity',0), 00107 'versions_move_placeholders_bad' => array('Move placeholders with bad integrity','Move-to placeholder records which has bad integrity',2), 00108 '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), 00109 ), 00110 'versions' => array(), 00111 ); 00112 00113 $startingPoint = $this->cli_isArg('--pid') ? t3lib_div::intInRange($this->cli_argValue('--pid'),0) : 0; 00114 $depth = $this->cli_isArg('--depth') ? t3lib_div::intInRange($this->cli_argValue('--depth'),0) : 1000; 00115 $this->genTree($startingPoint,$depth,(int)$this->cli_argValue('--echotree')); 00116 00117 $resultArray['versions'] = $this->recStats['versions']; 00118 $resultArray['versions_published'] = $this->recStats['versions_published']; 00119 $resultArray['versions_liveWS'] = $this->recStats['versions_liveWS']; 00120 $resultArray['versions_lost_workspace'] = $this->recStats['versions_lost_workspace']; 00121 $resultArray['versions_inside_versioned_page'] = $this->recStats['versions_inside_versioned_page']; 00122 00123 // Finding all placeholders with no records attached! 00124 $resultArray['versions_unused_placeholders'] = array(); 00125 foreach($GLOBALS['TCA'] as $table => $cfg) { 00126 if ($cfg['ctrl']['versioningWS']) { 00127 $placeHolders = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,pid',$table,'t3ver_state=1 AND pid>=0'.t3lib_BEfunc::deleteClause($table)); 00128 foreach($placeHolders as $phrec) { 00129 if (count(t3lib_BEfunc::selectVersionsOfRecord($table, $phrec['uid'], 'uid'))<=1) { 00130 $resultArray['versions_unused_placeholders'][t3lib_div::shortmd5($table.':'.$phrec['uid'])] = $table.':'.$phrec['uid']; 00131 } 00132 } 00133 } 00134 } 00135 asort($resultArray['versions_unused_placeholders']); 00136 00137 // Finding all move placeholders with inconsistencies: 00138 $resultArray['versions_move_placeholders_ok'] = array(); 00139 $resultArray['versions_move_placeholders_bad'] = array(); 00140 foreach($GLOBALS['TCA'] as $table => $cfg) { 00141 if ((int)$cfg['ctrl']['versioningWS']>=2) { 00142 $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)); 00143 foreach($placeHolders as $phrec) { 00144 $shortID = t3lib_div::shortmd5($table.':'.$phrec['uid']); 00145 if ((int)$phrec['t3ver_wsid']!=0) { 00146 $phrecCopy = $phrec; 00147 if (t3lib_BEfunc::movePlhOL($table,$phrec)) { 00148 if ($wsAlt = t3lib_BEfunc::getWorkspaceVersionOfRecord($phrecCopy['t3ver_wsid'], $table, $phrec['uid'], 'uid,pid,t3ver_state')) { 00149 if ($wsAlt['t3ver_state']!=4) { 00150 $resultArray['versions_move_placeholders_bad'][$shortID] = array($table.':'.$phrec['uid'],'State for version was not "4" as it should be!',$phrecCopy); 00151 } else { 00152 $resultArray['versions_move_placeholders_ok'][$shortID] = array( 00153 $table.':'.$phrec['uid'], 00154 'PLH' => $phrecCopy, 00155 'online' => $phrec, 00156 'PNT' => $wsAlt 00157 ); 00158 } 00159 } else { 00160 $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); 00161 } 00162 } else { 00163 $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); 00164 } 00165 } else { 00166 $resultArray['versions_move_placeholders_bad'][$shortID] = array($table.':'.$phrec['uid'],'Placeholder was not assigned a workspace value in t3ver_wsid.',$phrec); 00167 } 00168 } 00169 } 00170 } 00171 00172 ksort($resultArray['versions_move_placeholders_ok']); 00173 ksort($resultArray['versions_move_placeholders_bad']); 00174 00175 // Finding move_id_check inconsistencies: 00176 $resultArray['versions_move_id_check'] = array(); 00177 foreach($GLOBALS['TCA'] as $table => $cfg) { 00178 if ((int)$cfg['ctrl']['versioningWS']>=2) { 00179 $placeHolders = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,pid,t3ver_move_id,t3ver_wsid,t3ver_state',$table,'t3ver_move_id!=0'.t3lib_BEfunc::deleteClause($table)); 00180 foreach($placeHolders as $phrec) { 00181 if ((int)$phrec['t3ver_state']==3) { 00182 if ($phrec['pid']!=-1) { 00183 // OK 00184 } else { 00185 $resultArray['versions_move_id_check'][] = array($table.':'.$phrec['uid'],'Record was offline, must not be!',$phrec); 00186 } 00187 } else { 00188 $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); 00189 } 00190 } 00191 } 00192 } 00193 00194 return $resultArray; 00195 } 00196 00197 /** 00198 * Mandatory autofix function 00199 * Will run auto-fix on the result array. Echos status during processing. 00200 * 00201 * @param array Result array from main() function 00202 * @return void 00203 */ 00204 function main_autoFix($resultArray) { 00205 00206 $kk = $this->cli_isArg('--flush-live') ? 'versions_liveWS' : 'versions_published'; 00207 00208 // Putting "pages" table in the bottom: 00209 if (isset($resultArray[$kk]['pages'])) { 00210 $_pages = $resultArray[$kk]['pages']; 00211 unset($resultArray[$kk]['pages']); 00212 $resultArray[$kk]['pages'] = $_pages; 00213 } 00214 00215 // Traversing records: 00216 foreach($resultArray[$kk] as $table => $list) { 00217 echo 'Flushing published records from table "'.$table.'":'.LF; 00218 foreach($list as $uid) { 00219 echo ' Flushing record "'.$table.':'.$uid.'": '; 00220 00221 if ($bypass = $this->cli_noExecutionCheck($table.':'.$uid)) { 00222 echo $bypass; 00223 } else { 00224 00225 // Execute CMD array: 00226 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 00227 $tce->stripslashes_values = FALSE; 00228 $tce->start(array(),array()); 00229 $tce->deleteEl($table,$uid, TRUE, TRUE); 00230 00231 // Return errors if any: 00232 if (count($tce->errorLog)) { 00233 echo ' ERROR from "TCEmain":'.LF.'TCEmain:'.implode(LF.'TCEmain:',$tce->errorLog); 00234 } else echo 'DONE'; 00235 } 00236 echo LF; 00237 } 00238 } 00239 00240 // Traverse workspace: 00241 foreach($resultArray['versions_lost_workspace'] as $table => $list) { 00242 echo 'Resetting workspace to zero for records from table "'.$table.'":'.LF; 00243 foreach($list as $uid) { 00244 echo ' Flushing record "'.$table.':'.$uid.'": '; 00245 if ($bypass = $this->cli_noExecutionCheck($table.':'.$uid)) { 00246 echo $bypass; 00247 } else { 00248 $fields_values = array( 00249 't3ver_wsid' => 0 00250 ); 00251 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table,'uid='.intval($uid),$fields_values); 00252 echo 'DONE'; 00253 } 00254 echo LF; 00255 } 00256 } 00257 00258 // Delete unused placeholders 00259 foreach($resultArray['versions_unused_placeholders'] as $recID) { 00260 list($table,$uid) = explode(':',$recID); 00261 echo 'Deleting unused placeholder (soft) "'.$table.':'.$uid.'": '; 00262 if ($bypass = $this->cli_noExecutionCheck($table.':'.$uid)) { 00263 echo $bypass; 00264 } else { 00265 00266 // Execute CMD array: 00267 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 00268 $tce->stripslashes_values = FALSE; 00269 $tce->start(array(),array()); 00270 $tce->deleteAction($table, $uid); 00271 00272 // Return errors if any: 00273 if (count($tce->errorLog)) { 00274 echo ' ERROR from "TCEmain":'.LF.'TCEmain:'.implode(LF.'TCEmain:',$tce->errorLog); 00275 } else echo 'DONE'; 00276 } 00277 echo LF; 00278 } 00279 } 00280 } 00281 00282 ?>
1.8.0