From cb9097e0199cf6afca3f144edb7d7addaec1cb59 Mon Sep 17 00:00:00 2001 From: Thomas Lange Date: Thu, 22 Jul 2021 21:04:02 +0200 Subject: Add pagination for search results Add pagination for search results in the admin and default theme. --- admin/page/search.php | 37 ++++++++++++++++++++++++++++++++---- admin/post/search.php | 37 ++++++++++++++++++++++++++++++++---- core/include/search/main.php | 23 +++++++++++++++++++++- core/namespace/ORM/Repository.php | 24 +++++++++++++++++------ theme/admin/html/page/search.php | 4 ++++ theme/admin/html/post/search.php | 4 ++++ theme/default/html/search/result.php | 2 ++ 7 files changed, 116 insertions(+), 15 deletions(-) diff --git a/admin/page/search.php b/admin/page/search.php index 8135b91..85448df 100644 --- a/admin/page/search.php +++ b/admin/page/search.php @@ -10,25 +10,54 @@ const AUTHENTICATION = TRUE; #=============================================================================== require '../../core/application.php'; +#=============================================================================== +# Get repositories +#=============================================================================== +$PageRepository = Application::getRepository('Page'); +$UserRepository = Application::getRepository('User'); + +#=============================================================================== +# Pagination +#=============================================================================== +$site_size = Application::get('ADMIN.PAGE.LIST_SIZE'); +$site_sort = Application::get('ADMIN.PAGE.LIST_SORT'); + +$currentSite = HTTP::GET('site') ?? 1; +$currentSite = intval($currentSite); +$offset = ($currentSite-1) * $site_size; + #=============================================================================== # Check for search request #=============================================================================== if($search = HTTP::GET('q')) { - $PageRepository = Application::getRepository('Page'); - $UserRepository = Application::getRepository('User'); - - foreach($PageRepository->search($search) as $Page) { + foreach($PageRepository->search($search, [], $site_size, $offset) as $Page) { $User = $UserRepository->find($Page->get('user')); $templates[] = generatePageItemTemplate($Page, $User); } } +#=============================================================================== +# Create pagination only if there are results +#=============================================================================== +if($count = $PageRepository->getLastSearchOverallCount()) { + $last = ceil($count / $site_size); + + $pagination_data = [ + 'THIS' => $currentSite, + 'LAST' => $last, + 'HTML' => createPaginationTemplate( + $currentSite, $last, Application::getAdminURL('page/search.php') + ) + ]; +} + #=============================================================================== # Build document #=============================================================================== $SearchTemplate = Template\Factory::build('page/search'); $SearchTemplate->set('QUERY', $search); $SearchTemplate->set('PAGES', $templates ?? []); +$SearchTemplate->set('PAGINATION', $pagination_data ?? []); $MainTemplate = Template\Factory::build('main'); $MainTemplate->set('NAME', $Language->text('title_page_search')); diff --git a/admin/post/search.php b/admin/post/search.php index b438201..a270ccb 100644 --- a/admin/post/search.php +++ b/admin/post/search.php @@ -10,25 +10,54 @@ const AUTHENTICATION = TRUE; #=============================================================================== require '../../core/application.php'; +#=============================================================================== +# Get repositories +#=============================================================================== +$PostRepository = Application::getRepository('Post'); +$UserRepository = Application::getRepository('User'); + +#=============================================================================== +# Pagination +#=============================================================================== +$site_size = Application::get('ADMIN.POST.LIST_SIZE'); +$site_sort = Application::get('ADMIN.POST.LIST_SORT'); + +$currentSite = HTTP::GET('site') ?? 1; +$currentSite = intval($currentSite); +$offset = ($currentSite-1) * $site_size; + #=============================================================================== # Check for search request #=============================================================================== if($search = HTTP::GET('q')) { - $PostRepository = Application::getRepository('Post'); - $UserRepository = Application::getRepository('User'); - - foreach($PostRepository->search($search) as $Post) { + foreach($PostRepository->search($search, [], $site_size, $offset) as $Post) { $User = $UserRepository->find($Post->get('user')); $templates[] = generatePostItemTemplate($Post, $User); } } +#=============================================================================== +# Create pagination only if there are results +#=============================================================================== +if($count = $PostRepository->getLastSearchOverallCount()) { + $last = ceil($count / $site_size); + + $pagination_data = [ + 'THIS' => $currentSite, + 'LAST' => $last, + 'HTML' => createPaginationTemplate( + $currentSite, $last, Application::getAdminURL('post/search.php') + ) + ]; +} + #=============================================================================== # Build document #=============================================================================== $SearchTemplate = Template\Factory::build('post/search'); $SearchTemplate->set('QUERY', $search); $SearchTemplate->set('POSTS', $templates ?? []); +$SearchTemplate->set('PAGINATION', $pagination_data ?? []); $MainTemplate = Template\Factory::build('main'); $MainTemplate->set('NAME', $Language->text('title_post_search')); diff --git a/core/include/search/main.php b/core/include/search/main.php index 564f0dd..14c2ac9 100644 --- a/core/include/search/main.php +++ b/core/include/search/main.php @@ -10,6 +10,16 @@ $Language = Application::getLanguage(); $PostRepository = Application::getRepository('Post'); $UserRepository = Application::getRepository('User'); +#=============================================================================== +# Pagination +#=============================================================================== +$site_size = Application::get('POST.LIST_SIZE'); +$site_sort = Application::get('POST.LIST_SORT'); + +$currentSite = HTTP::GET('site') ?? 1; +$currentSite = intval($currentSite); +$offset = ($currentSite-1) * $site_size; + if($search = HTTP::GET('q')) { $filter = [ 'day' => HTTP::GET('d'), @@ -17,7 +27,7 @@ if($search = HTTP::GET('q')) { 'year' => HTTP::GET('y') ]; - if(!$posts = $PostRepository->search($search, $filter)) { + if(!$posts = $PostRepository->search($search, $filter, $site_size, $offset)) { $message = $Language->text('search_no_results', escapeHTML($search)); } } @@ -49,6 +59,9 @@ if(!empty($posts)) { $templates[] = generatePostItemTemplate($Post, $User); } + $count = $PostRepository->getLastSearchOverallCount(); + $last = ceil($count / $site_size); + $ResultTemplate = Template\Factory::build('search/result'); $ResultTemplate->set('FORM', $form_data); $ResultTemplate->set('SEARCH', $search_data); @@ -56,6 +69,14 @@ if(!empty($posts)) { 'LIST' => $templates ?? [] ]); + $ResultTemplate->set('PAGINATION', [ + 'THIS' => $currentSite, + 'LAST' => $last, + 'HTML' => createPaginationTemplate( + $currentSite, $last, Application::getURL('search/') + ) + ]); + $MainTemplate = Template\Factory::build('main'); $MainTemplate->set('HTML', $ResultTemplate); $MainTemplate->set('HEAD', [ diff --git a/core/namespace/ORM/Repository.php b/core/namespace/ORM/Repository.php index b2778f4..44bd62e 100644 --- a/core/namespace/ORM/Repository.php +++ b/core/namespace/ORM/Repository.php @@ -7,6 +7,9 @@ abstract class Repository { protected $Database; protected $entities = []; + # See "search" method for more details. + private $lastSearchOverallCount = 0; + abstract public static function getTableName(): string; abstract public static function getClassName(): string; @@ -262,10 +265,6 @@ abstract class Repository { # Get entities based on search query #=============================================================================== public function search(string $search, array $filter = [], int $limit = NULL, int $offset = 0): array { - if($search === '*') { - return $this->getAll([], NULL, 20); - } - if(strlen($filter['year'] ?? '') !== 0) { $extend[] = 'YEAR(time_insert) = ? AND'; $params[] = $filter['year']; @@ -287,14 +286,27 @@ abstract class Repository { $dateparts = implode(' ', $extend ?? []); - $query = 'SELECT * FROM %s WHERE %s MATCH(name, body) + $query = 'SELECT *, COUNT(*) OVER() AS _count FROM %s WHERE %s MATCH(name, body) AGAINST(? IN BOOLEAN MODE) %s'; $query = sprintf($query, static::getTableName(), $dateparts, $limit ?? 'LIMIT 20'); $Statement = $this->Database->prepare($query); $Statement->execute(array_merge($params ?? [], [$search])); - return $this->fetchEntities($Statement); + if($entities = $this->fetchEntities($Statement)) { + # Temporary (maybe crappy) solution to prevent a second count query. + # Virtual column "_count" does not belong into the entities. + $this->lastSearchOverallCount = $entities[0]->get('_count'); + } + + return $entities; + } + + #=============================================================================== + # Get the number of overall results for the last performed search + #=============================================================================== + public function getLastSearchOverallCount(): int { + return $this->lastSearchOverallCount; } #=============================================================================== diff --git a/theme/admin/html/page/search.php b/theme/admin/html/page/search.php index 240e512..906502f 100644 --- a/theme/admin/html/page/search.php +++ b/theme/admin/html/page/search.php @@ -21,4 +21,8 @@ + + + + diff --git a/theme/admin/html/post/search.php b/theme/admin/html/post/search.php index 835a4ef..1afc5e7 100644 --- a/theme/admin/html/post/search.php +++ b/theme/admin/html/post/search.php @@ -21,4 +21,8 @@ + + + + diff --git a/theme/default/html/search/result.php b/theme/default/html/search/result.php index 2dac0ec..8de0e25 100644 --- a/theme/default/html/search/result.php +++ b/theme/default/html/search/result.php @@ -34,3 +34,5 @@ + + -- cgit v1.2.3