Rewrite pagination functions

Remove global variable $page from pagination functions, refactor
them and add inline documentation.
This commit is contained in:
Dmitriy Simushev 2014-01-20 11:52:22 +00:00
parent a2451c0575
commit ee834e6621
12 changed files with 197 additions and 146 deletions

View File

@ -606,9 +606,8 @@ function setup_redirect_links($threadid, $operator, $token)
$groupscount = count($groups); $groupscount = count($groups);
} }
prepare_pagination(max($operatorscount, $groupscount), 8); $p = pagination_info(max($operatorscount, $groupscount), 8);
$p = $page['pagination']; $page['pagination'] = $p;
$limit = $p['limit'];
$operators = array_slice($operators, $p['start'], $p['end'] - $p['start']); $operators = array_slice($operators, $p['start'], $p['end'] - $p['start']);
$groups = array_slice($groups, $p['start'], $p['end'] - $p['start']); $groups = array_slice($groups, $p['start'], $p['end'] - $p['start']);

View File

@ -15,14 +15,24 @@
* limitations under the License. * limitations under the License.
*/ */
// Import namespaces and classes of the core /**
use Mibew\Database; * String used to separate pagination links from each other
*/
define('PAGINATION_SPACING', "   ");
$pagination_spacing = "   "; /**
$links_on_page = 5; * Count of pagination links on the page
*/
define('PAGINATION_LINKS_ON_PAGE', 5);
function generate_pagination_link($page, $title) /**
{ * Builds HTML markup for pagination link based on currently requested page.
*
* @param int $page Page number
* @param string $title Link title
* @return string HTML markup
*/
function generate_pagination_link($page, $title) {
$lnk = $_SERVER['REQUEST_URI']; $lnk = $_SERVER['REQUEST_URI'];
$href = preg_replace("/\?page=\d+\&/", "?", preg_replace("/\&page=\d+/", "", $lnk)); $href = preg_replace("/\?page=\d+\&/", "?", preg_replace("/\&page=\d+/", "", $lnk));
$href .= strstr($href, "?") ? "&page=$page" : "?page=$page"; $href .= strstr($href, "?") ? "&page=$page" : "?page=$page";
@ -41,104 +51,106 @@ function generate_pagination_image($style_path, $id, $alt) {
return "<img src=\"" . $style_path . "/images/$id.gif\" border=\"0\" alt=\"" . htmlspecialchars($alt) . "\"/>"; return "<img src=\"" . $style_path . "/images/$id.gif\" border=\"0\" alt=\"" . htmlspecialchars($alt) . "\"/>";
} }
function prepare_pagination($items_count, $default_items_per_page = 15) /**
{ * Returns information about pagination.
global $page; *
* @param int $items_count Count of items which are separated by pages.
* @param int $default_items_per_page Count of items per page.
* @return array|boolean Associative array of pagination info or FALSE if the
* info array cannot be build. Info array contatins the following keys:
* - page: int, number of current page.
* - total: int, total pages count.
* - items: int, items per page.
* - count: int, total items count.
* - start: int, index of item to start from.
* - end: int, index of item to end at.
*/
function pagination_info($items_count, $default_items_per_page = 15) {
if ($items_count) { if ($items_count) {
$items_per_page = verifyparam("items", "/^\d{1,3}$/", $default_items_per_page); $items_per_page = verifyparam("items", "/^\d{1,3}$/", $default_items_per_page);
if ($items_per_page < 2) if ($items_per_page < 2) {
$items_per_page = 2; $items_per_page = 2;
}
$total_pages = div($items_count + $items_per_page - 1, $items_per_page); $total_pages = div($items_count + $items_per_page - 1, $items_per_page);
$curr_page = verifyparam("page", "/^\d{1,6}$/", 1); $curr_page = verifyparam("page", "/^\d{1,6}$/", 1);
if ($curr_page < 1) if ($curr_page < 1) {
$curr_page = 1; $curr_page = 1;
if ($curr_page > $total_pages) }
if ($curr_page > $total_pages) {
$curr_page = $total_pages; $curr_page = $total_pages;
}
$start_index = ($curr_page - 1) * $items_per_page; $start_index = ($curr_page - 1) * $items_per_page;
$end_index = min($start_index + $items_per_page, $items_count); $end_index = min($start_index + $items_per_page, $items_count);
$page['pagination'] =
array("page" => $curr_page, "items" => $items_per_page, "total" => $total_pages,
"count" => $items_count, "start" => $start_index, "end" => $end_index,
"limit" => "LIMIT $start_index," . ($end_index - $start_index));
} else {
$page['pagination'] = true;
}
}
function setup_pagination($items, $default_items_per_page = 15) return array(
{ "page" => $curr_page,
global $page; "items" => $items_per_page,
prepare_pagination($items ? count($items) : 0, $default_items_per_page); "total" => $total_pages,
if ($items && count($items) > 0) { "count" => $items_count,
$p = $page['pagination']; "start" => $start_index,
$page['pagination.items'] = array_slice($items, $p['start'], $p['end'] - $p['start']); "end" => $end_index,
);
} else { } else {
$page['pagination.items'] = false; return false;
} }
} }
/** /**
* Selects rows from database taking pagination into account. * Prepare all info that needed to build paginated items
* *
* @global array $page * @param array $items Items which are separated by pages.
* @param string $fields Selected fields * @param int $default_items_per_page Count of items per page.
* @param string $table Table name in database * @return array Associative array of with the following keys:
* @param string $conditions Where close * - info: array, pagination info. See description of the result of
* @param string $order Order clause * pagination_info function for details.
* @param string $countfields Field, substituted in SQL COUNT function * - items: slice of items to display.
* @param array $values Associative array of substituted values. Keys are named placeholders in the
* query(see \Mibew\Database::query() and its $values parameter description)
*
* @see \Mibew\Database::query()
*/ */
function select_with_pagintation($fields, $table, $conditions, $order, $countfields, $values) function setup_pagination($items, $default_items_per_page = 15) {
{ if (count($items) > 0) {
global $page; $info = pagination_info(count($items), $default_items_per_page);
$db = Database::getInstance(); if ($info) {
$items_slice = array_slice(
list($count) = $db->query( $items,
"select count(". ($countfields ? $countfields : "*") .") from {$table} " . $info['start'],
"where " . (count($conditions) ? implode(" and ", $conditions) : "") . $info['end'] - $info['start']
($order ? " " . $order : ""),
$values,
array(
'return_rows' => Database::RETURN_ONE_ROW,
'fetch_type' => Database::FETCH_NUM
)
); );
return array(
prepare_pagination($count); 'info' => $info,
if ($count) { 'items' => $items_slice,
$p = $page['pagination'];
$limit = $p['limit'];
$page['pagination.items'] = $db->query(
"select {$fields} from {$table} " .
"where " . (count($conditions) ? implode(" and ", $conditions) : "") .
($order ? " " . $order : "") . " " . $limit,
$values,
array('return_rows' => Database::RETURN_ALL_ROWS)
); );
} else {
$page['pagination.items'] = array();
} }
}
return array(
'info' => false,
'items' => false,
);
} }
function setup_empty_pagination() /**
{ * Builds HTML markup for pagination pager.
global $page; *
$page['pagination.items'] = false; * @param string $style_path Root path of the style.
$page['pagination'] = false; * @param array $pagination Pagination info. See description of the result of
} * pagination_info function for details.
* @param bool $bottom Indicates if pager will be displayed at the bottom of a
function generate_pagination($style_path, $pagination, $bottom = true) * page.
{ * @return string HTML markup
global $pagination_spacing, $links_on_page; */
$result = getlocal2("tag.pagination.info", function generate_pagination($style_path, $pagination, $bottom = true) {
array($pagination['page'], $pagination['total'], $pagination['start'] + 1, $pagination['end'], $pagination['count'])) . "<br/>"; $result = getlocal2(
"tag.pagination.info",
array(
$pagination['page'],
$pagination['total'],
$pagination['start'] + 1,
$pagination['end'],
$pagination['count']
)
) . "<br/>";
if ($pagination['total'] > 1) { if ($pagination['total'] > 1) {
if (!$bottom) { if (!$bottom) {
@ -149,25 +161,39 @@ function generate_pagination($style_path, $pagination, $bottom = true)
$result .= "<div class='pagination'>"; $result .= "<div class='pagination'>";
$curr_page = $pagination['page']; $curr_page = $pagination['page'];
$minPage = max($curr_page - $links_on_page, 1); $minPage = max($curr_page - PAGINATION_LINKS_ON_PAGE, 1);
$maxPage = min($curr_page + $links_on_page, $pagination['total']); $maxPage = min($curr_page + PAGINATION_LINKS_ON_PAGE, $pagination['total']);
if ($curr_page > 1) { if ($curr_page > 1) {
$result .= generate_pagination_link($curr_page - 1, generate_pagination_image($style_path, "prevpage", getlocal("tag.pagination.previous"))) . $pagination_spacing; $result .= generate_pagination_link(
$curr_page - 1,
generate_pagination_image(
$style_path,
"prevpage",
getlocal("tag.pagination.previous")
)
) . PAGINATION_SPACING;
} }
for ($i = $minPage; $i <= $maxPage; $i++) { for ($i = $minPage; $i <= $maxPage; $i++) {
$title = abs($curr_page - $i) >= $links_on_page && $i != 1 ? "..." : $i; $title = abs($curr_page - $i) >= PAGINATION_LINKS_ON_PAGE && $i != 1 ? "..." : $i;
if ($i != $curr_page) if ($i != $curr_page)
$result .= generate_pagination_link($i, $title); $result .= generate_pagination_link($i, $title);
else else
$result .= "<span class=\"pagecurrent\">$title</span>"; $result .= "<span class=\"pagecurrent\">$title</span>";
if ($i < $maxPage) if ($i < $maxPage)
$result .= $pagination_spacing; $result .= PAGINATION_SPACING;
} }
if ($curr_page < $pagination['total']) { if ($curr_page < $pagination['total']) {
$result .= $pagination_spacing . generate_pagination_link($curr_page + 1, generate_pagination_image($style_path, "nextpage", getlocal("tag.pagination.next"))); $result .= PAGINATION_SPACING . generate_pagination_link(
$curr_page + 1,
generate_pagination_image(
$style_path,
"nextpage",
getlocal("tag.pagination.next")
)
);
} }
$result .= "</div>"; $result .= "</div>";
} }

View File

@ -58,7 +58,10 @@ $blockedList = $db->query(
$page['title'] = getlocal("page_bans.title"); $page['title'] = getlocal("page_bans.title");
$page['menuid'] = "blocked"; $page['menuid'] = "blocked";
setup_pagination($blockedList); $pagination = setup_pagination($blockedList);
$page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items'];
prepare_menu($operator); prepare_menu($operator);
$page_style = new PageStyle(PageStyle::currentStyle()); $page_style = new PageStyle(PageStyle::currentStyle());

View File

@ -88,10 +88,12 @@ if (isset($_GET['act']) && $_GET['act'] == 'delete') {
} }
} }
# get messages // Get messages and setup pagination
$messages = load_canned_messages($lang, $groupid); $messages = load_canned_messages($lang, $groupid);
setup_pagination($messages); $pagination = setup_pagination($messages);
$page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items'];
# form values # form values

View File

@ -79,25 +79,53 @@ if ($query !== false) {
} }
// Load threads // Load threads
select_with_pagintation("DISTINCT {chatthread}.*", list($threads_count) = $db->query(
"{chatthread}, {chatmessage}", "SELECT COUNT(DISTINCT {chatthread}.dtmcreated) " .
"FROM {chatthread}, {chatmessage} " .
"WHERE {chatmessage}.threadid = {chatthread}.threadid " .
"AND ({chatthread}.invitationstate = :invitation_accepted " .
"OR {chatthread}.invitationstate = :invitation_not_invited) " .
"AND (" . implode(' OR ', $searchConditions) . ")",
$values,
array( array(
"{chatmessage}.threadid = {chatthread}.threadid", 'return_rows' => Database::RETURN_ONE_ROW,
"({chatthread}.invitationstate = :invitation_accepted " . 'fetch_type' => Database::FETCH_NUM
"OR {chatthread}.invitationstate = :invitation_not_invited)", )
"(" . implode(' or ', $searchConditions) . ")" );
),
"order by {chatthread}.dtmcreated DESC",
"DISTINCT {chatthread}.dtmcreated", $values);
// Build Thread object $pagination_info = pagination_info($threads_count);
foreach ($page['pagination.items'] as $key => $item) {
$page['pagination.items'][$key] = Thread::createFromDbInfo($item); if ($threads_count && $pagination_info) {
$page['pagination'] = $pagination_info;
$limit_start = intval($pagination_info['start']);
$limit_end = intval($pagination_info['end'] - $pagination_info['start']);
$threads_list = $db->query(
"SELECT DISTINCT {chatthread}.* " .
"FROM {chatthread}, {chatmessage} " .
"WHERE {chatmessage}.threadid = {chatthread}.threadid " .
"AND ({chatthread}.invitationstate = :invitation_accepted " .
"OR {chatthread}.invitationstate = :invitation_not_invited) " .
"AND (" . implode(' OR ', $searchConditions) . ") " .
"ORDER BY {chatthread}.dtmcreated DESC " .
"LIMIT " . $limit_start . ", " .$limit_end,
$values,
array('return_rows' => Database::RETURN_ALL_ROWS)
);
foreach ($threads_list as $item) {
$page['pagination.items'][] = Thread::createFromDbInfo($item);
}
} else {
$page['pagination'] = false;
$page['pagination.items'] = false;
} }
$page['formq'] = topage($query); $page['formq'] = topage($query);
} else { } else {
setup_empty_pagination(); $page['pagination'] = false;
$page['pagination.items'] = false;
} }
$page['formtype'] = $searchType; $page['formtype'] = $searchType;

