From ac17522b7f465d8903fed011bf27694d8b21803e Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Wed, 12 Feb 2020 22:13:37 +0100 Subject: [PATCH] [TASK] Remove unused code in New CE Wizard / PagePositionMap There are a few places where unused options can be simplified, and the dependency on the PagePositionMap class can be placed in one dedicated method. Several guard clauses are useless due to method parameter types, and are cleaned up. This is a pre-patch to bring more functionality into New Content Element Wizard. Resolves: #90366 Releases: master Change-Id: I912efbe25f6ff79670f404d7f44dbad0993295db Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63211 Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> --- .../NewContentElementController.php | 216 ++++++++---------- .../View/ContentMovingPagePositionMap.php | 4 +- .../Classes/Tree/View/PagePositionMap.php | 38 +-- 3 files changed, 100 insertions(+), 158 deletions(-) diff --git a/typo3/sysext/backend/Classes/Controller/ContentElement/NewContentElementController.php b/typo3/sysext/backend/Classes/Controller/ContentElement/NewContentElementController.php index d0867a5ab663..b2647da33c70 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 30a4fa5e6a91..ea170169f446 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 c05152b336e2..0d353e498fb5 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.) * -- GitLab