Merge pull request #3273 from joannechester/master
[civicrm-core.git] / CRM / Utils / Pager.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
06b69b18 4 | CiviCRM version 4.5 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
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
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
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
46require_once 'Pager/Sliding.php';
47class 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 *
f4aaa82a
EM
67 * @param $params
68 *
69 * @internal param \total $int the total count of items to be displayed
70 * @internal param \currentPage $int the page currently being displayed
71 * @internal param \status $string the status message to be displayed. It embeds a token
6a488035
TO
72 * %%statusMessage%% that will be replaced with which items
73 * are currently being displayed
f4aaa82a
EM
74 * @internal param \csvString $string the title of the link to be displayed for the export
75 * @internal param \perPage $int the number of items displayed per page
6a488035 76 *
f4aaa82a 77 * @return \CRM_Utils_Pager the newly created and initialized pager object@access public
6a488035
TO
78 */
79 function __construct($params) {
80 if ($params['status'] === NULL) {
81 $params['status'] = ts('Contacts %%StatusMessage%%');
82 }
83
84 $this->initialize($params);
85
86 $this->Pager_Sliding($params);
87
88 list($offset, $limit) = $this->getOffsetAndRowCount();
89 $start = $offset + 1;
90 $end = $offset + $limit;
91 if ($end > $params['total']) {
92 $end = $params['total'];
93 }
94
95 if ($params['total'] == 0) {
96 $statusMessage = '';
97 }
98 else {
99 $statusMessage = ts('%1 - %2 of %3', array(1 => $start, 2 => $end, 3 => $params['total']));
100 }
101 $params['status'] = str_replace('%%StatusMessage%%', $statusMessage, $params['status']);
102
103 $this->_response = array(
104 'first' => $this->getFirstPageLink(),
105 'back' => $this->getBackPageLink(),
106 'next' => $this->getNextPageLink(),
107 'last' => $this->getLastPageLink(),
108 'currentPage' => $this->getCurrentPageID(),
109 'numPages' => $this->numPages(),
110 'csvString' => CRM_Utils_Array::value('csvString', $params),
111 'status' => CRM_Utils_Array::value('status', $params),
112 'buttonTop' => CRM_Utils_Array::value('buttonTop', $params),
113 'buttonBottom' => CRM_Utils_Array::value('buttonBottom', $params),
fe010227 114 'currentLocation' => $this->getCurrentLocation(),
6a488035
TO
115 );
116
117 /**
118 * A page cannot have two variables with the same form name. Hence in the
119 * pager display, we have a form submission at the top with the normal
120 * page variable, but a different form element for one at the bottom
121 *
122 */
123 $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']));
124 $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']));
125 }
126
127 /**
128 * helper function to assign remaining pager options as good default
129 * values
130 *
131 * @param array $params the set of options needed to initialize the parent
132 * constructor
133 *
134 * @access public
135 *
136 * @return void
137 *
138 */
139 function initialize(&$params) {
140 /* set the mode for the pager to Sliding */
141
142 $params['mode'] = 'Sliding';
143
144 /* also set the urlVar to be a crm specific get variable */
145
146 $params['urlVar'] = self::PAGE_ID;
147
148 /* set this to a small value, since we dont use this functionality */
149
150 $params['delta'] = 1;
151
152 $params['totalItems'] = $params['total'];
153 $params['append'] = TRUE;
154 $params['separator'] = '';
155 $params['spacesBeforeSeparator'] = 1;
156 $params['spacesAfterSeparator'] = 1;
157 $params['extraVars'] = array('force' => 1);
158 $params['excludeVars'] = array('reset', 'snippet', 'section');
159
160 // set previous and next text labels
161 $params['prevImg'] = ' ' . ts('&lt; Previous');
162 $params['nextImg'] = ts('Next &gt;') . ' ';
163
164
165 // set first and last text fragments
166 $params['firstPagePre'] = '';
167 $params['firstPageText'] = ' ' . ts('&lt;&lt; First');
168 $params['firstPagePost'] = '';
169
170 $params['lastPagePre'] = '';
171 $params['lastPageText'] = ts('Last &gt;&gt;') . ' ';
172 $params['lastPagePost'] = '';
173
174 if (isset($params['pageID'])) {
175 $params['currentPage'] = $this->getPageID($params['pageID'], $params);
176 }
177
178 $params['perPage'] = $this->getPageRowCount($params['rowCount']);
179
180 return $params;
181 }
182
183 /**
184 * Figure out the current page number based on value of
185 * GET / POST variables. Hierarchy rules are followed,
186 * POST over-rides a GET, a POST at the top overrides
187 * a POST at the bottom (of the page)
188 *
f4aaa82a
EM
189 * @param int $defaultPageId defaultPageId current pageId
190 *
191 * @param $params
6a488035
TO
192 *
193 * @return int new pageId to display to the user
194 * @access public
6a488035
TO
195 */
196 function getPageID($defaultPageId = 1, &$params) {
197 // POST has higher priority than GET vars
198 // else if a value is set that has higher priority and finally the GET var
199 $currentPage = $defaultPageId;
200 if (!empty($_POST)) {
201 if (isset($_POST[CRM_Utils_Array::value('buttonTop', $params)]) && isset($_POST[self::PAGE_ID])) {
202 $currentPage = max((int )@$_POST[self::PAGE_ID], 1);
203 }
204 elseif (isset($_POST[$params['buttonBottom']]) && isset($_POST[self::PAGE_ID_BOTTOM])) {
205 $currentPage = max((int )@$_POST[self::PAGE_ID_BOTTOM], 1);
206 }
207 elseif (isset($_POST[self::PAGE_ID])) {
208 $currentPage = max((int )@$_POST[self::PAGE_ID], 1);
209 }
210 elseif (isset($_POST[self::PAGE_ID_BOTTOM])) {
211 $currentPage = max((int )@$_POST[self::PAGE_ID_BOTTOM]);
212 }
213 }
214 elseif (isset($_GET[self::PAGE_ID])) {
215 $currentPage = max((int )@$_GET[self::PAGE_ID], 1);
216 }
217 return $currentPage;
218 }
219
220 /**
221 * Get the number of rows to display from either a GET / POST variable
222 *
223 * @param int $defaultPageRowCount the default value if not set
224 *
225 * @return int the rowCount value to use
226 * @access public
227 *
228 */
229 function getPageRowCount($defaultPageRowCount = self::ROWCOUNT) {
230 // POST has higher priority than GET vars
231 if (isset($_POST[self::PAGE_ROWCOUNT])) {
232 $rowCount = max((int )@$_POST[self::PAGE_ROWCOUNT], 1);
233 }
234 elseif (isset($_GET[self::PAGE_ROWCOUNT])) {
235 $rowCount = max((int )@$_GET[self::PAGE_ROWCOUNT], 1);
236 }
237 else {
238 $rowCount = $defaultPageRowCount;
239 }
240 return $rowCount;
241 }
242
243 /**
244 * Use the pager class to get the pageId and Offset
245 *
246 * @param void
247 *
248 * @return array: an array of the pageID and offset
249 *
250 * @access public
251 *
252 */
253 function getOffsetAndRowCount() {
254 $pageId = $this->getCurrentPageID();
255 if (!$pageId) {
256 $pageId = 1;
257 }
258
259 $offset = ($pageId - 1) * $this->_perPage;
260
261 return array($offset, $this->_perPage);
262 }
263
fe010227
CW
264 function getCurrentLocation() {
265 $config = CRM_Core_Config::singleton();
266 $path = CRM_Utils_Array::value($config->userFrameworkURLVar, $_GET);
267 return CRM_Utils_System::url($path, CRM_Utils_System::getLinksUrl(self::PAGE_ID, FALSE, TRUE), FALSE, NULL, FALSE) . $this->getCurrentPageID();
6a488035
TO
268 }
269
270 function getFirstPageLink() {
271 if ($this->isFirstPage()) {
272 return '';
273 }
274
10824c72 275 $href = $this->makeURL(self::PAGE_ID, 1);
d8249fcb 276 return sprintf('<a class="crm-pager-link" href="%s" title="%s">%s</a>',
6a488035
TO
277 $href,
278 str_replace('%d', 1, $this->_altFirst),
279 $this->_firstPagePre . $this->_firstPageText . $this->_firstPagePost
280 ) . $this->_spacesBefore . $this->_spacesAfter;
281 }
282
283 function getLastPageLink() {
284 if ($this->isLastPage()) {
285 return '';
286 }
287
10824c72 288 $href = $this->makeURL(self::PAGE_ID, $this->_totalPages);
d8249fcb 289 return sprintf('<a class="crm-pager-link" href="%s" title="%s">%s</a>',
6a488035
TO
290 $href,
291 str_replace('%d', $this->_totalPages, $this->_altLast),
292 $this->_lastPagePre . $this->_lastPageText . $this->_lastPagePost
293 );
294 }
295
296 function getBackPageLink() {
297 if ($this->_currentPage > 1) {
10824c72 298 $href = $this->makeURL(self::PAGE_ID, $this->getPreviousPageID());
d8249fcb 299 return sprintf('<a class="crm-pager-link" href="%s" title="%s">%s</a>',
6a488035
TO
300 $href,
301 $this->_altPrev, $this->_prevImg
302 ) . $this->_spacesBefore . $this->_spacesAfter;
303 }
304 return '';
305 }
306
307 function getNextPageLink() {
308 if ($this->_currentPage < $this->_totalPages) {
10824c72 309 $href = $this->makeURL(self::PAGE_ID, $this->getNextPageID());
d8249fcb 310 return $this->_spacesAfter . sprintf('<a class="crm-pager-link" href="%s" title="%s">%s</a>',
6a488035
TO
311 $href,
312 $this->_altNext, $this->_nextImg
313 ) . $this->_spacesBefore . $this->_spacesAfter;
314 }
315 return '';
316 }
10824c72
CW
317
318 /**
319 * Build a url for pager links
320 */
321 function makeURL($key, $value) {
322 $href = CRM_Utils_System::makeURL($key);
323 // CRM-12212 Remove alpha sort param
324 if (strpos($href, '&amp;sortByCharacter=')) {
325 $href = preg_replace('#(.*)\&amp;sortByCharacter=[^&]*(.*)#', '\1\2', $href);
326 }
327 return $href . $value;
328 }
6a488035
TO
329}
330