View File

@ -216,7 +216,9 @@ foreach ($allkeys as $key) {
$order = verifyparam("sort", "/^(id|l1)$/", "id"); $order = verifyparam("sort", "/^(id|l1)$/", "id");
usort($result, "compare_localization_by_$order"); usort($result, "compare_localization_by_$order");
setup_pagination($result, 100); $pagination = setup_pagination($result, 100);
$page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items'];
$page['formtarget'] = $target; $page['formtarget'] = $target;
$page['formsource'] = $source; $page['formsource'] = $source;

View File

@ -65,7 +65,12 @@ function threads_by_userid($userid)
$found = threads_by_userid($userid); $found = threads_by_userid($userid);
prepare_menu($operator); prepare_menu($operator);
setup_pagination($found, 6);
// Setup pagination
$pagination = setup_pagination($found, 6);
$page['pagination'] = $pagination['info'];
$page['pagination.items'] = $pagination['items'];
foreach ($page['pagination.items'] as $key => $item) { foreach ($page['pagination.items'] as $key => $item) {
$page['pagination.items'][$key] = Thread::createFromDbInfo($item); $page['pagination.items'][$key] = Thread::createFromDbInfo($item);
} }

View File

@ -40,8 +40,6 @@ require_once(dirname(__FILE__).'/inc_errors.php');
</div> </div>
<br clear="all"/> <br clear="all"/>
<?php if( $page['pagination'] ) { ?>
<table class="list"> <table class="list">
<thead> <thead>
<tr class="header"> <tr class="header">
@ -100,10 +98,9 @@ if( $page['pagination.items'] ) {
</tbody> </tbody>
</table> </table>
<?php <?php
if( $page['pagination.items'] ) { if ($page['pagination']) {
echo "<br/>"; echo "<br/>";
echo generate_pagination($page['stylepath'], $page['pagination']); echo generate_pagination($page['stylepath'], $page['pagination']);
}
} }
?> ?>
<script type="text/javascript" language="javascript"><!-- <script type="text/javascript" language="javascript"><!--

View File

@ -63,8 +63,6 @@ require_once(dirname(__FILE__).'/inc_errors.php');
</div> </div>
<br clear="all"/> <br clear="all"/>
<?php if( $page['pagination'] ) { ?>
<table class="translate"> <table class="translate">
<thead> <thead>
<tr class="header"><th> <tr class="header"><th>
@ -107,10 +105,9 @@ if( $page['pagination.items'] ) {
</tbody> </tbody>
</table> </table>
<?php <?php
if( $page['pagination.items'] ) { if ($page['pagination']) {
echo "<br/>"; echo "<br/>";
echo generate_pagination($page['stylepath'], $page['pagination']); echo generate_pagination($page['stylepath'], $page['pagination']);
}
} }
?> ?>

View File

@ -59,8 +59,6 @@ function tpl_content() { global $page;
<br/> <br/>
<?php if( $page['pagination'] ) { ?>
<table class="list"> <table class="list">
<thead> <thead>
<tr class="header"> <tr class="header">
@ -117,10 +115,9 @@ if( $page['pagination.items'] ) {
</tbody> </tbody>
</table> </table>
<?php <?php
if( $page['pagination.items'] ) { if ($page['pagination']) {
echo "<br/>"; echo "<br/>";
echo generate_pagination($page['stylepath'], $page['pagination']); echo generate_pagination($page['stylepath'], $page['pagination']);
}
} }
?> ?>

View File

@ -65,10 +65,9 @@ function tpl_content() { global $page;
<?php <?php
if( $page['pagination'] ) { if ($page['pagination']) {
if( $page['pagination.items'] ) {
echo generate_pagination($page['stylepath'], $page['pagination'], false); echo generate_pagination($page['stylepath'], $page['pagination'], false);
} }
?> ?>
<table class="translate"> <table class="translate">
@ -111,10 +110,9 @@ if( $page['pagination.items'] ) {
</tbody> </tbody>
</table> </table>
<?php <?php
if( $page['pagination.items'] ) { if ($page['pagination']) {
echo "<br/>"; echo "<br/>";
echo generate_pagination($page['stylepath'], $page['pagination']); echo generate_pagination($page['stylepath'], $page['pagination']);
}
} }
?> ?>

View File

@ -22,8 +22,6 @@ function tpl_content() { global $page;
<br /> <br />
<br /> <br />
<?php if( $page['pagination'] ) { ?>
<table class="list"> <table class="list">
<thead> <thead>
<tr class="header"> <tr class="header">
@ -70,10 +68,9 @@ if( $page['pagination.items'] ) {
</tbody> </tbody>
</table> </table>
<?php <?php
if( $page['pagination.items'] ) { if ($page['pagination']) {
echo "<br/>"; echo "<br/>";
echo generate_pagination($page['stylepath'], $page['pagination']); echo generate_pagination($page['stylepath'], $page['pagination']);
}
} }
?> ?>