[BUGFIX] Remove NOT NULL from optional text fields in system extensions
[Packages/TYPO3.CMS.git] / typo3 / sysext / lowlevel / Classes / CleanFlexformCommand.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
17 /**
18 * cleanflexform
19 */
20 class CleanFlexformCommand extends CleanerCommand
21 {
22 /**
23 * Constructor
24 */
25 public function __construct()
26 {
27 parent::__construct();
28 // Setting up help:
29 $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.');
30 $this->cli_options[] = array('--pid id', 'Setting start page in page tree. Default is the page tree root, 0 (zero)');
31 $this->cli_options[] = array('--depth int', 'Setting traversal depth. 0 (zero) will only analyse start page (see --pid), 1 will traverse one level of subpages etc.');
32 $this->cli_help['name'] = 'cleanflexform -- Find flexform fields with unclean XML';
33 $this->cli_help['description'] = trim('
34 Traversing page tree and finding records with FlexForm fields with XML that could be cleaned up. This will just remove obsolete data garbage.
35
36 Automatic Repair:
37 Cleaning XML for FlexForm fields.
38 ');
39 $this->cli_help['examples'] = '';
40 }
41
42 /**
43 * Find orphan records
44 * VERY CPU and memory intensive since it will look up the whole page tree!
45 *
46 * @return array
47 */
48 public function main()
49 {
50 // Initialize result array:
51 $resultArray = array(
52 'message' => $this->cli_help['name'] . LF . LF . $this->cli_help['description'],
53 'headers' => array(
54 'dirty' => array('', '', 2)
55 ),
56 'dirty' => array()
57 );
58 $startingPoint = $this->cli_isArg('--pid') ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->cli_argValue('--pid'), 0) : 0;
59 $depth = $this->cli_isArg('--depth') ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->cli_argValue('--depth'), 0) : 1000;
60 $this->cleanFlexForm_dirtyFields = &$resultArray['dirty'];
61 // Do not repair flexform data in deleted records.
62 $this->genTree_traverseDeleted = false;
63 $this->genTree($startingPoint, $depth, (int)$this->cli_argValue('--echotree'), 'main_parseTreeCallBack');
64 asort($resultArray);
65 return $resultArray;
66 }
67
68 /**
69 * Call back function for page tree traversal!
70 *
71 * @param string $tableName Table name
72 * @param int $uid UID of record in processing
73 * @param int $echoLevel Echo level (see calling function
74 * @param string $versionSwapmode Version swap mode on that level (see calling function
75 * @param int $rootIsVersion Is root version (see calling function
76 * @return void
77 */
78 public function main_parseTreeCallBack($tableName, $uid, $echoLevel, $versionSwapmode, $rootIsVersion)
79 {
80 foreach ($GLOBALS['TCA'][$tableName]['columns'] as $colName => $config) {
81 if ($config['config']['type'] == 'flex') {
82 if ($echoLevel > 2) {
83 echo LF . ' [cleanflexform:] Field "' . $colName . '" in ' . $tableName . ':' . $uid . ' was a flexform and...';
84 }
85 $recRow = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordRaw($tableName, 'uid=' . (int)$uid);
86 $flexObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class);
87 if ($recRow[$colName]) {
88 // Clean XML:
89 $newXML = $flexObj->cleanFlexFormXML($tableName, $colName, $recRow);
90 if (md5($recRow[$colName]) != md5($newXML)) {
91 if ($echoLevel > 2) {
92 echo ' was DIRTY, needs cleanup!';
93 }
94 $this->cleanFlexForm_dirtyFields[\TYPO3\CMS\Core\Utility\GeneralUtility::shortMd5($tableName . ':' . $uid . ':' . $colName)] = $tableName . ':' . $uid . ':' . $colName;
95 } else {
96 if ($echoLevel > 2) {
97 echo ' was CLEAN';
98 }
99 }
100 } elseif ($echoLevel > 2) {
101 echo ' was EMPTY';
102 }
103 }
104 }
105 }
106
107 /**
108 * Mandatory autofix function
109 * Will run auto-fix on the result array. Echos status during processing.
110 *
111 * @param array $resultArray Result array from main() function
112 * @return void
113 */
114 public function main_autoFix($resultArray)
115 {
116 foreach ($resultArray['dirty'] as $fieldID) {
117 list($table, $uid, $field) = explode(':', $fieldID);
118 echo 'Cleaning XML in "' . $fieldID . '": ';
119 if ($bypass = $this->cli_noExecutionCheck($fieldID)) {
120 echo $bypass;
121 } else {
122 // Clean XML:
123 $data = array();
124 $recRow = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordRaw($table, 'uid=' . (int)$uid);
125 $flexObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class);
126 if ($recRow[$field]) {
127 $data[$table][$uid][$field] = $flexObj->cleanFlexFormXML($table, $field, $recRow);
128 }
129 // Execute Data array:
130 $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
131 $tce->stripslashes_values = false;
132 $tce->dontProcessTransformations = true;
133 $tce->bypassWorkspaceRestrictions = true;
134 $tce->bypassFileHandling = true;
135 // Check has been done previously that there is a backend user which is Admin and also in live workspace
136 $tce->start($data, array());
137 $tce->process_datamap();
138 // Return errors if any:
139 if (count($tce->errorLog)) {
140 echo ' ERROR from "TCEmain":' . LF . 'TCEmain:' . implode((LF . 'TCEmain:'), $tce->errorLog);
141 } else {
142 echo 'DONE';
143 }
144 }
145 echo LF;
146 }
147 }
148 }