Chris@76
|
1 <?php
|
Chris@76
|
2
|
Chris@76
|
3 /**
|
Chris@76
|
4 * Simple Machines Forum (SMF)
|
Chris@76
|
5 *
|
Chris@76
|
6 * @package SMF
|
Chris@76
|
7 * @author Simple Machines http://www.simplemachines.org
|
Chris@76
|
8 * @copyright 2011 Simple Machines
|
Chris@76
|
9 * @license http://www.simplemachines.org/about/smf/license.php BSD
|
Chris@76
|
10 *
|
Chris@76
|
11 * @version 2.0
|
Chris@76
|
12 */
|
Chris@76
|
13
|
Chris@76
|
14 if (!defined('SMF'))
|
Chris@76
|
15 die('Hacking attempt...');
|
Chris@76
|
16
|
Chris@76
|
17 /* This file contains a standard way of displaying lists for SMF.
|
Chris@76
|
18 */
|
Chris@76
|
19
|
Chris@76
|
20 function createList($listOptions)
|
Chris@76
|
21 {
|
Chris@76
|
22 global $context, $settings, $options, $txt, $modSettings, $scripturl;
|
Chris@76
|
23
|
Chris@76
|
24 assert(isset($listOptions['id']));
|
Chris@76
|
25 assert(isset($listOptions['columns']));
|
Chris@76
|
26 assert(is_array($listOptions['columns']));
|
Chris@76
|
27 assert((empty($listOptions['items_per_page']) || (isset($listOptions['get_count']['function'], $listOptions['base_href']) && is_numeric($listOptions['items_per_page']))));
|
Chris@76
|
28 assert((empty($listOptions['default_sort_col']) || isset($listOptions['columns'][$listOptions['default_sort_col']])));
|
Chris@76
|
29 assert((!isset($listOptions['form']) || isset($listOptions['form']['href'])));
|
Chris@76
|
30
|
Chris@76
|
31 // All the context data will be easily accessible by using a reference.
|
Chris@76
|
32 $context[$listOptions['id']] = array();
|
Chris@76
|
33 $list_context = &$context[$listOptions['id']];
|
Chris@76
|
34
|
Chris@76
|
35 // Figure out the sort.
|
Chris@76
|
36 if (empty($listOptions['default_sort_col']))
|
Chris@76
|
37 {
|
Chris@76
|
38 $list_context['sort'] = array();
|
Chris@76
|
39 $sort = '1=1';
|
Chris@76
|
40 }
|
Chris@76
|
41 else
|
Chris@76
|
42 {
|
Chris@76
|
43 $request_var_sort = isset($listOptions['request_vars']['sort']) ? $listOptions['request_vars']['sort'] : 'sort';
|
Chris@76
|
44 $request_var_desc = isset($listOptions['request_vars']['desc']) ? $listOptions['request_vars']['desc'] : 'desc';
|
Chris@76
|
45 if (isset($_REQUEST[$request_var_sort], $listOptions['columns'][$_REQUEST[$request_var_sort]], $listOptions['columns'][$_REQUEST[$request_var_sort]]['sort']))
|
Chris@76
|
46 $list_context['sort'] = array(
|
Chris@76
|
47 'id' => $_REQUEST[$request_var_sort],
|
Chris@76
|
48 'desc' => isset($_REQUEST[$request_var_desc]) && isset($listOptions['columns'][$_REQUEST[$request_var_sort]]['sort']['reverse']),
|
Chris@76
|
49 );
|
Chris@76
|
50 else
|
Chris@76
|
51 $list_context['sort'] = array(
|
Chris@76
|
52 'id' => $listOptions['default_sort_col'],
|
Chris@76
|
53 'desc' => (!empty($listOptions['default_sort_dir']) && $listOptions['default_sort_dir'] == 'desc') || (!empty($listOptions['columns'][$listOptions['default_sort_col']]['sort']['default']) && substr($listOptions['columns'][$listOptions['default_sort_col']]['sort']['default'], -4, 4) == 'desc') ? true : false,
|
Chris@76
|
54 );
|
Chris@76
|
55
|
Chris@76
|
56 // Set the database column sort.
|
Chris@76
|
57 $sort = $listOptions['columns'][$list_context['sort']['id']]['sort'][$list_context['sort']['desc'] ? 'reverse' : 'default'];
|
Chris@76
|
58 }
|
Chris@76
|
59
|
Chris@76
|
60 $list_context['start_var_name'] = isset($listOptions['start_var_name']) ? $listOptions['start_var_name'] : 'start';
|
Chris@76
|
61 // In some cases the full list must be shown, regardless of the amount of items.
|
Chris@76
|
62 if (empty($listOptions['items_per_page']))
|
Chris@76
|
63 {
|
Chris@76
|
64 $list_context['start'] = 0;
|
Chris@76
|
65 $list_context['items_per_page'] = 0;
|
Chris@76
|
66 }
|
Chris@76
|
67 // With items per page set, calculate total number of items and page index.
|
Chris@76
|
68 else
|
Chris@76
|
69 {
|
Chris@76
|
70 // First get an impression of how many items to expect.
|
Chris@76
|
71 if (isset($listOptions['get_count']['file']))
|
Chris@76
|
72 require_once($listOptions['get_count']['file']);
|
Chris@76
|
73 $list_context['total_num_items'] = call_user_func_array($listOptions['get_count']['function'], empty($listOptions['get_count']['params']) ? array() : $listOptions['get_count']['params']);
|
Chris@76
|
74
|
Chris@76
|
75 // Default the start to the beginning...sounds logical.
|
Chris@76
|
76 $list_context['start'] = isset($_REQUEST[$list_context['start_var_name']]) ? (int) $_REQUEST[$list_context['start_var_name']] : 0;
|
Chris@76
|
77 $list_context['items_per_page'] = $listOptions['items_per_page'];
|
Chris@76
|
78
|
Chris@76
|
79 // Then create a page index.
|
Chris@76
|
80 $list_context['page_index'] = constructPageIndex($listOptions['base_href'] . (empty($list_context['sort']) ? '' : ';' . $request_var_sort . '=' . $list_context['sort']['id'] . ($list_context['sort']['desc'] ? ';' . $request_var_desc : '')) . ($list_context['start_var_name'] != 'start' ? ';' . $list_context['start_var_name'] . '=%1$d' : ''), $list_context['start'], $list_context['total_num_items'], $list_context['items_per_page'], $list_context['start_var_name'] != 'start');
|
Chris@76
|
81 }
|
Chris@76
|
82
|
Chris@76
|
83 // Prepare the headers of the table.
|
Chris@76
|
84 $list_context['headers'] = array();
|
Chris@76
|
85 foreach ($listOptions['columns'] as $column_id => $column)
|
Chris@76
|
86 $list_context['headers'][] = array(
|
Chris@76
|
87 'id' => $column_id,
|
Chris@76
|
88 'label' => isset($column['header']['eval']) ? eval($column['header']['eval']) : (isset($column['header']['value']) ? $column['header']['value'] : ''),
|
Chris@76
|
89 'href' => empty($listOptions['default_sort_col']) || empty($column['sort']) ? '' : $listOptions['base_href'] . ';' . $request_var_sort . '=' . $column_id . ($column_id === $list_context['sort']['id'] && !$list_context['sort']['desc'] && isset($column['sort']['reverse']) ? ';' . $request_var_desc : '') . (empty($list_context['start']) ? '' : ';' . $list_context['start_var_name'] . '=' . $list_context['start']),
|
Chris@76
|
90 'sort_image' => empty($listOptions['default_sort_col']) || empty($column['sort']) || $column_id !== $list_context['sort']['id'] ? null : ($list_context['sort']['desc'] ? 'down' : 'up'),
|
Chris@76
|
91 'class' => isset($column['header']['class']) ? $column['header']['class'] : '',
|
Chris@76
|
92 'style' => isset($column['header']['style']) ? $column['header']['style'] : '',
|
Chris@76
|
93 'colspan' => isset($column['header']['colspan']) ? $column['header']['colspan'] : '',
|
Chris@76
|
94 );
|
Chris@76
|
95
|
Chris@76
|
96 // We know the amount of columns, might be useful for the template.
|
Chris@76
|
97 $list_context['num_columns'] = count($listOptions['columns']);
|
Chris@76
|
98 $list_context['width'] = isset($listOptions['width']) ? $listOptions['width'] : '0';
|
Chris@76
|
99
|
Chris@76
|
100 // Get the file with the function for the item list.
|
Chris@76
|
101 if (isset($listOptions['get_items']['file']))
|
Chris@76
|
102 require_once($listOptions['get_items']['file']);
|
Chris@76
|
103
|
Chris@76
|
104 // Call the function and include which items we want and in what order.
|
Chris@76
|
105 $list_items = call_user_func_array($listOptions['get_items']['function'], array_merge(array($list_context['start'], $list_context['items_per_page'], $sort), empty($listOptions['get_items']['params']) ? array() : $listOptions['get_items']['params']));
|
Chris@76
|
106
|
Chris@76
|
107 // Loop through the list items to be shown and construct the data values.
|
Chris@76
|
108 $list_context['rows'] = array();
|
Chris@76
|
109 foreach ($list_items as $item_id => $list_item)
|
Chris@76
|
110 {
|
Chris@76
|
111 $cur_row = array();
|
Chris@76
|
112 foreach ($listOptions['columns'] as $column_id => $column)
|
Chris@76
|
113 {
|
Chris@76
|
114 $cur_data = array();
|
Chris@76
|
115
|
Chris@76
|
116 // A value straight from the database?
|
Chris@76
|
117 if (isset($column['data']['db']))
|
Chris@76
|
118 $cur_data['value'] = $list_item[$column['data']['db']];
|
Chris@76
|
119
|
Chris@76
|
120 // Take the value from the database and make it HTML safe.
|
Chris@76
|
121 elseif (isset($column['data']['db_htmlsafe']))
|
Chris@76
|
122 $cur_data['value'] = htmlspecialchars($list_item[$column['data']['db_htmlsafe']]);
|
Chris@76
|
123
|
Chris@76
|
124 // Using sprintf is probably the most readable way of injecting data.
|
Chris@76
|
125 elseif (isset($column['data']['sprintf']))
|
Chris@76
|
126 {
|
Chris@76
|
127 $params = array();
|
Chris@76
|
128 foreach ($column['data']['sprintf']['params'] as $sprintf_param => $htmlsafe)
|
Chris@76
|
129 $params[] = $htmlsafe ? htmlspecialchars($list_item[$sprintf_param]) : $list_item[$sprintf_param];
|
Chris@76
|
130 $cur_data['value'] = vsprintf($column['data']['sprintf']['format'], $params);
|
Chris@76
|
131 }
|
Chris@76
|
132
|
Chris@76
|
133 // The most flexible way probably is applying a custom function.
|
Chris@76
|
134 elseif (isset($column['data']['function']))
|
Chris@76
|
135 $cur_data['value'] = $column['data']['function']($list_item);
|
Chris@76
|
136
|
Chris@76
|
137 // A modified value (inject the database values).
|
Chris@76
|
138 elseif (isset($column['data']['eval']))
|
Chris@76
|
139 $cur_data['value'] = eval(preg_replace('~%([a-zA-Z0-9\-_]+)%~', '$list_item[\'$1\']', $column['data']['eval']));
|
Chris@76
|
140
|
Chris@76
|
141 // A literal value.
|
Chris@76
|
142 elseif (isset($column['data']['value']))
|
Chris@76
|
143 $cur_data['value'] = $column['data']['value'];
|
Chris@76
|
144
|
Chris@76
|
145 // Empty value.
|
Chris@76
|
146 else
|
Chris@76
|
147 $cur_data['value'] = '';
|
Chris@76
|
148
|
Chris@76
|
149 // Allow for basic formatting.
|
Chris@76
|
150 if (!empty($column['data']['comma_format']))
|
Chris@76
|
151 $cur_data['value'] = comma_format($cur_data['value']);
|
Chris@76
|
152 elseif (!empty($column['data']['timeformat']))
|
Chris@76
|
153 $cur_data['value'] = timeformat($cur_data['value']);
|
Chris@76
|
154
|
Chris@76
|
155 // Set a style class for this column?
|
Chris@76
|
156 if (isset($column['data']['class']))
|
Chris@76
|
157 $cur_data['class'] = $column['data']['class'];
|
Chris@76
|
158
|
Chris@76
|
159 // Fully customized styling for the cells in this column only.
|
Chris@76
|
160 if (isset($column['data']['style']))
|
Chris@76
|
161 $cur_data['style'] = $column['data']['style'];
|
Chris@76
|
162
|
Chris@76
|
163 // Add the data cell properties to the current row.
|
Chris@76
|
164 $cur_row[$column_id] = $cur_data;
|
Chris@76
|
165 }
|
Chris@76
|
166
|
Chris@76
|
167 // Insert the row into the list.
|
Chris@76
|
168 $list_context['rows'][$item_id] = $cur_row;
|
Chris@76
|
169 }
|
Chris@76
|
170
|
Chris@76
|
171 // The title is currently optional.
|
Chris@76
|
172 if (isset($listOptions['title']))
|
Chris@76
|
173 $list_context['title'] = $listOptions['title'];
|
Chris@76
|
174
|
Chris@76
|
175 // In case there's a form, share it with the template context.
|
Chris@76
|
176 if (isset($listOptions['form']))
|
Chris@76
|
177 {
|
Chris@76
|
178 $list_context['form'] = $listOptions['form'];
|
Chris@76
|
179
|
Chris@76
|
180 if (!isset($list_context['form']['hidden_fields']))
|
Chris@76
|
181 $list_context['form']['hidden_fields'] = array();
|
Chris@76
|
182
|
Chris@76
|
183 // Always add a session check field.
|
Chris@76
|
184 $list_context['form']['hidden_fields'][$context['session_var']] = $context['session_id'];
|
Chris@76
|
185
|
Chris@76
|
186 // Include the starting page as hidden field?
|
Chris@76
|
187 if (!empty($list_context['form']['include_start']) && !empty($list_context['start']))
|
Chris@76
|
188 $list_context['form']['hidden_fields'][$list_context['start_var_name']] = $list_context['start'];
|
Chris@76
|
189
|
Chris@76
|
190 // If sorting needs to be the same after submitting, add the parameter.
|
Chris@76
|
191 if (!empty($list_context['form']['include_sort']) && !empty($list_context['sort']))
|
Chris@76
|
192 {
|
Chris@76
|
193 $list_context['form']['hidden_fields']['sort'] = $list_context['sort']['id'];
|
Chris@76
|
194 if ($list_context['sort']['desc'])
|
Chris@76
|
195 $list_context['form']['hidden_fields']['desc'] = 1;
|
Chris@76
|
196 }
|
Chris@76
|
197 }
|
Chris@76
|
198
|
Chris@76
|
199 // Wanna say something nice in case there are no items?
|
Chris@76
|
200 if (isset($listOptions['no_items_label']))
|
Chris@76
|
201 {
|
Chris@76
|
202 $list_context['no_items_label'] = $listOptions['no_items_label'];
|
Chris@76
|
203 $list_context['no_items_align'] = isset($listOptions['no_items_align']) ? $listOptions['no_items_align'] : '';
|
Chris@76
|
204 }
|
Chris@76
|
205
|
Chris@76
|
206 // A list can sometimes need a few extra rows above and below.
|
Chris@76
|
207 if (isset($listOptions['additional_rows']))
|
Chris@76
|
208 {
|
Chris@76
|
209 $list_context['additional_rows'] = array();
|
Chris@76
|
210 foreach ($listOptions['additional_rows'] as $row)
|
Chris@76
|
211 {
|
Chris@76
|
212 if (empty($row))
|
Chris@76
|
213 continue;
|
Chris@76
|
214
|
Chris@76
|
215 // Supported row positions: top_of_list, after_title,
|
Chris@76
|
216 // above_column_headers, below_table_data, bottom_of_list.
|
Chris@76
|
217 if (!isset($list_context['additional_rows'][$row['position']]))
|
Chris@76
|
218 $list_context['additional_rows'][$row['position']] = array();
|
Chris@76
|
219 $list_context['additional_rows'][$row['position']][] = $row;
|
Chris@76
|
220 }
|
Chris@76
|
221 }
|
Chris@76
|
222
|
Chris@76
|
223 // Add an option for inline JavaScript.
|
Chris@76
|
224 if (isset($listOptions['javascript']))
|
Chris@76
|
225 $list_context['javascript'] = $listOptions['javascript'];
|
Chris@76
|
226
|
Chris@76
|
227 // We want a menu.
|
Chris@76
|
228 if (isset($listOptions['list_menu']))
|
Chris@76
|
229 $list_context['list_menu'] = $listOptions['list_menu'];
|
Chris@76
|
230
|
Chris@76
|
231 // Make sure the template is loaded.
|
Chris@76
|
232 loadTemplate('GenericList');
|
Chris@76
|
233 }
|
Chris@76
|
234
|
Chris@76
|
235 ?> |