[TASK] Set TYPO3 version to 9.5.0-dev
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / FrontendEditing / FrontendEditingController.php
1 <?php
2 namespace TYPO3\CMS\Core\FrontendEditing;
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\Adminpanel\View\AdminPanelView;
18 use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
20 use TYPO3\CMS\Core\Context\Context;
21 use TYPO3\CMS\Core\Context\LanguageAspect;
22 use TYPO3\CMS\Core\Database\ConnectionPool;
23 use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
24 use TYPO3\CMS\Core\Database\Query\Restriction\FrontendGroupRestriction;
25 use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
26 use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
27 use TYPO3\CMS\Core\DataHandling\DataHandler;
28 use TYPO3\CMS\Core\Type\Bitmask\Permission;
29 use TYPO3\CMS\Core\Utility\GeneralUtility;
30 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
31
32 /**
33 * Controller class for frontend editing.
34 */
35 class FrontendEditingController
36 {
37 /**
38 * GET/POST parameters for the FE editing.
39 * Accessed as $GLOBALS['BE_USER']->frontendEdit->TSFE_EDIT, thus public
40 *
41 * @var array
42 */
43 public $TSFE_EDIT;
44
45 /**
46 * Initializes configuration options.
47 */
48 public function initConfigOptions()
49 {
50 $this->TSFE_EDIT = GeneralUtility::_GP('TSFE_EDIT');
51 // Include classes for editing IF editing module in Admin Panel is open
52 if (((int)$this->getTypoScriptFrontendController()->displayEditIcons === 1
53 || (int)$this->getTypoScriptFrontendController()->displayFieldEditIcons === 1)
54 && $this->isEditAction()
55 ) {
56 $this->editAction();
57 }
58 }
59
60 /**
61 * Generates the "edit panels" which can be shown for a page or records on a page when the Admin Panel is enabled for a backend users surfing the frontend.
62 * With the "edit panel" the user will see buttons with links to editing, moving, hiding, deleting the element
63 * This function is used for the cObject EDITPANEL and the stdWrap property ".editPanel"
64 *
65 * @param string $content A content string containing the content related to the edit panel. For cObject "EDITPANEL" this is empty but not so for the stdWrap property. The edit panel is appended to this string and returned.
66 * @param array $conf TypoScript configuration properties for the editPanel
67 * @param string $currentRecord The "table:uid" of the record being shown. If empty string then $this->currentRecord is used. For new records (set by $conf['newRecordFromTable']) it's auto-generated to "[tablename]:NEW
68 * @param array $dataArray Alternative data array to use. Default is $this->data
69 * @return string The input content string with the editPanel appended. This function returns only an edit panel appended to the content string if a backend user is logged in (and has the correct permissions). Otherwise the content string is directly returned.
70 */
71 public function displayEditPanel($content, array $conf, $currentRecord, array $dataArray)
72 {
73 if ($conf['newRecordFromTable']) {
74 $currentRecord = $conf['newRecordFromTable'] . ':NEW';
75 $conf['allow'] = 'new';
76 $checkEditAccessInternals = false;
77 } else {
78 $checkEditAccessInternals = true;
79 }
80 list($table, $uid) = explode(':', $currentRecord);
81 // Page ID for new records, 0 if not specified
82 $newRecordPid = (int)$conf['newRecordInPid'];
83 $newUid = null;
84 if (!$conf['onlyCurrentPid'] || $dataArray['pid'] == $this->getTypoScriptFrontendController()->id) {
85 if ($table === 'pages') {
86 $newUid = $uid;
87 } else {
88 if ($conf['newRecordFromTable']) {
89 $newUid = $this->getTypoScriptFrontendController()->id;
90 if ($newRecordPid) {
91 $newUid = $newRecordPid;
92 }
93 } else {
94 $newUid = -1 * $uid;
95 }
96 }
97 }
98 if ($this->getTypoScriptFrontendController()->displayEditIcons && $table && $this->allowedToEdit($table, $dataArray, $conf, $checkEditAccessInternals) && $this->allowedToEditLanguage($table, $dataArray)) {
99 $editClass = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/classes/class.frontendedit.php']['edit'];
100 if ($editClass) {
101 $edit = GeneralUtility::makeInstance($editClass);
102 $allowedActions = $this->getAllowedEditActions($table, $conf, $dataArray['pid']);
103 $content = $edit->editPanel($content, $conf, $currentRecord, $dataArray, $table, $allowedActions, $newUid, $this->getHiddenFields($dataArray));
104 }
105 }
106 return $content;
107 }
108
109 /**
110 * Adds an edit icon to the content string. The edit icon links to FormEngine with proper parameters for editing the table/fields of the context.
111 * This implements TYPO3 context sensitive editing facilities. Only backend users will have access (if properly configured as well).
112 *
113 * @param string $content The content to which the edit icons should be appended
114 * @param string $params The parameters defining which table and fields to edit. Syntax is [tablename]:[fieldname],[fieldname],[fieldname],... OR [fieldname],[fieldname],[fieldname],... (basically "[tablename]:" is optional, default table is the one of the "current record" used in the function). The fieldlist is sent as "&columnsOnly=" parameter to FormEngine
115 * @param array $conf TypoScript properties for configuring the edit icons.
116 * @param string $currentRecord The "table:uid" of the record being shown. If empty string then $this->currentRecord is used. For new records (set by $conf['newRecordFromTable']) it's auto-generated to "[tablename]:NEW
117 * @param array $dataArray Alternative data array to use. Default is $this->data
118 * @param string $addUrlParamStr Additional URL parameters for the link pointing to FormEngine
119 * @return string The input content string, possibly with edit icons added (not necessarily in the end but just after the last string of normal content.
120 */
121 public function displayEditIcons($content, $params, array $conf = [], $currentRecord = '', array $dataArray = [], $addUrlParamStr = '')
122 {
123 // Check incoming params:
124 list($currentRecordTable, $currentRecordUID) = explode(':', $currentRecord);
125 list($fieldList, $table) = array_reverse(GeneralUtility::trimExplode(':', $params, true));
126 // Reverse the array because table is optional
127 if (!$table) {
128 $table = $currentRecordTable;
129 } elseif ($table != $currentRecordTable) {
130 // If the table is set as the first parameter, and does not match the table of the current record, then just return.
131 return $content;
132 }
133 $editUid = $dataArray['_LOCALIZED_UID'] ?: $currentRecordUID;
134 // Edit icons imply that the editing action is generally allowed, assuming page and content element permissions permit it.
135 if (!array_key_exists('allow', $conf)) {
136 $conf['allow'] = 'edit';
137 }
138 if ($this->getTypoScriptFrontendController()->displayFieldEditIcons && $table && $this->allowedToEdit($table, $dataArray, $conf) && $fieldList && $this->allowedToEditLanguage($table, $dataArray)) {
139 $editClass = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/classes/class.frontendedit.php']['edit'];
140 if ($editClass) {
141 $edit = GeneralUtility::makeInstance($editClass);
142 $content = $edit->editIcons($content, $params, $conf, $currentRecord, $dataArray, $addUrlParamStr, $table, $editUid, $fieldList);
143 }
144 }
145 return $content;
146 }
147
148 /*****************************************************
149 *
150 * Frontend Editing
151 *
152 ****************************************************/
153 /**
154 * Returns TRUE if an edit-action is sent from the Admin Panel
155 *
156 * @return bool
157 */
158 public function isEditAction()
159 {
160 if (is_array($this->TSFE_EDIT)) {
161 if ($this->TSFE_EDIT['cancel']) {
162 unset($this->TSFE_EDIT['cmd']);
163 } else {
164 $cmd = (string)$this->TSFE_EDIT['cmd'];
165 if (($cmd !== 'edit' || is_array($this->TSFE_EDIT['data']) && ($this->TSFE_EDIT['doSave'] || $this->TSFE_EDIT['update'] || $this->TSFE_EDIT['update_close'])) && $cmd !== 'new') {
166 // $cmd can be a command like "hide" or "move". If $cmd is "edit" or "new" it's an indication to show the formfields. But if data is sent with update-flag then $cmd = edit is accepted because edit may be sent because of .keepGoing flag.
167 return true;
168 }
169 }
170 }
171 return false;
172 }
173
174 /**
175 * Returns TRUE if an edit form is shown on the page.
176 *
177 * @return bool
178 */
179 public function isEditFormShown()
180 {
181 if (is_array($this->TSFE_EDIT)) {
182 $cmd = (string)$this->TSFE_EDIT['cmd'];
183 if ($cmd === 'edit' || $cmd === 'new') {
184 return true;
185 }
186 }
187 }
188
189 /**
190 * Management of the on-page frontend editing forms and edit panels.
191 * Basically taking in the data and commands and passes them on to the proper classes as they should be.
192 *
193 * @throws \UnexpectedValueException if TSFE_EDIT[cmd] is not a valid command
194 */
195 public function editAction()
196 {
197 // Commands
198 list($table, $uid) = explode(':', $this->TSFE_EDIT['record']);
199 $uid = (int)$uid;
200 $cmd = $this->TSFE_EDIT['cmd'];
201 // Look for some TSFE_EDIT data that indicates we should save.
202 if (($this->TSFE_EDIT['doSave'] || $this->TSFE_EDIT['update'] || $this->TSFE_EDIT['update_close']) && is_array($this->TSFE_EDIT['data'])) {
203 $cmd = 'save';
204 }
205 if ($cmd === 'save' || $cmd && $table && $uid && isset($GLOBALS['TCA'][$table])) {
206 // Hook for defining custom editing actions. Naming is incorrect, but preserves compatibility.
207 $_params = [];
208 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extEditAction'] ?? [] as $_funcRef) {
209 GeneralUtility::callUserFunction($_funcRef, $_params, $this);
210 }
211 // Perform the requested editing command.
212 $cmdAction = 'do' . ucwords($cmd);
213 if (is_callable([$this, $cmdAction])) {
214 $this->{$cmdAction}($table, $uid);
215 } else {
216 throw new \UnexpectedValueException('The specified frontend edit command (' . $cmd . ') is not valid.', 1225818120);
217 }
218 }
219 }
220
221 /**
222 * Hides a specific record.
223 *
224 * @param string $table The table name for the record to hide.
225 * @param int $uid The UID for the record to hide.
226 */
227 public function doHide($table, $uid)
228 {
229 $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
230 if ($hideField) {
231 $recData = [];
232 $recData[$table][$uid][$hideField] = 1;
233 $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
234 $dataHandler->start($recData, []);
235 $dataHandler->process_datamap();
236 }
237 }
238
239 /**
240 * Unhides (shows) a specific record.
241 *
242 * @param string $table The table name for the record to unhide.
243 * @param int $uid The UID for the record to unhide.
244 */
245 public function doUnhide($table, $uid)
246 {
247 $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
248 if ($hideField) {
249 $recData = [];
250 $recData[$table][$uid][$hideField] = 0;
251 $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
252 $dataHandler->start($recData, []);
253 $dataHandler->process_datamap();
254 }
255 }
256
257 /**
258 * Moves a record up.
259 *
260 * @param string $table The table name for the record to move.
261 * @param int $uid The UID for the record to hide.
262 */
263 public function doUp($table, $uid)
264 {
265 $this->move($table, $uid, 'up');
266 }
267
268 /**
269 * Moves a record down.
270 *
271 * @param string $table The table name for the record to move.
272 * @param int $uid The UID for the record to move.
273 */
274 public function doDown($table, $uid)
275 {
276 $this->move($table, $uid, 'down');
277 }
278
279 /**
280 * Moves a record after a given element. Used for drag.
281 *
282 * @param string $table The table name for the record to move.
283 * @param int $uid The UID for the record to move.
284 */
285 public function doMoveAfter($table, $uid)
286 {
287 $afterUID = $this->TSFE_EDIT['moveAfter'];
288 $this->move($table, $uid, '', $afterUID);
289 }
290
291 /**
292 * Moves a record
293 *
294 * @param string $table The table name for the record to move.
295 * @param int $uid The UID for the record to move.
296 * @param string $direction The direction to move, either 'up' or 'down'.
297 * @param int $afterUID The UID of record to move after. This is specified for dragging only.
298 */
299 protected function move($table, $uid, $direction = '', $afterUID = 0)
300 {
301 $dataHandlerCommands = [];
302 $sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby'];
303 if ($sortField) {
304 // Get the current record
305 // Only fetch uid, pid and the fields that are necessary to detect the sorting factors
306 if (isset($GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields'])) {
307 $copyAfterDuplicateFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields'], true);
308 } else {
309 $copyAfterDuplicateFields = [];
310 }
311
312 $fields = $copyAfterDuplicateFields;
313 $fields[] = 'uid';
314 $fields[] = 'pid';
315 $fields[] = $sortField;
316 $fields = array_unique($fields);
317
318 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
319 ->getQueryBuilderForTable($table);
320 $queryBuilder->getRestrictions()->removeAll();
321
322 $currentRecord = $queryBuilder
323 ->select(...$fields)
324 ->from($table)
325 ->where($queryBuilder->expr()->eq(
326 'uid',
327 $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
328 ))
329 ->execute()
330 ->fetch();
331
332 if (is_array($currentRecord)) {
333 // Fetch the record before or after the current one
334 // to define the data handler commands
335 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
336 ->getQueryBuilderForTable($table);
337
338 $queryBuilder
339 ->select('uid', 'pid')
340 ->from($table)
341 ->where($queryBuilder->expr()->eq(
342 'pid',
343 $queryBuilder->createNamedParameter($currentRecord['pid'], \PDO::PARAM_INT)
344 ))
345 ->setMaxResults(2);
346
347 // Disable the default restrictions (but not all) if the admin panel is in preview mode
348 if ($this->getBackendUser()->adminPanel instanceof AdminPanelView && $this->getBackendUser()->adminPanel->extGetFeAdminValue('preview')) {
349 $queryBuilder->getRestrictions()
350 ->removeByType(StartTimeRestriction::class)
351 ->removeByType(EndTimeRestriction::class)
352 ->removeByType(HiddenRestriction::class)
353 ->removeByType(FrontendGroupRestriction::class);
354 }
355
356 if (!empty($copyAfterDuplicateFields)) {
357 foreach ($copyAfterDuplicateFields as $fieldName) {
358 $queryBuilder->andWhere($queryBuilder->expr()->eq(
359 $fieldName,
360 $queryBuilder->createNamedParameter($currentRecord[$fieldName], \PDO::PARAM_STR)
361 ));
362 }
363 }
364 if (!empty($direction)) {
365 if ($direction === 'up') {
366 $queryBuilder->andWhere(
367 $queryBuilder->expr()->lt(
368 $sortField,
369 $queryBuilder->createNamedParameter($currentRecord[$sortField], \PDO::PARAM_INT)
370 )
371 );
372 $queryBuilder->orderBy($sortField, 'DESC');
373 } else {
374 $queryBuilder->andWhere(
375 $queryBuilder->expr()->gt(
376 $sortField,
377 $queryBuilder->createNamedParameter($currentRecord[$sortField], \PDO::PARAM_INT)
378 )
379 );
380 $queryBuilder->orderBy($sortField, 'ASC');
381 }
382 }
383
384 $result = $queryBuilder->execute();
385 if ($recordBefore = $result->fetch()) {
386 if ($afterUID) {
387 $dataHandlerCommands[$table][$uid]['move'] = -$afterUID;
388 } elseif ($direction === 'down') {
389 $dataHandlerCommands[$table][$uid]['move'] = -$recordBefore['uid'];
390 } elseif ($recordAfter = $result->fetch()) {
391 // Must take the second record above...
392 $dataHandlerCommands[$table][$uid]['move'] = -$recordAfter['uid'];
393 } else {
394 // ... and if that does not exist, use pid
395 $dataHandlerCommands[$table][$uid]['move'] = $currentRecord['pid'];
396 }
397 } elseif ($direction === 'up') {
398 $dataHandlerCommands[$table][$uid]['move'] = $currentRecord['pid'];
399 }
400 }
401
402 // If any data handler commands were set, execute the data handler command
403 if (!empty($dataHandlerCommands)) {
404 $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
405 $dataHandler->start([], $dataHandlerCommands);
406 $dataHandler->process_cmdmap();
407 }
408 }
409 }
410
411 /**
412 * Deletes a specific record.
413 *
414 * @param string $table The table name for the record to delete.
415 * @param int $uid The UID for the record to delete.
416 */
417 public function doDelete($table, $uid)
418 {
419 $cmdData[$table][$uid]['delete'] = 1;
420 if (!empty($cmdData)) {
421 $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
422 $dataHandler->start([], $cmdData);
423 $dataHandler->process_cmdmap();
424 }
425 }
426
427 /**
428 * Saves a record based on its data array.
429 *
430 * @param string $table The table name for the record to save.
431 * @param int $uid The UID for the record to save.
432 */
433 public function doSave($table, $uid)
434 {
435 $data = $this->TSFE_EDIT['data'];
436 if (!empty($data)) {
437 $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
438 $dataHandler->start($data, []);
439 $dataHandler->process_uploads($_FILES);
440 $dataHandler->process_datamap();
441 // Save the new UID back into TSFE_EDIT
442 $newUID = $dataHandler->substNEWwithIDs['NEW'];
443 if ($newUID) {
444 $this->TSFE_EDIT['newUID'] = $newUID;
445 }
446 }
447 }
448
449 /**
450 * Saves a record based on its data array and closes it.
451 * Note: This method is only a wrapper for doSave() but is needed so
452 *
453 * @param string $table The table name for the record to save.
454 * @param int $uid The UID for the record to save.
455 */
456 public function doSaveAndClose($table, $uid)
457 {
458 $this->doSave($table, $uid);
459 }
460
461 /**
462 * Stub for closing a record. No real functionality needed since content
463 * element rendering will take care of everything.
464 *
465 * @param string $table The table name for the record to close.
466 * @param int $uid The UID for the record to close.
467 */
468 public function doClose($table, $uid)
469 {
470 }
471
472 /**
473 * Checks whether the user has access to edit the language for the
474 * requested record.
475 *
476 * @param string $table The name of the table.
477 * @param array $currentRecord The record.
478 * @return bool
479 */
480 protected function allowedToEditLanguage($table, array $currentRecord)
481 {
482 // If no access right to record languages, return immediately
483 /** @var LanguageAspect $languageAspect */
484 $languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
485 if ($table === 'pages') {
486 $lang = $languageAspect->getId();
487 } elseif ($table === 'tt_content') {
488 $lang = $languageAspect->getContentId();
489 } elseif ($GLOBALS['TCA'][$table]['ctrl']['languageField']) {
490 $lang = $currentRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']];
491 } else {
492 $lang = -1;
493 }
494 return $this->getBackendUser()->checkLanguageAccess($lang);
495 }
496
497 /**
498 * Checks whether the user is allowed to edit the requested table.
499 *
500 * @param string $table The name of the table.
501 * @param array $dataArray The data array.
502 * @param array $conf The configuration array for the edit panel.
503 * @param bool $checkEditAccessInternals Boolean indicating whether recordEditAccessInternals should not be checked. Defaults
504 * @return bool
505 */
506 protected function allowedToEdit($table, array $dataArray, array $conf, $checkEditAccessInternals = true)
507 {
508 // Unless permissions specifically allow it, editing is not allowed.
509 $mayEdit = false;
510 if ($checkEditAccessInternals) {
511 $editAccessInternals = $this->getBackendUser()->recordEditAccessInternals($table, $dataArray, false, false);
512 } else {
513 $editAccessInternals = true;
514 }
515 if ($editAccessInternals) {
516 if ($table === 'pages') {
517 if ($this->getBackendUser()->isAdmin() || $this->getBackendUser()->doesUserHaveAccess($dataArray, Permission::PAGE_EDIT)) {
518 $mayEdit = true;
519 }
520 } else {
521 if ($this->getBackendUser()->isAdmin() || $this->getBackendUser()->doesUserHaveAccess(BackendUtility::getRecord('pages', $dataArray['pid']), Permission::CONTENT_EDIT)) {
522 $mayEdit = true;
523 }
524 }
525 if (!$conf['onlyCurrentPid'] || $dataArray['pid'] == $this->getTypoScriptFrontendController()->id) {
526 // Permissions:
527 $types = GeneralUtility::trimExplode(',', strtolower($conf['allow']), true);
528 $allow = array_flip($types);
529 $perms = $this->getBackendUser()->calcPerms($this->getTypoScriptFrontendController()->page);
530 if ($table === 'pages') {
531 $allow = $this->getAllowedEditActions($table, $conf, $dataArray['pid'], $allow);
532 // Can only display editbox if there are options in the menu
533 if (!empty($allow)) {
534 $mayEdit = true;
535 }
536 } else {
537 $mayEdit = !empty($allow) && $perms & Permission::CONTENT_EDIT;
538 }
539 }
540 }
541 return $mayEdit;
542 }
543
544 /**
545 * Takes an array of generally allowed actions and filters that list based on page and content permissions.
546 *
547 * @param string $table The name of the table.
548 * @param array $conf The configuration array.
549 * @param int $pid The PID where editing will occur.
550 * @param string $allow Comma-separated list of actions that are allowed in general.
551 * @return array
552 */
553 protected function getAllowedEditActions($table, array $conf, $pid, $allow = '')
554 {
555 if (!$allow) {
556 $types = GeneralUtility::trimExplode(',', strtolower($conf['allow']), true);
557 $allow = array_flip($types);
558 }
559 if (!$conf['onlyCurrentPid'] || $pid == $this->getTypoScriptFrontendController()->id) {
560 // Permissions
561 $types = GeneralUtility::trimExplode(',', strtolower($conf['allow']), true);
562 $allow = array_flip($types);
563 $perms = $this->getBackendUser()->calcPerms($this->getTypoScriptFrontendController()->page);
564 if ($table === 'pages') {
565 // Rootpage
566 if (count($this->getTypoScriptFrontendController()->config['rootLine']) === 1) {
567 unset($allow['move']);
568 unset($allow['hide']);
569 unset($allow['delete']);
570 }
571 if (!($perms & Permission::PAGE_EDIT) || !$this->getBackendUser()->checkLanguageAccess(0)) {
572 unset($allow['edit']);
573 unset($allow['move']);
574 unset($allow['hide']);
575 }
576 if (!($perms & Permission::PAGE_DELETE)) {
577 unset($allow['delete']);
578 }
579 if (!($perms & Permission::PAGE_NEW)) {
580 unset($allow['new']);
581 }
582 }
583 }
584 return $allow;
585 }
586
587 /**
588 * Adds any extra Javascript includes needed for Front-end editing
589 *
590 * @return string
591 */
592 public function getJavascriptIncludes()
593 {
594 // No extra JS includes needed
595 return '';
596 }
597
598 /**
599 * Gets the hidden fields (array key=field name, value=field value) to be used in the edit panel for a particular content element.
600 * In the normal case, no hidden fields are needed but special controllers such as TemplaVoila need to track flexform pointers, etc.
601 *
602 * @param array $dataArray The data array for a specific content element.
603 * @return array
604 */
605 public function getHiddenFields(array $dataArray)
606 {
607 // No special hidden fields needed.
608 return [];
609 }
610
611 /**
612 * @return FrontendBackendUserAuthentication|null
613 */
614 protected function getBackendUser(): ?FrontendBackendUserAuthentication
615 {
616 return $GLOBALS['BE_USER'] instanceof FrontendBackendUserAuthentication ? $GLOBALS['BE_USER'] : null;
617 }
618
619 /**
620 * @return TypoScriptFrontendController
621 */
622 protected function getTypoScriptFrontendController(): TypoScriptFrontendController
623 {
624 return $GLOBALS['TSFE'];
625 }
626 }