00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00056 class tx_lowlevel_orphan_records extends tx_lowlevel_cleaner_core {
00057
00063 function tx_lowlevel_orphan_records() {
00064 parent::tx_lowlevel_cleaner_core();
00065
00066
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_help['name'] = 'orphan_records -- To find records that has lost their connection with the page tree';
00069 $this->cli_help['description'] = trim('
00070 Assumptions:
00071 - That all actively used records on the website from TCA configured tables are located in the page tree exclusively.
00072
00073 All records managed by TYPO3 via the TCA array configuration has to belong to a page in the page tree, either directly or indirectly as a version of another record.
00074 VERY TIME, CPU and MEMORY intensive operation since the full page tree is looked up!
00075
00076 Automatic Repair of Errors:
00077 - Silently deleting the orphaned records. In theory they should not be used anywhere in the system, but there could be references. See below for more details on this matter.
00078
00079 Manual repair suggestions:
00080 - Possibly re-connect orphaned records to page tree by setting their "pid" field to a valid page id. A lookup in the sys_refindex table can reveal if there are references to a orphaned record. If there are such references (from records that are not themselves orphans) you might consider to re-connect the record to the page tree, otherwise it should be safe to delete it.
00081 ');
00082 $this->cli_help['todo'] = trim('
00083 - Implement a check for references to orphaned records and if a reference comes from a record that is not orphaned itself, we might rather like to re-connect the record to the page tree.
00084 - Implement that orphans can be fixed by setting the PID to a certain page instead of deleting.');
00085
00086 $this->cli_help['examples'] = '/.../cli_dispatch.phpsh lowlevel_cleaner orphan_records -s -r
00087 Will report orphan uids from TCA tables.';
00088 }
00089
00096 function main() {
00097 global $TYPO3_DB;
00098
00099
00100 $resultArray = array(
00101 'message' => $this->cli_help['name'].chr(10).chr(10).$this->cli_help['description'],
00102 'headers' => array(
00103 'orphans' => array('Index of orphaned records','',3),
00104 'misplaced_at_rootlevel' => array('Records that should not be at root level but are.','Fix manually by moving record into page tree',2),
00105 'misplaced_inside_tree' => array('Records that should be at root level but are not.','Fix manually by moving record to tree root',2),
00106 'illegal_record_under_versioned_page' => array('Records that cannot be attached to a versioned page','(Listed under orphaned records so is fixed along with orphans.)',2),
00107 ),
00108 'orphans' => array(),
00109 'misplaced_at_rootlevel' => array(),
00110 'misplaced_inside_tree' => array(),
00111 'illegal_record_under_versioned_page' => array(),
00112 );
00113
00114 $startingPoint = 0;
00115 $pt = t3lib_div::milliseconds();
00116
00117 $this->genTree($startingPoint,1000,(int)$this->cli_argValue('--echotree'));
00118
00119 $resultArray['misplaced_at_rootlevel'] = $this->recStats['misplaced_at_rootlevel'];
00120 $resultArray['misplaced_inside_tree'] = $this->recStats['misplaced_inside_tree'];
00121 $resultArray['illegal_record_under_versioned_page'] = $this->recStats['illegal_record_under_versioned_page'];
00122
00123
00124 foreach($GLOBALS['TCA'] as $tableName => $cfg) {
00125
00126 $idList = is_array($this->recStats['all'][$tableName]) && count($this->recStats['all'][$tableName]) ? implode(',',$this->recStats['all'][$tableName]) : 0;
00127
00128
00129 $orphanRecords = array_keys($GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
00130 'uid',
00131 $tableName,
00132 'uid NOT IN ('.$idList.')',
00133 '','','','uid'
00134 ));
00135
00136 if (count($orphanRecords)) {
00137 $resultArray['orphans'][$tableName] = implode(',',$orphanRecords);
00138 }
00139 }
00140
00141 return $resultArray;
00142 }
00143
00151 function main_autoFix($resultArray) {
00152
00153
00154 if (isset($resultArray['orphans']['pages'])) {
00155 $_pages = $resultArray['orphans']['pages'];
00156 unset($resultArray['orphans']['pages']);
00157 $resultArray['orphans']['pages'] = $_pages;
00158 }
00159
00160
00161 foreach($resultArray['orphans'] as $table => $list) {
00162 echo 'Removing orphans from table "'.$table.'":'.chr(10);
00163 $list = explode(',',$list);
00164 foreach($list as $uid) {
00165 echo ' Flushing orphan record "'.$table.':'.$uid.'": ';
00166 if ($bypass = $this->cli_noExecutionCheck($table.':'.$uid)) {
00167 echo $bypass;
00168 } else {
00169
00170
00171 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
00172 $tce->stripslashes_values = FALSE;
00173 $tce->start(array(),array());
00174 $tce->deleteRecord($table,$uid, TRUE, TRUE);
00175
00176
00177 if (count($tce->errorLog)) {
00178 echo ' ERROR from "TCEmain":'.chr(10).'TCEmain:'.implode(chr(10).'TCEmain:',$tce->errorLog);
00179 } else echo 'DONE';
00180 }
00181 echo chr(10);
00182 }
00183 }
00184 }
00185 }
00186
00187 ?>