Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
232624b1 | 4 | | CiviCRM version 4.4 | |
6a488035 TO |
5 | +--------------------------------------------------------------------+ |
6 | | Copyright CiviCRM LLC (c) 2004-2013 | | |
7 | +--------------------------------------------------------------------+ | |
8 | | This file is a part of CiviCRM. | | |
9 | | | | |
10 | | CiviCRM is free software; you can copy, modify, and distribute it | | |
11 | | under the terms of the GNU Affero General Public License | | |
12 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | | |
13 | | | | |
14 | | CiviCRM is distributed in the hope that it will be useful, but | | |
15 | | WITHOUT ANY WARRANTY; without even the implied warranty of | | |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | |
17 | | See the GNU Affero General Public License for more details. | | |
18 | | | | |
19 | | You should have received a copy of the GNU Affero General Public | | |
20 | | License and the CiviCRM Licensing Exception along | | |
21 | | with this program; if not, contact CiviCRM LLC | | |
22 | | at info[AT]civicrm[DOT]org. If you have questions about the | | |
23 | | GNU Affero General Public License or the licensing of CiviCRM, | | |
24 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | | |
25 | +--------------------------------------------------------------------+ | |
26 | */ | |
27 | ||
28 | /** | |
29 | * | |
30 | * @package CRM | |
31 | * @copyright CiviCRM LLC (c) 2004-2013 | |
32 | * $Id$ | |
33 | * | |
34 | */ | |
35 | ||
36 | /** | |
37 | * | |
38 | * This class extends the PEAR pager object by substituting standard default pager arguments | |
39 | * We also extract the pageId from either the GET variables or the POST variable (since we | |
40 | * use a POST to jump to a specific page). At some point we should evaluate if we want | |
41 | * to use Pager_Jumping instead. We've changed the format to allow navigation by jumping | |
42 | * to a page and also First, Prev CURRENT Next Last | |
43 | * | |
44 | */ | |
45 | ||
46 | require_once 'Pager/Sliding.php'; | |
47 | class CRM_Utils_Pager extends Pager_Sliding { | |
48 | ||
49 | /** | |
50 | * constants for static parameters of the pager | |
51 | */ | |
52 | CONST ROWCOUNT = 50, PAGE_ID = 'crmPID', PAGE_ID_TOP = 'crmPID', PAGE_ID_BOTTOM = 'crmPID_B', PAGE_ROWCOUNT = 'crmRowCount'; | |
53 | ||
54 | /** | |
55 | * the output of the pager. This is a name/value array with various keys | |
56 | * that an application could use to display the pager | |
57 | * @var array | |
58 | */ | |
59 | public $_response; | |
60 | ||
61 | /** | |
62 | * The pager constructor. Takes a few values, and then assigns a lot of defaults | |
63 | * to the PEAR pager class | |
64 | * We have embedded some html in this class. Need to figure out how to export this | |
65 | * to the top level at some point in time | |
66 | * | |
67 | * @param int total the total count of items to be displayed | |
68 | * @param int currentPage the page currently being displayed | |
69 | * @param string status the status message to be displayed. It embeds a token | |
70 | * %%statusMessage%% that will be replaced with which items | |
71 | * are currently being displayed | |
72 | * @param string csvString the title of the link to be displayed for the export | |
73 | * @param int perPage the number of items displayed per page | |
74 | * | |
75 | * @return object the newly created and initialized pager object | |
76 | * | |
77 | * @access public | |
78 | * | |
79 | */ | |
80 | function __construct($params) { | |
81 | if ($params['status'] === NULL) { | |
82 | $params['status'] = ts('Contacts %%StatusMessage%%'); | |
83 | } | |
84 | ||
85 | $this->initialize($params); | |
86 | ||
87 | $this->Pager_Sliding($params); | |
88 | ||
89 | list($offset, $limit) = $this->getOffsetAndRowCount(); | |
90 | $start = $offset + 1; | |
91 | $end = $offset + $limit; | |
92 | if ($end > $params['total']) { | |
93 | $end = $params['total']; | |
94 | } | |
95 | ||
96 | if ($params['total'] == 0) { | |
97 | $statusMessage = ''; | |
98 | } | |
99 | else { | |
100 | $statusMessage = ts('%1 - %2 of %3', array(1 => $start, 2 => $end, 3 => $params['total'])); | |
101 | } | |
102 | $params['status'] = str_replace('%%StatusMessage%%', $statusMessage, $params['status']); | |
103 | ||
104 | $this->_response = array( | |
105 | 'first' => $this->getFirstPageLink(), | |
106 | 'back' => $this->getBackPageLink(), | |
107 | 'next' => $this->getNextPageLink(), | |
108 | 'last' => $this->getLastPageLink(), | |
109 | 'currentPage' => $this->getCurrentPageID(), | |
110 | 'numPages' => $this->numPages(), | |
111 | 'csvString' => CRM_Utils_Array::value('csvString', $params), | |
112 | 'status' => CRM_Utils_Array::value('status', $params), | |
113 | 'buttonTop' => CRM_Utils_Array::value('buttonTop', $params), | |
114 | 'buttonBottom' => CRM_Utils_Array::value('buttonBottom', $params), | |
115 | 'twentyfive' => $this->getPerPageLink(25), | |
116 | 'fifty' => $this->getPerPageLink(50), | |
117 | 'onehundred' => $this->getPerPageLink(100), | |
118 | ); | |
119 | ||
120 | /** | |
121 | * A page cannot have two variables with the same form name. Hence in the | |
122 | * pager display, we have a form submission at the top with the normal | |
123 | * page variable, but a different form element for one at the bottom | |
124 | * | |
125 | */ | |
126 | $this->_response['titleTop'] = ts('Page %1 of %2', array(1 => '<input size="2" maxlength="3" name="' . self::PAGE_ID . '" type="text" value="' . $this->_response['currentPage'] . '" />', 2 => $this->_response['numPages'])); | |
127 | $this->_response['titleBottom'] = ts('Page %1 of %2', array(1 => '<input size="2" maxlength="3" name="' . self::PAGE_ID_BOTTOM . '" type="text" value="' . $this->_response['currentPage'] . '" />', 2 => $this->_response['numPages'])); | |
128 | } | |
129 | ||
130 | /** | |
131 | * helper function to assign remaining pager options as good default | |
132 | * values | |
133 | * | |
134 | * @param array $params the set of options needed to initialize the parent | |
135 | * constructor | |
136 | * | |
137 | * @access public | |
138 | * | |
139 | * @return void | |
140 | * | |
141 | */ | |
142 | function initialize(&$params) { | |
143 | /* set the mode for the pager to Sliding */ | |
144 | ||
145 | $params['mode'] = 'Sliding'; | |
146 | ||
147 | /* also set the urlVar to be a crm specific get variable */ | |
148 | ||
149 | $params['urlVar'] = self::PAGE_ID; | |
150 | ||
151 | /* set this to a small value, since we dont use this functionality */ | |
152 | ||
153 | $params['delta'] = 1; | |
154 | ||
155 | $params['totalItems'] = $params['total']; | |
156 | $params['append'] = TRUE; | |
157 | $params['separator'] = ''; | |
158 | $params['spacesBeforeSeparator'] = 1; | |
159 | $params['spacesAfterSeparator'] = 1; | |
160 | $params['extraVars'] = array('force' => 1); | |
161 | $params['excludeVars'] = array('reset', 'snippet', 'section'); | |
162 | ||
163 | // set previous and next text labels | |
164 | $params['prevImg'] = ' ' . ts('< Previous'); | |
165 | $params['nextImg'] = ts('Next >') . ' '; | |
166 | ||
167 | ||
168 | // set first and last text fragments | |
169 | $params['firstPagePre'] = ''; | |
170 | $params['firstPageText'] = ' ' . ts('<< First'); | |
171 | $params['firstPagePost'] = ''; | |
172 | ||
173 | $params['lastPagePre'] = ''; | |
174 | $params['lastPageText'] = ts('Last >>') . ' '; | |
175 | $params['lastPagePost'] = ''; | |
176 | ||
177 | if (isset($params['pageID'])) { | |
178 | $params['currentPage'] = $this->getPageID($params['pageID'], $params); | |
179 | } | |
180 | ||
181 | $params['perPage'] = $this->getPageRowCount($params['rowCount']); | |
182 | ||
183 | return $params; | |
184 | } | |
185 | ||
186 | /** | |
187 | * Figure out the current page number based on value of | |
188 | * GET / POST variables. Hierarchy rules are followed, | |
189 | * POST over-rides a GET, a POST at the top overrides | |
190 | * a POST at the bottom (of the page) | |
191 | * | |
192 | * @param int defaultPageId current pageId | |
193 | * | |
194 | * @return int new pageId to display to the user | |
195 | * @access public | |
196 | * | |
197 | */ | |
198 | function getPageID($defaultPageId = 1, &$params) { | |
199 | // POST has higher priority than GET vars | |
200 | // else if a value is set that has higher priority and finally the GET var | |
201 | $currentPage = $defaultPageId; | |
202 | if (!empty($_POST)) { | |
203 | if (isset($_POST[CRM_Utils_Array::value('buttonTop', $params)]) && isset($_POST[self::PAGE_ID])) { | |
204 | $currentPage = max((int )@$_POST[self::PAGE_ID], 1); | |
205 | } | |
206 | elseif (isset($_POST[$params['buttonBottom']]) && isset($_POST[self::PAGE_ID_BOTTOM])) { | |
207 | $currentPage = max((int )@$_POST[self::PAGE_ID_BOTTOM], 1); | |
208 | } | |
209 | elseif (isset($_POST[self::PAGE_ID])) { | |
210 | $currentPage = max((int )@$_POST[self::PAGE_ID], 1); | |
211 | } | |
212 | elseif (isset($_POST[self::PAGE_ID_BOTTOM])) { | |
213 | $currentPage = max((int )@$_POST[self::PAGE_ID_BOTTOM]); | |
214 | } | |
215 | } | |
216 | elseif (isset($_GET[self::PAGE_ID])) { | |
217 | $currentPage = max((int )@$_GET[self::PAGE_ID], 1); | |
218 | } | |
219 | return $currentPage; | |
220 | } | |
221 | ||
222 | /** | |
223 | * Get the number of rows to display from either a GET / POST variable | |
224 | * | |
225 | * @param int $defaultPageRowCount the default value if not set | |
226 | * | |
227 | * @return int the rowCount value to use | |
228 | * @access public | |
229 | * | |
230 | */ | |
231 | function getPageRowCount($defaultPageRowCount = self::ROWCOUNT) { | |
232 | // POST has higher priority than GET vars | |
233 | if (isset($_POST[self::PAGE_ROWCOUNT])) { | |
234 | $rowCount = max((int )@$_POST[self::PAGE_ROWCOUNT], 1); | |
235 | } | |
236 | elseif (isset($_GET[self::PAGE_ROWCOUNT])) { | |
237 | $rowCount = max((int )@$_GET[self::PAGE_ROWCOUNT], 1); | |
238 | } | |
239 | else { | |
240 | $rowCount = $defaultPageRowCount; | |
241 | } | |
242 | return $rowCount; | |
243 | } | |
244 | ||
245 | /** | |
246 | * Use the pager class to get the pageId and Offset | |
247 | * | |
248 | * @param void | |
249 | * | |
250 | * @return array: an array of the pageID and offset | |
251 | * | |
252 | * @access public | |
253 | * | |
254 | */ | |
255 | function getOffsetAndRowCount() { | |
256 | $pageId = $this->getCurrentPageID(); | |
257 | if (!$pageId) { | |
258 | $pageId = 1; | |
259 | } | |
260 | ||
261 | $offset = ($pageId - 1) * $this->_perPage; | |
262 | ||
263 | return array($offset, $this->_perPage); | |
264 | } | |
265 | ||
266 | /** | |
267 | * given a number create a link that will display the number of | |
268 | * rows as specified by that link | |
269 | * | |
270 | * @param int $perPage the number of rows | |
271 | * | |
272 | * @return string the link | |
273 | * @access void | |
274 | */ | |
275 | function getPerPageLink($perPage) { | |
276 | if ($perPage != $this->_perPage) { | |
10824c72 | 277 | $href = $this->makeURL(self::PAGE_ROWCOUNT, $perPage); |
6a488035 TO |
278 | $link = sprintf('<a href="%s" %s>%s</a>', |
279 | $href, | |
280 | $this->_classString, | |
281 | $perPage | |
282 | ) . $this->_spacesBefore . $this->_spacesAfter; | |
283 | } | |
284 | else { | |
285 | $link = $this->_spacesBefore . $perPage . $this->_spacesAfter; | |
286 | } | |
287 | ||
288 | return $link; | |
289 | } | |
290 | ||
291 | function getFirstPageLink() { | |
292 | if ($this->isFirstPage()) { | |
293 | return ''; | |
294 | } | |
295 | ||
10824c72 | 296 | $href = $this->makeURL(self::PAGE_ID, 1); |
6a488035 TO |
297 | return sprintf('<a href="%s" title="%s">%s</a>', |
298 | $href, | |
299 | str_replace('%d', 1, $this->_altFirst), | |
300 | $this->_firstPagePre . $this->_firstPageText . $this->_firstPagePost | |
301 | ) . $this->_spacesBefore . $this->_spacesAfter; | |
302 | } | |
303 | ||
304 | function getLastPageLink() { | |
305 | if ($this->isLastPage()) { | |
306 | return ''; | |
307 | } | |
308 | ||
10824c72 | 309 | $href = $this->makeURL(self::PAGE_ID, $this->_totalPages); |
6a488035 TO |
310 | return sprintf('<a href="%s" title="%s">%s</a>', |
311 | $href, | |
312 | str_replace('%d', $this->_totalPages, $this->_altLast), | |
313 | $this->_lastPagePre . $this->_lastPageText . $this->_lastPagePost | |
314 | ); | |
315 | } | |
316 | ||
317 | function getBackPageLink() { | |
318 | if ($this->_currentPage > 1) { | |
10824c72 | 319 | $href = $this->makeURL(self::PAGE_ID, $this->getPreviousPageID()); |
6a488035 TO |
320 | return sprintf('<a href="%s" title="%s">%s</a>', |
321 | $href, | |
322 | $this->_altPrev, $this->_prevImg | |
323 | ) . $this->_spacesBefore . $this->_spacesAfter; | |
324 | } | |
325 | return ''; | |
326 | } | |
327 | ||
328 | function getNextPageLink() { | |
329 | if ($this->_currentPage < $this->_totalPages) { | |
10824c72 | 330 | $href = $this->makeURL(self::PAGE_ID, $this->getNextPageID()); |
6a488035 TO |
331 | return $this->_spacesAfter . sprintf('<a href="%s" title="%s">%s</a>', |
332 | $href, | |
333 | $this->_altNext, $this->_nextImg | |
334 | ) . $this->_spacesBefore . $this->_spacesAfter; | |
335 | } | |
336 | return ''; | |
337 | } | |
10824c72 CW |
338 | |
339 | /** | |
340 | * Build a url for pager links | |
341 | */ | |
342 | function makeURL($key, $value) { | |
343 | $href = CRM_Utils_System::makeURL($key); | |
344 | // CRM-12212 Remove alpha sort param | |
345 | if (strpos($href, '&sortByCharacter=')) { | |
346 | $href = preg_replace('#(.*)\&sortByCharacter=[^&]*(.*)#', '\1\2', $href); | |
347 | } | |
348 | return $href . $value; | |
349 | } | |
6a488035 TO |
350 | } |
351 |