TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
RteController.php
Go to the documentation of this file.
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;
21 use TYPO3\CMS\Backend\Form\FormEngine;
30 
35 {
41  public $content;
42 
48  public $P;
49 
55  public $popView;
56 
62  public $R_URI;
63 
69  public $MCONF = [];
70 
74  public function __construct()
75  {
76  parent::__construct();
77  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
78  $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_wizards.xlf');
79  $GLOBALS['SOBE'] = $this;
80 
81  $this->init();
82  }
83 
89  protected function init()
90  {
91  // Setting GPvars:
92  $this->P = GeneralUtility::_GP('P');
93  $this->popView = GeneralUtility::_GP('popView');
94  $this->R_URI = GeneralUtility::linkThisScript(['popView' => '']);
95  // "Module name":
96  $this->MCONF['name'] = 'wizard_rte';
97  // Need to NOT have the page wrapped in DIV since if we do that we destroy
98  // the feature that the RTE spans the whole height of the page!!!
99  }
100 
109  public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
110  {
111  $this->main();
112 
113  $response->getBody()->write($this->moduleTemplate->renderContent());
114  return $response;
115  }
116 
122  public function main()
123  {
124  $this->content .= '<form action="'
125  . htmlspecialchars(BackendUtility::getModuleUrl('tce_db'))
126  . '" method="post" enctype="multipart/form-data" id="RteController" name="editform" '
127  . ' onsubmit="return TBE_EDITOR.checkSubmit(1);">';
128  // Translate id to the workspace version:
129  if ($versionedRecord = BackendUtility::getWorkspaceVersionOfRecord(
130  $this->getBackendUserAuthentication()->workspace,
131  $this->P['table'],
132  $this->P['uid'],
133  'uid'
134  )) {
135  $this->P['uid'] = $versionedRecord['uid'];
136  }
137  // If all parameters are available:
138  if ($this->P['table']
139  && $this->P['field']
140  && $this->P['uid']
141  && $this->checkEditAccess($this->P['table'], $this->P['uid'])) {
143  $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class);
145  $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
147  $nodeFactory = GeneralUtility::makeInstance(NodeFactory::class);
148 
149  $formDataCompilerInput = [
150  'vanillaUid' => (int)$this->P['uid'],
151  'tableName' => $this->P['table'],
152  'command' => 'edit',
153  'disabledWizards' => true,
154  ];
155 
156  $formData = $formDataCompiler->compile($formDataCompilerInput);
157 
158  $formData['fieldListToRender'] = $this->P['field'];
159  $formData['renderType'] = 'outerWrapContainer';
160  $formResult = $nodeFactory->create($formData)->render();
161 
163  $formResultCompiler = GeneralUtility::makeInstance(FormResultCompiler::class);
164  $formResultCompiler->mergeResult($formResult);
165 
166  // override the default jumpToUrl
167  $this->moduleTemplate->addJavaScriptCode(
168  'RteWizardInlineCode',
169  'function jumpToUrl(URL,formEl) {
170  if (document.editform) {
171  if (!TBE_EDITOR.isFormChanged()) {
172  window.location.href = URL;
173  } else if (formEl) {
174  if (formEl.type=="checkbox") formEl.checked = formEl.checked ? 0 : 1;
175  }
176  } else {
177  window.location.href = URL;
178  }
179  }
180  '
181  );
182 
183  // Setting JavaScript of the pid value for viewing:
184  if ($this->popView) {
185  $this->moduleTemplate->addJavaScriptCode(
186  'PopupViewInlineJS',
188  $formData['databaseRow']['pid'],
189  '',
190  BackendUtility::BEgetRootLine($formData['databaseRow']['pid'])
191  )
192  );
193  }
194 
195  $pageTsConfigMerged = $formData['pageTsConfigMerged'];
196  if ((string)$pageTsConfigMerged['TCEFORM.'][$this->P['table'] . '.'][$this->P['field'] . '.']['RTEfullScreenWidth'] !== '') {
197  $width = (string)$pageTsConfigMerged['TCEFORM.'][$this->P['table'] . '.'][$this->P['field'] . '.']['RTEfullScreenWidth'];
198  } else {
199  $width = '100%';
200  }
201  // Get the form field and wrap it in the table with the buttons:
202  $formContent = $formResult['html'];
203  $formContent = '
204  <table border="0" cellpadding="0" cellspacing="0" width="' . $width . '" id="typo3-rtewizard">
205  <tr>
206  <td width="' . $width . '" colspan="2" id="c-formContent">' . $formContent . '</td>
207  <td></td>
208  </tr>
209  </table>';
210 
211  // Adding hidden fields:
212  $formContent .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($this->R_URI) . '" />
213  <input type="hidden" name="_serialNumber" value="' . md5(microtime()) . '" />';
214  // Finally, add the whole setup:
215  $this->content .= $formResultCompiler->addCssFiles()
216  . $formContent
217  . $formResultCompiler->printNeededJSFunctions();
218  } else {
219  // ERROR:
220  $this->content .= '<h2>' . htmlspecialchars($this->getLanguageService()->getLL('forms_title')) . '</h2>'
221  . '<div><span class="text-danger">'
222  . htmlspecialchars($this->getLanguageService()->getLL('table_noData'))
223  . '</span></div>';
224  }
225  // Setting up the buttons and markers for docHeader
226  $this->getButtons();
227  // Build the <body> for the module
228 
229  $this->content .= '</form>';
230  $this->moduleTemplate->setContent($this->content);
231  }
232 
238  protected function getButtons()
239  {
240  $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
241  if ($this->P['table']
242  && $this->P['field']
243  && $this->P['uid']
244  && $this->checkEditAccess($this->P['table'], $this->P['uid'])) {
245  $closeUrl = GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']);
246  // Getting settings for the undo button:
247  $undoButton = false;
248 
249  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
250  ->getQueryBuilderForTable('sys_history');
251 
252  $undoButtonR = $queryBuilder
253  ->select('tstamp')
254  ->from('sys_history')
255  ->where(
256  $queryBuilder->expr()->eq(
257  'tablename',
258  $queryBuilder->createNamedParameter($this->P['table'], \PDO::PARAM_STR)
259  ),
260  $queryBuilder->expr()->eq(
261  'recuid',
262  $queryBuilder->createNamedParameter($this->P['uid'], \PDO::PARAM_INT)
263  )
264  )
265  ->orderBy('tstamp', 'desc')
266  ->setMaxResults(1)
267  ->execute()
268  ->fetchColumn();
269 
270  if ($undoButtonR !== false) {
271  $undoButton = true;
272  }
273  // Close
274  $closeButton = $buttonBar->makeLinkButton()
275  ->setHref($closeUrl)
276  ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))
277  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL));
278  $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 10);
279 
280  // Save
281  $saveButton = $buttonBar->makeInputButton()
282  ->setName('_savedok_x')
283  ->setValue('1')
284  ->setForm('RteController')
285  ->setOnClick('TBE_EDITOR.checkAndDoSubmit(1); return false;')
286  ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDoc'))
287  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL));
288  // Save & View
289  $saveAndViewButton = $buttonBar->makeInputButton()
290  ->setName('_savedokview_x')
291  ->setValue('1')
292  ->setForm('RteController')
293  ->setOnClick('document.editform.redirect.value+= ' . GeneralUtility::quoteJSvalue('&popView=1') . '; '
294  . ' TBE_EDITOR.checkAndDoSubmit(1); return false;')
295  ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveDocShow'))
296  ->setIcon(
297  $this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-view', Icon::SIZE_SMALL)
298  );
299 
300  // Save & Close
301  $saveAndCloseButton = $buttonBar->makeInputButton()
302  ->setName('_saveandclosedok_x')
303  ->setValue('1')
304  ->setForm('RteController')
305  ->setOnClick('document.editform.redirect.value=' . GeneralUtility::quoteJSvalue($closeUrl)
306  . '; TBE_EDITOR.checkAndDoSubmit(1); return false;')
307  ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:rm.saveCloseDoc'))
308  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
309  'actions-document-save-close',
311  ));
312 
313  // Save SplitButton
314  $saveSplitButton = $buttonBar->makeSplitButton()
315  ->addItem($saveButton)
316  ->addItem($saveAndViewButton)
317  ->addItem($saveAndCloseButton);
318  $buttonBar->addButton($saveSplitButton, ButtonBar::BUTTON_POSITION_LEFT, 20);
319 
320  // Undo/Revert:
321  if ($undoButton) {
322  $aOnClick = 'window.location.href=' .
324  BackendUtility::getModuleUrl(
325  'record_history',
326  [
327  'element' => $this->P['table'] . ':' . $this->P['uid'],
328  'revert' => 'field:' . $this->P['field'],
329  'returnUrl' => $this->R_URI,
330  ]
331  )
332  ) . '; return false;';
333 
334  $undoText = $this->getLanguageService()->sL(
335  'LLL:EXT:lang/Resources/Private/Language/locallang_wizards.xlf:rte_undoLastChange'
336  );
337  $lastChangeLabel = sprintf(
338  $undoText,
340  ($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp']),
341  $this->getLanguageService()->sL(
342  'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears'
343  )
344  )
345  );
346 
347  $undoRevertButton = $buttonBar->makeLinkButton()
348  ->setHref('#')
349  ->setOnClick($aOnClick)
350  ->setTitle($lastChangeLabel)
351  ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-edit-undo', Icon::SIZE_SMALL));
352  $buttonBar->addButton($undoRevertButton, ButtonBar::BUTTON_POSITION_LEFT, 30);
353  }
354  // Shortcut
355  $shortButton = $buttonBar->makeShortcutButton()
356  ->setModuleName($this->MCONF['name'])
357  ->setGetVariables(['P']);
358  $buttonBar->addButton($shortButton);
359  }
360  }
361 }
static calcAge($seconds, $labels= 'min|hrs|days|yrs|min|hour|day|year')
static viewOnClick($pageUid, $backPath= '', $rootLine=null, $anchorSection= '', $alternativeUrl= '', $additionalGetVars= '', $switchFocus=true)
mainAction(ServerRequestInterface $request, ResponseInterface $response)
static BEgetRootLine($uid, $clause= '', $workspaceOL=false)
static linkThisScript(array $getParams=[])
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static makeInstance($className,...$constructorArguments)
static getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields= '*')