Line # | Frequency | Source Line |
1 | | <?php |
2 | | // $Id: tablesort.inc,v 1.47 2008/01/04 09:31:48 goba Exp $ |
3 | |
|
4 | | /** |
5 | | * @file |
6 | | * Functions to aid in the creation of sortable tables. |
7 | | * |
8 | | * All tables created with a call to theme('table') have the option of having |
9 | | * column headers that the user can click on to sort the table by that column. |
10 | | */ |
11 | |
|
12 | | /** |
13 | | * Initialize the table sort context. |
14 | | */ |
15 | | function tablesort_init($header) { |
16 | | $ts = tablesort_get_order($header); |
17 | | $ts['sort'] = tablesort_get_sort($header); |
18 | | $ts['query_string'] = tablesort_get_querystring(); |
19 | | return $ts; |
20 | | } |
21 | |
|
22 | | /** |
23 | | * Create an SQL sort clause. |
24 | | * |
25 | | * This function produces the ORDER BY clause to insert in your SQL queries, |
26 | | * assuring that the returned database table rows match the sort order chosen |
27 | | * by the user. |
28 | | * |
29 | | * @param $header |
30 | | * An array of column headers in the format described in theme_table(). |
31 | | * @param $before |
32 | | * An SQL string to insert after ORDER BY and before the table sorting code. |
33 | | * Useful for sorting by important attributes like "sticky" first. |
34 | | * @return |
35 | | * An SQL string to append to the end of a query. |
36 | | * |
37 | | * @ingroup database |
38 | | */ |
39 | | function tablesort_sql($header, $before = '') { |
40 | | $ts = tablesort_init($header); |
41 | | if ($ts['sql']) { |
42 | | // Based on code from db_escape_table(), but this can also contain a dot. |
43 | | $field = preg_replace('/[^A-Za-z0-9_.]+/', '', $ts['sql']); |
44 | |
|
45 | | // Sort order can only be ASC or DESC. |
46 | | $sort = drupal_strtoupper($ts['sort']); |
47 | | $sort = in_array($sort, array('ASC', 'DESC')) ? $sort : ''; |
48 | |
|
49 | | return " ORDER BY $before $field $sort"; |
50 | | } |
51 | | } |
52 | |
|
53 | | /** |
54 | | * Format a column header. |
55 | | * |
56 | | * If the cell in question is the column header for the current sort criterion, |
57 | | * it gets special formatting. All possible sort criteria become links. |
58 | | * |
59 | | * @param $cell |
60 | | * The cell to format. |
61 | | * @param $header |
62 | | * An array of column headers in the format described in theme_table(). |
63 | | * @param $ts |
64 | | * The current table sort context as returned from tablesort_init(). |
65 | | * @return |
66 | | * A properly formatted cell, ready for _theme_table_cell(). |
67 | | */ |
68 | | function tablesort_header($cell, $header, $ts) { |
69 | | // Special formatting for the currently sorted column header. |
70 | | if (is_array($cell) && isset($cell['field'])) { |
71 | | $title = t('sort by @s', array('@s' => $cell['data'])); |
72 | | if ($cell['data'] == $ts['name']) { |
73 | | $ts['sort'] = (($ts['sort'] == 'asc') ? 'desc' : 'asc'); |
74 | | if (isset($cell['class'])) { |
75 | | $cell['class'] .= ' active'; |
76 | | } |
77 | | else { |
78 | | $cell['class'] = 'active'; |
79 | | } |
80 | | $image = theme('tablesort_indicator', $ts['sort']); |
81 | | } |
82 | | else { |
83 | | // If the user clicks a different header, we want to sort ascending initially. |
84 | | $ts['sort'] = 'asc'; |
85 | | $image = ''; |
86 | | } |
87 | |
|
88 | | if (!empty($ts['query_string'])) { |
89 | | $ts['query_string'] = '&'. $ts['query_string']; |
90 | | } |
91 | | $cell['data'] = l($cell['data'] . $image, $_GET['q'], array('attributes' => array('title' => $title), 'query' => 'sort='. $ts['sort'] .'&order='. urlencode($cell['data']) . $ts['query_string'], 'html' => TRUE)); |
92 | |
|
93 | | unset($cell['field'], $cell['sort']); |
94 | | } |
95 | | return $cell; |
96 | | } |
97 | |
|
98 | | /** |
99 | | * Format a table cell. |
100 | | * |
101 | | * Adds a class attribute to all cells in the currently active column. |
102 | | * |
103 | | * @param $cell |
104 | | * The cell to format. |
105 | | * @param $header |
106 | | * An array of column headers in the format described in theme_table(). |
107 | | * @param $ts |
108 | | * The current table sort context as returned from tablesort_init(). |
109 | | * @param $i |
110 | | * The index of the cell's table column. |
111 | | * @return |
112 | | * A properly formatted cell, ready for _theme_table_cell(). |
113 | | */ |
114 | | function tablesort_cell($cell, $header, $ts, $i) { |
115 | 1 | if (isset($header[$i]['data']) && $header[$i]['data'] == $ts['name'] && !empty($header[$i]['field'])) { |
116 | | if (is_array($cell)) { |
117 | | if (isset($cell['class'])) { |
118 | | $cell['class'] .= ' active'; |
119 | | } |
120 | | else { |
121 | | $cell['class'] = 'active'; |
122 | | } |
123 | | } |
124 | | else { |
125 | | $cell = array('data' => $cell, 'class' => 'active'); |
126 | | } |
127 | | } |
128 | 1 | return $cell; |
129 | | } |
130 | |
|
131 | | /** |
132 | | * Compose a query string to append to table sorting requests. |
133 | | * |
134 | | * @return |
135 | | * A query string that consists of all components of the current page request |
136 | | * except for those pertaining to table sorting. |
137 | | */ |
138 | | function tablesort_get_querystring() { |
139 | | return drupal_query_string_encode($_REQUEST, array_merge(array('q', 'sort', 'order'), array_keys($_COOKIE))); |
140 | | } |
141 | |
|
142 | | /** |
143 | | * Determine the current sort criterion. |
144 | | * |
145 | | * @param $headers |
146 | | * An array of column headers in the format described in theme_table(). |
147 | | * @return |
148 | | * An associative array describing the criterion, containing the keys: |
149 | | * - "name": The localized title of the table column. |
150 | | * - "sql": The name of the database field to sort on. |
151 | | */ |
152 | | function tablesort_get_order($headers) { |
153 | | $order = isset($_GET['order']) ? $_GET['order'] : ''; |
154 | | foreach ($headers as $header) { |
155 | | if (isset($header['data']) && $order == $header['data']) { |
156 | | return array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : ''); |
157 | | } |
158 | |
|
159 | | if (isset($header['sort']) && ($header['sort'] == 'asc' || $header['sort'] == 'desc')) { |
160 | | $default = array('name' => $header['data'], 'sql' => isset($header['field']) ? $header['field'] : ''); |
161 | | } |
162 | | } |
163 | |
|
164 | | if (isset($default)) { |
165 | | return $default; |
166 | | } |
167 | | else { |
168 | | // The first column specified is initial 'order by' field unless otherwise specified |
169 | | if (is_array($headers[0])) { |
170 | | $headers[0] += array('data' => NULL, 'field' => NULL); |
171 | | return array('name' => $headers[0]['data'], 'sql' => $headers[0]['field']); |
172 | | } |
173 | | else { |
174 | | return array('name' => $headers[0]); |
175 | | } |
176 | | } |
177 | | } |
178 | |
|
179 | | /** |
180 | | * Determine the current sort direction. |
181 | | * |
182 | | * @param $headers |
183 | | * An array of column headers in the format described in theme_table(). |
184 | | * @return |
185 | | * The current sort direction ("asc" or "desc"). |
186 | | */ |
187 | | function tablesort_get_sort($headers) { |
188 | | if (isset($_GET['sort'])) { |
189 | | return ($_GET['sort'] == 'desc') ? 'desc' : 'asc'; |
190 | | } |
191 | | // User has not specified a sort. Use default if specified; otherwise use "asc". |
192 | | else { |
193 | | foreach ($headers as $header) { |
194 | | if (is_array($header) && array_key_exists('sort', $header)) { |
195 | | return $header['sort']; |
196 | | } |
197 | | } |
198 | | } |
199 | | return 'asc'; |
200 | | } |