Commit 62be6503 authored by Benni Mack's avatar Benni Mack Committed by Georg Ringer
Browse files

[TASK] Clean up Move Element Controller

This change

* Streamlines Controller Code
* Avoids unneeded Fluid assigns
* Uses strict typing

Resolves: #94604
Releases: master
Change-Id: I91035f9c70e4df80c443e3a45f044f10c28fdb27
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69722

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
parent 2ea7f0c5
......@@ -41,61 +41,15 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
*/
class MoveElementController
{
/**
* @var int
*/
protected $sys_language = 0;
/**
* @var int
*/
protected $page_id;
protected int $sys_language = 0;
protected int $page_id = 0;
protected string $table = '';
protected string $R_URI = '';
protected int $moveUid = 0;
protected int $makeCopy = 0;
protected string $perms_clause = '';
/**
* @var string
*/
protected $table;
/**
* @var string
*/
protected $R_URI;
/**
* @var int
*/
protected $input_moveUid;
/**
* @var int
*/
protected $moveUid;
/**
* @var int
*/
protected $makeCopy;
/**
* Pages-select clause
*
* @var string
*/
protected $perms_clause;
/**
* Content for module accumulated here.
*
* @var string
*/
protected $content;
/**
* ModuleTemplate object
*
* @var ModuleTemplate
*/
protected $moduleTemplate;
protected ?ModuleTemplate $moduleTemplate = null;
protected IconFactory $iconFactory;
protected PageRenderer $pageRenderer;
......@@ -111,70 +65,59 @@ class MoveElementController
$this->moduleTemplateFactory = $moduleTemplateFactory;
}
/**
* Injects the request object for the current request or subrequest
* As this controller goes only through the main() method, it is rather simple for now
*
* @param ServerRequestInterface $request the current request
* @return ResponseInterface the response with the content
*/
public function mainAction(ServerRequestInterface $request): ResponseInterface
{
$this->moduleTemplate = $this->moduleTemplateFactory->create($request);
$this->getLanguageService()->includeLLFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
$this->init($request);
$this->renderContent();
return new HtmlResponse($this->content);
}
/**
* Constructor, initializing internal variables.
*
* @param ServerRequestInterface $request
*/
protected function init(ServerRequestInterface $request)
{
$parsedBody = $request->getParsedBody();
$queryParams = $request->getQueryParams();
// Setting internal vars:
$this->sys_language = (int)($parsedBody['sys_language'] ?? $queryParams['sys_language'] ?? 0);
$this->page_id = (int)($parsedBody['uid'] ?? $queryParams['uid'] ?? 0);
$this->table = $parsedBody['table'] ?? $queryParams['table'] ?? null;
$this->table = (string)($parsedBody['table'] ?? $queryParams['table'] ?? '');
$this->R_URI = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
$this->input_moveUid = $parsedBody['moveUid'] ?? $queryParams['moveUid'] ?? null;
$this->moveUid = $this->input_moveUid ?: $this->page_id;
$this->makeCopy = $parsedBody['makeCopy'] ?? $queryParams['makeCopy'] ?? 0;
// Select-pages where clause for read-access:
$this->moveUid = (int)(($parsedBody['moveUid'] ?? $queryParams['moveUid'] ?? false) ?: $this->page_id);
$this->makeCopy = (int)($parsedBody['makeCopy'] ?? $queryParams['makeCopy'] ?? 0);
// Select-pages where clause for read-access
$this->perms_clause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW);
// Setting up the buttons and markers for docheader
$this->getButtons();
// Build the <body> for the module
$this->moduleTemplate->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:movingElement'));
$this->moduleTemplate->setContent($this->renderContent());
return new HtmlResponse($this->moduleTemplate->renderContent());
}
/**
* Creating the module output.
*/
protected function renderContent(): void
protected function renderContent(): string
{
$lang = $this->getLanguageService();
if ($this->page_id) {
$assigns = [];
$backendUser = $this->getBackendUser();
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip');
// Get record for element:
$elRow = BackendUtility::getRecordWSOL($this->table, $this->moveUid);
// Headerline: Icon, record title:
$assigns['table'] = $this->table;
$assigns['elRow'] = $elRow;
$assigns['recordTooltip'] = BackendUtility::getRecordToolTip($elRow, $this->table);
$assigns['recordTitle'] = BackendUtility::getRecordTitle($this->table, $elRow, true);
// Make-copy checkbox (clicking this will reload the page with the GET var makeCopy set differently):
$assigns['makeCopyChecked'] = $this->makeCopy ? ' checked="checked"' : '';
$assigns['makeCopyUrl'] = GeneralUtility::linkThisScript(['makeCopy' => !$this->makeCopy]);
// IF the table is "pages":
if ((string)$this->table === 'pages') {
// Get page record (if accessible):
$pageInfo = BackendUtility::readPageAccess($this->page_id, $this->perms_clause);
if (is_array($pageInfo) && $backendUser->isInWebMount($pageInfo['pid'], $this->perms_clause)) {
if (!$this->page_id) {
return '';
}
$assigns = [];
$backendUser = $this->getBackendUser();
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip');
// Get record for element:
$elRow = BackendUtility::getRecordWSOL($this->table, $this->moveUid);
// Headerline: Icon, record title:
$assigns['table'] = $this->table;
$assigns['elRow'] = $elRow;
$assigns['recordTooltip'] = BackendUtility::getRecordToolTip($elRow, $this->table);
$assigns['recordTitle'] = BackendUtility::getRecordTitle($this->table, $elRow, true);
// Make-copy checkbox (clicking this will reload the page with the GET var makeCopy set differently):
$assigns['makeCopyChecked'] = (bool)$this->makeCopy;
$assigns['makeCopyUrl'] = GeneralUtility::linkThisScript(['makeCopy' => !$this->makeCopy]);
// Get page record (if accessible):
if ($this->table !== 'pages' && $this->moveUid === $this->page_id) {
$this->page_id = $elRow['pid'];
}
$pageInfo = BackendUtility::readPageAccess($this->page_id, $this->perms_clause);
$assigns['pageInfo'] = $pageInfo;
if (is_array($pageInfo) && $backendUser->isInWebMount($pageInfo['pid'], $this->perms_clause)) {
switch ($this->table) {
case 'pages':
// Initialize the position map:
$posMap = GeneralUtility::makeInstance(PageMovingPagePositionMap::class);
$posMap->moveOrCopy = $this->makeCopy ? 'copy' : 'move';
......@@ -184,38 +127,26 @@ class MoveElementController
$pidPageInfo = BackendUtility::readPageAccess($pageInfo['pid'], $this->perms_clause);
if (is_array($pidPageInfo)) {
if ($backendUser->isInWebMount($pidPageInfo['pid'], $this->perms_clause)) {
$assigns['pages']['goUpUrl'] = GeneralUtility::linkThisScript([
$assigns['goUpUrl'] = GeneralUtility::linkThisScript([
'uid' => (int)$pageInfo['pid'],
'moveUid' => $this->moveUid
]);
} else {
$assigns['pages']['pidPageInfo'] = $pidPageInfo;
$assigns['pidPageInfo'] = $pidPageInfo;
}
$assigns['pages']['pidRecordTitle'] = BackendUtility::getRecordTitle('pages', $pidPageInfo, true);
$assigns['pidRecordTitle'] = BackendUtility::getRecordTitle('pages', $pidPageInfo, true);
}
}
// Create the position tree:
$assigns['pages']['positionTree'] = $posMap->positionTree($this->page_id, $pageInfo, $this->perms_clause, $this->R_URI);
}
}
// IF the table is "tt_content":
if ((string)$this->table === 'tt_content') {
// First, get the record:
$tt_content_rec = BackendUtility::getRecord('tt_content', $this->moveUid);
// ?
if (!$this->input_moveUid) {
$this->page_id = $tt_content_rec['pid'];
}
// Checking if the parent page is readable:
$pageInfo = BackendUtility::readPageAccess($this->page_id, $this->perms_clause);
if (is_array($pageInfo) && $backendUser->isInWebMount($pageInfo['pid'], $this->perms_clause)) {
$assigns['positionTree'] = $posMap->positionTree($this->page_id, $pageInfo, $this->perms_clause, $this->R_URI);
break;
case 'tt_content':
// Initialize the position map:
$posMap = GeneralUtility::makeInstance(ContentMovingPagePositionMap::class);
$posMap->moveOrCopy = $this->makeCopy ? 'copy' : 'move';
$posMap->moveUid = $this->moveUid;
$posMap->cur_sys_language = $this->sys_language;
// Headerline for the parent page: Icon, record title:
$assigns['ttContent']['pageInfo'] = $pageInfo;
$assigns['ttContent']['recordTooltip'] = BackendUtility::getRecordToolTip($pageInfo, 'pages');
$assigns['ttContent']['recordTitle'] = BackendUtility::getRecordTitle('pages', $pageInfo, true);
$colPosArray = GeneralUtility::callUserFunction(BackendLayoutView::class . '->getColPosListItemsParsed', $this->page_id, $this);
......@@ -226,44 +157,42 @@ class MoveElementController
// Removing duplicates, if any
$colPosList = implode(',', array_unique($colPosIds));
// Adding parent page-header and the content element columns from position-map:
$assigns['ttContent']['contentElementColumns'] = $posMap->printContentElementColumns($this->page_id, $this->moveUid, $colPosList, 1, $this->R_URI);
$assigns['contentElementColumns'] = $posMap->printContentElementColumns($this->page_id, $this->moveUid, $colPosList, $this->R_URI);
// Print a "go-up" link IF there is a real parent page (and if the user has read-access to that page).
if ($pageInfo['pid']) {
if ($pageInfo['pid'] > 0) {
$pidPageInfo = BackendUtility::readPageAccess($pageInfo['pid'], $this->perms_clause);
if (is_array($pidPageInfo)) {
if ($backendUser->isInWebMount($pidPageInfo['pid'], $this->perms_clause)) {
$assigns['ttContent']['goUpUrl'] = GeneralUtility::linkThisScript([
$assigns['goUpUrl'] = GeneralUtility::linkThisScript([
'uid' => (int)$pageInfo['pid'],
'moveUid' => $this->moveUid
]);
} else {
$assigns['ttContent']['pidPageInfo'] = $pidPageInfo;
$assigns['pidPageInfo'] = $pidPageInfo;
}
$assigns['ttContent']['pidRecordTitle'] = BackendUtility::getRecordTitle('pages', $pidPageInfo, true);
$assigns['pidRecordTitle'] = BackendUtility::getRecordTitle('pages', $pidPageInfo, true);
}
}
// Create the position tree (for pages):
$assigns['ttContent']['positionTree'] = $posMap->positionTree($this->page_id, $pageInfo, $this->perms_clause, $this->R_URI);
$assigns['positionTree'] = $posMap->positionTree($this->page_id, $pageInfo, $this->perms_clause, $this->R_URI);
}
}
// Rendering of the output via fluid
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
$view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
'EXT:backend/Resources/Private/Templates/ContentElement/MoveElement.html'
));
$view->assignMultiple($assigns);
$this->content .= $view->render();
}
// Setting up the buttons and markers for docheader
$this->getButtons();
// Build the <body> for the module
$this->moduleTemplate->setTitle($lang->getLL('movingElement'));
$this->moduleTemplate->setContent($this->content);
// Rendering of the output via fluid
$view = $this->initializeView();
$view->assignMultiple($assigns);
return $view->render();
}
$this->content = $this->moduleTemplate->renderContent();
protected function initializeView(): StandaloneView
{
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']);
$view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']);
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
'EXT:backend/Resources/Private/Templates/ContentElement/MoveElement.html'
));
return $view;
}
/**
......@@ -273,12 +202,12 @@ class MoveElementController
{
$buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
if ($this->page_id) {
if ((string)$this->table === 'pages') {
if ($this->table === 'pages') {
$cshButton = $buttonBar->makeHelpButton()
->setModuleName('xMOD_csh_corebe')
->setFieldName('move_el_pages');
$buttonBar->addButton($cshButton);
} elseif ((string)$this->table === 'tt_content') {
} elseif ($this->table === 'tt_content') {
$cshButton = $buttonBar->makeHelpButton()
->setModuleName('xMOD_csh_corebe')
->setFieldName('move_el_cs');
......@@ -288,24 +217,19 @@ class MoveElementController
if ($this->R_URI) {
$backButton = $buttonBar->makeLinkButton()
->setHref($this->R_URI)
->setTitle($this->getLanguageService()->getLL('goBack'))
->setShowLabelText(true)
->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:goBack'))
->setIcon($this->iconFactory->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
$buttonBar->addButton($backButton);
}
}
}
/**
* @return LanguageService
*/
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
/**
* @return BackendUserAuthentication
*/
protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
......
......@@ -336,7 +336,7 @@ class NewContentElementController
$clientContext
);
$posMap->cur_sys_language = $this->sys_language;
$this->view->assign('posMap', $posMap->printContentElementColumns($this->id, 0, $colPosList, 1, $this->R_URI));
$this->view->assign('posMap', $posMap->printContentElementColumns($this->id, 0, $colPosList, $this->R_URI));
}
/**
......
......@@ -29,13 +29,6 @@ class ContentMovingPagePositionMap extends PagePositionMap
*/
public $dontPrintPageInsertIcons = 1;
/**
* Page tree implementation class name
*
* @var string
*/
protected $pageTreeClassName = PageTreeView::class;
/**
* Wrapping page title.
*
......
......@@ -29,13 +29,6 @@ class PageMovingPagePositionMap extends PagePositionMap
*/
public $l_insertNewPageHere = 'movePageToHere';
/**
* Page tree implementation class name
*
* @var string
*/
protected $pageTreeClassName = PageTreeView::class;
/**
* Creates the onclick event for the insert-icons.
*
......
......@@ -350,11 +350,10 @@ class PagePositionMap
* @param int $pid page id onto which to insert content element.
* @param int $moveUid Move-uid (tt_content element uid?)
* @param string $colPosList List of columns to show
* @param bool $showHidden If not set, then hidden/starttime/endtime records are filtered out.
* @param string $R_URI Request URI
* @return string HTML
*/
public function printContentElementColumns($pid, $moveUid, $colPosList, $showHidden, $R_URI)
public function printContentElementColumns($pid, $moveUid, $colPosList, $R_URI)
{
$this->R_URI = $R_URI;
$this->moveUid = $moveUid;
......@@ -362,13 +361,11 @@ class PagePositionMap
$lines = [];
foreach ($colPosArray as $kk => $vv) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
$queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, (int)$this->getBackendUser()->workspace));
if ($showHidden) {
$queryBuilder->getRestrictions()
->removeByType(HiddenRestriction::class)
->removeByType(StartTimeRestriction::class)
->removeByType(EndTimeRestriction::class);
}
$queryBuilder->getRestrictions()
->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, (int)$this->getBackendUser()->workspace))
->removeByType(HiddenRestriction::class)
->removeByType(StartTimeRestriction::class)
->removeByType(EndTimeRestriction::class);
$queryBuilder
->select('*')
->from('tt_content')
......@@ -435,12 +432,12 @@ class PagePositionMap
}
$table .= '<tr>';
for ($col = 1; $col <= $colCount; $col++) {
$columnConfig = $rowConfig['columns.'][$col . '.'];
if (!isset($columnConfig)) {
$columnConfig = $rowConfig['columns.'][$col . '.'] ?? false;
if (!$columnConfig) {
continue;
}
// Which tt_content colPos should be displayed inside this cell
$columnKey = (int)$columnConfig['colPos'];
$columnKey = (int)($columnConfig['colPos'] ?? 0);
$head = '';
foreach ($tcaItems as $item) {
if ($item[1] == $columnKey) {
......@@ -458,7 +455,7 @@ class PagePositionMap
$table .= '<p>';
if (isset($columnConfig['colPos']) && $head) {
$table .= '<strong>' . $head . '</strong>';
} elseif ($columnConfig['colPos']) {
} elseif (isset($columnConfig['colPos'])) {
$table .= '<em>' . $this->getLanguageService()->getLL('noAccess') . '</em>';
} else {
$table .= '<em>' . ($this->getLanguageService()->sL($columnConfig['name']) ?: '') . ' (' . $this->getLanguageService()->getLL('notAssigned') . ')' . '</em>';
......
<h1><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:movingElement" /></h1>
<div>
<div class="mb-2" {recordTooltip}><core:iconForRecord table="{table}" row="{elRow}" />{recordTitle -> f:format.raw()}</div>
<div class="form-check">
<input type="checkbox" name="makeCopy" id="makeCopy" value="1" {makeCopyChecked} class="form-check-input"
<h3 class="mb-2">
<span {recordTooltip -> f:format.raw()}><core:iconForRecord table="{table}" row="{elRow}" /></span>
{recordTitle -> f:format.raw()}
</h3>
<div class="pt-2">
<div class="form-check form-switch">
<input type="checkbox" name="makeCopy" id="makeCopy" value="1" {f:if(condition: makeCopyChecked, then: 'checked')} class="form-check-input"
data-global-event="change" data-action-navigate="$data" data-navigate-value="{makeCopyUrl}">
<label for="makeCopy" class="form-check-label"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:makeCopy" /></label>
</div>
</div>
<h2><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:selectPositionOfElement" /></h2>
<div>
<f:if condition="{pages}">
<f:if condition="{pages.goUpUrl}">
<f:if condition="{table} == 'pages'">
<f:if condition="{goUpUrl}">
<f:then>
<a href="{pages.goUpUrl}"><core:icon identifier="actions-view-go-up" />{pages.pidRecordTitle -> f:format.raw()}</a><br />
<a href="{goUpUrl}"><core:icon identifier="actions-view-go-up" />{pidRecordTitle -> f:format.raw()}</a>
</f:then>
<f:else>
<f:if condition="{pages.pidPageInfo}">
<core:iconForRecord table="pages" row="{pages.pidPageInfo}" />
<f:if condition="{pidPageInfo}">
<core:iconForRecord table="pages" row="{pidPageInfo}" />
</f:if>
{pages.pidRecordTitle -> f:format.raw()}<br />
{pidRecordTitle -> f:format.raw()}
</f:else>
</f:if>
{pages.positionTree -> f:format.raw()}
</f:if>
<f:if condition="{ttContent}">
<span {ttContent.recordToolTip}><core:iconForRecord table="pages" row="{ttContent.pageInfo}" /></span>
<f:if condition="{table} == 'tt_content'">
<f:if condition="{pageInfo}">
<span {ttContent.recordTooltip -> f:format.raw()}><core:iconForRecord table="pages" row="{pageInfo}" /></span>
</f:if>
{ttContent.recordTitle}<br />
{ttContent.contentElementColumns -> f:format.raw()}<br /><br />
<f:if condition="{ttContent.pageInfo.pid}">
<f:if condition="{ttContent.goUpUrl}">
{contentElementColumns -> f:format.raw()}<br />
<f:if condition="{pageInfo.pid} > 0">
<f:if condition="{goUpUrl}">
<f:then>
<a href="{ttContent.goUpUrl}"><core:icon identifier="actions-view-go-up" />{ttContent.pidRecordTitle -> f:format.raw()}</a><br />
<a href="{goUpUrl}"><core:icon identifier="actions-view-go-up" />{pidRecordTitle -> f:format.raw()}</a>
</f:then>
<f:else>
<core:iconForRecord table="pages" row="{ttContent.pidPageInfo}" />
{ttContent.pidRecordTitle -> f:format.raw()}<br />
<core:iconForRecord table="pages" row="{pidPageInfo}" /> {pidRecordTitle -> f:format.raw()}
</f:else>
</f:if>
</f:if>
{ttContent.positionTree -> f:format.raw()}
</f:if>
</div>
{positionTree -> f:format.raw()}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment