Skip to content
Snippets Groups Projects
Verified Commit bd018a37 authored by Kevin Ditscheid's avatar Kevin Ditscheid
Browse files

[TASK] Create view helper for the related news fetching

parent 4cb2a099
No related branches found
No related tags found
1 merge request!41[TASK] Add related news by tag or category
......@@ -28,6 +28,9 @@ namespace SGalinski\SgNews\Domain\Repository;
use SGalinski\SgNews\Domain\Model\Author;
use SGalinski\SgNews\Domain\Model\News;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
......@@ -514,23 +517,71 @@ class NewsRepository extends AbstractRepository {
* @return QueryResultInterface
*/
public function findRelated(News $news, int $limit = 0) {
$connection = $this->getConnection();
$qb = $connection->createQueryBuilder();
$constraints = [];
$tags = $news->getTags();
if ($tags->count() > 0) {
$tagConstraints = [];
foreach ($tags as $tag) {
$qb->leftJoin('pages', 'sys_category_records_mm', 'tags', 'pages.uid=tags.uid_foreign');
$tagConstraints[] = $qb->expr()->eq('tags.uid_local', $tag->getUid());
}
$constraints[] = $qb->expr()->eq('tags.tablenames', $qb->createNamedParameter('pages'));
$constraints[] = $qb->expr()->eq('tags.fieldname', $qb->createNamedParameter('tx_sgnews_tags'));
$constraints[] = $qb->expr()->orX($tagConstraints);
} else {
$constraints[] = $qb->expr()->eq('pid', $news->getPid());
}
$result = $qb->select('lastUpdated')
->from('pages')
->where(
$qb->expr()->eq('doktype', $qb->createNamedParameter(News::DOK_TYPE_NEWS, Connection::PARAM_INT)),
$qb->expr()->gt('lastUpdated', $news->getLastUpdated()->getTimestamp()),
$qb->expr()->andX(...$constraints)
)
->setMaxResults($limit)
->orderBy('lastUpdated', 'asc')
->execute();
$max = $result->fetchOne();
$result = $qb->select('lastUpdated')
->from('pages')
->where(
$qb->expr()->eq('doktype', $qb->createNamedParameter(News::DOK_TYPE_NEWS, Connection::PARAM_INT)),
$qb->expr()->lt('lastUpdated', $news->getLastUpdated()->getTimestamp()),
$qb->expr()->andX(...$constraints)
)
->setMaxResults($limit)
->orderBy('lastUpdated', 'desc')
->execute();
$min = $result->fetchOne();
$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(FALSE);
$query->setOrderings([
'crdate' => QueryInterface::ORDER_DESCENDING
]);
$contains = [];
$constraints = [];
if ($max) {
$constraints[] = $query->lessThan('lastUpdated', $max);
}
if ($min) {
$constraints[] = $query->greaterThan('lastUpdated', $min);
}
$tags = $news->getTags();
if ($tags->count() > 0) {
foreach ($tags as $tag) {
$contains[] = $query->contains('tags', $tag);
$constraints[] = $query->contains('tags', $tag);
}
} else {
$contains[] = $query->equals('pid', $news->getPid());
$constraints[] = $query->equals('pid', $news->getPid());
}
$query->matching(
$contains
$constraints
);
if ($limit > 0) {
$query->setLimit($limit);
......@@ -538,4 +589,9 @@ class NewsRepository extends AbstractRepository {
return $query->execute();
}
protected function getConnection(): Connection {
return GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('pages');
}
}
<?php
namespace SGalinski\SgNews\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
class RelatedViewHelper extends AbstractViewHelper {
/**
* 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)');
}
/**
* Render the ViewHelper
* It works like the for-ViewHelper by running through the child content and adding the related news records to it
*
* @return string
*/
public function render() {
$news = $this->arguments['news'];
$newsRepository = GeneralUtility::makeInstance(NewsRepository::class);
$related = $newsRepository->findRelated($news);
$templateVariableContainer = $this->renderingContext->getVariableProvider();
$output = '';
if (isset($this->arguments['iteration'])) {
$iterationData = [
'index' => 0,
'cycle' => 1,
'total' => count($related)
];
}
foreach ($related as $relatedNews) {
$templateVariableContainer->add($this->arguments['as'], $relatedNews);
if (isset($this->arguments['iteration'])) {
$iterationData['isFirst'] = $iterationData['cycle'] === 1;
$iterationData['isLast'] = $iterationData['cycle'] === $iterationData['total'];
$iterationData['isEven'] = $iterationData['cycle'] % 2 === 0;
$iterationData['isOdd'] = !$iterationData['isEven'];
$templateVariableContainer->add($this->arguments['iteration'], $iterationData);
$iterationData['index']++;
$iterationData['cycle']++;
}
$output .= $this->renderChildren();
$templateVariableContainer->remove($this->arguments['as']);
if (isset($this->arguments['iteration'])) {
$templateVariableContainer->remove($this->arguments['iteration']);
}
}
return $output;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment