3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
30 * Base class to provide generic sort functionality.
32 * Note that some ideas have been borrowed from the drupal tablesort.inc code.
34 * Also note that since the Pager and Sort class are similar, do match the function names
35 * if introducing additional functionality
38 * @copyright CiviCRM LLC (c) 2004-2016
40 class CRM_Utils_Sort
{
43 * Constants to determine what direction each variable
48 const ASCENDING
= 1, DESCENDING
= 2, DONTCARE
= 4,
51 * The name for the sort GET/POST param
55 SORT_ID
= 'crmSID', SORT_DIRECTION
= 'crmSortDirection', SORT_ORDER
= 'crmSortOrder';
58 * Name of the sort function. Used to isolate session variables
64 * Array of variables that influence the query
71 * The newly formulated base url to be used as links
72 * for various table elements
79 * What's the name of the sort variable in a REQUEST
86 * What variable are we currently sorting on
90 protected $_currentSortID;
93 * What direction are we sorting on
97 protected $_currentSortDirection;
100 * The output generated for the current form
107 * The constructor takes an assoc array
108 * key names of variable (which should be the same as the column name)
109 * value: ascending or descending
112 * Assoc array as described above.
113 * @param string $defaultSortOrder
116 * @return \CRM_Utils_Sort
118 public function __construct(&$vars, $defaultSortOrder = NULL) {
119 $this->_vars
= array();
120 $this->_response
= array();
122 foreach ($vars as $weight => $value) {
123 $this->_vars
[$weight] = array(
124 'name' => CRM_Utils_Type
::validate($value['sort'], 'MysqlColumnNameOrAlias'),
125 'direction' => CRM_Utils_Array
::value('direction', $value),
126 'title' => $value['name'],
130 $this->_currentSortID
= 1;
131 if (isset($this->_vars
[$this->_currentSortID
])) {
132 $this->_currentSortDirection
= $this->_vars
[$this->_currentSortID
]['direction'];
134 $this->_urlVar
= self
::SORT_ID
;
135 $this->_link
= CRM_Utils_System
::makeURL($this->_urlVar
, TRUE);
137 $this->initialize($defaultSortOrder);
141 * Function returns the string for the order by clause.
144 * the order by clause
146 public function orderBy() {
147 if (empty($this->_vars
[$this->_currentSortID
])) {
151 if ($this->_vars
[$this->_currentSortID
]['direction'] == self
::ASCENDING ||
152 $this->_vars
[$this->_currentSortID
]['direction'] == self
::DONTCARE
154 $this->_vars
[$this->_currentSortID
]['name'] = str_replace(' ', '_', $this->_vars
[$this->_currentSortID
]['name']);
155 return CRM_Utils_Type
::escape($this->_vars
[$this->_currentSortID
]['name'], 'MysqlColumnNameOrAlias') . ' asc';
158 $this->_vars
[$this->_currentSortID
]['name'] = str_replace(' ', '_', $this->_vars
[$this->_currentSortID
]['name']);
159 return CRM_Utils_Type
::escape($this->_vars
[$this->_currentSortID
]['name'], 'MysqlColumnNameOrAlias') . ' desc';
164 * Create the sortID string to be used in the GET param.
169 * The direction of the sort.
172 * the string to append to the url
174 public static function sortIDValue($index, $dir) {
175 return ($dir == self
::DESCENDING
) ?
$index . '_d' : $index . '_u';
179 * Init the sort ID values in the object.
181 * @param string $defaultSortOrder
182 * The sort order to use by default.
184 public function initSortID($defaultSortOrder) {
185 $url = CRM_Utils_Array
::value(self
::SORT_ID
, $_GET, $defaultSortOrder);
191 list($current, $direction) = explode('_', $url);
193 // if current is weird and does not exist in the vars array, skip
194 if (!array_key_exists($current, $this->_vars
)) {
198 if ($direction == 'u') {
199 $direction = self
::ASCENDING
;
201 elseif ($direction == 'd') {
202 $direction = self
::DESCENDING
;
205 $direction = self
::DONTCARE
;
208 $this->_currentSortID
= $current;
209 $this->_currentSortDirection
= $direction;
210 $this->_vars
[$current]['direction'] = $direction;
216 * @param string $defaultSortOrder
217 * The sort order to use by default.
219 public function initialize($defaultSortOrder) {
220 $this->initSortID($defaultSortOrder);
222 $this->_response
= array();
224 $current = $this->_currentSortID
;
225 foreach ($this->_vars
as $index => $item) {
226 $name = $item['name'];
227 $this->_response
[$name] = array();
229 $newDirection = ($item['direction'] == self
::ASCENDING
) ? self
::DESCENDING
: self
::ASCENDING
;
231 if ($current == $index) {
232 if ($item['direction'] == self
::ASCENDING
) {
233 $class = 'sorting_asc';
236 $class = 'sorting_desc';
243 $this->_response
[$name]['link'] = '<a href="' . $this->_link
. $this->sortIDValue($index, $newDirection) . '" class="' . $class . '">' . $item['title'] . '</a>';
248 * Getter for currentSortID.
251 * returns of the current sort id
253 public function getCurrentSortID() {
254 return $this->_currentSortID
;
258 * Getter for currentSortDirection.
261 * returns of the current sort direction
263 public function getCurrentSortDirection() {
264 return $this->_currentSortDirection
;
268 * Universal callback function for sorting by weight, id, title or name
276 public static function cmpFunc($a, $b) {
277 $cmp_order = array('weight', 'id', 'title', 'name');
278 foreach ($cmp_order as $attribute) {
279 if (isset($a[$attribute]) && isset($b[$attribute])) {
280 if ($a[$attribute] < $b[$attribute]) {
283 elseif ($a[$attribute] > $b[$attribute]) {
285 } // else: $a and $b are equal wrt to this attribute, try next...
288 // if we get here, $a and $b are equal for all we know
289 // however, as I understand we don't want equality here: