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_lost_files extends tx_lowlevel_cleaner_core {
00057
00058 var $checkRefIndex = TRUE;
00059
00065 function tx_lowlevel_lost_files() {
00066 parent::tx_lowlevel_cleaner_core();
00067
00068 $this->cli_options[] = array('--excludePath [path-list]', 'Comma separated list of paths to exclude. Example: "uploads/[path1],uploads/[path2],..."');
00069
00070
00071 $this->cli_help['name'] = 'lost_files -- Looking for files in the uploads/ folder which does not have a reference in TYPO3 managed records.';
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 - that all contents in the uploads folder are files attached to TCA records and exclusively managed by TCEmain through "group" type fields
00076 - exceptions are: index.html and .htaccess files (ignored)
00077 - exceptions are: RTEmagic* image files (ignored)
00078 - files found in deleted records are included (otherwise you would see a false list of lost files)
00079
00080 The assumptions are not requirements by the TYPO3 API but reflects the de facto implementation of most TYPO3 installations and therefore a practical approach to cleaning up the uploads/ folder.
00081 Therefore, if all "group" type fields in TCA and flexforms are positioned inside the uploads/ folder and if no files inside are managed manually it should be safe to clean out files with no relations found in the system.
00082 Under such circumstances there should theoretically be no lost files in the uploads/ folder since TCEmain should have managed relations automatically including adding and deleting files.
00083 However, there is at least one reason known to why files might be found lost and that is when FlexForms are used. In such a case a change of/in the Data Structure XML (or the ability of the system to find the Data Structure definition!) used for the flexform could leave lost files behind. This is not unlikely to happen when records are deleted. More details can be found in a note to the function t3lib_BEfunc::getFlexFormDS()
00084 Another scenario could of course be de-installation of extensions which managed files in the uploads/ folders.
00085
00086 Automatic Repair of Errors:
00087 - Simply delete lost files (Warning: First, make sure those files are not used somewhere TYPO3 does not know about! See the assumptions above).
00088 ');
00089
00090 $this->cli_help['examples'] = '/.../cli_dispatch.phpsh lowlevel_cleaner lost_files -s -r
00091 Will report lost files.';
00092 }
00093
00094
00105 function main() {
00106 global $TYPO3_DB;
00107
00108
00109 $resultArray = array(
00110 'message' => $this->cli_help['name'].chr(10).chr(10).$this->cli_help['description'],
00111 'headers' => array(
00112 'managedFiles' => array('Files related to TYPO3 records and managed by TCEmain','These files you definitely want to keep.',0),
00113 'ignoredFiles' => array('Ignored files (index.html, .htaccess etc.)','These files are allowed in uploads/ folder',0),
00114 'RTEmagicFiles' => array('RTE magic images - those found (and ignored)','These files are also allowed in some uploads/ folders as RTEmagic images.',0),
00115 'lostFiles' => array('Lost files - those you can delete','You can delete these files!',3),
00116 'warnings' => array('Warnings picked up','',2)
00117 ),
00118 'managedFiles' => array(),
00119 'ignoredFiles' => array(),
00120 'RTEmagicFiles' => array(),
00121 'lostFiles' => array(),
00122 'warnings' => array()
00123 );
00124
00125
00126 $fileArr = array();
00127 $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,PATH_site.'uploads/');
00128 $fileArr = t3lib_div::removePrefixPathFromList($fileArr,PATH_site);
00129
00130 $excludePaths = t3lib_div::trimExplode(',',$this->cli_argValue('--excludePath',0),1);
00131
00132
00133 foreach($fileArr as $key => $value) {
00134
00135 $include = TRUE;
00136 foreach($excludePaths as $exclPath) {
00137 if (t3lib_div::isFirstPartOfStr($value,$exclPath)) {
00138 $include = FALSE;
00139 }
00140 }
00141
00142 if ($include) {
00143
00144 if (substr($value,-11) == '/index.html' || substr($value,-10) == '/.htaccess') {
00145 unset($fileArr[$key]) ;
00146 $resultArray['ignoredFiles'][] = $value;
00147 } else {
00148
00149 $recs = $TYPO3_DB->exec_SELECTgetRows(
00150 '*',
00151 'sys_refindex',
00152 'ref_table='.$TYPO3_DB->fullQuoteStr('_FILE', 'sys_refindex').
00153 ' AND ref_string='.$TYPO3_DB->fullQuoteStr($value, 'sys_refindex').
00154 ' AND softref_key='.$TYPO3_DB->fullQuoteStr('', 'sys_refindex'),
00155 '',
00156 'sorting DESC'
00157 );
00158
00159
00160 if (count($recs)) {
00161 unset($fileArr[$key]) ;
00162 $resultArray['managedFiles'][] = $value;
00163 if (count($recs)>1) {
00164 $resultArray['warnings'][]='Warning: File "'.$value.'" had '.count($recs).' references from group-fields, should have only one!';
00165 }
00166 } else {
00167
00168 if (ereg('^RTEmagic[P|C]_',basename($value))) {
00169 unset($fileArr[$key]) ;
00170 $resultArray['RTEmagicFiles'][] = $value;
00171 } else {
00172
00173 unset($fileArr[$key]) ;
00174 $resultArray['lostFiles'][] = $value;
00175 }
00176 }
00177 }
00178 }
00179 }
00180
00181
00182
00183
00184 return $resultArray;
00185 }
00186
00194 function main_autoFix($resultArray) {
00195 foreach($resultArray['lostFiles'] as $key => $value) {
00196 $absFileName = t3lib_div::getFileAbsFileName($value);
00197 echo 'Deleting file: "'.$absFileName.'": ';
00198 if ($bypass = $this->cli_noExecutionCheck($absFileName)) {
00199 echo $bypass;
00200 } else {
00201 if ($absFileName && @is_file($absFileName)) {
00202 unlink($absFileName);
00203 echo 'DONE';
00204 } else {
00205 echo ' ERROR: File "'.$absFileName.'" was not found!';
00206 }
00207 }
00208 echo chr(10);
00209 }
00210 }
00211 }
00212
00213 ?>