diff --git a/typo3/sysext/backend/Classes/Controller/ContentElement/NewContentElementController.php b/typo3/sysext/backend/Classes/Controller/ContentElement/NewContentElementController.php index d0867a5ab66303f12e3ad6db2c04e1aaa63569f6..b2647da33c704d35748387536f68a89f21548a66 100644 --- a/typo3/sysext/backend/Classes/Controller/ContentElement/NewContentElementController.php +++ b/typo3/sysext/backend/Classes/Controller/ContentElement/NewContentElementController.php @@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\Controller\ContentElement; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Template\ModuleTemplate; use TYPO3\CMS\Backend\Tree\View\ContentCreationPagePositionMap; use TYPO3\CMS\Backend\Utility\BackendUtility; @@ -71,27 +72,6 @@ class NewContentElementController */ protected $uid_pid; - /** - * Module TSconfig. - * - * @var array - */ - protected $modTSconfig = []; - - /** - * Used to accumulate the content of the module. - * - * @var string - */ - protected $content; - - /** - * Access boolean. - * - * @var bool - */ - protected $access; - /** * config of the wizard * @@ -104,16 +84,6 @@ class NewContentElementController */ protected $pageInfo; - /** - * @var string - */ - protected $onClickEvent; - - /** - * @var array - */ - protected $MCONF; - /** * @var StandaloneView */ @@ -163,16 +133,11 @@ class NewContentElementController $colPos = $parsedBody['colPos'] ?? $queryParams['colPos'] ?? null; $this->colPos = $colPos === null ? null : (int)$colPos; $this->uid_pid = (int)($parsedBody['uid_pid'] ?? $queryParams['uid_pid'] ?? 0); - $this->MCONF['name'] = 'xMOD_db_new_content_el'; - $this->modTSconfig['properties'] = BackendUtility::getPagesTSconfig($this->id)['mod.']['wizards.']['newContentElement.'] ?? []; - $config = BackendUtility::getPagesTSconfig($this->id); - $this->config = $config['mod.']['wizards.']['newContentElement.']; + $this->config = BackendUtility::getPagesTSconfig($this->id)['mod.']['wizards.']['newContentElement.']['wizardItems.'] ?? []; // Setting up the context sensitive menu: $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu'); // Getting the current page and receiving access information (used in main()) - $perms_clause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW); - $this->pageInfo = BackendUtility::readPageAccess($this->id, $perms_clause); - $this->access = is_array($this->pageInfo); + $this->pageInfo = BackendUtility::readPageAccess($this->id, $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW)); } /** @@ -186,7 +151,7 @@ class NewContentElementController { $this->init($request); $this->prepareContent('window'); - $this->moduleTemplate->setContent($this->content); + $this->moduleTemplate->setContent($this->view->render()); return new HtmlResponse($this->moduleTemplate->renderContent()); } @@ -201,7 +166,26 @@ class NewContentElementController { $this->init($request); $this->prepareContent('list_frame'); - return new HtmlResponse($this->content); + return new HtmlResponse($this->view->render()); + } + + /** + * Create on-click event value. + * + * @param string $clientContext + * @return string + */ + protected function onClickInsertRecord(string $clientContext): string + { + // $this->uid_pid can be negative (= pointing to tt_content record) or positive (= "page ID") + $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); + $location = (string)$uriBuilder->buildUriFromRoute('record_edit', [ + 'edit[tt_content][' . $this->uid_pid . ']' => 'new', + 'defVals[tt_content][colPos]' => $this->colPos, + 'defVals[tt_content][sys_language_uid]' => $this->sys_language, + 'returnUrl' => GeneralUtility::_GP('returnUrl') + ]); + return $clientContext . '.location.href=' . GeneralUtility::quoteJSvalue($location) . '+document.editForm.defValues.value; return false;'; } /** @@ -210,38 +194,19 @@ class NewContentElementController * @param string $clientContext JavaScript client context to be used * + 'window', legacy if rendered in current document * + 'list_frame', in case rendered in global modal - * * @throws \UnexpectedValueException */ protected function prepareContent(string $clientContext): void { - $hasAccess = true; - if ($this->id && $this->access) { - - // Init position map object: - $posMap = GeneralUtility::makeInstance( - ContentCreationPagePositionMap::class, - null, - $clientContext - ); - $posMap->cur_sys_language = $this->sys_language; - // If a column is pre-set: + // Setting up the buttons for docheader + $this->getButtons(); + $hasAccess = $this->id && is_array($this->pageInfo); + if ($hasAccess) { + // If a column is pre-set if (isset($this->colPos)) { - if ($this->uid_pid < 0) { - $row = []; - $row['uid'] = abs($this->uid_pid); - } else { - $row = ''; - } - $this->onClickEvent = $posMap->onClickInsertRecord( - $row, - $this->colPos, - '', - $this->uid_pid, - $this->sys_language - ); + $onClickEvent = $this->onClickInsertRecord($clientContext); } else { - $this->onClickEvent = ''; + $onClickEvent = ''; } // *************************** // Creating content @@ -267,8 +232,8 @@ class NewContentElementController $menuItems = []; $this->view->assignMultiple([ - 'hasClickEvent' => $this->onClickEvent !== '', - 'onClickEvent' => 'function goToalt_doc() { ' . $this->onClickEvent . '}', + 'hasClickEvent' => $onClickEvent !== '', + 'onClickEvent' => 'function goToalt_doc() { ' . $onClickEvent . '}', ]); foreach ($wizardItems as $wizardKey => $wInfo) { @@ -280,7 +245,7 @@ class NewContentElementController ]; $key = count($menuItems) - 1; } else { - if (!$this->onClickEvent) { + if (!$onClickEvent) { // Radio button: $wizardOnClick = 'document.editForm.defValues.value=unescape(' . GeneralUtility::quoteJSvalue(rawurlencode($wInfo['params'])) . '); window.location.hash=\'#sel2\';'; // Onclick action for icon/title: @@ -292,7 +257,7 @@ class NewContentElementController $icon = $this->moduleTemplate->getIconFactory()->getIcon($wInfo['iconIdentifier'])->render(); $this->menuItemView->assignMultiple([ - 'onClickEvent' => $this->onClickEvent, + 'onClickEvent' => $onClickEvent, 'aOnClick' => $aOnClick, 'wizardInformation' => $wInfo, 'icon' => $icon, @@ -310,29 +275,35 @@ class NewContentElementController )); // If the user must also select a column: - if (!$this->onClickEvent) { - - // Load SHARED page-TSconfig settings and retrieve column list from there, if applicable: - $colPosArray = GeneralUtility::callUserFunction( - BackendLayoutView::class . '->getColPosListItemsParsed', - $this->id, - $this - ); - $colPosIds = array_column($colPosArray, 1); - // Removing duplicates, if any - $colPosList = implode(',', array_unique(array_map('intval', $colPosIds))); - // Finally, add the content of the column selector to the content: - $this->view->assign('posMap', $posMap->printContentElementColumns($this->id, 0, $colPosList, 1, $this->R_URI)); + if (!$onClickEvent) { + $this->definePositionMapEntries($clientContext); } - } else { - // In case of no access: - $hasAccess = false; } $this->view->assign('hasAccess', $hasAccess); + } - $this->content = $this->view->render(); - // Setting up the buttons and markers for docheader - $this->getButtons(); + /** + * User must select a column as well (when in "main mode"), so the position map is initialized and assigned to + * the view. + * + * @param string $clientContext + */ + protected function definePositionMapEntries(string $clientContext): void + { + // Load SHARED page-TSconfig settings and retrieve column list from there, if applicable: + $colPosArray = GeneralUtility::makeInstance(BackendLayoutView::class)->getColPosListItemsParsed((int)$this->id); + $colPosIds = array_column($colPosArray, 1); + // Removing duplicates, if any + $colPosList = implode(',', array_unique(array_map('intval', $colPosIds))); + // Finally, add the content of the column selector to the content: + // Init position map object + $posMap = GeneralUtility::makeInstance( + ContentCreationPagePositionMap::class, + null, + $clientContext + ); + $posMap->cur_sys_language = $this->sys_language; + $this->view->assign('posMap', $posMap->printContentElementColumns($this->id, 0, $colPosList, 1, $this->R_URI)); } /** @@ -364,41 +335,39 @@ class NewContentElementController protected function getWizards(): array { $wizardItems = []; - if (is_array($this->config)) { - $wizards = $this->config['wizardItems.'] ?? []; - $appendWizards = $this->getAppendWizards($wizards['elements.'] ?? []); - if (is_array($wizards)) { - foreach ($wizards as $groupKey => $wizardGroup) { - $this->prepareDependencyOrdering($wizards[$groupKey], 'before'); - $this->prepareDependencyOrdering($wizards[$groupKey], 'after'); + $wizards = $this->config; + $appendWizards = $this->getAppendWizards($wizards['elements.'] ?? []); + if (is_array($wizards)) { + foreach ($wizards as $groupKey => $wizardGroup) { + $this->prepareDependencyOrdering($wizards[$groupKey], 'before'); + $this->prepareDependencyOrdering($wizards[$groupKey], 'after'); + } + $wizards = GeneralUtility::makeInstance(DependencyOrderingService::class)->orderByDependencies($wizards); + + foreach ($wizards as $groupKey => $wizardGroup) { + $groupKey = rtrim($groupKey, '.'); + $showItems = GeneralUtility::trimExplode(',', $wizardGroup['show'], true); + $showAll = in_array('*', $showItems, true); + $groupItems = []; + if (is_array($appendWizards[$groupKey . '.']['elements.'])) { + $wizardElements = array_merge((array)$wizardGroup['elements.'], $appendWizards[$groupKey . '.']['elements.']); + } else { + $wizardElements = $wizardGroup['elements.']; } - $wizards = GeneralUtility::makeInstance(DependencyOrderingService::class)->orderByDependencies($wizards); - - foreach ($wizards as $groupKey => $wizardGroup) { - $groupKey = rtrim($groupKey, '.'); - $showItems = GeneralUtility::trimExplode(',', $wizardGroup['show'], true); - $showAll = in_array('*', $showItems, true); - $groupItems = []; - if (is_array($appendWizards[$groupKey . '.']['elements.'])) { - $wizardElements = array_merge((array)$wizardGroup['elements.'], $appendWizards[$groupKey . '.']['elements.']); - } else { - $wizardElements = $wizardGroup['elements.']; - } - if (is_array($wizardElements)) { - foreach ($wizardElements as $itemKey => $itemConf) { - $itemKey = rtrim($itemKey, '.'); - if ($showAll || in_array($itemKey, $showItems)) { - $tmpItem = $this->getWizardItem($itemConf); - if ($tmpItem) { - $groupItems[$groupKey . '_' . $itemKey] = $tmpItem; - } + if (is_array($wizardElements)) { + foreach ($wizardElements as $itemKey => $itemConf) { + $itemKey = rtrim($itemKey, '.'); + if ($showAll || in_array($itemKey, $showItems)) { + $tmpItem = $this->getWizardItem($itemConf); + if ($tmpItem) { + $groupItems[$groupKey . '_' . $itemKey] = $tmpItem; } } } - if (!empty($groupItems)) { - $wizardItems[$groupKey] = $this->getWizardGroupHeader($wizardGroup); - $wizardItems = array_merge($wizardItems, $groupItems); - } + } + if (!empty($groupItems)) { + $wizardItems[$groupKey] = $this->getWizardGroupHeader($wizardGroup); + $wizardItems = array_merge($wizardItems, $groupItems); } } } @@ -413,9 +382,6 @@ class NewContentElementController */ protected function getAppendWizards(array $wizardElements): array { - if (!is_array($wizardElements)) { - $wizardElements = []; - } if (is_array($GLOBALS['TBE_MODULES_EXT']['xMOD_db_new_content_el']['addElClasses'])) { foreach ($GLOBALS['TBE_MODULES_EXT']['xMOD_db_new_content_el']['addElClasses'] as $class => $path) { if (!class_exists($class) && file_exists($path)) { @@ -473,8 +439,7 @@ class NewContentElementController $removeItems = []; $keepItems = []; // Get TCEFORM from TSconfig of current page - $row = ['pid' => $this->id]; - $TCEFORM_TSconfig = BackendUtility::getTCEFORM_TSconfig('tt_content', $row); + $TCEFORM_TSconfig = BackendUtility::getTCEFORM_TSconfig('tt_content', ['pid' => $this->id]); $headersUsed = []; // Traverse wizard items: foreach ($wizardItems as $key => $cfg) { @@ -582,7 +547,6 @@ class NewContentElementController */ protected function getFluidTemplateObject(string $filename = 'Main.html'): StandaloneView { - /** @var StandaloneView $view */ $view = GeneralUtility::makeInstance(StandaloneView::class); $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/NewContentElement/' . $filename)); $view->getRequest()->setControllerExtensionName('Backend'); diff --git a/typo3/sysext/backend/Classes/Tree/View/ContentMovingPagePositionMap.php b/typo3/sysext/backend/Classes/Tree/View/ContentMovingPagePositionMap.php index 30a4fa5e6a910e73491791f6fb97e312ed607f29..ea170169f4461f938fc8f7c0084f2a5f448a1449 100644 --- a/typo3/sysext/backend/Classes/Tree/View/ContentMovingPagePositionMap.php +++ b/typo3/sysext/backend/Classes/Tree/View/ContentMovingPagePositionMap.php @@ -14,6 +14,8 @@ namespace TYPO3\CMS\Backend\Tree\View; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Utility\GeneralUtility; + /** * Position map class for moving content elements. * @@ -42,7 +44,7 @@ class ContentMovingPagePositionMap extends PagePositionMap */ public function linkPageTitle($str, $rec) { - $url = \TYPO3\CMS\Core\Utility\GeneralUtility::linkThisScript(['uid' => (int)$rec['uid'], 'moveUid' => $this->moveUid]); + $url = GeneralUtility::linkThisScript(['uid' => (int)$rec['uid'], 'moveUid' => $this->moveUid]); return '<a href="' . htmlspecialchars($url) . '">' . $str . '</a>'; } diff --git a/typo3/sysext/backend/Classes/Tree/View/PagePositionMap.php b/typo3/sysext/backend/Classes/Tree/View/PagePositionMap.php index c05152b336e2a8211048c9730c367952a0a8391b..0d353e498fb5dc9a5cc8757f410358c66b176afe 100644 --- a/typo3/sysext/backend/Classes/Tree/View/PagePositionMap.php +++ b/typo3/sysext/backend/Classes/Tree/View/PagePositionMap.php @@ -26,6 +26,7 @@ use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\MathUtility; /** * Position map class - generating a page tree / content element list which links for inserting (copy/move) of records. @@ -387,7 +388,7 @@ class PagePositionMap while ($row = $res->fetch()) { BackendUtility::workspaceOL('tt_content', $row); if (is_array($row)) { - $lines[$vv][] = $this->wrapRecordHeader($this->getRecordHeader($row), $row); + $lines[$vv][] = $this->getRecordHeader($row); $lines[$vv][] = $this->insertPositionIcon($row, $vv, $kk, $moveUid, $pid); } } @@ -405,7 +406,7 @@ class PagePositionMap */ public function printRecordMap($lines, $colPosArray, $pid = 0) { - $count = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange(count($colPosArray), 1); + $count = MathUtility::forceIntegerInRange(count($colPosArray), 1); $backendLayout = GeneralUtility::callUserFunction(\TYPO3\CMS\Backend\View\BackendLayoutView::class . '->getSelectedBackendLayout', $pid, $this); if (isset($backendLayout['__config']['backend_layout.'])) { $this->getLanguageService()->includeLLFile('EXT:backend/Resources/Private/Language/locallang_layout.xlf'); @@ -449,11 +450,11 @@ class PagePositionMap // Render header $table .= '<p>'; if (isset($columnConfig['colPos']) && $head) { - $table .= '<strong>' . $this->wrapColumnHeader($head, '') . '</strong>'; + $table .= '<strong>' . $head . '</strong>'; } elseif ($columnConfig['colPos']) { - $table .= '<em>' . $this->wrapColumnHeader($this->getLanguageService()->getLL('noAccess'), '') . '</em>'; + $table .= '<em>' . $this->getLanguageService()->getLL('noAccess') . '</em>'; } else { - $table .= '<em>' . $this->wrapColumnHeader(($this->getLanguageService()->sL($columnConfig['name']) ?: '') . ' (' . $this->getLanguageService()->getLL('notAssigned') . ')', '') . '</em>'; + $table .= '<em>' . ($this->getLanguageService()->sL($columnConfig['name']) ?: '') . ' (' . $this->getLanguageService()->getLL('notAssigned') . ')' . '</em>'; } $table .= '</p>'; // Render lines @@ -475,7 +476,7 @@ class PagePositionMap $row = ''; foreach ($colPosArray as $kk => $vv) { $row .= '<td class="col-nowrap col-min" width="' . round(100 / $count) . '%">'; - $row .= '<p><strong>' . $this->wrapColumnHeader(htmlspecialchars($this->getLanguageService()->sL(BackendUtility::getLabelFromItemlist('tt_content', 'colPos', $vv))), $vv) . '</strong></p>'; + $row .= '<p><strong>' . htmlspecialchars($this->getLanguageService()->sL(BackendUtility::getLabelFromItemlist('tt_content', 'colPos', $vv))) . '</strong></p>'; if (!empty($lines[$vv])) { $row .= '<ul class="list-unstyled">'; foreach ($lines[$vv] as $line) { @@ -501,19 +502,6 @@ class PagePositionMap return $table; } - /** - * Wrapping the column header - * - * @param string $str Header value - * @param string $vv Column info. - * @return string - * @see printRecordMap() - */ - public function wrapColumnHeader($str, $vv) - { - return $str; - } - /** * Creates a linked position icon. * @@ -568,18 +556,6 @@ class PagePositionMap return $this->clientContext . '.location.href=' . GeneralUtility::quoteJSvalue((string)$location) . ';return false;'; } - /** - * Wrapping the record header (from getRecordHeader()) - * - * @param string $str HTML content - * @param string $row Record array. - * @return string HTML content - */ - public function wrapRecordHeader($str, $row) - { - return $str; - } - /** * Create record header (includes the record icon, record title etc.) *