[TASK] Remove unused code from RecordHistory
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / Wizard / RteController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller\Wizard;
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\Backend\Form\FormDataCompiler;
20 use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord;
21 use TYPO3\CMS\Backend\Form\FormEngine;
22 use TYPO3\CMS\Backend\Form\FormResultCompiler;
23 use TYPO3\CMS\Backend\Form\NodeFactory;
24 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
25 use TYPO3\CMS\Backend\Utility\BackendUtility;
26 use TYPO3\CMS\Core\Imaging\Icon;
27 use TYPO3\CMS\Core\Imaging\IconFactory;
28 use TYPO3\CMS\Core\Utility\GeneralUtility;
29
30 /**
31 * Script class for rendering the full screen RTE display
32 */
33 class RteController extends AbstractWizardController
34 {
35 /**
36 * Content accumulation for the module.
37 *
38 * @var string
39 */
40 public $content;
41
42 /**
43 * Wizard parameters, coming from FormEngine linking to the wizard.
44 *
45 * @var array
46 */
47 public $P;
48
49 /**
50 * If set, launch a new window with the current records pid.
51 *
52 * @var string
53 */
54 public $popView;
55
56 /**
57 * Set to the URL of this script including variables which is needed to re-display the form. See main()
58 *
59 * @var string
60 */
61 public $R_URI;
62
63 /**
64 * Module configuration
65 *
66 * @var array
67 */
68 public $MCONF = array();
69
70 /**
71 * Constructor
72 */
73 public function __construct()
74 {
75 parent::__construct();
76 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
77 $this->getLanguageService()->includeLLFile('EXT:lang/locallang_wizards.xlf');
78 $GLOBALS['SOBE'] = $this;
79
80 $this->init();
81 }
82
83 /**
84 * Initialization of the class
85 *
86 * @return void
87 */
88 protected function init()
89 {
90 // Setting GPvars:
91 $this->P = GeneralUtility::_GP('P');
92 $this->popView = GeneralUtility::_GP('popView');
93 $this->R_URI = GeneralUtility::linkThisScript(array('popView' => ''));
94 // "Module name":
95 $this->MCONF['name'] = 'wizard_rte';
96 // Need to NOT have the page wrapped in DIV since if we do that we destroy
97 // the feature that the RTE spans the whole height of the page!!!
98 }
99
100 /**
101 * Injects the request object for the current request or subrequest
102 * As this controller goes only through the main() method, it is rather simple for now
103 *
104 * @param ServerRequestInterface $request
105 * @param ResponseInterface $response
106 * @return ResponseInterface
107 */
108 public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
109 {
110 $this->main();
111
112 $response->getBody()->write($this->moduleTemplate->renderContent());
113 return $response;
114 }
115
116 /**
117 * Main function, rendering the document with the iFrame with the RTE in.
118 *
119 * @return void
120 */
121 public function main()
122 {
123 $this->content .= '<form action="'
124 . htmlspecialchars(BackendUtility::getModuleUrl('tce_db'))
125 . '" method="post" enctype="multipart/form-data" id="RteController" name="editform" '
126 . ' onsubmit="return TBE_EDITOR.checkSubmit(1);">';
127 // Translate id to the workspace version:
128 if ($versionedRecord = BackendUtility::getWorkspaceVersionOfRecord(
129 $this->getBackendUserAuthentication()->workspace,
130 $this->P['table'],
131 $this->P['uid'],
132 'uid'
133 )) {
134 $this->P['uid'] = $versionedRecord['uid'];
135 }
136 // If all parameters are available:
137 if ($this->P['table']
138 && $this->P['field']
139 && $this->P['uid']
140 && $this->checkEditAccess($this->P['table'], $this->P['uid'])) {
141 /** @var TcaDatabaseRecord $formDataGroup */
142 $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class);
143 /** @var FormDataCompiler $formDataCompiler */
144 $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
145 /** @var NodeFactory $nodeFactory */
146 $nodeFactory = GeneralUtility::makeInstance(NodeFactory::class);
147
148 $formDataCompilerInput = [
149 'vanillaUid' => (int)$this->P['uid'],
150 'tableName' => $this->P['table'],
151 'command' => 'edit',
152 'disabledWizards' => true,
153 ];
154
155 $formData = $formDataCompiler->compile($formDataCompilerInput);
156
157 $formData['fieldListToRender'] = $this->P['field'];
158 $formData['renderType'] = 'outerWrapContainer';
159 $formResult = $nodeFactory->create($formData)->render();
160
161 /** @var FormResultCompiler $formResultCompiler */
162 $formResultCompiler = GeneralUtility::makeInstance(FormResultCompiler::class);
163 $formResultCompiler->mergeResult($formResult);
164
165 // override the default jumpToUrl
166 $this->moduleTemplate->addJavaScriptCode(
167 'RteWizardInlineCode',
168 'function jumpToUrl(URL,formEl) {
169 if (document.editform) {
170 if (!TBE_EDITOR.isFormChanged()) {
171 window.location.href = URL;
172 } else if (formEl) {
173 if (formEl.type=="checkbox") formEl.checked = formEl.checked ? 0 : 1;
174 }
175 } else {
176 window.location.href = URL;
177 }
178 }
179 '
180 );
181
182 // Setting JavaScript of the pid value for viewing:
183 if ($this->popView) {
184 $this->moduleTemplate->addJavaScriptCode(
185 'PopupViewInlineJS',
186 BackendUtility::viewOnClick(
187 $formData['databaseRow']['pid'],
188 '',
189 BackendUtility::BEgetRootLine($formData['databaseRow']['pid'])
190 )
191 );
192 }
193
194 $pageTsConfigMerged = $formData['pageTsConfigMerged'];
195 if ((string)$pageTsConfigMerged['TCEFORM.'][$this->P['table'] . '.'][$this->P['field'] . '.']['RTEfullScreenWidth'] !== '') {
196 $width = (string)$pageTsConfigMerged['TCEFORM.'][$this->P['table'] . '.'][$this->P['field'] . '.']['RTEfullScreenWidth'];
197 } else {
198 $width = '100%';
199 }
200 // Get the form field and wrap it in the table with the buttons:
201 $formContent = $formResult['html'];
202 $formContent = '
203 <table border="0" cellpadding="0" cellspacing="0" width="' . $width . '" id="typo3-rtewizard">
204 <tr>
205 <td width="' . $width . '" colspan="2" id="c-formContent">' . $formContent . '</td>
206 <td></td>
207 </tr>
208 </table>';
209
210 // Adding hidden fields:
211 $formContent .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($this->R_URI) . '" />
212 <input type="hidden" name="_serialNumber" value="' . md5(microtime()) . '" />';
213 // Finally, add the whole setup:
214 $this->content .= $formResultCompiler->JStop()
215 . $formContent
216 . $formResultCompiler->printNeededJSFunctions();
217 } else {
218 // ERROR:
219 $this->content .= '<h2>' . $this->getLanguageService()->getLL('forms_title', true) . '</h2>'
220 . '<div><span class="text-danger">'
221 . $this->getLanguageService()->getLL('table_noData', true)
222 . '</span></div>';
223 }
224 // Setting up the buttons and markers for docHeader
225 $this->getButtons();
226 // Build the <body> for the module
227
228 $this->content .= '</form>';
229 $this->moduleTemplate->setContent($this->content);
230 }
231
232 /**
233 * Create the panel of buttons for submitting the form or otherwise perform operations.
234 *
235 * @return array All available buttons as an assoc. array
236 */
237 protected function getButtons()
238 {
239 $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
240 if ($this->P['table']
241 && $this->P['field']
242 && $this->P['uid']
243 && $this->checkEditAccess($this->P['table'], $this->P['uid'])) {
244 $closeUrl = GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']);
245 // Getting settings for the undo button:
246 $undoButton = 0;
247 $databaseConnection = $this->getDatabaseConnection();
248 $undoRes = $databaseConnection->exec_SELECTquery(
249 'tstamp',
250 'sys_history',
251 'tablename=' . $databaseConnection->fullQuoteStr(
252 $this->P['table'],
253 'sys_history'
254 ) . ' AND recuid=' . (int)$this->P['uid'],
255 '',
256 'tstamp DESC',
257 '1'
258 );
259 if ($undoButtonR = $databaseConnection->sql_fetch_assoc($undoRes)) {
260 $undoButton = 1;
261 }
262
263 // Close
264 $closeButton = $buttonBar->makeLinkButton()
265 ->setHref($closeUrl)
266 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc'))
267 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL));
268 $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 10);
269
270 // Save
271 $saveButton = $buttonBar->makeInputButton()
272 ->setName('_savedok_x')
273 ->setValue('1')
274 ->setForm('RteController')
275 ->setOnClick('TBE_EDITOR.checkAndDoSubmit(1); return false;')
276 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc'))
277 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL));
278 // Save & View
279 $saveAndViewButton = $buttonBar->makeInputButton()
280 ->setName('_savedokview_x')
281 ->setValue('1')
282 ->setForm('RteController')
283 ->setOnClick('document.editform.redirect.value+= ' . GeneralUtility::quoteJSvalue('&popView=1') . '; '
284 . ' TBE_EDITOR.checkAndDoSubmit(1); return false;')
285 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDocShow'))
286 ->setIcon(
287 $this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-view', Icon::SIZE_SMALL)
288 );
289
290 // Save & Close
291 $saveAndCloseButton = $buttonBar->makeInputButton()
292 ->setName('_saveandclosedok_x')
293 ->setValue('1')
294 ->setForm('RteController')
295 ->setOnClick('document.editform.redirect.value=' . GeneralUtility::quoteJSvalue($closeUrl)
296 . '; TBE_EDITOR.checkAndDoSubmit(1); return false;')
297 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc'))
298 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
299 'actions-document-save-close',
300 Icon::SIZE_SMALL
301 ));
302
303 // Save SplitButton
304 $saveSplitButton = $buttonBar->makeSplitButton()
305 ->addItem($saveButton)
306 ->addItem($saveAndViewButton)
307 ->addItem($saveAndCloseButton);
308 $buttonBar->addButton($saveSplitButton, ButtonBar::BUTTON_POSITION_LEFT, 20);
309
310 // Undo/Revert:
311 if ($undoButton) {
312 $aOnClick = 'window.location.href=' .
313 GeneralUtility::quoteJSvalue(
314 BackendUtility::getModuleUrl(
315 'record_history',
316 array(
317 'element' => $this->P['table'] . ':' . $this->P['uid'],
318 'revert' => 'field:' . $this->P['field'],
319 'returnUrl' => $this->R_URI,
320 )
321 )
322 ) . '; return false;';
323
324 $undoText = $this->getLanguageService()->sL(
325 'LLL:EXT:lang/locallang_wizards.xlf:rte_undoLastChange'
326 );
327 $lastChangeLabel = sprintf(
328 $undoText,
329 BackendUtility::calcAge(
330 ($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp']),
331 $this->getLanguageService()->sL(
332 'LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears'
333 )
334 )
335 );
336
337 $undoRevertButton = $buttonBar->makeLinkButton()
338 ->setHref('#')
339 ->setOnClick($aOnClick)
340 ->setTitle($lastChangeLabel)
341 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-edit-undo', Icon::SIZE_SMALL));
342 $buttonBar->addButton($undoRevertButton, ButtonBar::BUTTON_POSITION_LEFT, 30);
343 }
344 // Shortcut
345 $shortButton = $buttonBar->makeShortcutButton()
346 ->setModuleName($this->MCONF['name'])
347 ->setGetVariables(['P']);
348 $buttonBar->addButton($shortButton);
349 }
350 }
351 }