Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Class paginator.
19
 *
20
 * @package    block_dash
21
 * @copyright  2019 bdecent gmbh <https://bdecent.de>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace block_dash\local;
26
use renderer_base;
27
 
28
/**
29
 * Class paginator.
30
 *
31
 * @package block_dash
32
 */
33
class paginator {
34
 
35
    /**
36
     * Template name.
37
     */
38
    const TEMPLATE = 'block_dash/paginator';
39
 
40
    /**
41
     * Per page default.
42
     */
43
    const PER_PAGE_DEFAULT = 10;
44
 
45
    /**
46
     * @var int Pagination per page.
47
     */
48
    protected $perpage;
49
 
50
    /**
51
     * @var int Pagination current page.
52
     */
53
    protected $currentpage;
54
 
55
    /**
56
     * @var callable Provided function to get count of items.
57
     */
58
    protected $countfunction;
59
 
60
    /**
61
     * @var bool If true, a human readable summary will be displayed above paginator (Showing x of x out of x).
62
     */
63
    protected $showpagesummary;
64
 
65
    /**
66
     * paginator constructor.
67
     * @param callable $countfunction
68
     * @param int $currentpage
69
     * @param int $perpage
70
     * @param bool $showpagesummary If true, a human readable summary will be displayed above paginator (Showing x of x out of x).
71
     * @throws \coding_exception
72
     */
73
    public function __construct(callable $countfunction, $currentpage = 0, $perpage = self::PER_PAGE_DEFAULT,
74
                                $showpagesummary = true) {
75
        if (!is_int($perpage)) {
76
            throw new \coding_exception('Per page value must be an integer.');
77
        }
78
 
79
        $this->perpage = $perpage;
80
        $this->currentpage = $currentpage;
81
        $this->countfunction = $countfunction;
82
        $this->showpagesummary = $showpagesummary;
83
    }
84
 
85
    /**
86
     * Get mustache template.
87
     *
88
     * @return string
89
     */
90
    public function get_template() {
91
        return self::TEMPLATE;
92
    }
93
 
94
    /**
95
     * Get limit from for query.
96
     *
97
     * @return float|int
98
     */
99
    public function get_limit_from() {
100
        return $this->get_current_page() * $this->perpage;
101
    }
102
 
103
    /**
104
     * Get per page for query.
105
     *
106
     * @return int
107
     */
108
    public function get_per_page() {
109
 
110
        return $this->perpage;
111
    }
112
 
113
    /**
114
     * Set per page for query.
115
     *
116
     * @param int $perpage
117
     */
118
    public function set_per_page($perpage) {
119
        $this->perpage = $perpage;
120
    }
121
 
122
    /**
123
     * Get current page for query.
124
     *
125
     * @return int
126
     */
127
    public function get_current_page() {
128
        return $this->currentpage;
129
    }
130
 
131
    /**
132
     * Set current page for query.
133
     *
134
     * @param int $page
135
     */
136
    public function set_current_page($page) {
137
        $this->currentpage = $page;
138
    }
139
 
140
    /**
141
     * Get count of all records.
142
     *
143
     * @return int
144
     */
145
    public function get_record_count() {
146
        $function = $this->countfunction;
147
        return $function();
148
    }
149
 
150
    /**
151
     * Get number of pages based on per page and count.
152
     *
153
     * @return int
154
     */
155
    public function get_page_count() {
156
        $count = $this->get_record_count();
157
        if ($count > 0) {
158
            return ceil($count / $this->get_per_page());
159
        }
160
 
161
        // Default to 0 pages.
162
        return 0;
163
    }
164
 
165
    /**
166
     * Get variables for template.
167
     *
168
     * @param renderer_base $output
169
     * @return array
170
     * @throws \coding_exception
171
     */
172
    public function export_for_template(renderer_base $output) {
173
        $count = $this->get_page_count();
174
        $frontdivider = false;
175
        $backdivider = false;
176
 
177
        $items = [];
178
        for ($i = 0; $i < $count; $i++) {
179
            $items[$i] = [
180
                'index' => $i,
181
                'page' => $i,
182
                'label' => $i + 1,
183
                'active' => $this->get_current_page() == $i,
184
            ];
185
        }
186
 
187
        // There's some hard coded values here. Maybe at some point clean up this algorithm.
188
        // But for now it works just fine.
189
        if ($this->get_current_page() >= 5) {
190
            for ($i = 1; $i < $this->get_current_page() - 2; $i++) {
191
                unset($items[$i]);
192
            }
193
            $frontdivider = true;
194
        }
195
 
196
        if ($this->get_page_count() - 1 >= $this->get_current_page() + 3) {
197
            $pagecount = $this->get_page_count();
198
            for ($i = $this->get_current_page() + 3; $i < $pagecount - 2; $i++) {
199
                unset($items[$i]);
200
                $backdivider = true;
201
            }
202
        }
203
 
204
        if ($frontdivider) {
205
            $items[1] = [
206
                'label' => '...',
207
                'disabled' => true,
208
            ];
209
            ksort($items);
210
        }
211
 
212
        if ($backdivider) {
213
            end($items);
214
            $items[key($items) - 1] = [
215
                'label' => '...',
216
                'disabled' => true,
217
            ];
218
            ksort($items);
219
        }
220
 
221
        // Add previous and next buttons.
222
        array_unshift($items, [
223
            'label' => get_string('previous'),
224
            'page' => $this->get_current_page() - 1,
225
            'disabled' => $this->get_current_page() == 0,
226
        ]);
227
 
228
        // Next button.
229
        $items[] = [
230
            'label' => get_string('next'),
231
            'page' => $this->get_current_page() + 1,
232
            'disabled' => $this->get_current_page() == $count - 1 || empty($count),
233
        ];
234
 
235
        $recordcount = $this->get_record_count();
236
        $limitto = (int)$this->get_per_page() + (int)$this->get_limit_from();
237
        if ($limitto > $recordcount) {
238
            $limitto = $recordcount;
239
        }
240
 
241
        // If there's no records hide the summary.
242
        if ($recordcount == 0) {
243
            $this->showpagesummary = false;
244
        }
245
 
246
        $summary = get_string('pagination_summary', 'block_dash', [
247
            'total' => $this->get_record_count(),
248
            'per_page' => $this->get_per_page(),
249
            'limit_from' => $this->get_limit_from() + 1,
250
            'limit_to' => $limitto,
251
        ]);
252
 
253
        return [
254
            'pages' => $items,
255
            'show_page_summary' => $this->showpagesummary,
256
            'summary' => $summary,
257
        ];
258
    }
259
}