From 922659cf75067070ccdc6ac2453e8a1821e0e445 Mon Sep 17 00:00:00 2001
From: Stefan Galinski <stefan@sgalinski.de>
Date: Mon, 18 Jul 2016 22:37:28 +0200
Subject: [PATCH] [FEATURE] Load more entries via AJAX inside the overview
 category menu

---
 Classes/Controller/OverviewController.php     | 64 ++++++++++++-------
 Classes/Domain/Repository/NewsRepository.php  |  6 +-
 .../Private/Templates/Overview/Overview.html  |  4 +-
 Resources/Public/Scripts/ScrollBrowser.js     | 58 ++++++++---------
 4 files changed, 76 insertions(+), 56 deletions(-)

diff --git a/Classes/Controller/OverviewController.php b/Classes/Controller/OverviewController.php
index 4857a91..b2ca37f 100644
--- a/Classes/Controller/OverviewController.php
+++ b/Classes/Controller/OverviewController.php
@@ -61,6 +61,29 @@ class OverviewController extends AbstractController {
 		}
 	}
 
+	/**
+	 * Highlights the best fitting news in the meta data of the page
+	 *
+	 * @param array $categoryIds
+	 */
+	protected function highlightBestFitNews(array $categoryIds) {
+		/** @var News $highlightedNews */
+		$highlightedNews = $this->newsRepository
+			->findLastUpdatedOrHighlightedNewsByCategories(1, FALSE, $categoryIds)->getFirst();
+		/** @var Category $category */
+		$category = $this->categoryRepository->findByUid($highlightedNews->getPid());
+		$highlightedNewsMetaData = NULL;
+		if ($category) {
+			$highlightedNewsMetaData = $this->getMetaDataForNews($highlightedNews, $category);
+		}
+
+		if ($highlightedNewsMetaData['image']) {
+			HeaderMetaDataService::addOgImageToHeader($highlightedNewsMetaData['image']);
+		} elseif ($highlightedNewsMetaData['teaserImage']) {
+			HeaderMetaDataService::addOgImageToHeader($highlightedNewsMetaData['teaserImage']);
+		}
+	}
+
 	/**
 	 * Renders the news overview grouped by categories
 	 *
@@ -71,18 +94,27 @@ class OverviewController extends AbstractController {
 		$newsLimitPerCategory = (int) $this->settings['newsLimit'];
 		$this->categoryRepository->setDefaultOrderings(['sorting' => Query::ORDER_ASCENDING]);
 
+		$offset = 0;
+		$currentPageBrowserPage = (int) GeneralUtility::_GP('tx_sgnews_pagebrowser')['currentPage'];
+		if ($currentPageBrowserPage && $newsLimitPerCategory) {
+			$offset = ($currentPageBrowserPage * $newsLimitPerCategory) - 1;
+		}
+
 		if ($this->settings['onlyNewsWithinThisPageSection']) {
 			/** @noinspection PhpUndefinedMethodInspection */
 			$categories = $this->categoryRepository->findByPid($GLOBALS['TSFE']->id);
 		} else {
 			$categories = $this->categoryRepository->findAll();
 		}
