‪TYPO3CMS  10.4
BackendLayoutRenderer.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\Log\LoggerAwareTrait;
44 
58 {
59  use LoggerAwareTrait;
60 
64  protected ‪$iconFactory;
65 
69  protected ‪$context;
70 
74  protected ‪$contentFetcher;
75 
79  protected ‪$clipboard;
80 
84  protected ‪$view;
85 
87  {
88  $this->context = ‪$context;
89  $this->contentFetcher = GeneralUtility::makeInstance(ContentFetcher::class, ‪$context);
90  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
91  $this->‪initializeClipboard();
92  $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
93  $controllerContext = $objectManager->get(ControllerContext::class);
94  $request = $objectManager->get(Request::class);
95  $controllerContext->setRequest($request);
96  $this->view = GeneralUtility::makeInstance(TemplateView::class);
97  $this->view->getRenderingContext()->setControllerContext($controllerContext);
98  $this->view->getRenderingContext()->getTemplatePaths()->fillDefaultsByPackageName('backend');
99  $this->view->getRenderingContext()->setControllerName('PageLayout');
100  $this->view->assign('context', ‪$context);
101  }
102 
104  {
105  $grid = GeneralUtility::makeInstance(Grid::class, ‪$context);
106  $recordRememberer = GeneralUtility::makeInstance(RecordRememberer::class);
107  if (‪$context->‪getDrawingConfiguration()->getLanguageMode()) {
108  $languageId = ‪$context->‪getSiteLanguage()->getLanguageId();
109  } else {
110  $languageId = ‪$context->‪getDrawingConfiguration()->getSelectedLanguageId();
111  }
112  foreach (‪$context->‪getBackendLayout()->getStructure()['__config']['backend_layout.']['rows.'] ?? [] as $row) {
113  $rowObject = GeneralUtility::makeInstance(GridRow::class, ‪$context);
114  foreach ($row['columns.'] as $column) {
115  $columnObject = GeneralUtility::makeInstance(GridColumn::class, ‪$context, $column);
116  $rowObject->addColumn($columnObject);
117  if (isset($column['colPos'])) {
118  $records = $this->contentFetcher->getContentRecordsPerColumn((int)$column['colPos'], $languageId);
119  $recordRememberer->rememberRecords($records);
120  foreach ($records as $contentRecord) {
121  $columnItem = GeneralUtility::makeInstance(GridColumnItem::class, ‪$context, $columnObject, $contentRecord);
122  $columnObject->addItem($columnItem);
123  }
124  }
125  }
126  $grid->addRow($rowObject);
127  }
128  return $grid;
129  }
130 
135  {
136  $languageColumns = [];
137  foreach (‪$context->‪getLanguagesToShow() as $siteLanguage) {
138  $localizedLanguageId = $siteLanguage->getLanguageId();
139  if ($localizedLanguageId === -1) {
140  continue;
141  }
142  if ($localizedLanguageId > 0) {
143  $localizedContext = ‪$context->‪cloneForLanguage($siteLanguage);
144  if (!$localizedContext->getLocalizedPageRecord()) {
145  continue;
146  }
147  } else {
148  $localizedContext = ‪$context;
149  }
150  $translationInfo = $this->contentFetcher->getTranslationData(
151  $this->contentFetcher->getFlatContentRecords($localizedLanguageId),
152  $localizedContext->getSiteLanguage()->getLanguageId()
153  );
154  $languageColumnObject = GeneralUtility::makeInstance(
155  LanguageColumn::class,
156  $localizedContext,
157  $this->‪getGridForPageLayoutContext($localizedContext),
158  $translationInfo
159  );
160  $languageColumns[] = $languageColumnObject;
161  }
162  return $languageColumns;
163  }
164 
166  {
167  $languageColumns = [];
168 
169  // default language
170  $translationInfo = $this->contentFetcher->getTranslationData(
171  $this->contentFetcher->getFlatContentRecords(0),
172  0
173  );
174 
175  $defaultLanguageColumnObject = GeneralUtility::makeInstance(
176  LanguageColumn::class,
177  ‪$context,
178  $this->‪getGridForPageLayoutContext($context),
179  $translationInfo
180  );
181  foreach (‪$context->‪getLanguagesToShow() as $siteLanguage) {
182  $localizedLanguageId = $siteLanguage->getLanguageId();
183  if ($localizedLanguageId <= 0) {
184  continue;
185  }
186 
187  $localizedContext = ‪$context->‪cloneForLanguage($siteLanguage);
188  if (!$localizedContext->getLocalizedPageRecord()) {
189  continue;
190  }
191 
192  $translationInfo = $this->contentFetcher->getTranslationData(
193  $this->contentFetcher->getFlatContentRecords($localizedLanguageId),
194  $localizedContext->getSiteLanguage()->getLanguageId()
195  );
196 
197  $translatedRows = $this->contentFetcher->getFlatContentRecords($localizedLanguageId);
198 
199  $grid = $defaultLanguageColumnObject->getGrid();
200  if ($grid === null) {
201  continue;
202  }
203 
204  foreach ($grid->getRows() as $rows) {
205  foreach ($rows->getColumns() as $column) {
206  if ($translationInfo['mode'] === 'connected') {
207  foreach ($column->getItems() as $item) {
208  // check if translation exists
209  foreach ($translatedRows as $translation) {
210  if ($translation['l18n_parent'] === $item->getRecord()['uid']) {
211  $translatedItem = GeneralUtility::makeInstance(GridColumnItem::class, $localizedContext, $column, $translation);
212  $item->addTranslation($localizedLanguageId, $translatedItem);
213  }
214  }
215  }
216  }
217  }
218  }
219 
220  $languageColumnObject = GeneralUtility::makeInstance(
221  LanguageColumn::class,
222  $localizedContext,
223  $this->‪getGridForPageLayoutContext($localizedContext),
224  $translationInfo
225  );
226  $languageColumns[$localizedLanguageId] = $languageColumnObject;
227  }
228  $languageColumns = [$defaultLanguageColumnObject] + $languageColumns;
229 
230  return $languageColumns;
231  }
232 
237  public function ‪drawContent(bool $renderUnused = true): string
238  {
239  $this->view->assign('hideRestrictedColumns', (bool)(‪BackendUtility::getPagesTSconfig($this->context->getPageId())['mod.']['web_layout.']['hideRestrictedCols'] ?? false));
240  $this->view->assign('newContentTitle', $this->‪getLanguageService()->getLL('newContentElement'));
241  $this->view->assign('newContentTitleShort', $this->‪getLanguageService()->getLL('content'));
242  $this->view->assign('allowEditContent', $this->‪getBackendUser()->check('tables_modify', 'tt_content'));
243 
244  if ($this->context->getDrawingConfiguration()->getLanguageMode()) {
245  if ($this->context->getDrawingConfiguration()->getDefaultLanguageBinding()) {
246  $this->view->assign('languageColumns', $this->‪getLanguageColumnsWithDefLangBindingForPageLayoutContext($this->context));
247  } else {
248  $this->view->assign('languageColumns', $this->‪getLanguageColumnsForPageLayoutContext($this->context));
249  }
250  } else {
252  // Check if we have to use a localized context for grid creation
253  if ($this->context->getDrawingConfiguration()->getSelectedLanguageId() > 0) {
254  // In case a localization is selected, clone the context with this language
255  $localizedContext = $this->context->‪cloneForLanguage(
256  $this->context->getSiteLanguage($this->context->getDrawingConfiguration()->getSelectedLanguageId())
257  );
258  if ($localizedContext->getLocalizedPageRecord()) {
259  // In case the localized context contains the corresponding
260  // localized page record use this context for grid creation.
261  ‪$context = $localizedContext;
262  }
263  }
264  $this->view->assign('grid', $this->‪getGridForPageLayoutContext($context));
265  }
266 
267  $rendered = $this->view->render('PageLayout');
268  if ($renderUnused) {
269  $unusedRecords = $this->contentFetcher->getUnusedRecords();
270 
271  if (!empty($unusedRecords)) {
272  $unusedElementsMessage = GeneralUtility::makeInstance(
273  FlashMessage::class,
274  $this->‪getLanguageService()->getLL('staleUnusedElementsWarning'),
275  $this->‪getLanguageService()->getLL('staleUnusedElementsWarningTitle'),
277  );
278  $service = GeneralUtility::makeInstance(FlashMessageService::class);
279  $queue = $service->getMessageQueueByIdentifier();
280  $queue->addMessage($unusedElementsMessage);
281 
282  $unusedGrid = GeneralUtility::makeInstance(Grid::class, $this->context);
283  $unusedRow = GeneralUtility::makeInstance(GridRow::class, $this->context);
284  $unusedColumn = GeneralUtility::makeInstance(GridColumn::class, $this->context, ['name' => 'unused']);
285 
286  $unusedGrid->addRow($unusedRow);
287  $unusedRow->addColumn($unusedColumn);
288 
289  foreach ($unusedRecords as $unusedRecord) {
290  $item = GeneralUtility::makeInstance(GridColumnItem::class, $this->context, $unusedColumn, $unusedRecord);
291  $unusedColumn->addItem($item);
292  }
293 
294  $this->view->assign('grid', $unusedGrid);
295  $rendered .= $this->view->render('UnusedRecords');
296  }
297  }
298  return $rendered;
299  }
300 
307  protected function ‪initializeClipboard(): void
308  {
309  $this->clipboard = GeneralUtility::makeInstance(Clipboard::class);
310  $this->clipboard->initializeClipboard();
311  $this->clipboard->lockToNormal();
312  $this->clipboard->cleanCurrent();
313  $this->clipboard->endClipboard();
314 
315  $elFromTable = $this->clipboard->elFromTable('tt_content');
316  if (!empty($elFromTable) && $this->‪isContentEditable()) {
317  $pasteItem = (int)substr((string)key($elFromTable), 11);
318  $pasteRecord = ‪BackendUtility::getRecord('tt_content', (int)$pasteItem);
319  $pasteTitle = (string)($pasteRecord['header'] ?: $pasteItem);
320  $copyMode = $this->clipboard->clipData['normal']['mode'] ? '-' . $this->clipboard->clipData['normal']['mode'] : '';
321  $addExtOnReadyCode = '
322  top.pasteIntoLinkTemplate = '
323  . $this->‪drawPasteIcon($pasteItem, $pasteTitle, $copyMode, 't3js-paste-into', 'pasteIntoColumn')
324  . ';
325  top.pasteAfterLinkTemplate = '
326  . $this->‪drawPasteIcon($pasteItem, $pasteTitle, $copyMode, 't3js-paste-after', 'pasteAfterRecord')
327  . ';';
328  } else {
329  $addExtOnReadyCode = '
330  top.pasteIntoLinkTemplate = \'\';
331  top.pasteAfterLinkTemplate = \'\';';
332  }
333  GeneralUtility::makeInstance(PageRenderer::class)->addJsInlineCode('pasteLinkTemplates', $addExtOnReadyCode);
334  }
335 
347  private function ‪drawPasteIcon(int $pasteItem, string $pasteTitle, string $copyMode, string $cssClass, string $title): string
348  {
349  $pasteIcon = json_encode(
350  ' <button type="button"'
351  . ' data-content="' . htmlspecialchars((string)$pasteItem) . '"'
352  . ' data-title="' . htmlspecialchars($pasteTitle) . '"'
353  . ' data-severity="warning"'
354  . ' class="t3js-paste t3js-paste' . htmlspecialchars($copyMode) . ' ' . htmlspecialchars($cssClass) . ' btn btn-default btn-sm"'
355  . ' title="' . htmlspecialchars($this->‪getLanguageService()->getLL($title)) . '">'
356  . $this->iconFactory->getIcon('actions-document-paste-into', ‪Icon::SIZE_SMALL)->render()
357  . '</button>'
358  );
359  return $pasteIcon;
360  }
361 
362  protected function ‪isContentEditable(): bool
363  {
364  if ($this->‪getBackendUser()->isAdmin()) {
365  return true;
366  }
367 
368  $pageRecord = $this->context->getPageRecord();
369  return !$pageRecord['editlock']
370  && $this->‪getBackendUser()->check('tables_modify', 'tt_content')
371  && $this->‪getBackendUser()->doesUserHaveAccess($pageRecord, ‪Permission::CONTENT_EDIT);
372  }
373 
374  protected function ‪getBackendUser(): ‪BackendUserAuthentication
375  {
376  return ‪$GLOBALS['BE_USER'];
377  }
378 
379  protected function ‪getLanguageService(): ‪LanguageService
380  {
381  return ‪$GLOBALS['LANG'];
382  }
383 }
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\$view
‪TemplateView $view
Definition: BackendLayoutRenderer.php:78
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:30
‪TYPO3\CMS\Backend\View\PageLayoutContext\getLanguagesToShow
‪SiteLanguage[] getLanguagesToShow()
Definition: PageLayoutContext.php:190
‪TYPO3\CMS\Backend\View\BackendLayout\Grid\Grid
Definition: Grid.php:39
‪TYPO3\CMS\Backend\Clipboard\Clipboard
Definition: Clipboard.php:43
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\getLanguageColumnsWithDefLangBindingForPageLayoutContext
‪getLanguageColumnsWithDefLangBindingForPageLayoutContext(PageLayoutContext $context)
Definition: BackendLayoutRenderer.php:159
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:26
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\$context
‪PageLayoutContext $context
Definition: BackendLayoutRenderer.php:66
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\$clipboard
‪Clipboard $clipboard
Definition: BackendLayoutRenderer.php:74
‪TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext
Definition: ControllerContext.php:28
‪TYPO3\CMS\Backend\View\BackendLayout\Grid\GridRow
Definition: GridRow.php:31
‪TYPO3\CMS\Backend\View\PageLayoutContext\getBackendLayout
‪getBackendLayout()
Definition: PageLayoutContext.php:149
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\$contentFetcher
‪ContentFetcher $contentFetcher
Definition: BackendLayoutRenderer.php:70
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:33
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\initializeClipboard
‪initializeClipboard()
Definition: BackendLayoutRenderer.php:301
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\__construct
‪__construct(PageLayoutContext $context)
Definition: BackendLayoutRenderer.php:80
‪TYPO3\CMS\Backend\View\BackendLayout\ContentFetcher
Definition: ContentFetcher.php:48
‪TYPO3\CMS\Fluid\View\TemplateView
Definition: TemplateView.php:25
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\isContentEditable
‪isContentEditable()
Definition: BackendLayoutRenderer.php:356
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:24
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\getGridForPageLayoutContext
‪getGridForPageLayoutContext(PageLayoutContext $context)
Definition: BackendLayoutRenderer.php:97
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:42
‪TYPO3\CMS\Core\Messaging\AbstractMessage\WARNING
‪const WARNING
Definition: AbstractMessage.php:30
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\getLanguageColumnsForPageLayoutContext
‪LanguageColumn[] getLanguageColumnsForPageLayoutContext(PageLayoutContext $context)
Definition: BackendLayoutRenderer.php:128
‪TYPO3\CMS\Backend\Utility\BackendUtility\getPagesTSconfig
‪static array getPagesTSconfig($id)
Definition: BackendUtility.php:698
‪TYPO3\CMS\Backend\View\PageLayoutContext\getSiteLanguage
‪getSiteLanguage(?int $languageId=null)
Definition: PageLayoutContext.php:209
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer
Definition: BackendLayoutRenderer.php:58
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\View\PageLayoutContext\cloneForLanguage
‪cloneForLanguage(SiteLanguage $language)
Definition: PageLayoutContext.php:121
‪TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumn
Definition: GridColumn.php:41
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:95
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:24
‪TYPO3\CMS\Core\Type\Bitmask\Permission\CONTENT_EDIT
‪const CONTENT_EDIT
Definition: Permission.php:53
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Backend\View\PageLayoutContext
Definition: PageLayoutContext.php:43
‪TYPO3\CMS\Backend\View\BackendLayout\RecordRememberer
Definition: RecordRememberer.php:26
‪TYPO3\CMS\Backend\View\BackendLayout\Grid\LanguageColumn
Definition: LanguageColumn.php:45
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\getLanguageService
‪getLanguageService()
Definition: BackendLayoutRenderer.php:373
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\getBackendUser
‪getBackendUser()
Definition: BackendLayoutRenderer.php:368
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\$iconFactory
‪IconFactory $iconFactory
Definition: BackendLayoutRenderer.php:62
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\drawPasteIcon
‪string drawPasteIcon(int $pasteItem, string $pasteTitle, string $copyMode, string $cssClass, string $title)
Definition: BackendLayoutRenderer.php:341
‪TYPO3\CMS\Backend\View\PageLayoutContext\getDrawingConfiguration
‪getDrawingConfiguration()
Definition: PageLayoutContext.php:154
‪TYPO3\CMS\Backend\View\Drawing
Definition: BackendLayoutRenderer.php:18
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem
Definition: GridColumnItem.php:42
‪TYPO3\CMS\Extbase\Object\ObjectManager
Definition: ObjectManager.php:28
‪TYPO3\CMS\Extbase\Mvc\Request
Definition: Request.php:31
‪TYPO3\CMS\Core\Messaging\FlashMessageService
Definition: FlashMessageService.php:27
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer\drawContent
‪string drawContent(bool $renderUnused=true)
Definition: BackendLayoutRenderer.php:231