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; ...@@ -28,6 +28,9 @@ namespace SGalinski\SgNews\Domain\Repository;
use SGalinski\SgNews\Domain\Model\Author; use SGalinski\SgNews\Domain\Model\Author;
use SGalinski\SgNews\Domain\Model\News; 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\Generic\QueryResult;
use TYPO3\CMS\Extbase\Persistence\QueryInterface; use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface; use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
...@@ -514,23 +517,71 @@ class NewsRepository extends AbstractRepository { ...@@ -514,23 +517,71 @@ class NewsRepository extends AbstractRepository {
* @return QueryResultInterface * @return QueryResultInterface
*/ */
public function findRelated(News $news, int $limit = 0) { 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 = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(FALSE); $query->getQuerySettings()->setRespectStoragePage(FALSE);
$query->setOrderings([ $query->setOrderings([
'crdate' => QueryInterface::ORDER_DESCENDING 'crdate' => QueryInterface::ORDER_DESCENDING
]); ]);
$contains = []; $constraints = [];
if ($max) {
$constraints[] = $query->lessThan('lastUpdated', $max);
}
if ($min) {
$constraints[] = $query->greaterThan('lastUpdated', $min);
}
$tags = $news->getTags(); $tags = $news->getTags();
if ($tags->count() > 0) { if ($tags->count() > 0) {
foreach ($tags as $tag) { foreach ($tags as $tag) {
$contains[] = $query->contains('tags', $tag); $constraints[] = $query->contains('tags', $tag);
} }
} else { } else {
$contains[] = $query->equals('pid', $news->getPid()); $constraints[] = $query->equals('pid', $news->getPid());
} }
$query->matching( $query->matching(
$contains $constraints
); );
if ($limit > 0) { if ($limit > 0) {
$query->setLimit($limit); $query->setLimit($limit);
...@@ -538,4 +589,9 @@ class NewsRepository extends AbstractRepository { ...@@ -538,4 +589,9 @@ class NewsRepository extends AbstractRepository {
return $query->execute(); 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