annotate forum/Sources/Subs-List.php @ 85:6d7b61434be7 website

Add a copy of this here, just in case!
author Chris Cannam
date Mon, 20 Jan 2014 11:02:36 +0000
parents e3e11437ecea
children
rev   line source
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 ?>