Basic pagination
This commit is contained in:
parent
02fa02f979
commit
73ddb24296
5 changed files with 152 additions and 33 deletions
|
@ -12,48 +12,48 @@ body {
|
||||||
margin: 1.5em 0.75em;
|
margin: 1.5em 0.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
#top-nav {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav ul {
|
#top-nav ul {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav li {
|
#top-nav li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav li input,
|
#top-nav li input,
|
||||||
nav li a {
|
#top-nav li a {
|
||||||
color: black;
|
color: black;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav li a {
|
#top-nav li a {
|
||||||
padding: 0.2em 0.75em;
|
padding: 0.2em 0.75em;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav li.search {
|
#top-nav li.search {
|
||||||
background: white;
|
background: white;
|
||||||
margin: 0 0.25em;
|
margin: 0 0.25em;
|
||||||
padding: 0.2em 0.5em;
|
padding: 0.2em 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav li a:focus,
|
#top-nav li a:focus,
|
||||||
nav li a:hover {
|
#top-nav li a:hover {
|
||||||
color: firebrick;
|
color: firebrick;
|
||||||
border-bottom: 3px solid firebrick;
|
border-bottom: 3px solid firebrick;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav li.search input {
|
#top-nav li.search input {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
public_html/media/css/post-list.css
Normal file
33
public_html/media/css/post-list.css
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
.paginator-wrapper {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paginator {
|
||||||
|
margin: 2em auto 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paginator li {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paginator li a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.2em 0.5em;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
background: #eee;
|
||||||
|
border: 1px solid silver;
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paginator li.active a {
|
||||||
|
color: red;
|
||||||
|
background: mistyrose;
|
||||||
|
border-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paginator li.inactive a {
|
||||||
|
color: gray;
|
||||||
|
}
|
|
@ -12,11 +12,16 @@ class PostController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @route /posts
|
* @route /posts
|
||||||
|
* @route /posts/{page}
|
||||||
* @route /posts/{query}
|
* @route /posts/{query}
|
||||||
* @validate query .*
|
* @route /posts/{query}/{page}
|
||||||
|
* @validate page \d*
|
||||||
|
* @validate query [^\/]*
|
||||||
*/
|
*/
|
||||||
public function listAction($query = null)
|
public function listAction($page = 1, $query = null)
|
||||||
{
|
{
|
||||||
|
$this->context->stylesheets []= 'post-list.css';
|
||||||
|
|
||||||
#redirect requests in form of /posts/?query=... to canonical address
|
#redirect requests in form of /posts/?query=... to canonical address
|
||||||
$formQuery = InputHelper::get('query');
|
$formQuery = InputHelper::get('query');
|
||||||
if (!empty($formQuery))
|
if (!empty($formQuery))
|
||||||
|
@ -27,33 +32,48 @@ class PostController
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->context->subTitle = 'browsing posts';
|
$this->context->subTitle = 'browsing posts';
|
||||||
$this->context->searchQuery = $query;
|
$page = intval($page);
|
||||||
|
$postsPerPage = intval($this->config->browsing->postsPerPage);
|
||||||
|
|
||||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ListPosts);
|
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ListPosts);
|
||||||
|
|
||||||
$page = 1;
|
$buildDbQuery = function($dbQuery)
|
||||||
$params = [];
|
|
||||||
|
|
||||||
$allowedSafety = array_filter(PostSafety::getAll(), function($safety)
|
|
||||||
{
|
{
|
||||||
return PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts, PostSafety::toString($safety));
|
$dbQuery->from('post');
|
||||||
});
|
|
||||||
//todo safety [user choice]
|
|
||||||
|
|
||||||
$whereSql = 'WHERE safety IN (' . R::genSlots($allowedSafety) . ')';
|
$allowedSafety = array_filter(PostSafety::getAll(), function($safety)
|
||||||
$params = array_merge($params, $allowedSafety);
|
{
|
||||||
|
return PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts, PostSafety::toString($safety));
|
||||||
|
});
|
||||||
|
//todo safety [user choice]
|
||||||
|
|
||||||
//todo construct WHERE based on filters
|
$dbQuery->where('safety IN (' . R::genSlots($allowedSafety) . ')');
|
||||||
|
foreach ($allowedSafety as $s)
|
||||||
|
$dbQuery->put($s);
|
||||||
|
|
||||||
//todo construct ORDER based on filers
|
//todo construct WHERE based on filters
|
||||||
$orderSql = 'ORDER BY upload_date DESC';
|
|
||||||
|
|
||||||
$limitSql = 'LIMIT ? OFFSET ?';
|
//todo construct ORDER based on filers
|
||||||
$postsPerPage = intval($this->config->browsing->postsPerPage);
|
};
|
||||||
$params[] = $postsPerPage;
|
|
||||||
$params[] = ($page - 1) * $postsPerPage;
|
|
||||||
|
|
||||||
$posts = R::findAll('post', sprintf('%s %s %s', $whereSql, $orderSql, $limitSql), $params);
|
$countDbQuery = R::$f->begin();
|
||||||
|
$countDbQuery->select('COUNT(1) AS count');
|
||||||
|
$buildDbQuery($countDbQuery);
|
||||||
|
$postCount = intval($countDbQuery->get('row')['count']);
|
||||||
|
$pageCount = ceil($postCount / $postsPerPage);
|
||||||
|
|
||||||
|
$searchDbQuery = R::$f->begin();
|
||||||
|
$searchDbQuery->select('*');
|
||||||
|
$buildDbQuery($searchDbQuery);
|
||||||
|
$searchDbQuery->orderBy('upload_date DESC');
|
||||||
|
$searchDbQuery->limit('?')->put($postsPerPage);
|
||||||
|
$searchDbQuery->offset('?')->put(($page - 1) * $postsPerPage);
|
||||||
|
|
||||||
|
$posts = $searchDbQuery->get();
|
||||||
|
$this->context->transport->searchQuery = $query;
|
||||||
|
$this->context->transport->page = $page;
|
||||||
|
$this->context->transport->postCount = $postCount;
|
||||||
|
$this->context->transport->pageCount = $pageCount;
|
||||||
$this->context->transport->posts = $posts;
|
$this->context->transport->posts = $posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav>
|
<nav id="top-nav">
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<ul>
|
<ul>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -2,8 +2,74 @@
|
||||||
<p class="alert alert-error"><?php echo $this->context->transport->errorMessage ?></p>
|
<p class="alert alert-error"><?php echo $this->context->transport->errorMessage ?></p>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($this->context->transport->posts as $post): ?>
|
<?php foreach ($this->context->transport->posts as $post): ?>
|
||||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $post->id]) ?>">
|
<a href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $post['id']]) ?>">
|
||||||
<img src="<?php echo \Chibi\UrlHelper::route('post', 'thumb', ['id' => $post->id]) ?>" alt="@<?php echo $post->id ?>"/>
|
<img src="<?php echo \Chibi\UrlHelper::route('post', 'thumb', ['id' => $post['id']]) ?>" alt="@<?php echo $post['id'] ?>"/>
|
||||||
</a>
|
</a>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (!function_exists('pageUrl'))
|
||||||
|
{
|
||||||
|
function pageUrl($page)
|
||||||
|
{
|
||||||
|
$context = \Chibi\Registry::getContext();
|
||||||
|
$page = max(1, $page);
|
||||||
|
$page = min($context->transport->pageCount, $page);
|
||||||
|
$params = [];
|
||||||
|
$params['page'] = $page;
|
||||||
|
if (!empty($context->transport->searchQuery))
|
||||||
|
{
|
||||||
|
$params['query'] = $context->transport->searchQuery;
|
||||||
|
}
|
||||||
|
return \Chibi\UrlHelper::route('post', 'list', $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<nav class="paginator-wrapper">
|
||||||
|
<ul class="paginator">
|
||||||
|
<?php if ($this->context->transport->page > 1): ?>
|
||||||
|
<li>
|
||||||
|
<?php else: ?>
|
||||||
|
<li class="inactive">
|
||||||
|
<?php endif ?>
|
||||||
|
<a href="<?php echo pageUrl($this->context->transport->page - 1) ?>">
|
||||||
|
«
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$pagesVisible = [];
|
||||||
|
$pagesVisible []= 1;
|
||||||
|
$pagesVisible []= $this->context->transport->pageCount;
|
||||||
|
$delta = 3;
|
||||||
|
$pagesVisible = array_merge($pagesVisible, range($this->context->transport->page - $delta, $this->context->transport->page + $delta));
|
||||||
|
$pagesVisible = array_filter($pagesVisible, function($x) { return $x >= 1 and $x <= $this->context->transport->pageCount; });
|
||||||
|
$pagesVisible = array_unique($pagesVisible);
|
||||||
|
sort($pagesVisible, SORT_NUMERIC);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php foreach ($pagesVisible as $page): ?>
|
||||||
|
<?php if ($page == $this->context->transport->page): ?>
|
||||||
|
<li class="active">
|
||||||
|
<?php else: ?>
|
||||||
|
<li>
|
||||||
|
<?php endif ?>
|
||||||
|
<a href="<?php echo pageUrl($page) ?>">
|
||||||
|
<?php echo $page ?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php endforeach ?>
|
||||||
|
|
||||||
|
<?php if ($this->context->transport->page < $this->context->transport->pageCount): ?>
|
||||||
|
<li>
|
||||||
|
<?php else: ?>
|
||||||
|
<li class="inactive">
|
||||||
|
<?php endif ?>
|
||||||
|
<a href="<?php echo pageUrl($this->context->transport->page + 1) ?>">
|
||||||
|
»
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
Loading…
Reference in a new issue