[CLEANUP] EXT:backend/Classes/Wizard/*.php
[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 TYPO3\CMS\Backend\Form\DataPreprocessor;
18 use TYPO3\CMS\Backend\Form\FormEngine;
19 use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
20 use TYPO3\CMS\Backend\Template\DocumentTemplate;
21 use TYPO3\CMS\Backend\Utility\BackendUtility;
22 use TYPO3\CMS\Backend\Utility\IconUtility;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24
25 /**
26 * Script class for rendering the full screen RTE display
27 *
28 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
29 */
30 class RteController extends AbstractWizardController {
31
32 /**
33 * Document template object
34 *
35 * @var DocumentTemplate
36 */
37 public $doc;
38
39 /**
40 * Content accumulation for the module.
41 *
42 * @var string
43 */
44 public $content;
45
46 /**
47 * Wizard parameters, coming from FormEngine linking to the wizard.
48 *
49 * @var array
50 */
51 public $P;
52
53 /**
54 * If set, launch a new window with the current records pid.
55 *
56 * @var string
57 */
58 public $popView;
59
60 /**
61 * Set to the URL of this script including variables which is needed to re-display the form. See main()
62 *
63 * @var string
64 */
65 public $R_URI;
66
67 /**
68 * Module configuration
69 *
70 * @var array
71 */
72 public $MCONF = array();
73
74 /**
75 * Constructor
76 */
77 public function __construct() {
78 $this->getLanguageService()->includeLLFile('EXT:lang/locallang_wizards.xlf');
79 $GLOBALS['SOBE'] = $this;
80
81 $this->init();
82 }
83
84 /**
85 * Initialization of the class
86 *
87 * @return void
88 */
89 protected function init() {
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 // Starting the document template object:
97 $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
98 $this->doc->backPath = $this->getBackPath();
99 $this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/wizard_rte.html');
100 // Need to NOT have the page wrapped in DIV since if we do that we destroy
101 // the feature that the RTE spans the whole height of the page!!!
102 $this->doc->divClass = '';
103 $this->doc->form = '<form action="' . htmlspecialchars(BackendUtility::getModuleUrl('tce_db')) . '" method="post" enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '" name="editform" onsubmit="return TBE_EDITOR.checkSubmit(1);">';
104 }
105
106 /**
107 * Main function, rendering the document with the iFrame with the RTE in.
108 *
109 * @return void
110 */
111 public function main() {
112 // Translate id to the workspace version:
113 if ($versionedRecord = BackendUtility::getWorkspaceVersionOfRecord($this->getBackendUserAuthentication()->workspace, $this->P['table'], $this->P['uid'], 'uid')) {
114 $this->P['uid'] = $versionedRecord['uid'];
115 }
116 // If all parameters are available:
117 if ($this->P['table'] && $this->P['field'] && $this->P['uid'] && $this->checkEditAccess($this->P['table'], $this->P['uid'])) {
118 // Getting the raw record (we need only the pid-value from here...)
119 $rawRecord = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
120 BackendUtility::fixVersioningPid($this->P['table'], $rawRecord);
121
122 // override the default jumpToUrl
123 $this->doc->JScodeArray['jumpToUrl'] = '
124 function jumpToUrl(URL,formEl) {
125 if (document.editform) {
126 if (!TBE_EDITOR.isFormChanged()) {
127 window.location.href = URL;
128 } else if (formEl) {
129 if (formEl.type=="checkbox") formEl.checked = formEl.checked ? 0 : 1;
130 }
131 } else {
132 window.location.href = URL;
133 }
134 }
135 ';
136
137 // Setting JavaScript of the pid value for viewing:
138 if ($this->popView) {
139 $this->doc->JScode = $this->doc->wrapScriptTags(BackendUtility::viewOnClick($rawRecord['pid'], '', BackendUtility::BEgetRootLine($rawRecord['pid'])));
140 }
141 // Initialize FormEngine - for rendering the field:
142 /** @var FormEngine $formEngine */
143 $formEngine = GeneralUtility::makeInstance(FormEngine::class);
144 // SPECIAL: Disables all wizards - we are NOT going to need them.
145 $formEngine->disableWizards = 1;
146 // Initialize style for RTE object:
147 // Getting reference to the RTE object used to render the field!
148 $RTEObject = BackendUtility::RTEgetObj();
149 if ($RTEObject->ID === 'rte') {
150 $RTEObject->RTEdivStyle = 'position:relative; left:0px; top:0px; height:100%; width:100%; border:solid 0px;';
151 }
152 // Fetching content of record:
153 /** @var DataPreprocessor $dataPreprocessor */
154 $dataPreprocessor = GeneralUtility::makeInstance(DataPreprocessor::class);
155 $dataPreprocessor->lockRecords = 1;
156 $dataPreprocessor->fetchRecord($this->P['table'], $this->P['uid'], '');
157 // Getting the processed record content out:
158 $processedRecord = reset($dataPreprocessor->regTableItems_data);
159 $processedRecord['uid'] = $this->P['uid'];
160 $processedRecord['pid'] = $rawRecord['pid'];
161 // TSconfig, setting width:
162 $fieldTSConfig = FormEngineUtility::getTSconfigForTableRow($this->P['table'], $processedRecord, $this->P['field']);
163 if ((string)$fieldTSConfig['RTEfullScreenWidth'] !== '') {
164 $width = $fieldTSConfig['RTEfullScreenWidth'];
165 } else {
166 $width = '100%';
167 }
168 // Get the form field and wrap it in the table with the buttons:
169 $formContent = $formEngine->getSoloField($this->P['table'], $processedRecord, $this->P['field']);
170 $formContent = '
171
172 <!-- RTE wizard: -->
173 <table border="0" cellpadding="0" cellspacing="0" width="' . $width . '" id="typo3-rtewizard">
174 <tr>
175 <td width="' . $width . '" colspan="2" id="c-formContent">' . $formContent . '</td>
176 <td></td>
177 </tr>
178 </table>';
179 // Adding hidden fields:
180 $formContent .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($this->R_URI) . '" />
181 <input type="hidden" name="_serialNumber" value="' . md5(microtime()) . '" />' . FormEngine::getHiddenTokenField('tceAction');
182 // Finally, add the whole setup:
183 $this->content .= $formEngine->printNeededJSFunctions_top() . $formContent . $formEngine->printNeededJSFunctions();
184 } else {
185 // ERROR:
186 $this->content .= $this->doc->section($this->getLanguageService()->getLL('forms_title'), '<span class="typo3-red">' . $this->getLanguageService()->getLL('table_noData', TRUE) . '</span>', 0, 1);
187 }
188 // Setting up the buttons and markers for docHeader
189 $docHeaderButtons = $this->getButtons();
190 $markers['CONTENT'] = $this->content;
191 // Build the <body> for the module
192 $this->content = $this->doc->startPage('');
193 $this->content .= $this->doc->moduleBody(array(), $docHeaderButtons, $markers);
194 $this->content .= $this->doc->endPage();
195 $this->content = $this->doc->insertStylesAndJS($this->content);
196 }
197
198 /**
199 * Outputting the accumulated content to screen
200 *
201 * @return void
202 */
203 public function printContent() {
204 $this->content .= $this->doc->endPage();
205 $this->content = $this->doc->insertStylesAndJS($this->content);
206 echo $this->content;
207 }
208
209 /**
210 * Create the panel of buttons for submitting the form or otherwise perform operations.
211 *
212 * @return array All available buttons as an assoc. array
213 */
214 protected function getButtons() {
215 $buttons = array(
216 'close' => '',
217 'save' => '',
218 'save_view' => '',
219 'save_close' => '',
220 'shortcut' => '',
221 'undo' => ''
222 );
223 if ($this->P['table'] && $this->P['field'] && $this->P['uid'] && $this->checkEditAccess($this->P['table'], $this->P['uid'])) {
224 $closeUrl = GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']);
225 // Getting settings for the undo button:
226 $undoButton = 0;
227 $databaseConnection = $this->getDatabaseConnection();
228 $undoRes = $databaseConnection->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $databaseConnection->fullQuoteStr($this->P['table'], 'sys_history') . ' AND recuid=' . (int)$this->P['uid'], '', 'tstamp DESC', '1');
229 if ($undoButtonR = $databaseConnection->sql_fetch_assoc($undoRes)) {
230 $undoButton = 1;
231 }
232 // Close
233 $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars('jumpToUrl(' . GeneralUtility::quoteJSvalue($closeUrl) . '); return false;') . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-close') . '</a>';
234 // Save
235 $buttons['save'] = IconUtility::getSpriteIcon('actions-document-save', array('html' => '<input type="image" name="_savedok" class="c-inputButton" src="clear.gif" onclick="TBE_EDITOR.checkAndDoSubmit(1); return false;" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', TRUE) . '" />'));
236 // Save & View
237 $buttons['save_view'] = IconUtility::getSpriteIcon('actions-document-save-view', array('html' => '<input type="image" class="c-inputButton" name="_savedokview" src="clear.gif" onclick="' . htmlspecialchars('document.editform.redirect.value+=\'&popView=1\'; TBE_EDITOR.checkAndDoSubmit(1); return false;') . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDocShow', TRUE) . '" />'));
238 // Save & Close
239 $buttons['save_close'] = IconUtility::getSpriteIcon('actions-document-save-close', array('html' => '<input type="image" class="c-inputButton" name="_saveandclosedok" src="clear.gif" onclick="' . htmlspecialchars('document.editform.redirect.value=' . GeneralUtility::quoteJSvalue($closeUrl) . '; TBE_EDITOR.checkAndDoSubmit(1); return false;') . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', TRUE) . '" />'));
240 // Undo/Revert:
241 if ($undoButton) {
242 $aOnClick = 'window.location.href=' .
243 GeneralUtility::quoteJSvalue(
244 BackendUtility::getModuleUrl(
245 'record_history',
246 array(
247 'element' => $this->P['table'] . ':' . $this->P['uid'],
248 'revert' => 'field:' . $this->P['field'],
249 'sumUp' => -1,
250 'returnUrl' => $this->R_URI,
251 )
252 )
253 ) . '; return false;';
254 $buttons['undo'] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"' . ' title="' . htmlspecialchars(sprintf($this->getLanguageService()->getLL('undoLastChange'), BackendUtility::calcAge(($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp']), $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')))) . '">' . IconUtility::getSpriteIcon('actions-edit-undo') . '</a>';
255 }
256 // Shortcut
257 if ($this->getBackendUserAuthentication()->mayMakeShortcut()) {
258 $buttons['shortcut'] = $this->doc->makeShortcutIcon('P', '', $this->MCONF['name'], 1);
259 }
260 }
261 return $buttons;
262 }
263
264 }