2 namespace TYPO3\CMS\Lowlevel;
39 parent::__construct();
41 $this->
cli_help[
'name'] =
'rte_images -- Looking up all occurencies of RTEmagic images in the database and check existence of parent and copy files on the file system plus report possibly lost files of this type.';
42 $this->
cli_help[
'description'] = trim(
'
44 - a perfect integrity of the reference index table (always update the reference index table before using this tool!)
45 - that all RTEmagic image files in the database are registered with the soft reference parser "images"
46 - images found in deleted records are included (means that you might find lost RTEmagic images after flushing deleted records)
48 The assumptions are not requirements by the TYPO3 API but reflects the de facto implementation of most TYPO3 installations.
49 However, many custom fields using an RTE will probably not have the "images" soft reference parser registered and so the index will be incomplete and not listing all RTEmagic image files.
50 The consequence of this limitation is that you should be careful if you wish to delete lost RTEmagic images - they could be referenced from a field not parsed by the "images" soft reference parser!
52 Automatic Repair of Errors:
53 - Will search for double-usages of RTEmagic images and make copies as required.
54 - Lost files can be deleted automatically by setting the value "lostFiles" as an optional parameter to --AUTOFIX, but otherwise delete them manually if you do not recognize them as used somewhere the system does not know about.
56 Manual repair suggestions:
57 - Missing files: Re-insert missing files or edit record where the reference is found.
59 $this->
cli_help[
'examples'] =
'/.../cli_dispatch.phpsh lowlevel_cleaner rte_images -s -r
60 Reports problems with RTE images';
74 'message' => $this->
cli_help[
'name'] . LF . LF . $this->
cli_help[
'description'],
76 'completeFileList' => array(
'Complete list of used RTEmagic files',
'Both parent and copy are listed here including usage count (which should in theory all be "1"). This list does not exclude files that might be missing.', 1),
77 'RTEmagicFilePairs' => array(
'Statistical info about RTEmagic files',
'(copy used as index)', 0),
78 'doubleFiles' => array(
'Duplicate RTEmagic image files',
'These files are RTEmagic images found used in multiple records! RTEmagic images should be used by only one record at a time. A large amount of such images probably stems from previous versions of TYPO3 (before 4.2) which did not support making copies automatically of RTEmagic images in case of new copies / versions.', 3),
79 'missingFiles' => array(
'Missing RTEmagic image files',
'These files are not found in the file system! Should be corrected!', 3),
80 'lostFiles' => array(
'Lost RTEmagic files from uploads/',
'These files you might be able to delete but only if _all_ RTEmagic images are found by the soft reference parser. If you are using the RTE in third-party extensions it is likely that the soft reference parser is not applied correctly to their RTE and thus these "lost" files actually represent valid RTEmagic images, just not registered. Lost files can be auto-fixed but only if you specifically set "lostFiles" as parameter to the --AUTOFIX option.', 2)
82 'RTEmagicFilePairs' => array(),
83 'doubleFiles' => array(),
84 'completeFileList' => array(),
85 'missingFiles' => array(),
86 'lostFiles' => array()
89 $recs =
$GLOBALS[
'TYPO3_DB']->exec_SELECTgetRows(
'*',
'sys_refindex',
'ref_table=' .
$GLOBALS[
'TYPO3_DB']->fullQuoteStr(
'_FILE',
'sys_refindex') .
' AND ref_string LIKE ' .
$GLOBALS[
'TYPO3_DB']->fullQuoteStr(
'%/RTEmagic%',
'sys_refindex') .
' AND softref_key=' .
$GLOBALS[
'TYPO3_DB']->fullQuoteStr(
'images',
'sys_refindex'),
'',
'sorting DESC');
91 if (is_array($recs)) {
92 foreach ($recs as $rec) {
95 $original =
'RTEmagicP_' . preg_replace(
'/\\.[[:alnum:]]+$/',
'', substr(
$filename, 10));
96 $infoString = $this->
infoStr($rec);
98 $resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'exists'] = @is_file((PATH_site . $rec[
'ref_string']));
99 $resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'original'] = substr($rec[
'ref_string'], 0, -strlen(
$filename)) . $original;
100 $resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'original_exists'] = @is_file((PATH_site . $resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'original']));
101 $resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'count']++;
102 $resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'usedIn'][$rec[
'hash']] = $infoString;
103 $resultArray[
'completeFileList'][$resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'original']]++;
104 $resultArray[
'completeFileList'][$rec[
'ref_string']]++;
106 if (!$resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'exists']) {
107 $resultArray[
'missingFiles'][$rec[
'ref_string']] = $resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'usedIn'];
109 if (!$resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'original_exists']) {
110 $resultArray[
'missingFiles'][$resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'original']] = $resultArray[
'RTEmagicFilePairs'][$rec[
'ref_string']][
'usedIn'];
115 foreach ($resultArray[
'RTEmagicFilePairs'] as $fileName => $fileInfo) {
116 if ($fileInfo[
'count'] > 1 && $fileInfo[
'exists'] && $fileInfo[
'original_exists']) {
117 $resultArray[
'doubleFiles'][$fileName] = $fileInfo[
'usedIn'];
123 $cleanerMode = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj(
$cleanerModules[
'lost_files'][0]);
124 $resLostFiles = $cleanerMode->main(array(),
false,
true);
125 if (is_array($resLostFiles[
'RTEmagicFiles'])) {
126 foreach ($resLostFiles[
'RTEmagicFiles'] as $fileName) {
127 if (!isset($resultArray[
'completeFileList'][$fileName])) {
128 $resultArray[
'lostFiles'][$fileName] = $fileName;
132 ksort($resultArray[
'RTEmagicFilePairs']);
133 ksort($resultArray[
'completeFileList']);
134 ksort($resultArray[
'missingFiles']);
135 ksort($resultArray[
'doubleFiles']);
136 ksort($resultArray[
'lostFiles']);
149 $limitTo = $this->cli_args[
'--AUTOFIX'][0];
150 if (is_array($resultArray[
'doubleFiles'])) {
151 if (!$limitTo || $limitTo ===
'doubleFiles') {
152 echo
'FIXING double-usages of RTE files in uploads/: ' . LF;
153 foreach ($resultArray[
'RTEmagicFilePairs'] as $fileName => $fileInfo) {
155 if ($fileInfo[
'count'] > 1 && $fileInfo[
'exists'] && $fileInfo[
'original_exists']) {
158 foreach ($fileInfo[
'usedIn'] as $hash => $recordID) {
160 echo
' Keeping file ' . $fileName .
' for record ' . $recordID . LF;
163 echo
' Copying file ' . basename($fileName) .
' for record ' . $recordID .
' ';
165 $dirPrefix = dirname($fileName) .
'/';
166 $rteOrigName = basename($fileInfo[
'original']);
172 $origDestName =
$fileProcObj->getUniqueName($rteOrigName, PATH_site . $dirPrefix);
174 $pI = pathinfo($fileName);
175 $copyDestName = dirname($origDestName) .
'/RTEmagicC_' . substr(basename($origDestName), 10) .
'.' . $pI[
'extension'];
177 echo
' to ' . basename($copyDestName);
182 \TYPO3\CMS\Core\Utility\GeneralUtility::upload_copy_move(PATH_site . $fileInfo[
'original'], $origDestName);
183 \TYPO3\CMS\Core\Utility\GeneralUtility::upload_copy_move(PATH_site . $fileName, $copyDestName);
185 if (@is_file($copyDestName)) {
186 $sysRefObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\ReferenceIndex::class);
187 $error = $sysRefObj->setReferenceValue($hash, \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($copyDestName));
189 echo
' - ERROR: TYPO3\\CMS\\Core\\Database\\ReferenceIndex::setReferenceValue(): ' . $error . LF;
195 echo
' - ERROR: File "' . $copyDestName .
'" was not created!';
199 echo
' - ERROR: Could not construct new unique names for file!';
202 echo
' - ERROR: Maybe directory of file was not within "uploads/"?';
211 echo
'Bypassing fixing of double-usages since --AUTOFIX was not "doubleFiles"' . LF;
214 if (is_array($resultArray[
'lostFiles'])) {
215 if ($limitTo ===
'lostFiles') {
216 echo
'Removing lost RTEmagic files from folders inside uploads/: ' . LF;
217 foreach ($resultArray[
'lostFiles'] as $key => $value) {
218 $absFileName = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($value);
219 echo
'Deleting file: "' . $absFileName .
'": ';
223 if ($absFileName && @is_file($absFileName)) {
224 unlink($absFileName);
227 echo
' ERROR: File "' . $absFileName .
'" was not found!';
234 echo
'Bypassing fixing of double-usages since --AUTOFIX was not "lostFiles"' . LF;
245 if (!is_object($this->fileProcObj)) {
246 $this->fileProcObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ExtendedFileUtility::class);
247 $this->fileProcObj->init(array(),
$GLOBALS[
'TYPO3_CONF_VARS'][
'BE'][
'fileExtensions']);
248 $this->fileProcObj->setActionPermissions();