[TASK] Use strict comparison for strings
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / Classes / Controller / ParseHtmlController.php
1 <?php
2 namespace TYPO3\CMS\Rtehtmlarea\Controller;
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 use Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Core\Configuration\Richtext;
20 use TYPO3\CMS\Core\Utility\ArrayUtility;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22
23 /**
24 * Content parsing for htmlArea RTE
25 */
26 class ParseHtmlController
27 {
28 /**
29 * @var string
30 */
31 public $content;
32
33 /**
34 * @var array
35 */
36 public $modData;
37
38 /**
39 * document template object
40 *
41 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
42 */
43 public $doc;
44
45 /**
46 * @var string
47 */
48 public $extKey = 'rtehtmlarea';
49
50 /**
51 * @var string
52 */
53 public $prefixId = 'TYPO3HtmlParser';
54
55 /**
56 * The name of the module
57 *
58 * @var string
59 */
60 protected $moduleName = 'rtehtmlarea_wizard_parse_html';
61
62 /**
63 * Initialize
64 */
65 public function __construct()
66 {
67 $this->init();
68 }
69
70 /**
71 * @return void
72 */
73 public function init()
74 {
75 $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
76 $this->doc->JScode = '';
77 $this->modData = $GLOBALS['BE_USER']->getModuleData($this->moduleName, 'ses');
78 if (GeneralUtility::_GP('OC_key')) {
79 $parts = explode('|', GeneralUtility::_GP('OC_key'));
80 $this->modData['openKeys'][$parts[1]] = $parts[0] === 'O' ? 1 : 0;
81 $GLOBALS['BE_USER']->pushModuleData($this->moduleName, $this->modData);
82 }
83 }
84
85 /**
86 * Injects the request object for the current request or subrequest
87 * As this controller goes only through the main_parse_html() method, it is rather simple for now
88 *
89 * @param ServerRequestInterface $request the current request
90 * @param ResponseInterface $response
91 * @return ResponseInterface the response with the content
92 */
93 public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
94 {
95 $this->content .= $this->main_parse_html($this->modData['openKeys']);
96
97 $response->getBody()->write($this->content);
98 $response = $response->withHeader('Content-Type', 'text/plain; charset=utf-8');
99 return $response;
100 }
101
102 /**
103 * Rich Text Editor (RTE) html parser
104 *
105 * @param array $openKeys Unused
106 * @return string
107 */
108 public function main_parse_html($openKeys)
109 {
110 $html = GeneralUtility::_GP('content');
111
112 // @todo: This needs refactoring to enable sane config in flex form, either transfer parts of 'config', or use data providers
113 $RTEtsConfigParts = explode(':', GeneralUtility::_GP('RTEtsConfigParams'));
114 $table = $RTEtsConfigParts[0];
115 $field = $RTEtsConfigParts[2];
116 $recordType = $RTEtsConfigParts[3];
117 $tcaConfigOfField = $GLOBALS['TCA'][$table][$field]['config'] ?? [];
118 $columnsOverridesConfigOfField = $GLOBALS['TCA'][$table]['types'][$recordType]['columnsOverrides'][$field]['config'] ?? [];
119 if (!empty($columnsOverridesConfigOfField)) {
120 ArrayUtility::mergeRecursiveWithOverrule($tcaConfigOfField, $columnsOverridesConfigOfField);
121 }
122 $richtextConfigurationProvider = GeneralUtility::makeInstance(Richtext::class);
123 $richtextConfiguration = $richtextConfigurationProvider->getConfiguration(
124 $RTEtsConfigParts[0],
125 $RTEtsConfigParts[2],
126 $RTEtsConfigParts[3],
127 $RTEtsConfigParts[4],
128 $tcaConfigOfField
129 );
130 $thisConfig = $richtextConfiguration;
131
132 $HTMLParser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Html\HtmlParser::class);
133 if (is_array($thisConfig['enableWordClean.'])) {
134 $HTMLparserConfig = $thisConfig['enableWordClean.']['HTMLparser.'];
135 if (is_array($HTMLparserConfig)) {
136 $this->keepSpanTagsWithId($HTMLparserConfig);
137 $HTMLparserConfig = $HTMLParser->HTMLparserConfig($HTMLparserConfig);
138 }
139 }
140 if (is_array($HTMLparserConfig)) {
141 $html = $HTMLParser->HTMLcleaner($html, $HTMLparserConfig[0], $HTMLparserConfig[1], $HTMLparserConfig[2], $HTMLparserConfig[3]);
142 }
143 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey][$this->prefixId]['cleanPastedContent'])) {
144 foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey][$this->prefixId]['cleanPastedContent'] as $classRef) {
145 $hookObj = GeneralUtility::getUserObj($classRef);
146 if (method_exists($hookObj, 'cleanPastedContent_afterCleanWord')) {
147 $html = $hookObj->cleanPastedContent_afterCleanWord($html, $thisConfig);
148 }
149 }
150 }
151 return $html;
152 }
153
154 /**
155 * Modify incoming HTMLparser config in an attempt to keep span tags with id
156 * Such tags are used by the RTE in order to restore the cursor position when the cleaning operation is completed.
157 *
158 * @param array $HTMLparserConfig: incoming HTMLParser configuration (wil be modified)
159 * @return void
160 */
161 protected function keepSpanTagsWithId(&$HTMLparserConfig)
162 {
163 // Allow span tag
164 if (isset($HTMLparserConfig['allowTags'])) {
165 if (!GeneralUtility::inList($HTMLparserConfig['allowTags'], 'span')) {
166 $HTMLparserConfig['allowTags'] .= ',span';
167 }
168 } else {
169 $HTMLparserConfig['allowTags'] = 'span';
170 }
171 // Allow attributes on span tags
172 if (isset($HTMLparserConfig['noAttrib']) && GeneralUtility::inList($HTMLparserConfig['noAttrib'], 'span')) {
173 $HTMLparserConfig['noAttrib'] = GeneralUtility::rmFromList('span', $HTMLparserConfig['noAttrib']);
174 }
175 // Do not remove span tags
176 if (isset($HTMLparserConfig['removeTags']) && GeneralUtility::inList($HTMLparserConfig['removeTags'], 'span')) {
177 $HTMLparserConfig['removeTags'] = GeneralUtility::rmFromList('span', $HTMLparserConfig['removeTags']);
178 }
179 // Review the tags array
180 if (is_array($HTMLparserConfig['tags.'])) {
181 // Allow span tag
182 if (isset($HTMLparserConfig['tags.']['span']) && !$HTMLparserConfig['tags.']['span']) {
183 $HTMLparserConfig['tags.']['span'] = 1;
184 }
185 if (is_array($HTMLparserConfig['tags.']['span.'])) {
186 if (isset($HTMLparserConfig['tags.']['span.']['allowedAttribs'])) {
187 if (!$HTMLparserConfig['tags.']['span.']['allowedAttribs']) {
188 $HTMLparserConfig['tags.']['span.']['allowedAttribs'] = 'id';
189 } elseif (!GeneralUtility::inList($HTMLparserConfig['tags.']['span.']['allowedAttribs'], 'id')) {
190 $HTMLparserConfig['tags.']['span.']['allowedAttribs'] .= ',id';
191 }
192 }
193 if (isset($HTMLparserConfig['tags.']['span.']['fixAttrib.']['id.']['unset'])) {
194 unset($HTMLparserConfig['tags.']['span.']['fixAttrib.']['id.']['unset']);
195 }
196 }
197 }
198 }
199 }