From 99e20da11a35952ec81f7098803fce9f602fffec Mon Sep 17 00:00:00 2001 From: Matthias Adrowski <matthias.adrowski@sgalinski.de> Date: Tue, 11 Jan 2022 09:14:33 +0100 Subject: [PATCH] [TASK] Add PreviewRenderer --- Classes/Preview/PreviewRenderer.php | 259 +++++++++++++++++++++ Configuration/TCA/Overrides/tt_content.php | 5 + 2 files changed, 264 insertions(+) create mode 100644 Classes/Preview/PreviewRenderer.php diff --git a/Classes/Preview/PreviewRenderer.php b/Classes/Preview/PreviewRenderer.php new file mode 100644 index 0000000..be836bf --- /dev/null +++ b/Classes/Preview/PreviewRenderer.php @@ -0,0 +1,259 @@ +<?php + +/*************************************************************** + * Copyright notice + * (c) sgalinski Internet Services (https://www.sgalinski.de) + * All rights reserved + * This script is part of the TYPO3 project. The TYPO3 project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ + +namespace SGalinski\SgNews\Preview; + +use TYPO3\CMS\Backend\Preview\PreviewRendererInterface; +use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem; +use TYPO3\CMS\Core\Localization\LanguageService; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Fluid\View\StandaloneView; + +/** + * + */ +class PreviewRenderer implements PreviewRendererInterface { + /** + * @var LanguageService $languageService + */ + protected LanguageService $languageService; + + public function __construct(LanguageService $languageService) { + $this->languageService = $languageService; + } + + /** + * Dedicated method for rendering preview header HTML for + * the page module only. Receives $item which is an instance of + * GridColumnItem which has a getter method to return the record. + * + * @param GridColumnItem $item + * @return string + */ + public function renderPageModulePreviewHeader(GridColumnItem $item): string { + $label = BackendUtility::getLabelFromItemListMerged( + $item->getRecord()['pid'], + 'tt_content', + 'list_type', + $item->getRecord()['list_type'] + ); + return '<h4><span class="label label-primary">' . $this->languageService->sL($label) . '</span> </h4>'; + } + + /** + * Dedicated method for rendering preview body HTML for + * the page module only. + * + * @param GridColumnItem $item + * @return string + */ + public function renderPageModulePreviewContent(GridColumnItem $item): string { + $row = $item->getRecord(); + switch ($row['list_type']) { + case 'sgnews_overview': + + + $view = $this->createViewWithTemplate('Overview'); + $view->assign('uid', $row['uid']); + + // Get available plugin settings and their values from flexform + $pluginConfiguration = GeneralUtility::xml2array( + $row['pi_flexform'], 'T3DataStructure' + )['data']['main']['lDEF']; + + $templateData = [ + 'groupBy' => $pluginConfiguration['settings.groupBy']['vDEF'], + 'enableFilter' => $pluginConfiguration['settings.enableFilter']['vDEF'], + 'newsLimit' => $pluginConfiguration['settings.newsLimit']['vDEF'], + 'onlyNewsWithinThisPageSection' => $pluginConfiguration['settings.onlyNewsWithinThisPageSection']['vDEF'], + 'starttime' => $pluginConfiguration['settings.starttime']['vDEF'], + 'endtime' => $pluginConfiguration['settings.endtime']['vDEF'], + 'sortBy' => $pluginConfiguration['settings.sortBy']['vDEF'], + 'sortDirection' => $pluginConfiguration['settings.sortDirection']['vDEF'] + ]; + + $view->assign('data', $templateData); + break; + + case 'sgnews_latest': + + + $view = $this->createViewWithTemplate('Latest'); + $view->assign('uid', $row['uid']); + + // Get available plugin settings and their values from flexform + $pluginConfiguration = GeneralUtility::xml2array( + $row['pi_flexform'], 'T3DataStructure' + )['data']['main']['lDEF']; + + $categories = $pluginConfiguration['settings.categories']['vDEF']; + $tags = $pluginConfiguration['settings.tags']['vDEF']; + $templateData = [ + 'limit' => $pluginConfiguration['settings.limit']['vDEF'], + 'categories' => is_string($categories) ? $this->addFieldContentsToRecordIdList( + 'pages', $categories + ) : '', + 'tags' => is_string($tags) ? $this->addFieldContentsToRecordIdList( + 'sys_category', $tags + ) : '', + 'starttime' => $pluginConfiguration['settings.starttime']['vDEF'], + 'endtime' => $pluginConfiguration['settings.endtime']['vDEF'], + 'sortBy' => $pluginConfiguration['settings.sortBy']['vDEF'] + ]; + + $view->assign('data', $templateData); + break; + + case 'sgnews_listbycategory': + + + $view = $this->createViewWithTemplate('ListByCategory'); + $view->assign('uid', $row['uid']); + + // Get available plugin settings and their values from flexform + $pluginConfiguration = GeneralUtility::xml2array( + $row['pi_flexform'], 'T3DataStructure' + )['data']['main']['lDEF']; + + $categories = $pluginConfiguration['settings.categories']['vDEF']; + $tags = $pluginConfiguration['settings.tags']['vDEF']; + $templateData = [ + 'newsLimitPerPage' => $pluginConfiguration['settings.newsLimitPerPage']['vDEF'], + 'categories' => is_string($categories) ? $this->addFieldContentsToRecordIdList( + 'pages', $categories + ) : '', + 'tags' => is_string($tags) ? $this->addFieldContentsToRecordIdList('sys_category', $tags) : '', + 'starttime' => $pluginConfiguration['settings.starttime']['vDEF'], + 'endtime' => $pluginConfiguration['settings.endtime']['vDEF'], + 'sortBy' => $pluginConfiguration['settings.sortBy']['vDEF'], + 'sortDirection' => $pluginConfiguration['settings.sortDirection']['vDEF'] + ]; + + $view->assign('data', $templateData); + break; + + case 'sgnews_newsbyauthor': + + + $view = $this->createViewWithTemplate('NewsByAuthor'); + $view->assign('uid', $row['uid']); + + // Get available plugin settings and their values from flexform + $pluginConfiguration = GeneralUtility::xml2array( + $row['pi_flexform'], 'T3DataStructure' + )['data']['main']['lDEF']; + + $newsAuthors = $pluginConfiguration['settings.newsAuthors']['vDEF']; + $templateData = [ + 'showDetails' => $pluginConfiguration['settings.showDetails']['vDEF'], + 'newsAuthors' => is_string($newsAuthors) ? $this->addFieldContentsToRecordIdList( + 'tx_sgnews_domain_model_author',$newsAuthors,'name' + ) : '' + ]; + + // Not using addFieldContentsToRecordIdList to avoid repetitive imploding and exploding. + $excludedNewsIds = GeneralUtility::intExplode( + ',', $pluginConfiguration['settings.excludedNews']['vDEF'], TRUE + ); + $excludedNewsListWithTitles = []; + foreach ($excludedNewsIds as $excludedNewsId) { + $excludedNewsListWithTitles[] = BackendUtility::getRecord( + 'pages', $excludedNewsId, 'title' + )['title'] . ' [' . $excludedNewsId . ']'; + } + $templateData['excludedNews'] = $excludedNewsListWithTitles; + + $view->assign('data', $templateData); + break; + + default: + // No need to do anything + } + return $view->render(); + } + + /** + * Render a footer for the record to display in page module below + * the body of the item's preview. + * + * @param GridColumnItem $item + * @return string + */ + public function renderPageModulePreviewFooter(GridColumnItem $item): string { + return ''; + } + + /** + * Dedicated method for wrapping a preview header and body HTML. + * + * @param string $previewHeader + * @param string $previewContent + * @param GridColumnItem $item + * @return string + */ + public function wrapPageModulePreview(string $previewHeader, string $previewContent, GridColumnItem $item): string { + return $previewHeader . $previewContent; + } + + /** + * Creates a new StandaloneView object with template and partial root paths, + * attaches the template with the given name to it and returns it. + * + * @param string $templateName + * @return StandaloneView + */ + protected function createViewWithTemplate(string $templateName): StandaloneView { + $view = GeneralUtility::makeInstance(StandaloneView::class); + $view->setTemplateRootPaths(['EXT:sg_news/Resources/Private/Templates/Backend']); + $view->setPartialRootPaths(['EXT:sg_news/Resources/Private/Partials/Backend']); + if (!str_ends_with($templateName, '.html')) { + $templateName .= '.html'; + } + $view->setTemplate($templateName); + return $view; + } + + /** + * Takes a comma-separated list of record IDs, the corresponding table and optionally the field to look up. + * Returns another comma-space-separated list of the same records with the content of the field added. + * The returned list should look nice enough to be rendered in the backend preview directly. + * + * @param string $table + * @param string $recordIdList + * @param string $field + * @return string + */ + protected function addFieldContentsToRecordIdList( + string $table, + string $recordIdList, + string $field = 'title' + ): string { + $recordIdsArray = GeneralUtility::intExplode(',', $recordIdList, TRUE); + $recordsWithTitlesArray = []; + + foreach ($recordIdsArray as $recordId) { + $recordsWithTitlesArray[] = BackendUtility::getRecord( + $table, $recordId, $field + )[$field] . ' [' . $recordId . ']'; + } + return implode(', ', $recordsWithTitlesArray); + } +} diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index 849be5b..8eb8532 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -75,3 +75,8 @@ $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['sgnews_newsb \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue( 'sgnews_newsbyauthor', 'FILE:EXT:sg_news/Configuration/FlexForms/NewsByAuthor.xml' ); + +$GLOBALS['TCA']['tt_content']['types']['list']['previewRenderer']['sgnews_overview'] = \SGalinski\SgNews\Preview\PreviewRenderer::class; +$GLOBALS['TCA']['tt_content']['types']['list']['previewRenderer']['sgnews_listbycategory'] = \SGalinski\SgNews\Preview\PreviewRenderer::class; +$GLOBALS['TCA']['tt_content']['types']['list']['previewRenderer']['sgnews_latest'] = \SGalinski\SgNews\Preview\PreviewRenderer::class; +$GLOBALS['TCA']['tt_content']['types']['list']['previewRenderer']['sgnews_newsbyauthor'] = \SGalinski\SgNews\Preview\PreviewRenderer::class; -- GitLab