[TASK] Use a cast to float instead of doubleval
[Packages/TYPO3.CMS.git] / typo3 / sysext / lowlevel / Classes / MissingFilesCommand.php
1 <?php
2 namespace TYPO3\CMS\Lowlevel;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16 use TYPO3\CMS\Core\Database\ConnectionPool;
17 use TYPO3\CMS\Core\Database\ReferenceIndex;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * Looking for missing files.
22 */
23 class MissingFilesCommand extends CleanerCommand
24 {
25 /**
26 * @var bool
27 */
28 public $checkRefIndex = true;
29
30 /**
31 * Constructor
32 */
33 public function __construct()
34 {
35 parent::__construct();
36 // Setting up help:
37 $this->cli_help['name'] = 'missing_files -- Find all file references from records pointing to a missing (non-existing) file.';
38 $this->cli_help['description'] = trim('
39 Assumptions:
40 - a perfect integrity of the reference index table (always update the reference index table before using this tool!)
41 - relevant soft reference parsers applied everywhere file references are used inline
42
43 Files may be missing for these reasons (except software bugs):
44 - someone manually deleted the file inside fileadmin/ or another user maintained folder. If the reference was a soft reference (opposite to a DataHandler managed file relation from "group" type fields), technically it is not an error although it might be a mistake that someone did so.
45 - someone manually deleted the file inside the uploads/ folder (typically containing managed files) which is an error since no user interaction should take place there.
46
47 Automatic Repair of Errors:
48 - Managed files (TCA/FlexForm attachments): Will silently remove the reference from the record since the file is missing. For this reason you might prefer a manual approach instead.
49 - Soft References: Requires manual fix if you consider it an error.
50
51 Manual repair suggestions:
52 - Managed files: You might be able to locate the file and re-insert it in the correct location. However, no automatic fix can do that for you.
53 - Soft References: You should investigate each case and edit the content accordingly. A soft reference to a file could be in an HTML image tag (for example <img src="missing_file.jpg" />) and you would have to either remove the whole tag, change the filename or re-create the missing file.
54 ');
55 $this->cli_help['examples'] = '/.../cli_dispatch.phpsh lowlevel_cleaner missing_files -s -r
56 This will show you missing files in the TYPO3 system and only report back if errors were found.';
57 }
58
59 /**
60 * Find file references that points to non-existing files in system
61 * Fix methods: API in \TYPO3\CMS\Core\Database\ReferenceIndex that allows to
62 * change the value of a reference (or remove it)
63 *
64 * @return array
65 */
66 public function main()
67 {
68 // Initialize result array:
69 $listExplain = ' Shows the relative filename of missing file as header and under a list of record fields in which the references are found. ' . $this->label_infoString;
70 $resultArray = [
71 'message' => $this->cli_help['name'] . LF . LF . $this->cli_help['description'],
72 'headers' => [
73 'managedFilesMissing' => ['List of missing files managed by DataHandler', $listExplain, 3],
74 'softrefFilesMissing' => ['List of missing files registered as a soft reference', $listExplain, 2]
75 ],
76 'managedFilesMissing' => [],
77 'softrefFilesMissing' => []
78 ];
79 // Select all files in the reference table
80 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
81 ->getQueryBuilderForTable('sys_refindex');
82
83 $result = $queryBuilder
84 ->select('*')
85 ->from('sys_refindex')
86 ->where(
87 $queryBuilder->expr()->eq('ref_table', $queryBuilder->createNamedParameter('_FILE', \PDO::PARAM_STR))
88 )
89 ->orderBy('sorting', 'DESC')
90 ->execute();
91 // Traverse the files and put into a large table:
92 while ($rec = $result->fetch()) {
93 // Compile info string for location of reference:
94 $infoString = $this->infoStr($rec);
95 // Handle missing file:
96 if (!@is_file((PATH_site . $rec['ref_string']))) {
97 if ((string)$rec['softref_key'] == '') {
98 $resultArrayIndex = 'managedFilesMissing';
99 } else {
100 $resultArrayIndex = 'softrefFilesMissing';
101 }
102 $resultArray[$resultArrayIndex][$rec['ref_string']][$rec['hash']] = $infoString;
103 ksort($resultArray[$resultArrayIndex][$rec['ref_string']]);
104 }
105 }
106
107 ksort($resultArray['managedFilesMissing']);
108 ksort($resultArray['softrefFilesMissing']);
109 return $resultArray;
110 }
111
112 /**
113 * Mandatory autofix function
114 * Will run auto-fix on the result array. Echos status during processing.
115 *
116 * @param array $resultArray Result array from main() function
117 * @return void
118 */
119 public function main_autoFix($resultArray)
120 {
121 foreach ($resultArray['managedFilesMissing'] as $key => $value) {
122 echo 'Processing file: ' . $key . LF;
123 foreach ($value as $hash => $recReference) {
124 echo ' Removing reference in record "' . $recReference . '": ';
125 if ($bypass = $this->cli_noExecutionCheck($recReference)) {
126 echo $bypass;
127 } else {
128 $sysRefObj = GeneralUtility::makeInstance(ReferenceIndex::class);
129 $error = $sysRefObj->setReferenceValue($hash, null);
130 if ($error) {
131 echo ' TYPO3\\CMS\\Core\\Database\\ReferenceIndex::setReferenceValue(): ' . $error . LF;
132 echo 'missing_files: exit on error' . LF;
133 die;
134 } else {
135 echo 'DONE';
136 }
137 }
138 echo LF;
139 }
140 }
141 }
142 }