‪TYPO3CMS  11.5
NewRecordController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
29 use TYPO3\CMS\Backend\Utility\BackendUtility;
39 use TYPO3\CMS\Core\Package\PackageManager;
40 use TYPO3\CMS\Core\Page\PageRenderer;
46 
52 {
56  protected ‪$pageinfo = [];
57 
61  protected ‪$pidInfo = [];
62 
67 
68  protected bool ‪$newPagesInto = false;
69  protected bool ‪$newContentInto = false;
70  protected bool ‪$newPagesAfter = false;
71 
77  protected ‪$newPagesSelectPosition = true;
78 
82  protected ‪$allowedNewTables;
83 
87  protected ‪$deniedNewTables;
88 
95  public ‪$id;
96 
100  protected ‪$returnUrl;
101 
105  protected ‪$perms_clause;
106 
112  protected ‪$content;
113 
117  protected ‪$tRows = [];
118 
124  protected ‪$moduleTemplate;
125 
129  protected ‪$view;
130 
131  protected PageRenderer ‪$pageRenderer;
133  protected ‪UriBuilder ‪$uriBuilder;
135 
136  public function ‪__construct(
138  PageRenderer ‪$pageRenderer,
141  ) {
142  $this->iconFactory = ‪$iconFactory;
143  $this->pageRenderer = ‪$pageRenderer;
144  $this->uriBuilder = ‪$uriBuilder;
145  $this->moduleTemplateFactory = ‪$moduleTemplateFactory;
146  }
147 
155  public function ‪mainAction(ServerRequestInterface $request): ResponseInterface
156  {
157  // Redirect if there is still a link with ?pagesOnly=1
158  if ($request->getQueryParams()['pagesOnly'] ?? null) {
159  $uri = $this->uriBuilder->buildUriFromRoute('db_new_pages', ['id' => (int)($request->getQueryParams()['id'] ?? 0), 'returnUrl' => $request->getQueryParams()['returnUrl'] ?? null]);
160  return new ‪RedirectResponse($uri, 301);
161  }
162 
163  $this->‪initializeView('NewRecord');
164  $this->‪init($request);
165 
166  // If there was a page - or if the user is admin (admins has access to the root) we proceed, otherwise just output the header
167  if (empty($this->pageinfo['uid']) && !$this->‪getBackendUserAuthentication()->isAdmin()) {
168  $this->moduleTemplate->setContent($this->view->render());
169  return new HtmlResponse($this->moduleTemplate->renderContent());
170  }
171 
173 
174  // Setting up the buttons and markers for docheader (done after permissions are checked)
175  $this->‪getButtons();
176  // Build the <body> for the module
177  $this->moduleTemplate->setContent($this->view->render());
178  return new ‪HtmlResponse($this->moduleTemplate->renderContent());
179  }
180 
184  public function ‪newPageAction(ServerRequestInterface $request): ResponseInterface
185  {
186  $this->‪initializeView('NewPagePosition');
187  $this->‪init($request);
188 
189  // If there was a page - or if the user is admin (admins has access to the root) we proceed, otherwise just output the header
190  if ((empty($this->pageinfo['uid']) && !$this->‪getBackendUserAuthentication()->isAdmin()) || !$this->‪isRecordCreationAllowedForTable('pages')) {
191  $this->moduleTemplate->setContent($this->view->render());
192  return new ‪HtmlResponse($this->moduleTemplate->renderContent());
193  }
194  if (!$this->‪doPageRecordsExistInSystem()) {
195  // No pages yet, no need to prompt for position, redirect to page creation.
196  $urlParameters = [
197  'edit' => [
198  'pages' => [
199  0 => 'new',
200  ],
201  ],
202  'returnNewPageId' => 1,
203  'returnUrl' => (string)$this->uriBuilder->buildUriFromRoute('db_new_pages', ['id' => $this->id]),
204  ];
205  $url = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
206  return new RedirectResponse($url);
207  }
208  $positionMap = GeneralUtility::makeInstance(PagePositionMap::class, NewRecordPageTreeView::class);
209  ‪$content = $positionMap->positionTree(
210  $this->id,
211  $this->pageinfo,
212  $this->perms_clause,
213  $this->returnUrl
214  );
215  $this->view->assign('pagePositionMapForPagesOnly', ‪$content);
216  // Setting up the buttons and markers for docheader (done after permissions are checked)
217  $this->‪getButtons(true);
218  // Build the <body> for the module
219  $this->moduleTemplate->setContent($this->view->render());
220  return new ‪HtmlResponse($this->moduleTemplate->renderContent());
221  }
222 
228  protected function ‪init(ServerRequestInterface $request): void
229  {
230  $this->moduleTemplate = $this->moduleTemplateFactory->create($request);
231  $this->‪getLanguageService()->‪includeLLFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
232  $beUser = $this->‪getBackendUserAuthentication();
233  // Page-selection permission clause (reading)
234  $this->perms_clause = $beUser->getPagePermsClause(‪Permission::PAGE_SHOW);
235  // This will hide records from display - it has nothing to do with user rights!!
236  $pidList = $beUser->getTSConfig()['options.']['hideRecords.']['pages'] ?? '';
237  if (!empty($pidList)) {
238  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
239  ->getQueryBuilderForTable('pages');
240  $this->perms_clause .= ' AND ' . $queryBuilder->expr()->notIn(
241  'pages.uid',
242  ‪GeneralUtility::intExplode(',', $pidList)
243  );
244  }
245  // Setting GPvars:
246  $parsedBody = $request->getParsedBody();
247  $queryParams = $request->getQueryParams();
248  // The page id to operate from
249  $this->id = (int)($parsedBody['id'] ?? $queryParams['id'] ?? 0);
250  $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
251  // Setting up the context sensitive menu:
252  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
253  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip');
254  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/PageActions');
255  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/NewContentElementWizardButton');
256  // Id a positive id is supplied, ask for the page record with permission information contained:
257  if ($this->id > 0) {
258  $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause) ?: [];
259  }
260  // If a page-record was returned, the user had read-access to the page.
261  if ($this->pageinfo['uid'] ?? false) {
262  // Get record of parent page
263  $this->pidInfo = BackendUtility::getRecord('pages', ($this->pageinfo['pid'] ?? 0)) ?? [];
264  // Checking the permissions for the user with regard to the parent page: Can he create new pages, new
265  // content record, new page after?
266  if ($beUser->doesUserHaveAccess($this->pageinfo, ‪Permission::PAGE_NEW)) {
267  $this->newPagesInto = true;
268  }
269  if ($beUser->doesUserHaveAccess($this->pageinfo, ‪Permission::CONTENT_EDIT)) {
270  $this->newContentInto = true;
271  }
272  if (($beUser->isAdmin() || !empty($this->pidInfo)) && $beUser->doesUserHaveAccess($this->pidInfo, ‪Permission::PAGE_NEW)) {
273  $this->newPagesAfter = true;
274  }
275  $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($this->pageinfo);
276  } elseif ($beUser->isAdmin()) {
277  // Admins can do it all
278  $this->newPagesInto = true;
279  $this->newContentInto = true;
280  $this->newPagesAfter = false;
281  } else {
282  // People with no permission can do nothing
283  $this->newPagesInto = false;
284  $this->newContentInto = false;
285  $this->newPagesAfter = false;
286  }
287  if ($this->pageinfo['uid'] ?? false) {
288  $title = strip_tags($this->pageinfo[‪$GLOBALS['TCA']['pages']['ctrl']['label']]);
289  } else {
290  $title = ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
291  }
292  $this->moduleTemplate->setTitle($title);
293  // Acquiring TSconfig for this module/current page:
294  $web_list_modTSconfig = BackendUtility::getPagesTSconfig($this->pageinfo['uid'] ?? 0)['mod.']['web_list.'] ?? [];
295  $this->allowedNewTables = ‪GeneralUtility::trimExplode(',', $web_list_modTSconfig['allowedNewTables'] ?? '', true);
296  $this->deniedNewTables = ‪GeneralUtility::trimExplode(',', $web_list_modTSconfig['deniedNewTables'] ?? '', true);
297  // Acquiring TSconfig for this module/parent page
298  $web_list_modTSconfig_pid = BackendUtility::getPagesTSconfig($this->pageinfo['pid'] ?? 0)['mod.']['web_list.'] ?? [];
299  $allowedNewTables_pid = ‪GeneralUtility::trimExplode(',', $web_list_modTSconfig_pid['allowedNewTables'] ?? '', true);
300  $deniedNewTables_pid = ‪GeneralUtility::trimExplode(',', $web_list_modTSconfig_pid['deniedNewTables'] ?? '', true);
301  if (!$this->‪isRecordCreationAllowedForTable('pages')) {
302  $this->newPagesInto = false;
303  }
304  if (!$this->‪isRecordCreationAllowedForTable('pages', $allowedNewTables_pid, $deniedNewTables_pid)) {
305  $this->newPagesAfter = false;
306  }
307  }
308 
312  protected function ‪getButtons(bool $createPage = false): void
313  {
314  $lang = $this->‪getLanguageService();
315  $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
316  // Regular new element:
317  if (!$createPage) {
318  // New page
319  if ($this->‪isRecordCreationAllowedForTable('pages')) {
320  $newPageButton = $buttonBar->makeLinkButton()
321  ->setHref((string)$this->uriBuilder->buildUriFromRoute('db_new_pages', ['id' => $this->id, 'returnUrl' => $this->returnUrl]))
322  ->setTitle($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newPage'))
323  ->setShowLabelText(true)
324  ->setIcon($this->iconFactory->getIcon('actions-page-new', ‪Icon::SIZE_SMALL));
325  $buttonBar->addButton($newPageButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 20);
326  }
327  // CSH
328  $cshButton = $buttonBar->makeHelpButton()->setModuleName('xMOD_csh_corebe')->setFieldName('new_regular');
329  $buttonBar->addButton($cshButton);
330  } elseif ($this->‪isRecordCreationAllowedForTable('pages')) {
331  // Pages only wizard
332  $cshButton = $buttonBar->makeHelpButton()->setModuleName('xMOD_csh_corebe')->setFieldName('new_pages');
333  $buttonBar->addButton($cshButton);
334  }
335  // Back
336  if ($this->returnUrl) {
337  $returnButton = $buttonBar->makeLinkButton()
338  ->setHref($this->returnUrl)
339  ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
340  ->setShowLabelText(true)
341  ->setIcon($this->iconFactory->getIcon('actions-view-go-back', ‪Icon::SIZE_SMALL));
342  $buttonBar->addButton($returnButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 10);
343  }
344 
345  if ($this->pageinfo['uid'] ?? false) {
346  // View
347  $pagesTSconfig = BackendUtility::getPagesTSconfig($this->pageinfo['uid']);
348  if (isset($pagesTSconfig['TCEMAIN.']['preview.']['disableButtonForDokType'])) {
349  $excludeDokTypes = ‪GeneralUtility::intExplode(
350  ',',
351  $pagesTSconfig['TCEMAIN.']['preview.']['disableButtonForDokType'],
352  true
353  );
354  } else {
355  // exclude sysfolders and recycler by default
356  $excludeDokTypes = [
360  ];
361  }
362  if (!in_array((int)$this->pageinfo['doktype'], $excludeDokTypes, true)) {
363  $previewDataAttributes = ‪PreviewUriBuilder::create((int)$this->pageinfo['uid'])
364  ->withRootLine(BackendUtility::BEgetRootLine($this->pageinfo['uid']))
365  ->buildDispatcherDataAttributes();
366  $viewButton = $buttonBar->makeLinkButton()
367  ->setHref('#')
368  ->setDataAttributes($previewDataAttributes ?? [])
369  ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showPage'))
370  ->setIcon($this->iconFactory->getIcon(
371  'actions-view-page',
373  ));
374  $buttonBar->addButton($viewButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 30);
375  }
376  }
377  }
378 
379  protected function ‪doPageRecordsExistInSystem(): bool
380  {
381  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
382  ->getQueryBuilderForTable('pages');
383  $queryBuilder->getRestrictions()
384  ->removeAll()
385  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
386  $numberOfPages = $queryBuilder
387  ->count('*')
388  ->from('pages')
389  ->executeQuery()
390  ->fetchOne();
391  return $numberOfPages > 0;
392  }
393 
397  protected function ‪renderNewRecordControls(): void
398  {
399  $lang = $this->‪getLanguageService();
400  // Get TSconfig for current page
401  $pageTS = BackendUtility::getPagesTSconfig($this->id);
402  // Finish initializing new pages options with TSconfig
403  // Each new page option may be hidden by TSconfig
404  // Enabled option for the position of a new page
405  $this->newPagesSelectPosition = !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageSelectPosition']);
406  $displayNewPagesIntoLink = $this->newPagesInto && !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageInside']);
407  $displayNewPagesAfterLink = $this->newPagesAfter && !empty($pageTS['mod.']['wizards.']['newRecord.']['pages.']['show.']['pageAfter']);
408  $iconFile = [
409  'backendaccess' => $this->iconFactory->getIcon('status-user-group-backend', ‪Icon::SIZE_SMALL)->render(),
410  'content' => $this->iconFactory->getIcon('content-panel', ‪Icon::SIZE_SMALL)->render(),
411  'frontendaccess' => $this->iconFactory->getIcon('status-user-group-frontend', ‪Icon::SIZE_SMALL)->render(),
412  'system' => $this->iconFactory->getIcon('apps-pagetree-root', ‪Icon::SIZE_SMALL)->render(),
413  ];
414  $groupTitles = [
415  'backendaccess' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:recordgroup.backendaccess'),
416  'content' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:recordgroup.content'),
417  'frontendaccess' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:recordgroup.frontendaccess'),
418  'system' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:system_records'),
419  ];
420  $groupedLinksOnTop = [];
421  foreach (‪$GLOBALS['TCA'] ?? [] as $table => $v) {
422  switch ($table) {
423  // New page
424  case 'pages':
425  if (!$this->‪isRecordCreationAllowedForTable('pages')) {
426  break;
427  }
428  // New pages INSIDE this pages
429  $newPageLinks = [];
430  if ($displayNewPagesIntoLink
431  && $this->‪isTableAllowedOnPage('pages', $this->pageinfo)
432  ) {
433  // Create link to new page inside
434  $newPageLinks[] = $this->‪renderLink(
435  htmlspecialchars($lang->sL($v['ctrl']['title'])) . ' (' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:db_new.php.inside')) . ')',
436  $table,
437  $this->id
438  );
439  }
440  // New pages AFTER this pages
441  if ($displayNewPagesAfterLink
442  && $this->‪isTableAllowedOnPage('pages', $this->pidInfo)
443  ) {
444  $newPageLinks[] = $this->‪renderLink(
445  htmlspecialchars($lang->sL($v['ctrl']['title'])) . ' (' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:db_new.php.after')) . ')',
446  'pages',
447  -$this->id
448  );
449  }
450  // New pages at selection position
451  if ($this->newPagesSelectPosition) {
452  // Link to page-wizard
453  $newPageLinks[] = $this->‪renderPageSelectPositionLink();
454  }
455  if (!empty($newPageLinks)) {
456  $groupedLinksOnTop['pages'] = [
457  'title' => $lang->getLL('createNewPage'),
458  'icon' => 'actions-page-new',
459  'items' => $newPageLinks,
460  ];
461  }
462  break;
463  case 'tt_content':
464  if (!$this->newContentInto || !$this->‪isRecordCreationAllowedForTable($table) || !$this->‪isTableAllowedOnPage($table, $this->pageinfo)) {
465  break;
466  }
467  $groupedLinksOnTop['tt_content'] = [
468  'title' => $lang->getLL('createNewContent'),
469  'icon' => 'actions-document-new',
470  'items' => [
471  $this->‪renderLink(htmlspecialchars($lang->sL($v['ctrl']['title'])), $table, $this->id),
473  ],
474  ];
475  break;
476  default:
477  if (!$this->newContentInto || !$this->‪isRecordCreationAllowedForTable($table) || !$this->‪isTableAllowedOnPage($table, $this->pageinfo)) {
478  break;
479  }
480  $nameParts = explode('_', $table);
481  $groupName = $v['ctrl']['groupName'] ?? null;
482  $title = (string)($v['ctrl']['title'] ?? '');
483  if (!isset($iconFile[$groupName]) || $nameParts[0] === 'tx' || $nameParts[0] === 'tt') {
484  $groupName = $groupName ?? $nameParts[1] ?? null;
485  // Try to extract extension name
486  if ($groupName) {
487  $_EXTKEY = '';
488  $titleIsTranslatableLabel = str_starts_with($title, 'LLL:EXT:');
489  if ($titleIsTranslatableLabel) {
490  // In case the title is a locallang reference, we can simply
491  // extract the extension name from the given extension path.
492  $_EXTKEY = substr($title, 8);
493  $_EXTKEY = substr($_EXTKEY, 0, (int)strpos($_EXTKEY, '/'));
494  } elseif (‪ExtensionManagementUtility::isLoaded($groupName)) {
495  // In case $title is not a locallang reference, we check the groupName to
496  // be a valid extension key. This most probably work since by convention the
497  // first part after tx_ / tt_ is the extension key.
498  $_EXTKEY = $groupName;
499  }
500  // Fetch the group title from the extension name
501  if ($_EXTKEY !== '') {
502  // Try to get the extension title
503  $package = GeneralUtility::makeInstance(PackageManager::class)->getPackage($_EXTKEY);
504  $groupTitle = $lang->sL('LLL:EXT:' . $_EXTKEY . '/Resources/Private/Language/locallang_db.xlf:extension.title');
505  // If no localisation available, read title from the Package MetaData
506  if (!$groupTitle) {
507  $groupTitle = $package->getPackageMetaData()->getTitle();
508  }
509  $extensionIcon = ‪ExtensionManagementUtility::getExtensionIcon($package->getPackagePath());
510  if (!empty($extensionIcon)) {
512  $package->getPackagePath(),
513  true
514  )) . '" width="16" height="16" alt="' . $groupTitle . '" />';
515  }
516  if (!empty($groupTitle)) {
517  $groupTitles[$groupName] = $groupTitle;
518  } else {
519  $groupTitles[$groupName] = ucwords($_EXTKEY);
520  }
521  }
522  } else {
523  // Fall back to "system" in case no $groupName could be found
524  $groupName = 'system';
525  }
526  }
527  $this->tRows[$groupName]['title'] = $this->tRows[$groupName]['title'] ?? $groupTitles[$groupName] ?? $nameParts[1] ?? $title;
528  $this->tRows[$groupName]['icon'] = $this->tRows[$groupName]['icon'] ?? $iconFile[$groupName] ?? $iconFile['system'] ?? '';
529  $this->tRows[$groupName]['html'][$table] = $this->‪renderLink(htmlspecialchars($lang->sL($v['ctrl']['title'])), $table, $this->id);
530  }
531  }
532  // User sort
533  if (isset($pageTS['mod.']['wizards.']['newRecord.']['order'])) {
534  $this->newRecordSortList = ‪GeneralUtility::trimExplode(',', $pageTS['mod.']['wizards.']['newRecord.']['order'], true);
535  }
536  uksort($this->tRows, [$this, 'sortTableRows']);
537  $this->view->assign('groupedLinksOnTop', $groupedLinksOnTop);
538  $this->view->assign('recordTypeGroups', $this->tRows);
539  }
540 
548  protected function ‪sortTableRows(string $a, string $b): int
549  {
550  if (!empty($this->newRecordSortList)) {
551  if (in_array($a, $this->newRecordSortList) && in_array($b, $this->newRecordSortList)) {
552  // Both are in the list, return relative to position in array
553  $sub = array_search($a, $this->newRecordSortList) - array_search($b, $this->newRecordSortList);
554  $ret = ($sub < 0 ? -1 : $sub == 0) ? 0 : 1;
555  } elseif (in_array($a, $this->newRecordSortList)) {
556  // First element is in array, put to top
557  $ret = -1;
558  } elseif (in_array($b, $this->newRecordSortList)) {
559  // Second element is in array, put first to bottom
560  $ret = 1;
561  } else {
562  // No element is in array, return alphabetic order
563  $ret = strnatcasecmp($this->tRows[$a]['title'] ?? '', $this->tRows[$b]['title'] ?? '');
564  }
565  return $ret;
566  }
567  // Return alphabetic order
568  return strnatcasecmp($this->tRows[$a]['title'] ?? '', $this->tRows[$b]['title'] ?? '');
569  }
570 
579  protected function ‪renderLink(string $linkText, string $table, int $pid): string
580  {
581  $recordLink = (string)$this->uriBuilder->buildUriFromRoute(
582  'record_edit',
583  [
584  'edit' => [
585  $table => [
586  $pid => 'new',
587  ],
588  ],
589  'returnUrl' => $this->returnUrl,
590  ]
591  );
592  return '
593  <a class="list-group-item list-group-item-action" href="' . htmlspecialchars($recordLink) . '">
594  ' . $this->iconFactory->getIconForRecord($table, [], ‪Icon::SIZE_SMALL)->render() . '
595  ' . $linkText . '
596  </a>';
597  }
598 
602  protected function ‪renderPageSelectPositionLink(): string
603  {
604  $url = (string)$this->uriBuilder->buildUriFromRoute(
605  'db_new_pages',
606  [
607  'id' => $this->id,
608  'returnUrl' => $this->returnUrl,
609  ]
610  );
611  return '
612  <a href="' . htmlspecialchars($url) . '" class="list-group-item list-group-item-action">
613  ' . $this->iconFactory->getIconForRecord('pages', [], ‪Icon::SIZE_SMALL)->render() . '
614  ' . htmlspecialchars($this->‪getLanguageService()->getLL('pageSelectPosition')) . '
615  </a>';
616  }
617 
621  protected function ‪renderNewContentElementWizardLink(): string
622  {
623  // If mod.newContentElementWizard.override is set, use that extension's wizard instead:
624  $moduleName = BackendUtility::getPagesTSconfig($this->id)['mod.']['newContentElementWizard.']['override'] ?? 'new_content_element_wizard';
625  $url = (string)$this->uriBuilder->buildUriFromRoute($moduleName, ['id' => $this->id, 'returnUrl' => $this->returnUrl]);
626  $title = $this->‪getLanguageService()->‪getLL('newContentElement');
627  return '
628  <typo3-backend-new-content-element-wizard-button url="' . htmlspecialchars($url) . '" title="' . htmlspecialchars($title) . '">
629  <button type="button" class="list-group-item list-group-item-action border-top-0">
630  ' . $this->iconFactory->getIcon('actions-document-new', ‪Icon::SIZE_SMALL)->render() . '
631  ' . htmlspecialchars($this->‪getLanguageService()->getLL('clickForWizard')) . '
632  </button>
633  </typo3-backend-new-content-element-wizard-button>';
634  }
635 
643  protected function ‪isTableAllowedOnPage(string $table, array $page): bool
644  {
645  $rootLevelConfiguration = (int)(‪$GLOBALS['TCA'][$table]['ctrl']['rootLevel'] ?? 0);
646  $rootLevelConstraintMatches = $rootLevelConfiguration === -1 || ($this->id xor $rootLevelConfiguration);
647  if (empty($page)) {
648  return $rootLevelConstraintMatches && $this->‪getBackendUserAuthentication()->‪isAdmin();
649  }
650  if (!$this->‪getBackendUserAuthentication()->workspaceCanCreateNewRecord($table)) {
651  return false;
652  }
653  // Checking doktype
654  $doktype = (int)$page['doktype'];
655  $allowedTableList = ‪$GLOBALS['PAGES_TYPES'][$doktype]['allowedTables'] ?? ‪$GLOBALS['PAGES_TYPES']['default']['allowedTables'] ?? '';
656  // If all tables or the table is listed as an allowed type, return TRUE
657  return $rootLevelConstraintMatches && (str_contains($allowedTableList, '*') || GeneralUtility::inList($allowedTableList, $table));
658  }
659 
676  protected function ‪isRecordCreationAllowedForTable(string $table, array ‪$allowedNewTables = [], array ‪$deniedNewTables = []): bool
677  {
678  if (!$this->‪getBackendUserAuthentication()->check('tables_modify', $table)) {
679  return false;
680  }
681 
682  $ctrl = ‪$GLOBALS['TCA'][$table]['ctrl'];
683  if (($ctrl['readOnly'] ?? false)
684  || ($ctrl['hideTable'] ?? false)
685  || ($ctrl['is_static'] ?? false)
686  || (($ctrl['adminOnly'] ?? false) && !$this->‪getBackendUserAuthentication()->isAdmin())
687  ) {
688  return false;
689  }
690 
693  // No deny/allow tables are set:
694  if (empty(‪$allowedNewTables) && empty(‪$deniedNewTables)) {
695  return true;
696  }
697 
698  return !in_array($table, ‪$deniedNewTables) && (empty(‪$allowedNewTables) || in_array($table, ‪$allowedNewTables));
699  }
700 
706  protected function ‪initializeView(string $templateName): void
707  {
708  $this->view = GeneralUtility::makeInstance(StandaloneView::class);
709  $this->view->setTemplate($templateName);
710  $this->view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']);
711  $this->view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']);
712  $this->view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']);
713  }
714 
718  protected function ‪getLanguageService(): ‪LanguageService
719  {
720  return ‪$GLOBALS['LANG'];
721  }
722 
727  {
728  return ‪$GLOBALS['BE_USER'];
729  }
730 }
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:30
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Backend\Controller\NewRecordController\$id
‪int $id
Definition: NewRecordController.php:88
‪TYPO3\CMS\Backend\Controller\NewRecordController\$moduleTemplateFactory
‪ModuleTemplateFactory $moduleTemplateFactory
Definition: NewRecordController.php:121
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪TYPO3\CMS\Backend\Template\Components\ButtonBar\BUTTON_POSITION_LEFT
‪const BUTTON_POSITION_LEFT
Definition: ButtonBar.php:36
‪TYPO3\CMS\Backend\Template\Components\ButtonBar
Definition: ButtonBar.php:32
‪TYPO3\CMS\Backend\Controller\NewRecordController\$newPagesAfter
‪bool $newPagesAfter
Definition: NewRecordController.php:67
‪TYPO3\CMS\Backend\Controller\NewRecordController\renderNewRecordControls
‪renderNewRecordControls()
Definition: NewRecordController.php:384
‪TYPO3\CMS\Backend\Controller\NewRecordController\renderLink
‪string renderLink(string $linkText, string $table, int $pid)
Definition: NewRecordController.php:566
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_NEW
‪const PAGE_NEW
Definition: Permission.php:50
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder\create
‪static static create(int $pageId, string $alternativeUri=null)
Definition: PreviewUriBuilder.php:75
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:26
‪TYPO3\CMS\Backend\Template\ModuleTemplateFactory
Definition: ModuleTemplateFactory.php:29
‪TYPO3\CMS\Backend\Controller\NewRecordController\getLanguageService
‪LanguageService getLanguageService()
Definition: NewRecordController.php:705
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isAdmin
‪bool isAdmin()
Definition: BackendUserAuthentication.php:245
‪TYPO3\CMS\Backend\Controller\NewRecordController\newPageAction
‪newPageAction(ServerRequestInterface $request)
Definition: NewRecordController.php:171
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Backend\Controller\NewRecordController\getButtons
‪getButtons(bool $createPage=false)
Definition: NewRecordController.php:299
‪TYPO3\CMS\Backend\Controller\NewRecordController\isTableAllowedOnPage
‪bool isTableAllowedOnPage(string $table, array $page)
Definition: NewRecordController.php:630
‪TYPO3\CMS\Backend\Controller\NewRecordController\$returnUrl
‪string $returnUrl
Definition: NewRecordController.php:92
‪TYPO3\CMS\Backend\Controller\NewRecordController\$view
‪StandaloneView $view
Definition: NewRecordController.php:116
‪TYPO3\CMS\Backend\Template\ModuleTemplate
Definition: ModuleTemplate.php:46
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Backend\Controller\NewRecordController\$pageRenderer
‪PageRenderer $pageRenderer
Definition: NewRecordController.php:118
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:43
‪TYPO3\CMS\Backend\Controller\NewRecordController
Definition: NewRecordController.php:52
‪TYPO3\CMS\Backend\Controller\NewRecordController\$deniedNewTables
‪array $deniedNewTables
Definition: NewRecordController.php:81
‪TYPO3\CMS\Backend\Controller\NewRecordController\renderNewContentElementWizardLink
‪renderNewContentElementWizardLink()
Definition: NewRecordController.php:608
‪TYPO3\CMS\Backend\Controller\NewRecordController\$pageinfo
‪array $pageinfo
Definition: NewRecordController.php:55
‪TYPO3\CMS\Backend\Controller\NewRecordController\$moduleTemplate
‪ModuleTemplate $moduleTemplate
Definition: NewRecordController.php:112
‪TYPO3\CMS\Backend\Controller\NewRecordController\$uriBuilder
‪UriBuilder $uriBuilder
Definition: NewRecordController.php:120
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:40
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap
Definition: PagePositionMap.php:36
‪TYPO3\CMS\Backend\Controller\NewRecordController\renderPageSelectPositionLink
‪renderPageSelectPositionLink()
Definition: NewRecordController.php:589
‪TYPO3\CMS\Backend\Tree\View\NewRecordPageTreeView
Definition: NewRecordPageTreeView.php:25
‪TYPO3\CMS\Backend\Controller\NewRecordController\$newPagesSelectPosition
‪bool $newPagesSelectPosition
Definition: NewRecordController.php:73
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SPACER
‪const DOKTYPE_SPACER
Definition: PageRepository.php:115
‪TYPO3\CMS\Backend\Controller\NewRecordController\sortTableRows
‪int sortTableRows(string $a, string $b)
Definition: NewRecordController.php:535
‪TYPO3\CMS\Backend\Controller\NewRecordController\mainAction
‪ResponseInterface mainAction(ServerRequestInterface $request)
Definition: NewRecordController.php:142
‪TYPO3\CMS\Backend\Controller\NewRecordController\doPageRecordsExistInSystem
‪doPageRecordsExistInSystem()
Definition: NewRecordController.php:366
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SYSFOLDER
‪const DOKTYPE_SYSFOLDER
Definition: PageRepository.php:116
‪TYPO3\CMS\Backend\Controller\NewRecordController\initializeView
‪initializeView(string $templateName)
Definition: NewRecordController.php:693
‪TYPO3\CMS\Core\Http\RedirectResponse
Definition: RedirectResponse.php:28
‪TYPO3\CMS\Backend\Controller\NewRecordController\getBackendUserAuthentication
‪BackendUserAuthentication getBackendUserAuthentication()
Definition: NewRecordController.php:713
‪TYPO3\CMS\Backend\Controller\NewRecordController\init
‪init(ServerRequestInterface $request)
Definition: NewRecordController.php:215
‪TYPO3\CMS\Fluid\View\StandaloneView
Definition: StandaloneView.php:31
‪TYPO3\CMS\Core\Type\Bitmask\Permission\CONTENT_EDIT
‪const CONTENT_EDIT
Definition: Permission.php:55
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder
Definition: PreviewUriBuilder.php:32
‪TYPO3\CMS\Backend\Controller\NewRecordController\$newRecordSortList
‪array $newRecordSortList
Definition: NewRecordController.php:63
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static int[] intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:927
‪TYPO3\CMS\Backend\Controller\NewRecordController\$pidInfo
‪array $pidInfo
Definition: NewRecordController.php:59
‪TYPO3\CMS\Backend\Controller\NewRecordController\$iconFactory
‪IconFactory $iconFactory
Definition: NewRecordController.php:119
‪TYPO3\CMS\Backend\Controller\NewRecordController\$newContentInto
‪bool $newContentInto
Definition: NewRecordController.php:66
‪TYPO3\CMS\Core\Localization\LanguageService\includeLLFile
‪array includeLLFile($fileRef)
Definition: LanguageService.php:271
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Backend\Controller\NewRecordController\$newPagesInto
‪bool $newPagesInto
Definition: NewRecordController.php:65
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:53
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\getExtensionIcon
‪static string getExtensionIcon($extensionPath, $returnFullPath=false)
Definition: ExtensionManagementUtility.php:1482
‪TYPO3\CMS\Backend\Controller\NewRecordController\isRecordCreationAllowedForTable
‪bool isRecordCreationAllowedForTable(string $table, array $allowedNewTables=[], array $deniedNewTables=[])
Definition: NewRecordController.php:663
‪TYPO3\CMS\Core\Utility\PathUtility\getAbsoluteWebPath
‪static string getAbsoluteWebPath($targetPath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:51
‪TYPO3\CMS\Core\Localization\LanguageService\getLL
‪string getLL($index)
Definition: LanguageService.php:121
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Controller\NewRecordController\$content
‪string $content
Definition: NewRecordController.php:102
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static bool isLoaded($key)
Definition: ExtensionManagementUtility.php:114
‪TYPO3\CMS\Backend\Controller\NewRecordController\$tRows
‪array $tRows
Definition: NewRecordController.php:106
‪TYPO3\CMS\Backend\Controller
Definition: AboutController.php:16
‪TYPO3\CMS\Backend\Controller\NewRecordController\__construct
‪__construct(IconFactory $iconFactory, PageRenderer $pageRenderer, UriBuilder $uriBuilder, ModuleTemplateFactory $moduleTemplateFactory)
Definition: NewRecordController.php:123
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_RECYCLER
‪const DOKTYPE_RECYCLER
Definition: PageRepository.php:117
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:26
‪TYPO3\CMS\Backend\Controller\NewRecordController\$perms_clause
‪string $perms_clause
Definition: NewRecordController.php:96
‪TYPO3\CMS\Backend\Controller\NewRecordController\$allowedNewTables
‪array $allowedNewTables
Definition: NewRecordController.php:77