+
+		$categoryIds = [];
 		foreach ($categories as $category) {
 			/** @var Category $category */
 			$categoryId = $category->getUid();
+			$categoryIds[] = $categoryId;
 
 			$newsMetaData = [];
-			$news = $this->newsRepository->findAllSortedNewsByCategories([$categoryId], $newsLimitPerCategory);
+			$news = $this->newsRepository->findAllSortedNewsByCategories([$categoryId], $newsLimitPerCategory, $offset);
 			foreach ($news as $newsEntry) {
 				/** @var News $newsEntry */
 				$data = $this->getMetaDataForNews($newsEntry, $category);
@@ -98,22 +130,12 @@ class OverviewController extends AbstractController {
 			];
 		}
 
-		/** @var News $highlightedNews */
-		$highlightedNews = $this->newsRepository->findLastUpdatedOrHighlightedNewsByCategories(1, FALSE)->getFirst();
-		$category = $newsByCategory[$highlightedNews->getPid()]['category'];
-		$highlightedNewsMetaData = NULL;
-		if ($category) {
-			$highlightedNewsMetaData = $this->getMetaDataForNews($highlightedNews, $category);
-		}
-
-		if ($highlightedNewsMetaData['image']) {
-			HeaderMetaDataService::addOgImageToHeader($highlightedNewsMetaData['image']);
-		} elseif ($highlightedNewsMetaData['teaserImage']) {
-			HeaderMetaDataService::addOgImageToHeader($highlightedNewsMetaData['teaserImage']);
-		}
+		$this->highlightBestFitNews($categoryIds);
 
+		$newsCount = $this->newsRepository->newsCountByCategories($categoryIds);
+		$numberOfPages = ($newsLimitPerCategory <= 0 ? 0 : ceil($newsCount / $newsLimitPerCategory));
+		$this->view->assign('numberOfPages', $numberOfPages);
 		$this->view->assign('newsByCategory', $newsByCategory);
-		$this->view->assign('highlightedNewsMetaData', $highlightedNewsMetaData);
 	}
 
 	/**
@@ -137,8 +159,9 @@ class OverviewController extends AbstractController {
 			$categoriesById = [];
 			foreach ($categories as $category) {
 				/** @var $category Category */
-				$categoryIds[] = $category->getUid();
-				$categoriesById[$category->getUid()] = $category;
+				$categoryId = $category->getUid();
+				$categoryIds[] = $categoryId;
+				$categoriesById[$categoryId] = $category;
 			}
 
 			$newsCount = $this->newsRepository->newsCountByCategories($categoryIds);
@@ -162,12 +185,7 @@ class OverviewController extends AbstractController {
 			$newsMetaData[] = $data;
 		}
 
-		$firstNews = $newsMetaData[0];
-		if (is_array($firstNews) && $firstNews['image'] !== '') {
-			HeaderMetaDataService::addOgImageToHeader($firstNews['image']);
-		} elseif (is_array($firstNews) && $firstNews['teaserImage'] !== '') {
-			HeaderMetaDataService::addOgImageToHeader($firstNews['teaserImage']);
-		}
+		$this->highlightBestFitNews($categoryIds);
 
 		$numberOfPages = ($newsPerPage <= 0 ? 0 : ceil($newsCount / $newsPerPage));
 		$this->view->assign('numberOfPages', $numberOfPages);
diff --git a/Classes/Domain/Repository/NewsRepository.php b/Classes/Domain/Repository/NewsRepository.php
index 9cdf5f9..478a54b 100644
--- a/Classes/Domain/Repository/NewsRepository.php
+++ b/Classes/Domain/Repository/NewsRepository.php
@@ -51,6 +51,10 @@ class NewsRepository extends AbstractRepository {
 			$categoryConstraint[] = $query->in('pid', $categoryIds);
 		}
 
+		if ($categoryIds !== NULL) {
+			$query->matching($query->logicalAnd($categoryConstraint));
+		}
+
 		if ($limit > 0) {
 			$query->setLimit($limit);
 		}
@@ -65,7 +69,7 @@ class NewsRepository extends AbstractRepository {
 				'crdate' => QueryInterface::ORDER_DESCENDING,
 			]
 		);
