diff --git a/Classes/Controller/LogController.php b/Classes/Controller/LogController.php index f031052..192af0d 100644 --- a/Classes/Controller/LogController.php +++ b/Classes/Controller/LogController.php @@ -75,26 +75,31 @@ public function listAction(?Filter $filter = null): void { $filter = $filter ?? unserialize($GLOBALS['BE_USER']->getSessionData(self::FILTER_SESSION_KEY)) ?? (new Filter()); $filter->setPageId(0); - $logEntries = $this->logRepository->findByFilter($filter); + $currentPage = GeneralUtility::_GP('currentPage') ? (int)GeneralUtility::_GP('currentPage') : 1; + $itemsPerPage = 20; + + $logEntries = $this->logRepository->findByFilter($filter, $currentPage, $itemsPerPage); + $totalResultsCount = $this->logRepository->countByFilter($filter); + $totalPages = (int)(ceil($totalResultsCount / 20)); + $statistics = new Statistic($logEntries); + $statistics->setTraffic($this->logRepository->getTrafficSumByFilter($filter)); // Store filter data in session of backend user (used for pagination) $GLOBALS['BE_USER']->setSessionData(self::FILTER_SESSION_KEY, serialize($filter)); - $itemsPerPage = 20; - $currentPage = GeneralUtility::_GP('currentPage') ? (int)GeneralUtility::_GP('currentPage') : 1; - - $paginator = new ArrayPaginator($logEntries->toArray(), $currentPage, $itemsPerPage); - $pagination = new SimplePagination($paginator); - $this->view->assignMultiple([ - 'logs' => $paginator->getPaginatedItems(), + 'logs' => $logEntries, 'users' => $this->getUsers(), 'fileTypes' => $this->getFileTypes(), 'filter' => $filter, - 'statistic' => new Statistic($logEntries), - 'paginator' => $paginator, - 'pagination' => $pagination, - 'totalResultCount' => count($logEntries), + 'statistic' => $statistics, + 'pagination' => [ + 'totalPages' => $totalPages, + 'currentPage' => $currentPage, + 'previousPage' => ($currentPage - 1) > 0 ? $currentPage - 1 : null, + 'nextPage' => $totalPages > $currentPage ? $currentPage + 1 : null, + ], + 'totalResultCount' => $totalResultsCount, ]); } @@ -145,7 +150,6 @@ public function showAction(?Filter $filter = null): void $filter = $filter ?? unserialize($GLOBALS['BE_USER']->getSessionData(self::FILTER_SESSION_KEY)) ?? (new Filter()); $filter->setPageId($pageId); - $logEntries = $this->logRepository->findByFilter($filter); // Store filter data in session of backend user (used for pagination) $GLOBALS['BE_USER']->setSessionData(self::FILTER_SESSION_KEY, serialize($filter)); @@ -153,19 +157,26 @@ public function showAction(?Filter $filter = null): void $itemsPerPage = 20; $currentPage = GeneralUtility::_GP('currentPage') ? (int)GeneralUtility::_GP('currentPage') : 1; - $paginator = new ArrayPaginator($logEntries->toArray(), $currentPage, $itemsPerPage); - $pagination = new SimplePagination($paginator); + $logEntries = $this->logRepository->findByFilter($filter, $currentPage, $itemsPerPage); + $totalResultsCount = $this->logRepository->countByFilter($filter); + $totalPages = (int)(ceil($totalResultsCount / 20)); + $statistics = new Statistic($logEntries); + $statistics->setTraffic($this->logRepository->getTrafficSumByFilter($filter)); $this->view->assignMultiple([ - 'logs' => $paginator->getPaginatedItems(), + 'logs' => $logEntries, 'page' => BackendUtility::getRecord('pages', $pageId), 'users' => $this->getUsers(), 'fileTypes' => $this->getFileTypes(), 'filter' => $filter, - 'statistic' => new Statistic($logEntries), - 'paginator' => $paginator, - 'pagination' => $pagination, - 'totalResultCount' => count($logEntries), + 'statistic' => $statistics, + 'pagination' => [ + 'totalPages' => $totalPages, + 'currentPage' => $currentPage, + 'previousPage' => ($currentPage - 1) > 0 ? $currentPage - 1 : null, + 'nextPage' => $totalPages > $currentPage ? $currentPage + 1 : null, + ], + 'totalResultCount' => $totalResultsCount, ]); } diff --git a/Classes/Domain/Repository/LogRepository.php b/Classes/Domain/Repository/LogRepository.php index 3a9d793..0b1e2a4 100644 --- a/Classes/Domain/Repository/LogRepository.php +++ b/Classes/Domain/Repository/LogRepository.php @@ -18,6 +18,7 @@ use Leuchtfeuer\SecureDownloads\Domain\Transfer\Filter; use Leuchtfeuer\SecureDownloads\Domain\Transfer\Token\AbstractToken; use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException; @@ -54,7 +55,7 @@ public function createQuery(): QueryInterface * * @return QueryResultInterface The query result. */ - public function findByFilter(?Filter $filter): QueryResultInterface + public function findByFilter(?Filter $filter, int $currentPage = 1, int $itemsPerPage = 20): QueryResultInterface { $query = $this->createQuery(); @@ -66,9 +67,53 @@ public function findByFilter(?Filter $filter): QueryResultInterface } } + $query->setLimit($itemsPerPage); + $query->setOffset($itemsPerPage * ($currentPage - 1)); + return $query->execute(); } + public function countByFilter(?Filter $filter): int + { + $query = $this->createQuery(); + + if ($filter instanceof Filter) { + try { + $this->applyFilter($query, $filter); + } catch (InvalidQueryException $exception) { + // Do nothing for now. + } + } + + return $query->count(); + } + + public function getTrafficSumByFilter(?Filter $filter): float + { + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_securedownloads_domain_model_log'); + $constraints = []; + + // FileType + $this->applyFileTypePropertyToFilterQB($filter->getFileType(), $queryBuilder, $constraints); + + // User Type + $this->applyUserTypePropertyToFilterQB($filter, $queryBuilder, $constraints); + + // Period + $this->applyPeriodPropertyToFilterQB($filter, $queryBuilder, $constraints); + + // User and Page + $this->applyEqualPropertyToFilterQB((int)$filter->getFeUserId(), 'user', $queryBuilder, $constraints); + $this->applyEqualPropertyToFilterQB((int)$filter->getPageId(), 'page', $queryBuilder, $constraints); + + return (float)$queryBuilder + ->selectLiteral('SUM(file_size) AS sum') + ->from('tx_securedownloads_domain_model_log') + ->where(...$constraints) + ->executeQuery() + ->fetchOne() ?? 0.0; + } + /** * Applies the filter to a query object. * @@ -112,6 +157,13 @@ protected function applyFileTypePropertyToFilter($fileType, QueryInterface $quer } } + protected function applyFileTypePropertyToFilterQB(string $fileType, QueryBuilder $queryBuilder, array &$constraints): void + { + if ($fileType !== '' && $fileType !== '0') { + $constraints[] = $queryBuilder->expr()->eq('media_type', $queryBuilder->createNamedParameter($fileType)); + } + } + /** * Applies the user type property of the filter to the query object. * @@ -121,15 +173,21 @@ protected function applyFileTypePropertyToFilter($fileType, QueryInterface $quer */ protected function applyUserTypePropertyToFilter(Filter $filter, QueryInterface $query, array &$constraints): void { - if ($filter->getUserType() != 0) { - $userQuery = $query->equals('user', null); + if ($filter->getUserType() === Filter::USER_TYPE_LOGGED_ON) { + $constraints[] = $query->greaterThan('user', 0); + } + if ($filter->getUserType() === Filter::USER_TYPE_LOGGED_OFF) { + $constraints[] = $query->equals('user', 0); + } + } - if ($filter->getUserType() === Filter::USER_TYPE_LOGGED_ON) { - $constraints[] = $query->logicalNot($userQuery); - } - if ($filter->getUserType() === Filter::USER_TYPE_LOGGED_OFF) { - $constraints[] = $userQuery; - } + protected function applyUserTypePropertyToFilterQB(Filter $filter, QueryBuilder $queryBuilder, array &$constraints): void + { + if ($filter->getUserType() === Filter::USER_TYPE_LOGGED_ON) { + $constraints[] = $queryBuilder->expr()->gt('user', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)); + } + if ($filter->getUserType() === Filter::USER_TYPE_LOGGED_OFF) { + $constraints[] = $queryBuilder->expr()->eq('user', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)); } } @@ -152,6 +210,17 @@ protected function applyPeriodPropertyToFilter(Filter $filter, QueryInterface $q } } + protected function applyPeriodPropertyToFilterQB(Filter $filter, QueryBuilder $queryBuilder, array &$constraints): void + { + if ((int)$filter->getFrom() !== 0) { + $constraints[] = $queryBuilder->expr()->gte('tstamp', $queryBuilder->createNamedParameter($filter->getFrom(), \PDO::PARAM_INT)); + } + + if ((int)$filter->getTill() !== 0) { + $constraints[] = $queryBuilder->expr()->lte('tstamp', $queryBuilder->createNamedParameter($filter->getTill(), \PDO::PARAM_INT)); + } + } + /** * Applies given property of the filter to the query object. * @@ -167,6 +236,13 @@ protected function applyEqualPropertyToFilter(int $property, string $propertyNam } } + protected function applyEqualPropertyToFilterQB(int $property, string $propertyName, QueryBuilder $queryBuilder, array &$constraints): void + { + if ($property !== 0) { + $constraints[] = $queryBuilder->expr()->eq($propertyName, $queryBuilder->createNamedParameter($property, \PDO::PARAM_INT)); + } + } + /** * Creates a log entry in the database. * diff --git a/Classes/Domain/Transfer/Statistic.php b/Classes/Domain/Transfer/Statistic.php index 4cc952b..f0b5501 100644 --- a/Classes/Domain/Transfer/Statistic.php +++ b/Classes/Domain/Transfer/Statistic.php @@ -60,6 +60,11 @@ public function getTraffic(): float return $this->traffic; } + public function setTraffic(float $traffic): void + { + $this->traffic = $traffic; + } + public function getFrom(): \DateTime { return $this->from; diff --git a/Resources/Private/Layouts/Default.html b/Resources/Private/Layouts/Default.html index 7600649..1b3fa13 100644 --- a/Resources/Private/Layouts/Default.html +++ b/Resources/Private/Layouts/Default.html @@ -6,7 +6,7 @@
- {statistic.traffic -> f:format.bytes()} + {statistic.traffic -> f:format.bytes(decimals: '2')} {statistic.from -> f:format.date(format: '{f:translate(key: \'dateformat\')}')} {statistic.till -> f:format.date(format: '{f:translate(key: \'dateformat\')}')} diff --git a/Resources/Private/Partials/Backend/View.html b/Resources/Private/Partials/Backend/View.html index 525dc22..c2deaf1 100644 --- a/Resources/Private/Partials/Backend/View.html +++ b/Resources/Private/Partials/Backend/View.html @@ -34,69 +34,68 @@ - - +
    - +
  • - + Previous
  • - +
  • 1
  • - +
  • ...
  • - +
  • - - {pagination.previousPageNumber} + + {pagination.previousPage}
  • - {paginator.currentPageNumber} + {pagination.currentPage}
  • - +
  • - - {pagination.nextPageNumber} + + {pagination.nextPage}
  • - +
  • ...
  • - +
  • - - {pagination.lastPageNumber} + + {pagination.totalPages}
  • - +
  • - + Next
-
\ No newline at end of file +