Skip to content
Snippets Groups Projects
Pagination.php 4.16 KiB
Newer Older
Stefan Galinski's avatar
Stefan Galinski committed

/***************************************************************
 *  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!
 ***************************************************************/

namespace SGalinski\SgJobs\Pagination;

use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;

/**
 * This class is a representation of the pagination
 * It contains functionality for handling the
 */
class Pagination {
	/**
	 * @var QueryResult
	 */
	private $queryResult;
	/**
	 * @var int
	 */
	private $currentPage;
	/**
	 * @var int
	 */
	private $limit;
	/**
	 * @var int
	 */
	private $nextPage;
	/**
	 * @var int
	 */
	private $previousPage;
	/**
	 * @var int
	 */
	private $lastPage;
	/**
	 * @var int
	 */
	private $firstPage;
	/**
	 * @var int
	 */
	private $startItem;
	/**
	 * @var int
	 */
	private $endItem;
	/**
	 * @var int
	 */
	private $totalItems;
	/**
	 * @var array
	 */
	private $items;

	public function __construct(QueryResult $queryResult, int $currentPage, int $limit) {
		$this->queryResult = $queryResult;
		$this->currentPage = $currentPage;
		$this->limit = $limit;
		$this->initialize();
	}

	public function initialize() {
		$this->firstPage = 1;
		$this->totalItems = $this->fetchTotalItemCount();
		$this->lastPage = (int) ceil($this->totalItems / $this->limit);
		// correct current page if out of bounds
		$this->currentPage = $this->currentPage < 1 ? 1 : min($this->currentPage, $this->lastPage);
		$this->previousPage = ($this->currentPage > 1) ? $this->currentPage - 1 : null;
		$this->nextPage = ($this->currentPage < $this->lastPage) ? $this->currentPage + 1 : null;
		$this->startItem = ($this->currentPage - 1) * $this->limit + 1;
		// correct startItem if out of bounds
		$this->startItem = max($this->startItem, 1);
		$this->endItem = ($this->currentPage - 1) * $this->limit + $this->limit;
		// correct endItem if out of bounds
		$this->endItem = min($this->endItem, $this->totalItems);
		$this->items = $this->fetchItems();
	}

	/**
	 * Reconfigure the query builder to fetch the total count of items
	 *
	 * @return int
	 */
	private function fetchTotalItemCount(): int {
		$query = clone $this->queryResult->getQuery();
		$query->setOffset(0)->setLimit(9999999);
		return $query->execute()->count();
	}

	/**
	 * Reconfigure the queryResult to fetch the items for the configured currentPage
	 *
	 * @return array
	 */
	private function fetchItems(): array {
		$query = clone $this->queryResult->getQuery();
		$query->setOffset($this->startItem - 1)->setLimit($this->limit);
		return $query->execute(TRUE);
	}

	/**
	 * @return int
	 */
	public function getCurrentPage(): int {
		return $this->currentPage;
	}

	/**
	 * @return int
	 */
	public function getLimit(): int {
		return $this->limit;
	}

	/**
	 * @return mixed
	 */
	public function getNextPage() {
		return $this->nextPage;
	}

	/**
	 * @return mixed
	 */
	public function getPreviousPage() {
		return $this->previousPage;
	}

	/**
	 * @return mixed
	 */
	public function getLastPage() {
		return $this->lastPage;
	}

	/**
	 * @return mixed
	 */
	public function getFirstPage() {
		return $this->firstPage;
	}

	/**
	 * @return mixed
	 */
	public function getStartItem() {
		return $this->startItem;
	}

	/**
	 * @return mixed
	 */
	public function getEndItem() {
		return $this->endItem;
	}

	/**
	 * @return mixed
	 */
	public function getTotalItems() {
		return $this->totalItems;
	}

	/**
	 * @return array
	 */
	public function getItems(): array {
		return $this->items;
	}
}