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
00049 require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
00050
00058 class tx_lowlevel_double_files extends tx_lowlevel_cleaner_core {
00059
00060 var $checkRefIndex = TRUE;
00061
00067 function tx_lowlevel_double_files() {
00068 parent::tx_lowlevel_cleaner_core();
00069
00070
00071 $this->cli_help['name'] = 'double_files -- Looking for files from TYPO3 managed records which are referenced more than one time (only one time allowed)';
00072 $this->cli_help['description'] = trim('
00073 Assumptions:
00074 - a perfect integrity of the reference index table (always update the reference index table before using this tool!)
00075 - files found in deleted records are included (otherwise you would see a false list of lost files)
00076
00077 Files attached to records in TYPO3 using a "group" type configuration in TCA or FlexForm DataStructure are managed exclusively by the system and there must always exist a 1-1 reference between the file and the reference in the record.
00078 This tool will expose when such files are referenced from multiple locations which is considered an integrity error.
00079 If a multi-reference is found it was typically created because the record was copied or modified outside of TCEmain which will otherwise maintain the relations correctly.
00080 Multi-references should be resolved to 1-1 references as soon as possible. The danger of keeping multi-references is that if the file is removed from one of the refering records it will actually be deleted in the file system, leaving missing files for the remaining referers!
00081
00082 Automatic Repair of Errors:
00083 - The multi-referenced file is copied under a new name and references updated.
00084
00085 Manual repair suggestions:
00086 - None that can not be handled by the automatic repair.
00087 ');
00088
00089 $this->cli_help['examples'] = '/.../cli_dispatch.phpsh lowlevel_cleaner double_files -s -r
00090 This will check the system for double files relations.';
00091 }
00092
00099 function main() {
00100 global $TYPO3_DB;
00101
00102
00103 $resultArray = array(
00104 'message' => $this->cli_help['name'].chr(10).chr(10).$this->cli_help['description'],
00105 'headers' => array(
00106 'multipleReferencesList_count' => array('Number of multi-reference files','(See below)',0),
00107 'singleReferencesList_count' => array('Number of files correctly referenced','The amount of correct 1-1 references',0),
00108 'multipleReferencesList' => array('Entries with files having multiple references','These are serious problems that should be resolved ASAP to prevent data loss! '.$this->label_infoString,3),
00109 'dirname_registry' => array('Registry of directories in which files are found.','Registry includes which table/field pairs store files in them plus how many files their store.',0),
00110 'missingFiles' => array('Tracking missing files','(Extra feature, not related to tracking of double references. Further, the list may include more files than found in the missing_files()-test because this list includes missing files from deleted records.)',0),
00111 'warnings' => array('Warnings picked up','',2)
00112 ),
00113 'multipleReferencesList_count' => 0,
00114 'singleReferencesList_count' => 0,
00115 'multipleReferencesList' => array(),
00116 'dirname_registry' => array(),
00117 'missingFiles' => array(),
00118 'warnings' => array()
00119 );
00120
00121
00122 $recs = $TYPO3_DB->exec_SELECTgetRows(
00123 '*',
00124 'sys_refindex',
00125 'ref_table='.$TYPO3_DB->fullQuoteStr('_FILE', 'sys_refindex').
00126 ' AND softref_key='.$TYPO3_DB->fullQuoteStr('', 'sys_refindex'),
00127 '',
00128 'sorting DESC'
00129 );
00130
00131
00132 $tempCount = array();
00133 if (is_array($recs)) {
00134 foreach($recs as $rec) {
00135
00136
00137 $infoString = $this->infoStr($rec);
00138
00139
00140 $resultArray['dirname_registry'][dirname($rec['ref_string'])][$rec['tablename'].':'.$rec['field']]++;
00141
00142
00143 if (!@is_file(PATH_site.$rec['ref_string'])) {
00144 $resultArray['missingFiles'][$rec['ref_string']][$rec['hash']] = $infoString;
00145 }
00146
00147
00148 if (isset($tempCount[$rec['ref_string']])) {
00149 if (!is_array($resultArray['multipleReferencesList'][$rec['ref_string']])) {
00150 $resultArray['multipleReferencesList'][$rec['ref_string']] = array();
00151 $resultArray['multipleReferencesList'][$rec['ref_string']][$tempCount[$rec['ref_string']][1]] = $tempCount[$rec['ref_string']][0];
00152 }
00153 $resultArray['multipleReferencesList'][$rec['ref_string']][$rec['hash']] = $infoString;
00154 } else {
00155 $tempCount[$rec['ref_string']] = array($infoString,$rec['hash']);
00156 }
00157 }
00158 }
00159
00160
00161 $resultArray['multipleReferencesList_count'] = count($resultArray['multipleReferencesList']);
00162 $resultArray['singleReferencesList_count'] = count($tempCount) - $resultArray['multipleReferencesList_count'];
00163
00164
00165 ksort($resultArray['dirname_registry']);
00166 foreach($resultArray['dirname_registry'] as $dir => $temp) {
00167 if (!t3lib_div::isFirstPartOfStr($dir,'uploads/')) {
00168 $resultArray['warnings'][] = 'Directory "'.$dir.'" was outside uploads/ which is unusual practice in TYPO3 although not forbidden. Directory used by the following table:field pairs: '.implode(',',array_keys($temp));
00169 }
00170 }
00171
00172 return $resultArray;
00173 }
00174
00182 function main_autoFix($resultArray) {
00183 foreach($resultArray['multipleReferencesList'] as $key => $value) {
00184 $absFileName = t3lib_div::getFileAbsFileName($key);
00185 if ($absFileName && @is_file($absFileName)) {
00186 echo 'Processing file: '.$key.chr(10);
00187 $c=0;
00188 foreach($value as $hash => $recReference) {
00189 if ($c==0) {
00190 echo ' Keeping '.$key.' for record "'.$recReference.'"'.chr(10);
00191 } else {
00192
00193 $fileFunc = t3lib_div::makeInstance('t3lib_basicFileFunctions');
00194 $newName = $fileFunc->getUniqueName(basename($key), dirname($absFileName));
00195 echo ' Copying '.$key.' to '.substr($newName,strlen(PATH_site)).' for record "'.$recReference.'": ';
00196
00197 if ($bypass = $this->cli_noExecutionCheck($recReference)) {
00198 echo $bypass;
00199 } else {
00200 t3lib_div::upload_copy_move($absFileName,$newName);
00201 clearstatcache();
00202
00203 if (@is_file($newName)) {
00204 $sysRefObj = t3lib_div::makeInstance('t3lib_refindex');
00205 $error = $sysRefObj->setReferenceValue($hash,basename($newName));
00206 if ($error) {
00207 echo ' ERROR: t3lib_refindex::setReferenceValue(): '.$error.chr(10);
00208 exit;
00209 } else echo "DONE";
00210 } else {
00211 echo ' ERROR: File "'.$newName.'" was not created!';
00212 }
00213 }
00214 echo chr(10);
00215 }
00216 $c++;
00217 }
00218 } else {
00219 echo ' ERROR: File "'.$absFileName.'" was not found!';
00220 }
00221 }
00222 }
00223 }
00224
00225 ?>