From 8f366710090ae322da447ffe01a50fe503307657 Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid <kevin.ditscheid@sgalinski.de> Date: Thu, 28 Apr 2022 09:41:57 +0200 Subject: [PATCH] [TASK] Introduce a Service for the new meta data --- Classes/Controller/AbstractController.php | 145 --------------- Classes/Controller/LatestController.php | 15 +- .../Controller/ListByCategoryController.php | 15 +- Classes/Controller/NewsByAuthorController.php | 15 +- Classes/Controller/OverviewController.php | 19 +- Classes/Controller/SingleViewController.php | 15 +- Classes/Domain/Model/News.php | 73 -------- Classes/Domain/Service/NewsService.php | 167 ++++++++++++++++++ Classes/ViewHelpers/RelatedViewHelper.php | 42 ++++- .../Templates/SingleView/SingleView.html | 29 ++- 10 files changed, 290 insertions(+), 245 deletions(-) create mode 100644 Classes/Domain/Service/NewsService.php diff --git a/Classes/Controller/AbstractController.php b/Classes/Controller/AbstractController.php index d4d44b1..d7fc772 100644 --- a/Classes/Controller/AbstractController.php +++ b/Classes/Controller/AbstractController.php @@ -27,32 +27,17 @@ namespace SGalinski\SgNews\Controller; ***************************************************************/ use RuntimeException; -use SGalinski\SgNews\Domain\Model\Category; -use SGalinski\SgNews\Domain\Model\News; -use SGalinski\SgNews\Service\ImageService; -use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Domain\Model\FileReference; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; /** * Abstract Controller */ abstract class AbstractController extends ActionController { - /** - * @var ImageService - */ - protected $imageService; - /** * @var array */ protected $extensionConfiguration = []; - /** - * @var array - */ - protected $cachedSingleNews = []; - /** * Initializes any action * @@ -65,13 +50,6 @@ abstract class AbstractController extends ActionController { parent::initializeAction(); } - /** - * @param ImageService $imageService - */ - public function injectImageService(ImageService $imageService) { - $this->imageService = $imageService; - } - /** * Error Handler * @@ -82,129 +60,6 @@ abstract class AbstractController extends ActionController { throw new RuntimeException(parent::errorAction()); } - /** - * Returns the metadata of the given news. - * - * @param News $news - * @param Category $category - * @return array - * @throws \InvalidArgumentException - */ - protected function getMetaDataForNews(News $news, Category $category): array { - $newsId = $news->getUid(); - if (isset($this->cachedSingleNews[$newsId])) { - return $this->cachedSingleNews[$newsId]; - } - - $fileRepository = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\FileRepository::class); - $fileObjects = $fileRepository->findByRelation('pages', 'media', $news->getUid()); - - $singleNewsImageData = $this->getDataForSingleViewImage($news, $category); - $teaserImageData = $this->getDataForTeaserImage($news, $category); - - // Use single news image data for teaser image data, if the teaser imaga data are empty. - $teaserIsEmpty = $teaserImageData['teaserImage'] === NULL && $teaserImageData['teaserImageObject'] === NULL; - $singleNewsIsEmpty = $singleNewsImageData['image'] === NULL && $singleNewsImageData['imageObject'] === NULL; - if ($teaserIsEmpty && !$singleNewsIsEmpty) { - $teaserImageData = [ - 'teaserImage' => $singleNewsImageData['image'], - 'teaserImageObject' => $singleNewsImageData['imageObject'], - ]; - } - - $newsRecord = array_merge( - [ - 'category' => $category, - 'news' => $news, - ], - $singleNewsImageData, - $teaserImageData, - ['media' => $fileObjects] - ); - - $this->cachedSingleNews[$newsId] = $newsRecord; - - return $newsRecord; - } - - /** - * Returns the single view image data as an array for the given news and category as fallback. - * - * @param News $news - * @param Category $category - * @return array - * @throws \InvalidArgumentException - */ - protected function getDataForSingleViewImage(News $news, Category $category): array { - /** @var FileReference $singleNewsImage */ - $singleNewsImage = $singleNewsImageObject = NULL; - $singleNewsImages = $news->getTeaser2Image(); - if (count($singleNewsImages)) { - $singleNewsImage = $singleNewsImages->current(); - } else { - $categoryImages = $category->getTeaser2Image(); - if (count($categoryImages)) { - $singleNewsImage = $categoryImages->current(); - } - } - - if ($singleNewsImage) { - $singleNewsImageObject = $singleNewsImage; - $originalResource = $singleNewsImage->getOriginalResource(); - if ($originalResource) { - $singleNewsImage = $originalResource->getPublicUrl(); - } - - if ($singleNewsImage) { - $singleNewsImage = $GLOBALS['TSFE']->absRefPrefix . $singleNewsImage; - } - } - - return [ - 'image' => $singleNewsImage, - 'imageObject' => $singleNewsImageObject, - ]; - } - - /** - * Returns the teaser image data as an array for the given news and category as fallback. - * - * @param News $news - * @param Category $category - * @return array - * @throws \InvalidArgumentException - */ - protected function getDataForTeaserImage(News $news, Category $category): array { - /** @var FileReference $teaserImage */ - $teaserImage = $teaserImageObject = NULL; - $teaserImages = $news->getTeaser1Image(); - if (count($teaserImages)) { - $teaserImage = $teaserImages->current(); - } else { - $categoryImages = $category->getTeaser1Image(); - if (count($categoryImages)) { - $teaserImage = $categoryImages->current(); - } - } - - if ($teaserImage) { - $teaserImageObject = $teaserImage; - $originalResource = $teaserImage->getOriginalResource(); - if ($originalResource) { - $teaserImage = $originalResource->getPublicUrl(); - } - - if ($teaserImage) { - $teaserImage = $GLOBALS['TSFE']->absRefPrefix . $teaserImage; - } - } - - return [ - 'teaserImage' => $teaserImage, - 'teaserImageObject' => $teaserImageObject, - ]; - } - /** * Calculate the pagination offset * diff --git a/Classes/Controller/LatestController.php b/Classes/Controller/LatestController.php index 393c956..e5eb3ea 100644 --- a/Classes/Controller/LatestController.php +++ b/Classes/Controller/LatestController.php @@ -31,6 +31,7 @@ use SGalinski\SgNews\Domain\Model\News; use SGalinski\SgNews\Domain\Repository\CategoryRepository; use SGalinski\SgNews\Domain\Repository\NewsRepository; use SGalinski\SgNews\Domain\Repository\TagRepository; +use SGalinski\SgNews\Domain\Service\NewsService; use SGalinski\SgNews\Service\ConfigurationService; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -53,6 +54,11 @@ class LatestController extends AbstractController { */ protected $newsRepository; + /** + * @var NewsService + */ + protected $newsService; + /** * Renders the news overview * @@ -96,7 +102,7 @@ class LatestController extends AbstractController { $categories[$categoryUid] = $category; } - $newsMetaData[] = $this->getMetaDataForNews($latestNewsEntry, $category); + $newsMetaData[] = $this->newsService->getMetaDataForNews($latestNewsEntry, $category); // Make sure, that the amount is the same as the configured limit. if (count($newsMetaData) >= $limit) { break; @@ -127,4 +133,11 @@ class LatestController extends AbstractController { public function injectTagRepository(TagRepository $tagRepository) { $this->tagRepository = $tagRepository; } + + /** + * @param NewsService $newsService + */ + public function injectNewsService(NewsService $newsService) { + $this->newsService = $newsService; + } } diff --git a/Classes/Controller/ListByCategoryController.php b/Classes/Controller/ListByCategoryController.php index 2f405c9..2a1c961 100644 --- a/Classes/Controller/ListByCategoryController.php +++ b/Classes/Controller/ListByCategoryController.php @@ -30,6 +30,7 @@ use SGalinski\SgNews\Domain\Model\News; use SGalinski\SgNews\Domain\Repository\CategoryRepository; use SGalinski\SgNews\Domain\Repository\NewsRepository; use SGalinski\SgNews\Domain\Repository\TagRepository; +use SGalinski\SgNews\Domain\Service\NewsService; use SGalinski\SgNews\Service\ConfigurationService; use SGalinski\SgNews\Service\HeaderMetaDataService; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; @@ -57,6 +58,11 @@ class ListByCategoryController extends AbstractController { */ protected $newsRepository; + /** + * @var NewsService + */ + protected $newsService; + /** * @param CategoryRepository $categoryRepository */ @@ -79,6 +85,13 @@ class ListByCategoryController extends AbstractController { $this->tagRepository = $tagRepository; } + /** + * @param NewsService $newsService + */ + public function injectNewsService(NewsService $newsService) { + $this->newsService = $newsService; + } + /** * Initialize the indexAction to set the currentPageBrowserPage parameter * @@ -164,7 +177,7 @@ class ListByCategoryController extends AbstractController { foreach ($news as $newsEntry) { /** @var News $newsEntry */ - $data = $this->getMetaDataForNews($newsEntry, $categories[$newsEntry->getPid()]); + $data = $this->newsService->getMetaDataForNews($newsEntry, $categories[$newsEntry->getPid()]); $newsMetaData[] = $data; if (!$headerSet) { diff --git a/Classes/Controller/NewsByAuthorController.php b/Classes/Controller/NewsByAuthorController.php index 4ace64d..217140f 100644 --- a/Classes/Controller/NewsByAuthorController.php +++ b/Classes/Controller/NewsByAuthorController.php @@ -32,6 +32,7 @@ use SGalinski\SgNews\Domain\Model\News; use SGalinski\SgNews\Domain\Repository\AuthorRepository; use SGalinski\SgNews\Domain\Repository\CategoryRepository; use SGalinski\SgNews\Domain\Repository\NewsRepository; +use SGalinski\SgNews\Domain\Service\NewsService; use SGalinski\SgSeo\Service\HeadTagService; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -40,6 +41,18 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; * News Author List Controller */ class NewsByAuthorController extends AbstractController { + /** + * @var NewsService + */ + protected $newsService; + + /** + * @param NewsService $newsService + */ + public function injectNewsService(NewsService $newsService) { + $this->newsService = $newsService; + } + /** * Renders the news author list. * @@ -118,7 +131,7 @@ class NewsByAuthorController extends AbstractController { $categories[$categoryId] = $category; } - $newsMetaData[] = $this->getMetaDataForNews($newsEntry, $categories[$categoryId]); + $newsMetaData[] = $this->newsService->getMetaDataForNews($newsEntry, $categories[$categoryId]); } } diff --git a/Classes/Controller/OverviewController.php b/Classes/Controller/OverviewController.php index 0a524e7..5b00281 100644 --- a/Classes/Controller/OverviewController.php +++ b/Classes/Controller/OverviewController.php @@ -31,6 +31,7 @@ use SGalinski\SgNews\Domain\Model\News; use SGalinski\SgNews\Domain\Repository\CategoryRepository; use SGalinski\SgNews\Domain\Repository\NewsRepository; use SGalinski\SgNews\Domain\Repository\TagRepository; +use SGalinski\SgNews\Domain\Service\NewsService; use SGalinski\SgNews\Service\ConfigurationService; use SGalinski\SgNews\Service\HeaderMetaDataService; use TYPO3\CMS\Core\Http\ImmediateResponseException; @@ -60,6 +61,11 @@ class OverviewController extends AbstractController { */ protected $newsRepository; + /** + * @var NewsService + */ + protected $newsService; + /** * @param CategoryRepository $categoryRepository */ @@ -82,6 +88,13 @@ class OverviewController extends AbstractController { $this->tagRepository = $tagRepository; } + /** + * @param NewsService $newsService + */ + public function injectNewsService(NewsService $newsService) { + $this->newsService = $newsService; + } + /** * Initialize the overviewAction to set the currentPageBrowserPage parameter * @@ -216,7 +229,7 @@ class OverviewController extends AbstractController { $newsEntry->getPid() ) ?? $this->categoryRepository->findByUid($newsEntry->getPid()); $newsCategoryId = $newsCategory->getUid(); - $newsMetaData = $this->getMetaDataForNews($newsEntry, $newsCategory); + $newsMetaData = $this->newsService->getMetaDataForNews($newsEntry, $newsCategory); if ((int) $this->settings['groupBy'] === 1) { if (!$areCategoriesCreated) { @@ -353,7 +366,7 @@ class OverviewController extends AbstractController { $category = $this->categoryRepository->findByUid($highlightedNews->getPid()); $highlightedNewsMetaData = NULL; if ($category) { - $highlightedNewsMetaData = $this->getMetaDataForNews($highlightedNews, $category); + $highlightedNewsMetaData = $this->newsService->getMetaDataForNews($highlightedNews, $category); } if (!version_compare(ExtensionManagementUtility::getExtensionVersion('sg_seo'), '5.0.0', '>=')) { @@ -470,7 +483,7 @@ class OverviewController extends AbstractController { ); foreach ($news as $newsEntry) { /** @var News $newsEntry */ - $data = $this->getMetaDataForNews($newsEntry, $categoriesById[$newsEntry->getPid()]); + $data = $this->newsService->getMetaDataForNews($newsEntry, $categoriesById[$newsEntry->getPid()]); $newsMetaData[] = $data; } diff --git a/Classes/Controller/SingleViewController.php b/Classes/Controller/SingleViewController.php index 3890778..a7d929f 100644 --- a/Classes/Controller/SingleViewController.php +++ b/Classes/Controller/SingleViewController.php @@ -31,6 +31,7 @@ use SGalinski\SgNews\Domain\Model\News; use SGalinski\SgNews\Domain\Repository\CategoryRepository; use SGalinski\SgNews\Domain\Repository\NewsRepository; use SGalinski\SgNews\Domain\Repository\TagRepository; +use SGalinski\SgNews\Domain\Service\NewsService; use SGalinski\SgNews\Service\HeaderMetaDataService; use TYPO3\CMS\Core\Charset\CharsetConverter; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; @@ -59,6 +60,11 @@ class SingleViewController extends AbstractController { */ protected $characterSetConverter; + /** + * @var NewsService + */ + protected $newsService; + /** * Renders the news single view * @@ -92,7 +98,7 @@ class SingleViewController extends AbstractController { // $similarNewsMetaData[] = $this->getMetaDataForNews($similarNewsEntry, $category); // } - $newsMetaData = $this->getMetaDataForNews($news, $newsCategory); + $newsMetaData = $this->newsService->getMetaDataForNews($news, $newsCategory); if (!version_compare(ExtensionManagementUtility::getExtensionVersion('sg_seo'), '5.0.0', '>=')) { if ($newsMetaData['image']) { HeaderMetaDataService::addOgImageToHeader($newsMetaData['image']); @@ -145,4 +151,11 @@ class SingleViewController extends AbstractController { public function injectTagRepository(TagRepository $tagRepository) { $this->tagRepository = $tagRepository; } + + /** + * @param NewsService $newsService + */ + public function injectNewsService(NewsService $newsService) { + $this->newsService = $newsService; + } } diff --git a/Classes/Domain/Model/News.php b/Classes/Domain/Model/News.php index 607c4a7..d042f4b 100644 --- a/Classes/Domain/Model/News.php +++ b/Classes/Domain/Model/News.php @@ -26,9 +26,6 @@ namespace SGalinski\SgNews\Domain\Model; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use SGalinski\SgNews\Domain\Repository\CategoryRepository; -use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Domain\Model\FileReference; use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy; use TYPO3\CMS\Extbase\Persistence\ObjectStorage; @@ -105,16 +102,6 @@ class News extends CategoryAndNews { */ protected $enableComments = TRUE; - /** - * @var Category - */ - protected $categoryCache = NULL; - - /** - * @var FileReference - */ - protected $teaserImageCache = NULL; - /** * Constructor */ @@ -415,64 +402,4 @@ class News extends CategoryAndNews { public function setEnableComments(bool $enableComments): void { $this->enableComments = $enableComments; } - - /** - * Get the assigned category - * - * @return Category - */ - public function getCategory(): Category { - if ($this->categoryCache instanceof Category) { - return $this->categoryCache; - } - - return $this->categoryCache = GeneralUtility::makeInstance(CategoryRepository::class) - ->findByUid($this->pid); - } - - /** - * Get the teaser image object - * - * @return FileReference|null - */ - public function getTeaserImageObject(): ?FileReference { - if ($this->teaserImageCache instanceof FileReference) { - return $this->teaserImageCache; - } - $teaserImage = $this->getTeaser1Image()->current(); - if ($teaserImage instanceof FileReference) { - return $this->teaserImageCache = $teaserImage; - } - - $teaserImage = $this->getCategory()->getTeaser1Image()->current(); - if ($teaserImage instanceof FileReference) { - return $this->teaserImageCache = $teaserImage; - } - - $teaserImage = $this->getTeaser2Image()->current(); - if ($teaserImage instanceof FileReference) { - return $this->teaserImageCache = $teaserImage; - } - - return NULL; - } - - /** - * Get the teaser image public url - * - * @return string - */ - public function getTeaserImage() { - $teaserImage = $this->getTeaserImageObject(); - if ($teaserImage === NULL) { - return ''; - } - - $originalResource = $teaserImage->getOriginalResource(); - if ($originalResource === NULL) { - return ''; - } - - return $originalResource->getPublicUrl(); - } } diff --git a/Classes/Domain/Service/NewsService.php b/Classes/Domain/Service/NewsService.php new file mode 100644 index 0000000..7ba3ad6 --- /dev/null +++ b/Classes/Domain/Service/NewsService.php @@ -0,0 +1,167 @@ +<?php + +namespace SGalinski\SgNews\Domain\Service; + +/*************************************************************** + * 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! + ***************************************************************/ + +use SGalinski\SgNews\Domain\Model\Category; +use SGalinski\SgNews\Domain\Model\News; +use TYPO3\CMS\Core\SingletonInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Domain\Model\FileReference; +use TYPO3\CMS\Core\Resource\FileRepository; + +/** + * This service takes care of meta data generation for the news objects + */ +class NewsService implements SingletonInterface { + /** + * @var array + */ + protected $cachedSingleNews = []; + + /** + * Returns the metadata of the given news. + * + * @param News $news + * @param Category $category + * @return array + * @throws \InvalidArgumentException + */ + public function getMetaDataForNews(News $news, Category $category): array { + $newsId = $news->getUid(); + if (isset($this->cachedSingleNews[$newsId])) { + return $this->cachedSingleNews[$newsId]; + } + + $fileRepository = GeneralUtility::makeInstance(FileRepository::class); + $fileObjects = $fileRepository->findByRelation('pages', 'media', $news->getUid()); + + $singleNewsImageData = $this->getDataForSingleViewImage($news, $category); + $teaserImageData = $this->getDataForTeaserImage($news, $category); + + // Use single news image data for teaser image data, if the teaser imaga data are empty. + $teaserIsEmpty = $teaserImageData['teaserImage'] === NULL && $teaserImageData['teaserImageObject'] === NULL; + $singleNewsIsEmpty = $singleNewsImageData['image'] === NULL && $singleNewsImageData['imageObject'] === NULL; + if ($teaserIsEmpty && !$singleNewsIsEmpty) { + $teaserImageData = [ + 'teaserImage' => $singleNewsImageData['image'], + 'teaserImageObject' => $singleNewsImageData['imageObject'], + ]; + } + + $newsRecord = array_merge( + [ + 'category' => $category, + 'news' => $news, + ], + $singleNewsImageData, + $teaserImageData, + ['media' => $fileObjects] + ); + + $this->cachedSingleNews[$newsId] = $newsRecord; + + return $newsRecord; + } + + /** + * Returns the single view image data as an array for the given news and category as fallback. + * + * @param News $news + * @param Category $category + * @return array + * @throws \InvalidArgumentException + */ + public function getDataForSingleViewImage(News $news, Category $category): array { + /** @var FileReference $singleNewsImage */ + $singleNewsImage = $singleNewsImageObject = NULL; + $singleNewsImages = $news->getTeaser2Image(); + if (count($singleNewsImages)) { + $singleNewsImage = $singleNewsImages->current(); + } else { + $categoryImages = $category->getTeaser2Image(); + if (count($categoryImages)) { + $singleNewsImage = $categoryImages->current(); + } + } + + if ($singleNewsImage) { + $singleNewsImageObject = $singleNewsImage; + $originalResource = $singleNewsImage->getOriginalResource(); + if ($originalResource) { + $singleNewsImage = $originalResource->getPublicUrl(); + } + + if ($singleNewsImage) { + $singleNewsImage = $GLOBALS['TSFE']->absRefPrefix . $singleNewsImage; + } + } + + return [ + 'image' => $singleNewsImage, + 'imageObject' => $singleNewsImageObject, + ]; + } + + /** + * Returns the teaser image data as an array for the given news and category as fallback. + * + * @param News $news + * @param Category $category + * @return array + * @throws \InvalidArgumentException + */ + public function getDataForTeaserImage(News $news, Category $category): array { + /** @var FileReference $teaserImage */ + $teaserImage = $teaserImageObject = NULL; + $teaserImages = $news->getTeaser1Image(); + if (count($teaserImages)) { + $teaserImage = $teaserImages->current(); + } else { + $categoryImages = $category->getTeaser1Image(); + if (count($categoryImages)) { + $teaserImage = $categoryImages->current(); + } + } + + if ($teaserImage) { + $teaserImageObject = $teaserImage; + $originalResource = $teaserImage->getOriginalResource(); + if ($originalResource) { + $teaserImage = $originalResource->getPublicUrl(); + } + + if ($teaserImage) { + $teaserImage = $GLOBALS['TSFE']->absRefPrefix . $teaserImage; + } + } + + return [ + 'teaserImage' => $teaserImage, + 'teaserImageObject' => $teaserImageObject, + ]; + } +} diff --git a/Classes/ViewHelpers/RelatedViewHelper.php b/Classes/ViewHelpers/RelatedViewHelper.php index 83629d2..69b8e78 100644 --- a/Classes/ViewHelpers/RelatedViewHelper.php +++ b/Classes/ViewHelpers/RelatedViewHelper.php @@ -2,8 +2,11 @@ namespace SGalinski\SgNews\ViewHelpers; +use SGalinski\SgNews\Domain\Repository\CategoryRepository; use SGalinski\SgNews\Domain\Repository\NewsRepository; +use SGalinski\SgNews\Domain\Service\NewsService; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Persistence\ObjectStorage; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; @@ -28,12 +31,30 @@ class RelatedViewHelper extends AbstractViewHelper { 'The news record from which to find related news', TRUE ); - $this->registerArgument('limit', 'int', 'Limit the amount of related news to display', FALSE, 5); - $this->registerArgument('as', 'string', 'The name of the iteration variable', TRUE); + $this->registerArgument( + 'limit', + 'int', + 'Limit the amount of related news to display', + FALSE, + 5 + ); + $this->registerArgument( + 'as', + 'string', + 'The name of the iteration variable', + TRUE + ); $this->registerArgument( 'iteration', 'string', 'The name of the variable to store iteration information (index, cycle, isFirst, isLast, isEven, isOdd)' ); + $this->registerArgument( + 'relatedNews', + ObjectStorage::class, + 'An optional list of related news to take instead of finding some via the news repository', + FALSE, + NULL + ); } /** @@ -49,10 +70,17 @@ class RelatedViewHelper extends AbstractViewHelper { public static function renderStatic( array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext ) { + $newsService = GeneralUtility::makeInstance(NewsService::class); + $categoryRepository = GeneralUtility::makeInstance(CategoryRepository::class); $templateVariableContainer = $renderingContext->getVariableProvider(); $news = $arguments['news']; $newsRepository = GeneralUtility::makeInstance(NewsRepository::class); - $related = $newsRepository->findRelated($news, (int) $arguments['limit']); + if ($arguments['relatedNews']) { + $related = $arguments['relatedNews']; + } else { + $related = $newsRepository->findRelated($news, (int) $arguments['limit']); + } + if (isset($arguments['iteration'])) { $iterationData = [ 'index' => 0, @@ -62,8 +90,14 @@ class RelatedViewHelper extends AbstractViewHelper { } $output = ''; + $categories = []; foreach ($related as $relatedNews) { - $templateVariableContainer->add($arguments['as'], $relatedNews); + if (!isset($categories[$relatedNews->getPid()])) { + $categories[$relatedNews->getPid()] = $categoryRepository->findByUid($relatedNews->getPid()); + } + + $newsMetaData = $newsService->getMetaDataForNews($relatedNews, $categories[$relatedNews->getPid()]); + $templateVariableContainer->add($arguments['as'], $newsMetaData); if (isset($iterationData)) { $iterationData['isFirst'] = $iterationData['cycle'] === 1; $iterationData['isLast'] = $iterationData['cycle'] === $iterationData['total']; diff --git a/Resources/Private/Templates/SingleView/SingleView.html b/Resources/Private/Templates/SingleView/SingleView.html index bc803ad..4073b8f 100644 --- a/Resources/Private/Templates/SingleView/SingleView.html +++ b/Resources/Private/Templates/SingleView/SingleView.html @@ -203,15 +203,19 @@ <h3> <f:translate key="frontend.singleview.relatedArticles"/> </h3> - - <ul> - <f:for each="{newsMetaData.news.relatedNews}" as="relatedNewsEntry"> - <li> - <a href="{f:uri.page(pageUid: '{relatedNewsEntry.uid}')}"> - {relatedNewsEntry.subtitleWithFallbackToTitle} - </a> + <ul class="tx-sgnews-list tx-sgnews-overview"> + <sg:related news="{newsMetaData.news}" + relatedNews="{newsMetaData.news.relatedNews}" + as="relatedNewsEntry"> + <li class="col-md-4 col-sm-6 col-xs-12"> + <f:render partial="Teaser" arguments="{ + newsMetaData: relatedNewsEntry, + headerTag: '<h2>', + closingHeaderTag: '</h2>', + showCategory: '1' + }" /> </li> - </f:for> + </sg:related> </ul> </div> </f:then> @@ -221,13 +225,6 @@ iteration="iterator" limit="5" as="relatedNewsEntry"> - <f:variable name="relatedNewsMetaData" - value="{ - news: relatedNewsEntry, - teaserImage: relatedNewsEntry.teaserImage, - teaserImageObject: relatedNewsEntry.teaserImageObject, - category: relatedNewsEntry.category - }" /> <f:if condition="{iterator.isFirst}"> <div class="tx-sgnews-single-related"> <h3> @@ -237,7 +234,7 @@ </f:if> <li class="col-md-4 col-sm-6 col-xs-12"> <f:render partial="Teaser" arguments="{ - newsMetaData: relatedNewsMetaData, + newsMetaData: relatedNewsEntry, headerTag: '<h2>', closingHeaderTag: '</h2>', showCategory: '1' -- GitLab