<?php 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; /** * Renders related news based on the current news */ class RelatedViewHelper extends AbstractViewHelper { use CompileWithRenderStatic; /** * @var bool */ protected $escapeOutput = FALSE; /** * Initialize the view helper arguments */ public function initializeArguments() { $this->registerArgument( 'news', 'SGalinski\SgNews\Domain\Model\News', '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( '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 ); } /** * It works like the for-ViewHelper by running through the child content and adding the related news records to it * * @param array $arguments * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return string * @throws \Doctrine\DBAL\Driver\Exception * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException */ 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); if ($arguments['relatedNews']) { $related = $arguments['relatedNews']; } else { $related = $newsRepository->findRelated($news, (int) $arguments['limit']); } if (isset($arguments['iteration'])) { $iterationData = [ 'index' => 0, 'cycle' => 1, 'total' => $related->count() ]; } $output = ''; $categories = []; foreach ($related 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']; $iterationData['isEven'] = $iterationData['cycle'] % 2 === 0; $iterationData['isOdd'] = !$iterationData['isEven']; $templateVariableContainer->add($arguments['iteration'], $iterationData); $iterationData['index']++; $iterationData['cycle']++; } $output .= $renderChildrenClosure(); $templateVariableContainer->remove($arguments['as']); if (isset($arguments['iteration'])) { $templateVariableContainer->remove($arguments['iteration']); } } return $output; } }