Passed
Push — 1.0.0-dev ( 8edc19...2b6704 )
by nguereza
03:32
created

Pagination::getPaginationBeginAndEndNumber()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 32
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 25
nc 12
nop 2
dl 0
loc 32
rs 8.8977
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 GNU GPL License (GPL)
9
	 *
10
	 * Copyright (C) 2017 Tony NGUEREZA
11
	 *
12
	 * This program is free software; you can redistribute it and/or
13
	 * modify it under the terms of the GNU General Public License
14
	 * as published by the Free Software Foundation; either version 3
15
	 * of the License, or (at your option) any later version.
16
	 *
17
	 * This program is distributed in the hope that it will be useful,
18
	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
	 * GNU General Public License for more details.
21
	 *
22
	 * You should have received a copy of the GNU General Public License
23
	 * along with this program; if not, write to the Free Software
24
	 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25
	*/
26
27
    class Pagination{
28
        
29
		/**
30
         * The list of loaded config
31
         * @var array
32
         */
33
        private $config = array();
34
35
        /**
36
         * The pagination current query string
37
         * @var string
38
         */
39
        private $paginationQueryString = null;
40
41
        /**
42
         * Create an instance of pagination
43
         * @param array $overwriteConfig the list of configuration to overwrite the defined configuration in config_pagination.php
44
         */
45
        public function __construct(array $overwriteConfig = array()){
46
            if (file_exists(CONFIG_PATH . 'config_pagination.php')){
47
                $config = array();
48
                require_once CONFIG_PATH . 'config_pagination.php';
49
                if (empty($config) || ! is_array($config)){
50
                    show_error('No configuration found in ' . CONFIG_PATH . 'config_pagination.php');
51
                }
52
				else{
53
					$config = array_merge($config, $overwriteConfig);
54
					$this->config = $config;
55
                    //put it gobally
56
					Config::setAll($config);
57
					unset($config);
58
				}
59
            }
60
            else{
61
                show_error('Unable to find the pagination configuration file');
62
            }
63
        }
64
65
66
        /**
67
         * Set the pagination custom configuration to overwrite the default configuration in
68
         * config_pagination.php
69
         * @param array $config the configuration to overwrite
70
         */
71
        public function setConfig(array $config = array()){
72
            if (! empty($config)){
73
                $this->config = array_merge($this->config, $config);
74
                Config::setAll($config);
75
            }
76
        }
77
78
        /**
79
         * Return the value of the pagination configuration
80
         * 
81
         * @return array
82
         */
83
        public function getConfig(){
84
            return $this->config;
85
        }
86
87
        /**
88
         * Return the value of the pagination query string
89
         * @return string
90
         */
91
        public function getPaginationQueryString(){
92
            return $this->paginationQueryString;
93
        }
94
95
         /**
96
         * Set the value of the pagination query string
97
         * @param string $paginationQueryString the new value
98
         * @return object
99
         */
100
        public function setPaginationQueryString($paginationQueryString){
101
            $this->paginationQueryString = $paginationQueryString;
102
            return $this;
103
        }
104
105
        /**
106
         * Determine automatically the value of the pagination query string
107
         * Using the REQUEST URI
108
         * 
109
         * @return object
110
         */
111
        public function determinePaginationQueryStringValue(){
112
            $pageQueryName = $this->config['page_query_string_name'];
113
            $queryString = Url::queryString();
114
            $currentUrl = Url::current();
115
            $query = '';
116
             if ($queryString == ''){
117
                $query = '?' . $pageQueryName . '=';
118
            }
119
            else{
120
                $tab = explode($pageQueryName . '=', $queryString);
121
                $nb = count($tab);
122
                if ($nb == 1){
123
                    $query = '?' . $queryString . '&' . $pageQueryName . '=';
124
                }
125
                else{
126
                    if ($tab[0] == ''){
127
                        $query = '?' . $pageQueryName . '=';
128
                    }
129
                    else{
130
                        $query = '?' . $tab[0] . '' . $pageQueryName . '=';
131
                    }
132
                }
133
            }
134
            $temp = explode('?', $currentUrl);
135
            $query = $temp[0] . $query;
136
            $this->paginationQueryString = $query;
137
            return $this;
138
        }
139
140
        /**
141
         * Generate the pagination link
142
         * @param  int $totalRows the total number of data
143
         * @param  int $currentPageNumber the current page number
144
         * 
145
         * @return string the pagination link
146
         */
147
        public function getLink($totalRows, $currentPageNumber){
148
            $numberOfLink = $this->config['nb_link'];
149
			$numberOfRowPerPage = $this->config['pagination_per_page'];
150
            if (empty($this->paginationQueryString)){
151
                //determine the pagination query string value
152
                $this->determinePaginationQueryStringValue();
153
            }
154
            //************************************
155
            $navbar = '';
156
            $numberOfPage = ceil($totalRows / $numberOfRowPerPage);
157
            $currentPageNumber = (int) $currentPageNumber;
158
            $numberOfLink = (int) $numberOfLink;
159
            $numberOfRowPerPage = (int) $numberOfRowPerPage;
160
			
161
            if ($currentPageNumber <= 0){
162
				$currentPageNumber = 1;
163
			}
164
            if ($numberOfPage <= 1 || $numberOfLink <= 0 || $numberOfRowPerPage <= 0) {
165
                return $navbar;
166
            }
167
            return $this->buildPaginationNavbar($currentPageNumber, $numberOfPage);
0 ignored issues
show
Bug introduced by
$numberOfPage of type double is incompatible with the type integer expected by parameter $numberOfPage of Pagination::buildPaginationNavbar(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

167
            return $this->buildPaginationNavbar($currentPageNumber, /** @scrutinizer ignore-type */ $numberOfPage);
Loading history...
168
        }
169
170
        /**
171
         * Build the pagination navbar with the link numbers
172
         * @param  int $currentPageNumber the current page number
173
         * @param  int $numberOfPage      the total number of page
174
         * @return string
175
         */
176
        protected function buildPaginationNavbar($currentPageNumber, $numberOfPage){
177
            $values = $this->getPaginationBeginAndEndNumber($currentPageNumber, $numberOfPage);
178
            $begin = $values['begin'];
179
            $end   = $values['end'];
180
            $navbar = null;
181
            if ($currentPageNumber == 1){
182
                $navbar .= $this->buildPaginationLinkForFirstPage($begin, $end, $currentPageNumber);
0 ignored issues
show
Bug introduced by
It seems like $begin can also be of type double; however, parameter $begin of Pagination::buildPaginationLinkForFirstPage() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

182
                $navbar .= $this->buildPaginationLinkForFirstPage(/** @scrutinizer ignore-type */ $begin, $end, $currentPageNumber);
Loading history...
183
            }
184
            else if ($currentPageNumber > 1 && $currentPageNumber < $numberOfPage){
185
                $navbar .= $this->buildPaginationLinkForMiddlePage($begin, $end, $currentPageNumber);
0 ignored issues
show
Bug introduced by
It seems like $begin can also be of type double; however, parameter $begin of Pagination::buildPaginationLinkForMiddlePage() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

185
                $navbar .= $this->buildPaginationLinkForMiddlePage(/** @scrutinizer ignore-type */ $begin, $end, $currentPageNumber);
Loading history...
186
            }
187
            else if ($currentPageNumber == $numberOfPage){
188
               $navbar .= $this->buildPaginationLinkForLastPage($begin, $end, $currentPageNumber);
0 ignored issues
show
Bug introduced by
It seems like $begin can also be of type double; however, parameter $begin of Pagination::buildPaginationLinkForLastPage() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

188
               $navbar .= $this->buildPaginationLinkForLastPage(/** @scrutinizer ignore-type */ $begin, $end, $currentPageNumber);
Loading history...
189
            }
190
            $navbar = $this->config['pagination_open'] . $navbar . $this->config['pagination_close'];
191
            return $navbar;
192
        }
193
194
        /**
195
         * Get the pagination begin and end link numbers
196
         * @param  int $currentPageNumber the current page number
197
         * @param  int $numberOfPage      the total number of page
198
         * @return array                    the begin and end number
199
         */
200
        protected function getPaginationBeginAndEndNumber($currentPageNumber, $numberOfPage){
201
            $start = null;
202
            $begin = null;
203
            $end   = null;
204
            $numberOfLink = $this->config['nb_link'];
205
            if ($numberOfLink % 2 == 0){
206
                $start = $currentPageNumber - ($numberOfLink / 2) + 1;
207
                $end   = $currentPageNumber + ($numberOfLink / 2);
208
            }
209
            else{
210
                $start = $currentPageNumber - floor($numberOfLink / 2);
211
                $end   = $currentPageNumber + floor($numberOfLink / 2);
212
            }
213
            if ($start <= 1){
214
                $begin = 1;
215
                $end   = $numberOfLink;
216
            }
217
            else if ($start > 1 && $end < $numberOfPage){
218
                $begin = $start;
219
                $end = $end;
220
            }
221
            else{
222
                $begin = ($numberOfPage - $numberOfLink) + 1;
223
                $end   = $numberOfPage;
224
            }
225
            if ($numberOfPage <= $numberOfLink){
226
                $begin = 1;
227
                $end = $numberOfPage;
228
            }
229
            return array(
230
                        'begin' => $begin,
231
                        'end' => $end
232
                    );
233
        }
234
235
        /**
236
         * Build the pagination link for the first page
237
         * @param  int $begin             the pagination begin number
238
         * @param  int $end               the pagination end number
239
         * @param  int $currentPageNumber the pagination current page number
240
         * @return string                    
241
         */
242
        protected function buildPaginationLinkForFirstPage($begin, $end, $currentPageNumber){
243
            $navbar = null;
244
            $query = $this->paginationQueryString;
245
            for($i = $begin; $i <= $end; $i++){
246
                if ($i == $currentPageNumber){
247
                    $navbar .= $this->config['active_link_open'] . $currentPageNumber . $this->config['active_link_close'];
248
                }
249
                else{
250
                    $navbar .= $this->config['digit_open'] 
251
                            . '<a href="' . $query . $i . '" ' . attributes_to_string($this->config['attributes']) . '>' . $i . '</a>' 
252
                            . $this->config['digit_close'];
253
                }
254
            }
255
            $navbar .= $this->config['next_open']
256
                         . '<a href="' . $query . ($currentPageNumber + 1) . '">' 
257
                         . $this->config['next_text'] . '</a>' . $this->config['next_close'];
258
            return $navbar;
259
        }
260
261
        /**
262
         * Build the pagination link for the page in the middle
263
         * @param  int $begin             the pagination begin number
264
         * @param  int $end               the pagination end number
265
         * @param  int $currentPageNumber the pagination current page number
266
         * @return string                    
267
         */
268
        protected function buildPaginationLinkForMiddlePage($begin, $end, $currentPageNumber){
269
            $navbar = null;
270
            $query = $this->paginationQueryString;
271
            $navbar .= $this->config['previous_open'] 
272
                            . '<a href="' . $query . ($currentPageNumber - 1) . '">' 
273
                            . $this->config['previous_text'] . '</a>' . $this->config['previous_close'];
274
            for($i = $begin; $i <= $end; $i++){
275
                if ($i == $currentPageNumber){
276
                    $navbar .= $this->config['active_link_open'] . $currentPageNumber . $this->config['active_link_close'];
277
                }
278
                else{
279
                    $navbar .= $this->config['digit_open'] 
280
                                    . '<a href="' . $query . $i . '"' . attributes_to_string($this->config['attributes']) . '>' . $i .'</a>' 
281
                                    . $this->config['digit_close'];
282
                }
283
            }
284
            $navbar .= $this->config['next_open']."<a href='$query".($currentPageNumber + 1)."'>".$this->config['next_text']."</a>".$this->config['next_close'];
285
            return $navbar;
286
        }
287
288
        /**
289
         * Build the pagination link for the last page
290
         * @param  int $begin             the pagination begin number
291
         * @param  int $end               the pagination end number
292
         * @param  int $currentPageNumber the pagination current page number
293
         * @return string                    
294
         */
295
        protected function buildPaginationLinkForLastPage($begin, $end, $currentPageNumber){
296
            $navbar = null;
297
            $query = $this->paginationQueryString;
298
            $navbar .= $this->config['previous_open'] 
299
                        . '<a href="' . $query . ($currentPageNumber - 1) . '">' 
300
                        . $this->config['previous_text'] . '</a>' . $this->config['previous_close'];
301
            for($i = $begin; $i <= $end; $i++){
302
                if ($i == $currentPageNumber){
303
                    $navbar .= $this->config['active_link_open'] 
304
                                . $currentPageNumber 
305
                                . $this->config['active_link_close'];
306
                }
307
                else{
308
                    $navbar .= $this->config['digit_open'] 
309
                                . '<a href="' . $query . $i . '"' . attributes_to_string($this->config['attributes']) . '>' . $i . '</a>' 
310
                                . $this->config['digit_close'];
311
                }
312
            }
313
            return $navbar;
314
        }
315
    }
316