1<?php
2/**
3 * XOOPS page navigation
4 *
5 * You may not change or alter any portion of this comment or credits
6 * of supporting developers from this source code or any supporting source code
7 * which is considered copyrighted (c) material of the original comment or credit authors.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13 * @license             GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
14 * @package             kernel
15 * @since               2.0.0
16 * @author              Kazumi Ono (http://www.myweb.ne.jp/, http://jp.xoops.org/)
17 */
18
19use Xmf\Request;
20
21defined('XOOPS_ROOT_PATH') || exit('Restricted access');
22
23/**
24 * Class XoopsPageNav
25 */
26class XoopsPageNav
27{
28    /**
29     * *#@+
30     *
31     * @access private
32     */
33    public $total;
34    public $perpage;
35    public $current;
36    public $url;
37    /**
38     * *#@-
39     */
40
41    /**
42     * Constructor
43     *
44     * @param int    $total_items   Total number of items
45     * @param int    $items_perpage Number of items per page
46     * @param int    $current_start First item on the current page
47     * @param string $start_name    Name for "start" or "offset"
48     * @param string $extra_arg     Additional arguments to pass in the URL
49     */
50    public function __construct($total_items, $items_perpage, $current_start, $start_name = 'start', $extra_arg = '')
51    {
52        $this->total   = (int)$total_items;
53        $this->perpage = (int)$items_perpage;
54        $this->current = (int)$current_start;
55        $this->extra   = $extra_arg;
56        if ($extra_arg != '' && (substr($extra_arg, -5) !== '&amp;' || substr($extra_arg, -1) !== '&')) {
57            $this->extra = '&amp;' . $extra_arg;
58        }
59        $this->url = htmlspecialchars(Request::getString('PHP_SELF', '', 'SERVER'), ENT_QUOTES) . '?' . trim($start_name) . '=';
60    }
61
62    /**
63     * Create text navigation
64     *
65     * @param  integer $offset
66     * @return string
67     */
68    public function renderNav($offset = 4)
69    {
70        $ret = '';
71        if ($this->total <= $this->perpage) {
72            return $ret;
73        }
74        if (($this->total != 0) && ($this->perpage != 0)) {
75            $total_pages = ceil($this->total / $this->perpage);
76            if ($total_pages > 1) {
77                $ret .= '<div id="xo-pagenav">';
78                $prev = $this->current - $this->perpage;
79                if ($prev >= 0) {
80                    $ret .= '<a class="xo-pagarrow" href="' . $this->url . $prev . $this->extra . '"><u>&laquo;</u></a> ';
81                }
82                $counter      = 1;
83                $current_page = (int)floor(($this->current + $this->perpage) / $this->perpage);
84                while ($counter <= $total_pages) {
85                    if ($counter == $current_page) {
86                        $ret .= '<strong class="xo-pagact" >(' . $counter . ')</strong> ';
87                    } elseif (($counter > $current_page - $offset && $counter < $current_page + $offset) || $counter == 1 || $counter == $total_pages) {
88                        if ($counter == $total_pages && $current_page < $total_pages - $offset) {
89                            $ret .= '... ';
90                        }
91                        $ret .= '<a class="xo-counterpage" href="' . $this->url . (($counter - 1) * $this->perpage) . $this->extra . '">' . $counter . '</a> ';
92                        if ($counter == 1 && $current_page > 1 + $offset) {
93                            $ret .= '... ';
94                        }
95                    }
96                    ++$counter;
97                }
98                $next = $this->current + $this->perpage;
99                if ($this->total > $next) {
100                    $ret .= '<a class="xo-pagarrow" href="' . $this->url . $next . $this->extra . '"><u>&raquo;</u></a> ';
101                }
102                $ret .= '</div> ';
103            }
104        }
105
106        return $ret;
107    }
108
109    /**
110     * Create a navigational dropdown list
111     *
112     * @param  boolean $showbutton Show the "Go" button?
113     * @return string
114     */
115    public function renderSelect($showbutton = false)
116    {
117        if ($this->total < $this->perpage) {
118            return null;
119        }
120        $total_pages = ceil($this->total / $this->perpage);
121        $ret         = '';
122        if ($total_pages > 1) {
123            $ret = '<form name="pagenavform">';
124            $ret .= '<select name="pagenavselect" onchange="location=this.options[this.options.selectedIndex].value;">';
125            $counter      = 1;
126            $current_page = (int)floor(($this->current + $this->perpage) / $this->perpage);
127            while ($counter <= $total_pages) {
128                if ($counter == $current_page) {
129                    $ret .= '<option value="' . $this->url . (($counter - 1) * $this->perpage) . $this->extra . '" selected>' . $counter . '</option>';
130                } else {
131                    $ret .= '<option value="' . $this->url . (($counter - 1) * $this->perpage) . $this->extra . '">' . $counter . '</option>';
132                }
133                ++$counter;
134            }
135            $ret .= '</select>';
136            if ($showbutton) {
137                $ret .= '&nbsp;<input type="submit" value="' . _GO . '" />';
138            }
139            $ret .= '</form>';
140        }
141
142        return $ret;
143    }
144
145    /**
146     * Create navigation with images
147     *
148     * @param  integer $offset
149     * @return string
150     */
151    public function renderImageNav($offset = 4)
152    {
153        if ($this->total < $this->perpage) {
154            return null;
155        }
156        $total_pages = ceil($this->total / $this->perpage);
157        $ret         = '';
158        if ($total_pages > 1) {
159            $ret  = '<table><tr>';
160            $prev = $this->current - $this->perpage;
161            if ($prev >= 0) {
162                $ret .= '<td class="pagneutral"><a href="' . $this->url . $prev . $this->extra . '">&lt;</a></td><td><img src="' . XOOPS_URL . '/images/blank.gif" width="6" alt="" /></td>';
163            } else {
164                $ret .= '<td class="pagno"></a></td><td><img src="' . XOOPS_URL . '/images/blank.gif" width="6" alt="" /></td>';
165            }
166            $counter      = 1;
167            $current_page = (int)floor(($this->current + $this->perpage) / $this->perpage);
168            while ($counter <= $total_pages) {
169                if ($counter == $current_page) {
170                    $ret .= '<td class="pagact"><strong>' . $counter . '</strong></td>';
171                } elseif (($counter > $current_page - $offset && $counter < $current_page + $offset) || $counter == 1 || $counter == $total_pages) {
172                    if ($counter == $total_pages && $current_page < $total_pages - $offset) {
173                        $ret .= '<td class="paginact">...</td>';
174                    }
175                    $ret .= '<td class="paginact"><a href="' . $this->url . (($counter - 1) * $this->perpage) . $this->extra . '">' . $counter . '</a></td>';
176                    if ($counter == 1 && $current_page > 1 + $offset) {
177                        $ret .= '<td class="paginact">...</td>';
178                    }
179                }
180                ++$counter;
181            }
182            $next = $this->current + $this->perpage;
183            if ($this->total > $next) {
184                $ret .= '<td><img src="' . XOOPS_URL . '/images/blank.gif" width="6" alt="" /></td><td class="pagneutral"><a href="' . $this->url . $next . $this->extra . '">&gt;</a></td>';
185            } else {
186                $ret .= '<td><img src="' . XOOPS_URL . '/images/blank.gif" width="6" alt="" /></td><td class="pagno"></td>';
187            }
188            $ret .= '</tr></table>';
189        }
190
191        return $ret;
192    }
193}
194