3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
14 * @copyright CiviCRM LLC https://civicrm.org/licensing
18 * This class extends the PEAR pager object by substituting standard default pager arguments
19 * We also extract the pageId from either the GET variables or the POST variable (since we
20 * use a POST to jump to a specific page). At some point we should evaluate if we want
21 * to use Pager_Jumping instead. We've changed the format to allow navigation by jumping
22 * to a page and also First, Prev CURRENT Next Last
25 require_once 'Pager/Sliding.php';
28 * Class CRM_Utils_Pager
30 class CRM_Utils_Pager
extends Pager_Sliding
{
33 * Constants for static parameters of the pager
35 const ROWCOUNT
= 50, PAGE_ID
= 'crmPID', PAGE_ID_TOP
= 'crmPID', PAGE_ID_BOTTOM
= 'crmPID_B', PAGE_ROWCOUNT
= 'crmRowCount';
38 * The output of the pager. This is a name/value array with various keys
39 * that an application could use to display the pager
46 * The pager constructor. Takes a few values, and then assigns a lot of defaults
47 * to the PEAR pager class
48 * We have embedded some html in this class. Need to figure out how to export this
49 * to the top level at some point in time
51 * @param array $params
53 * @return \CRM_Utils_Pager the newly created and initialized pager object
55 public function __construct($params) {
56 if ($params['status'] === NULL) {
57 $params['status'] = ts('Contacts %%StatusMessage%%');
60 $this->initialize($params);
62 parent
::__construct($params);
64 list($offset, $limit) = $this->getOffsetAndRowCount();
66 $end = $offset +
$limit;
67 if ($end > $params['total']) {
68 $end = $params['total'];
71 if ($params['total'] == 0) {
75 $statusMessage = ts('%1 - %2 of %3', [1 => $start, 2 => $end, 3 => $params['total']]);
77 $params['status'] = str_replace('%%StatusMessage%%', $statusMessage, $params['status']);
80 'first' => $this->getFirstPageLink(),
81 'back' => $this->getBackPageLink(),
82 'next' => $this->getNextPageLink(),
83 'last' => $this->getLastPageLink(),
84 'currentPage' => $this->getCurrentPageID(),
85 'numPages' => $this->numPages(),
86 'csvString' => CRM_Utils_Array
::value('csvString', $params),
87 'status' => CRM_Utils_Array
::value('status', $params),
88 'buttonTop' => CRM_Utils_Array
::value('buttonTop', $params),
89 'buttonBottom' => CRM_Utils_Array
::value('buttonBottom', $params),
90 'currentLocation' => $this->getCurrentLocation(),
94 * A page cannot have two variables with the same form name. Hence in the
95 * pager display, we have a form submission at the top with the normal
96 * page variable, but a different form element for one at the bottom.
98 $this->_response
['titleTop'] = ts('Page %1 of %2', [
99 1 => '<input size="2" maxlength="4" name="' . self
::PAGE_ID
. '" type="text" value="' . $this->_response
['currentPage'] . '" />',
100 2 => $this->_response
['numPages'],
102 $this->_response
['titleBottom'] = ts('Page %1 of %2', [
103 1 => '<input size="2" maxlength="4" name="' . self
::PAGE_ID_BOTTOM
. '" type="text" value="' . $this->_response
['currentPage'] . '" />',
104 2 => $this->_response
['numPages'],
109 * Helper function to assign remaining pager options as good default
112 * @param array $params
113 * The set of options needed to initialize the parent constructor.
117 public function initialize(&$params) {
118 // set the mode for the pager to Sliding
120 $params['mode'] = 'Sliding';
122 // also set the urlVar to be a crm specific get variable.
124 $params['urlVar'] = self
::PAGE_ID
;
126 // set this to a small value, since we dont use this functionality
128 $params['delta'] = 1;
130 $params['totalItems'] = $params['total'];
131 $params['append'] = TRUE;
132 $params['separator'] = '';
133 $params['spacesBeforeSeparator'] = 1;
134 $params['spacesAfterSeparator'] = 1;
135 $params['extraVars'] = ['force' => 1];
136 $params['excludeVars'] = ['reset', 'snippet', 'section'];
138 // set previous and next text labels
139 $params['prevImg'] = ' ' . ts('< Previous');
140 $params['nextImg'] = ts('Next >') . ' ';
142 // set first and last text fragments
143 $params['firstPagePre'] = '';
144 $params['firstPageText'] = ' ' . ts('<< First');
145 $params['firstPagePost'] = '';
147 $params['lastPagePre'] = '';
148 $params['lastPageText'] = ts('Last >>') . ' ';
149 $params['lastPagePost'] = '';
151 if (isset($params['pageID'])) {
152 $params['currentPage'] = $this->getPageID($params['pageID'], $params);
155 $params['perPage'] = $this->getPageRowCount($params['rowCount']);
161 * Figure out the current page number based on value of
162 * GET / POST variables. Hierarchy rules are followed,
163 * POST over-rides a GET, a POST at the top overrides
164 * a POST at the bottom (of the page)
166 * @param int $defaultPageId
167 * DefaultPageId current pageId.
169 * @param array $params
172 * new pageId to display to the user
174 public function getPageID($defaultPageId = 1, &$params) {
175 // POST has higher priority than GET vars
176 // else if a value is set that has higher priority and finally the GET var
177 $currentPage = $defaultPageId;
178 if (!empty($_POST)) {
179 if (isset($_POST[CRM_Utils_Array
::value('buttonTop', $params)]) && isset($_POST[self
::PAGE_ID
])) {
180 $currentPage = max((int ) @$_POST[self
::PAGE_ID
], 1);
182 elseif (isset($_POST[$params['buttonBottom']]) && isset($_POST[self
::PAGE_ID_BOTTOM
])) {
183 $currentPage = max((int ) @$_POST[self
::PAGE_ID_BOTTOM
], 1);
185 elseif (isset($_POST[self
::PAGE_ID
])) {
186 $currentPage = max((int ) @$_POST[self
::PAGE_ID
], 1);
188 elseif (isset($_POST[self
::PAGE_ID_BOTTOM
])) {
189 $currentPage = max((int ) @$_POST[self
::PAGE_ID_BOTTOM
]);
192 elseif (isset($_GET[self
::PAGE_ID
])) {
193 $currentPage = max((int ) @$_GET[self
::PAGE_ID
], 1);
199 * Get the number of rows to display from either a GET / POST variable
201 * @param int $defaultPageRowCount
202 * The default value if not set.
205 * the rowCount value to use
207 public function getPageRowCount($defaultPageRowCount = self
::ROWCOUNT
) {
208 // POST has higher priority than GET vars
209 if (isset($_POST[self
::PAGE_ROWCOUNT
])) {
210 $rowCount = max((int ) @$_POST[self
::PAGE_ROWCOUNT
], 1);
212 elseif (isset($_GET[self
::PAGE_ROWCOUNT
])) {
213 $rowCount = max((int ) @$_GET[self
::PAGE_ROWCOUNT
], 1);
216 $rowCount = $defaultPageRowCount;
222 * Use the pager class to get the pageId and Offset.
225 * an array of the pageID and offset
227 public function getOffsetAndRowCount() {
228 $pageId = $this->getCurrentPageID();
233 $offset = ($pageId - 1) * $this->_perPage
;
235 return [$offset, $this->_perPage
];
241 public function getCurrentLocation() {
242 $config = CRM_Core_Config
::singleton();
243 $path = CRM_Utils_Array
::value($config->userFrameworkURLVar
, $_GET);
244 return CRM_Utils_System
::url($path, CRM_Utils_System
::getLinksUrl(self
::PAGE_ID
, FALSE, TRUE), FALSE, NULL, FALSE) . $this->getCurrentPageID();
250 public function getFirstPageLink() {
251 if ($this->isFirstPage()) {
254 $href = $this->makeURL(self
::PAGE_ID
, 1);
255 return $this->formatLink($href, str_replace('%d', 1, $this->_altFirst
), $this->_firstPagePre
. $this->_firstPageText
. $this->_firstPagePost
) .
256 $this->_spacesBefore
. $this->_spacesAfter
;
262 public function getLastPageLink() {
263 if ($this->isLastPage()) {
266 $href = $this->makeURL(self
::PAGE_ID
, $this->_totalPages
);
267 return $this->formatLink($href, str_replace('%d', $this->_totalPages
, $this->_altLast
), $this->_lastPagePre
. $this->_lastPageText
. $this->_lastPagePost
);
273 public function getBackPageLink() {
274 if ($this->_currentPage
> 1) {
275 $href = $this->makeURL(self
::PAGE_ID
, $this->getPreviousPageID());
276 return $this->formatLink($href, $this->_altPrev
, $this->_prevImg
) . $this->_spacesBefore
. $this->_spacesAfter
;
284 public function getNextPageLink() {
285 if ($this->_currentPage
< $this->_totalPages
) {
286 $href = $this->makeURL(self
::PAGE_ID
, $this->getNextPageID());
287 return $this->_spacesAfter
.
288 $this->formatLink($href, $this->_altNext
, $this->_nextImg
) .
289 $this->_spacesBefore
. $this->_spacesAfter
;
295 * Build a url for pager links.
298 * @param string $value
302 public function makeURL($key, $value) {
303 $href = CRM_Utils_System
::makeURL($key, TRUE);
304 // CRM-12212 Remove alpha sort param
305 if (strpos($href, '&sortByCharacter=')) {
306 $href = preg_replace('#(.*)\&sortByCharacter=[^&]*(.*)#', '\1\2', $href);
308 return $href . $value;
312 * Output the html pager link.
313 * @param string $href
314 * @param string $title
315 * @param string $image
318 private function formatLink($href, $title, $image) {
319 return sprintf('<a class="crm-pager-link action-item crm-hover-button" href="%s" title="%s">%s</a>', $href, $title, $image);