Test Failed
Push — 1.0.0-dev ( c68446...90e1c2 )
by nguereza
02:35
created

Pagination::setPaginationQueryString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
    defined('ROOT_PATH') || exit('Access denied');
3
    /**
4
     * TNH Framework
5
     *
6
     * A simple PHP framework using HMVC architecture
7
     *
8
     * This content is released under the MIT License (MIT)
9
     *
10
     * Copyright (c) 2017 TNH Framework
11
     *
12
     * Permission is hereby granted, free of charge, to any person obtaining a copy
13
     * of this software and associated documentation files (the "Software"), to deal
14
     * in the Software without restriction, including without limitation the rights
15
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
     * copies of the Software, and to permit persons to whom the Software is
17
     * furnished to do so, subject to the following conditions:
18
     *
19
     * The above copyright notice and this permission notice shall be included in all
20
     * copies or substantial portions of the Software.
21
     *
22
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
     * SOFTWARE.
29
     */
30
31
    class Pagination {
32
        
33
        /**
34
         * The list of loaded config
35
         * @var array
36
         */
37
        private $config = array();
38
39
        /**
40
         * The pagination current query string
41
         * @var string
42
         */
43
        private $paginationQueryString = null;
44
45
        /**
46
         * Create an instance of pagination
47
         * @param array $overwriteConfig the list of configuration to overwrite the 
48
         * defined configuration in config_pagination.php
49
         */
50
        public function __construct(array $overwriteConfig = array()) {
51
            $config = array();
52
            if (file_exists(CONFIG_PATH . 'config_pagination.php')) {
53
                require CONFIG_PATH . 'config_pagination.php';
54
            } 
55
            $config = array_merge($config, $overwriteConfig);
56
            $this->config = $config;
57
            //put it gobally
58
            get_instance()->config->setAll($config);
59
            unset($config);
60
        }
61
62
63
        /**
64
         * Set the pagination custom configuration to overwrite the default configuration in
65
         * config_pagination.php
66
         * @param array $config the configuration to overwrite
67
         */
68
        public function setConfig(array $config = array()) {
69
            if (!empty($config)) {
70
                $this->config = array_merge($this->config, $config);
71
                get_instance()->config->setAll($config);
72
            }
73
        }
74
75
        /**
76
         * Return the value of the pagination configuration
77
         * 
78
         * @return array
79
         */
80
        public function getConfig() {
81
            return $this->config;
82
        }
83
84
        /**
85
         * Return the value of the pagination query string
86
         * @return string
87
         */
88
        public function getPaginationQueryString() {
89
            return $this->paginationQueryString;
90
        }
91
92
        /**
93
        * Set the value of the pagination query string
94
        * @param string $pQueryString the new value
95
        * @return object
96
        */
97
        public function setPaginationQueryString($pQueryString) {
98
            $this->paginationQueryString = $pQueryString;
99
            return $this;
100
        }
101
102
        /**
103
         * Determine automatically the value of the pagination query string
104
         * Using the REQUEST URI
105
         * 
106
         * @return object
107
         */
108
        public function determinePaginationQueryStringValue() {
109
            $pageQueryName = $this->config['page_query_string_name'];
110
            $queryString = get_instance()->url->queryString();
111
            $currentUrl = get_instance()->url->current();
112
            $query = '';
113
            if ($queryString == '') {
114
                $query = '?' . $pageQueryName . '=';
115
            } else {
116
                $tab = explode($pageQueryName . '=', $queryString);
117
                $nb = count($tab);
118
                if ($nb == 1) {
119
                    $query = '?' . $queryString . '&' . $pageQueryName . '=';
120
                } else {
121
                    if ($tab[0] == '') {
122
                        $query = '?' . $pageQueryName . '=';
123
                    } else {
124
                        $query = '?' . $tab[0] . '' . $pageQueryName . '=';
125
                    }
126
                }
127
            }
128
            $temp = explode('?', $currentUrl);
129
            $query = $temp[0] . $query;
130
            $this->paginationQueryString = $query;
131
            return $this;
132
        }
133
134
        /**
135
         * Generate the pagination link
136
         * @param  int $totalRows the total number of data
137
         * @param  int $currentPageNumber the current page number
138
         * 
139
         * @return null|string the pagination link
140
         */
141
        public function getLink($totalRows, $currentPageNumber) {
142
            $numberOfLink = $this->config['nb_link'];
143
            $numberOfRowPerPage = $this->config['pagination_per_page'];
144
            if (empty($this->paginationQueryString)) {
145
                //determine the pagination query string value
146
                $this->determinePaginationQueryStringValue();
147
            }
148
            //************************************
149
            $navbar = null;
150
            $numberOfPage = (int) ceil($totalRows / $numberOfRowPerPage);
151
            $currentPageNumber = (int) $currentPageNumber;
152
            $numberOfLink = (int) $numberOfLink;
153
            $numberOfRowPerPage = (int) $numberOfRowPerPage;
154
			
155
            if ($currentPageNumber <= 0) {
156
                $currentPageNumber = 1;
157
            }
158
            if ($numberOfPage <= 1 || $numberOfLink <= 0 || $numberOfRowPerPage <= 0) {
159
                return $navbar;
160
            }
161
            return $this->buildPaginationNavbar($currentPageNumber, $numberOfPage);
162
        }
163
164
        /**
165
         * Build the pagination navbar with the link numbers
166
         * @param  int $currentPageNumber the current page number
167
         * @param  int $numberOfPage      the total number of page
168
         * @return string
169
         */
170
        protected function buildPaginationNavbar($currentPageNumber, $numberOfPage) {
171
            $values = $this->getPaginationBeginAndEndNumber($currentPageNumber, $numberOfPage);
172
            $begin = $values['begin'];
173
            $end   = $values['end'];
174
            $navbar = null;
175
            if ($currentPageNumber == 1) {
176
                $navbar .= $this->buildPaginationLinkForFirstPage($begin, $end, $currentPageNumber);
177
            } else if ($currentPageNumber > 1 && $currentPageNumber < $numberOfPage) {
178
                $navbar .= $this->buildPaginationLinkForMiddlePage($begin, $end, $currentPageNumber);
179
            } else if ($currentPageNumber == $numberOfPage) {
180
                $navbar .= $this->buildPaginationLinkForLastPage($begin, $end, $currentPageNumber);
181
            }
182
            $navbar = $this->config['pagination_open'] . $navbar . $this->config['pagination_close'];
183
            return $navbar;
184
        }
185
186
        /**
187
         * Get the pagination begin and end link numbers
188
         * @param  int $currentPageNumber the current page number
189
         * @param  int $numberOfPage      the total number of page
190
         * @return array                    the begin and end number
191
         */
192
        protected function getPaginationBeginAndEndNumber($currentPageNumber, $numberOfPage) {
193
            $start = null;
194
            $begin = null;
195
            $end   = null;
196
            $numberOfLink = $this->config['nb_link'];
197
            if ($numberOfLink % 2 == 0) {
198
                $start = $currentPageNumber - ($numberOfLink / 2) + 1;
199
                $end   = $currentPageNumber + ($numberOfLink / 2);
200
            } else {
201
                $start = $currentPageNumber - floor($numberOfLink / 2);
202
                $end   = $currentPageNumber + floor($numberOfLink / 2);
203
            }
204
            if ($start <= 1) {
205
                $begin = 1;
206
                $end   = $numberOfLink;
207
            } else if ($start > 1 && $end < $numberOfPage) {
208
                $begin = $start;
209
            } else {
210
                $begin = ($numberOfPage - $numberOfLink) + 1;
211
                $end   = $numberOfPage;
212
            }
213
            if ($numberOfPage <= $numberOfLink) {
214
                $begin = 1;
215
                $end = $numberOfPage;
216
            }
217
            return array(
218
                        'begin' => (int) $begin,
219
                        'end' => (int) $end
220
                    );
221
        }
222
223
        /**
224
         * Build the pagination link for the page in the middle
225
         * @param  int $begin             the pagination begin number
226
         * @param  int $end               the pagination end number
227
         * @param  int $currentPageNumber the pagination current page number
228
         * @return string                    
229
         */
230
        protected function buildPaginationLinkForMiddlePage($begin, $end, $currentPageNumber) {
231
            $navbar = null;
232
            $query = $this->paginationQueryString;
233
            $navbar .= $this->config['previous_open'] 
234
                            . '<a href="' . $query . ($currentPageNumber - 1) . '">' 
235
                            . $this->config['previous_text'] . '</a>' . $this->config['previous_close'];
236
            for ($i = $begin; $i <= $end; $i++) {
237
                if ($i == $currentPageNumber) {
238
                    $navbar .= $this->config['active_link_open'] . $currentPageNumber . $this->config['active_link_close'];
239
                } else {
240
                    $navbar .= $this->config['digit_open'] 
241
                                    . '<a href="' . $query . $i . '"' 
242
                                    . attributes_to_string($this->config['attributes']) . '>' . $i . '</a>' 
243
                                    . $this->config['digit_close'];
244
                }
245
            }
246
            $navbar .= $this->config['next_open'] . '<a href="' . $query . ($currentPageNumber + 1) . '">' 
247
                       . $this->config['next_text'] . '</a>' . $this->config['next_close'];
248
            return $navbar;
249
        }
250
251
252
         /**
253
         * Build the pagination link for the first page
254
         * @see Pagination::buildPaginationLinkForFirstAndLastPage
255
         */
256
        protected function buildPaginationLinkForFirstPage($begin, $end, $currentPageNumber) {
257
            return $this->buildPaginationLinkForFirstAndLastPage($begin, $end, $currentPageNumber, 'first');
258
        }
259
260
        /**
261
         * Build the pagination link for the last page
262
         * @see Pagination::buildPaginationLinkForFirstAndLastPage
263
         */
264
        protected function buildPaginationLinkForLastPage($begin, $end, $currentPageNumber) {
265
            return $this->buildPaginationLinkForFirstAndLastPage($begin, $end, $currentPageNumber, 'last');
266
        }
267
268
        /**
269
         * Build the pagination link for the first and last page
270
         * 
271
         * @param  int $begin the pagination begin number
272
         * @param  int $end the pagination end number
273
         * @param  int $currentPageNumber the pagination current page number
274
         * @param string $type can be "first", "last"
275
         * 
276
         * @return string                    
277
         */
278
        protected function buildPaginationLinkForFirstAndLastPage($begin, $end, $currentPageNumber, $type = 'first') {
279
            $navbar = null;
280
            $query = $this->paginationQueryString;
281
            if ($type == 'last') {
282
                $navbar .= $this->config['previous_open'] 
283
                        . '<a href="' . $query . ($currentPageNumber - 1) . '">' 
284
                        . $this->config['previous_text'] . '</a>' . $this->config['previous_close'];
285
            }
286
            for ($i = $begin; $i <= $end; $i++) {
287
                if ($i == $currentPageNumber) {
288
                    $navbar .= $this->config['active_link_open'] . $currentPageNumber . $this->config['active_link_close'];
289
                } else {
290
                    $navbar .= $this->config['digit_open'] 
291
                            . '<a href="' . $query . $i . '"' 
292
                            . attributes_to_string($this->config['attributes']) . '>' . $i . '</a>' 
293
                            . $this->config['digit_close'];
294
                }
295
            }
296
            if ($type == 'first') {
297
                $navbar .= $this->config['next_open']
298
                            . '<a href="' . $query . ($currentPageNumber + 1) . '">' 
299
                            . $this->config['next_text'] . '</a>' . $this->config['next_close'];
300
            }
301
            return $navbar;
302
        }
303
    }
304