-		return $query->matching($query->logicalAnd($categoryConstraint))->execute();
+		return $query->execute();
 	}
 
 	/**
diff --git a/Resources/Private/Templates/Overview/Overview.html b/Resources/Private/Templates/Overview/Overview.html
index f0b9fa3..5f59968 100644
--- a/Resources/Private/Templates/Overview/Overview.html
+++ b/Resources/Private/Templates/Overview/Overview.html
@@ -23,7 +23,7 @@
 				<f:for each="{newsByCategory}" as="dataByCategory">
 					<div class="tx-sgnews-categories-tabcontent" id="tx-sgnews-categories-tabcontent{dataByCategory.category.uid}">
 						<h4 class="tx-sgnews-tab-title">{dataByCategory.category.title}</h4>
-						<ul class="tx-sgnews-list row">
+						<ul class="tx-sgnews-list tx-sgnews-list-{dataByCategory.category.uid} row" data-category="{dataByCategory.category.uid}">
 							<f:for each="{dataByCategory.newsMetaData}" as="newsMetaDataEntry">
 								<li class="col-md-4 col-sm-6 col-xs-12">
 									<f:render partial="Teaser" arguments="{
@@ -45,5 +45,7 @@
 				</f:for>
 			</div>
 		</div>
+
+		<sg:pageBrowser numberOfPages="{numberOfPages}" />
 	</f:if>
 </f:section>
diff --git a/Resources/Public/Scripts/ScrollBrowser.js b/Resources/Public/Scripts/ScrollBrowser.js
index 395cbcb..9b45a2a 100644
--- a/Resources/Public/Scripts/ScrollBrowser.js
+++ b/Resources/Public/Scripts/ScrollBrowser.js
@@ -24,8 +24,8 @@
 
 var SG = SG || {};
 
-SG.ElementScrollBrowser = function(resultList) {
-	this.initialize(resultList);
+SG.ElementScrollBrowser = function() {
+	this.initialize();
 };
 
 SG.ElementScrollBrowser.prototype = {
@@ -39,11 +39,6 @@ SG.ElementScrollBrowser.prototype = {
 	 */
 	lock: false,
 
-	/**
-	 * @var object
-	 */
-	resultList: null,
-
 	/**
 	 * @var string|null
 	 */
@@ -64,10 +59,9 @@ SG.ElementScrollBrowser.prototype = {
 	 *
 	 * @return {void}
 	 */
-	initialize: function(resultList) {
+	initialize: function() {
 		$('.tx-sgnews-pagebrowser').css('display', 'none');
-		this.resultList = resultList;
-		this.loadIndicator = this.resultList.children(':last');
+		this.loadIndicator = $('.tx-sgnews-list').children(':last');
 		if (!this.loadIndicator.length) {
 			return;
 		}
@@ -86,22 +80,27 @@ SG.ElementScrollBrowser.prototype = {
 					{
 						url: this.url,
 
-						beforeSend: function() {
-							//var loader = '<li class="tx-sgnews-load-indicator"></li>';
-							//resultList.append(loader);
-							//resultList.find('.tx-sgnews-indicator').show();
-						},
-
 						success: function(response) {
-							var results = $(response).find('.tx-sgnews-list').children();
-							if (results.length) {
-								this.lastUrl = this.url;
-								this.url = $(response).find('.tx-pagebrowse-next a').attr('href');
-								//resultList.find('.tx-sgnews-load-indicator').remove();
-								resultList.append(results);
-								this.loadIndicator = resultList.children(':last');
-								this.lock = false;
-							}
+							var results = $(response).find('.tx-sgnews-list');
+							results.each(function(index, result) {
+								var $result = $(result);
+								var children = $result.children();
+								if (!children.length) {
+									return;
+								}
+
+								var $resultList = $('.tx-sgnews-list-' + $result.data('category'));
+								if (!$resultList.length) {
+									$resultList = $('.tx-sgnews-list');
+								}
+								$resultList.append(children);
+
+								this.loadIndicator = $resultList.children(':last');
+							});
+
+							this.lastUrl = this.url;
+							this.url = $(response).find('.tx-pagebrowse-next a').attr('href');
+							this.lock = false;
 						}.bind(this)
 					}
 				);
@@ -121,9 +120,6 @@ SG.ElementScrollBrowser.prototype = {
 	}
 };
 
-$(document).ready(
-	function() {
-		var resultList = $(this).find('.tx-sgnews-list');
-		(new SG.ElementScrollBrowser(resultList));
-	}
-);
+$(document).ready(function() {
+	(new SG.ElementScrollBrowser());
+});
-- 
GitLab