Mercurial > hg > vamp-website
comparison forum/Sources/Reports.php @ 76:e3e11437ecea website
Add forum code
author | Chris Cannam |
---|---|
date | Sun, 07 Jul 2013 11:25:48 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
75:72f59aa7e503 | 76:e3e11437ecea |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * Simple Machines Forum (SMF) | |
5 * | |
6 * @package SMF | |
7 * @author Simple Machines http://www.simplemachines.org | |
8 * @copyright 2011 Simple Machines | |
9 * @license http://www.simplemachines.org/about/smf/license.php BSD | |
10 * | |
11 * @version 2.0 | |
12 */ | |
13 | |
14 if (!defined('SMF')) | |
15 die('Hacking attempt...'); | |
16 | |
17 /* This file is exclusively for generating reports to help assist forum | |
18 administrators keep track of their forum configuration and state. The | |
19 core report generation is done in two areas. Firstly, a report "generator" | |
20 will fill context with relevant data. Secondly, the choice of sub-template | |
21 will determine how this data is shown to the user. It has the following | |
22 functions: | |
23 | |
24 void ReportsMain() | |
25 - requires the admin_forum permission. | |
26 - loads the Reports template and language files. | |
27 - decides which type of report to generate, if this isn't passed | |
28 through the querystring it will set the report_type sub-template to | |
29 force the user to choose which type. | |
30 - when generating a report chooses which sub_template to use. | |
31 - depends on the cal_enabled setting, and many of the other cal_ | |
32 settings. | |
33 - will call the relevant report generation function. | |
34 - if generating report will call finishTables before returning. | |
35 - accessed through ?action=admin;area=reports. | |
36 | |
37 void xxxxxxReport() | |
38 - functions ending with "Report" are responsible for generating data | |
39 for reporting. | |
40 - they are all called from ReportsMain. | |
41 - never access the context directly, but use the data handling | |
42 functions to do so. | |
43 | |
44 void newTable(string title = '', string default_value = '', | |
45 string shading = 'all', string width_normal = 'auto', | |
46 string align_normal = 'center', string width_shaded = 'auto', | |
47 string align_shaded = 'auto') | |
48 - the core of this file, it creates a new, but empty, table of data in | |
49 context, ready for filling using addData(). | |
50 - takes a lot of possible attributes, these have the following effect: | |
51 + title = Title to be displayed with this data table. | |
52 + default_value = Value to be displayed if a key is missing from a | |
53 row. | |
54 + shading = Should the left, top or both (all) parts of the table | |
55 beshaded? | |
56 + width_normal = width of an unshaded column (auto means not | |
57 defined). | |
58 + align_normal = alignment of data in an unshaded column. | |
59 + width_shaded = width of a shaded column (auto means not | |
60 defined). | |
61 + align_shaded = alignment of data in a shaded column. | |
62 - fills the context variable current_table with the ID of the table | |
63 created. | |
64 - keeps track of the current table count using context variable | |
65 table_count. | |
66 | |
67 void addData(array inc_data, int custom_table = null) | |
68 - adds an array of data into an existing table. | |
69 - if there are no existing tables, will create one with default | |
70 attributes. | |
71 - if custom_table isn't specified, it will use the last table created, | |
72 if it is specified and doesn't exist the function will return false. | |
73 - if a set of keys have been specified, the function will check each | |
74 required key is present in the incoming data. If this data is missing | |
75 the current tables default value will be used. | |
76 - if any key in the incoming data begins with '#sep#', the function | |
77 will add a separator accross the table at this point. | |
78 - once the incoming data has been sanitized, it is added to the table. | |
79 | |
80 void addSeparator(string title = '', int custom_table = null) | |
81 - adds a separator with title given by attribute "title" after the | |
82 current row in the table. | |
83 - if there are no existing tables, will create one with default | |
84 attributes. | |
85 - if custom_table isn't specified, it will use the last table created, | |
86 if it is specified and doesn't exist the function will return false. | |
87 - if the table is currently having data added by column this may have | |
88 unpredictable visual results. | |
89 | |
90 void finishTables() | |
91 - is (unfortunately) required to create some useful variables for | |
92 templates. | |
93 - foreach data table created, it will count the number of rows and | |
94 columns in the table. | |
95 - will also create a max_width variable for the table, to give an | |
96 estimate width for the whole table - if it can. | |
97 | |
98 void setKeys(string method = 'rows', array keys = array(), | |
99 bool reverse = false) | |
100 - sets the current set of "keys" expected in each data array passed to | |
101 addData. It also sets the way we are adding data to the data table. | |
102 - method specifies whether the data passed to addData represents a new | |
103 column, or a new row. | |
104 - keys is an array whose keys are the keys for data being passed to | |
105 addData(). | |
106 - if reverse is set to true, then the values of the variable "keys" | |
107 are used as oppossed to the keys(!) | |
108 */ | |
109 | |
110 // Handling function for generating reports. | |
111 function ReportsMain() | |
112 { | |
113 global $txt, $modSettings, $context, $scripturl; | |
114 | |
115 // Only admins, only EVER admins! | |
116 isAllowedTo('admin_forum'); | |
117 | |
118 // Let's get our things running... | |
119 loadTemplate('Reports'); | |
120 loadLanguage('Reports'); | |
121 | |
122 $context['page_title'] = $txt['generate_reports']; | |
123 | |
124 // These are the types of reports which exist - and the functions to generate them. | |
125 $context['report_types'] = array( | |
126 'boards' => 'BoardReport', | |
127 'board_perms' => 'BoardPermissionsReport', | |
128 'member_groups' => 'MemberGroupsReport', | |
129 'group_perms' => 'GroupPermissionsReport', | |
130 'staff' => 'StaffReport', | |
131 ); | |
132 | |
133 $is_first = 0; | |
134 foreach ($context['report_types'] as $k => $temp) | |
135 $context['report_types'][$k] = array( | |
136 'id' => $k, | |
137 'title' => isset($txt['gr_type_' . $k]) ? $txt['gr_type_' . $k] : $type['id'], | |
138 'description' => isset($txt['gr_type_desc_' . $k]) ? $txt['gr_type_desc_' . $k] : null, | |
139 'function' => $temp, | |
140 'is_first' => $is_first++ == 0, | |
141 ); | |
142 | |
143 // If they haven't choosen a report type which is valid, send them off to the report type chooser! | |
144 if (empty($_REQUEST['rt']) || !isset($context['report_types'][$_REQUEST['rt']])) | |
145 { | |
146 $context['sub_template'] = 'report_type'; | |
147 return; | |
148 } | |
149 $context['report_type'] = $_REQUEST['rt']; | |
150 | |
151 // What are valid templates for showing reports? | |
152 $reportTemplates = array( | |
153 'main' => array( | |
154 'layers' => null, | |
155 ), | |
156 'print' => array( | |
157 'layers' => array('print'), | |
158 ), | |
159 ); | |
160 | |
161 // Specific template? Use that instead of main! | |
162 if (isset($_REQUEST['st']) && isset($reportTemplates[$_REQUEST['st']])) | |
163 { | |
164 $context['sub_template'] = $_REQUEST['st']; | |
165 | |
166 // Are we disabling the other layers - print friendly for example? | |
167 if ($reportTemplates[$_REQUEST['st']]['layers'] !== null) | |
168 $context['template_layers'] = $reportTemplates[$_REQUEST['st']]['layers']; | |
169 } | |
170 | |
171 // Make the page title more descriptive. | |
172 $context['page_title'] .= ' - ' . (isset($txt['gr_type_' . $context['report_type']]) ? $txt['gr_type_' . $context['report_type']] : $context['report_type']); | |
173 // Now generate the data. | |
174 $context['report_types'][$context['report_type']]['function'](); | |
175 | |
176 // Finish the tables before exiting - this is to help the templates a little more. | |
177 finishTables(); | |
178 } | |
179 | |
180 // Standard report about what settings the boards have. | |
181 function BoardReport() | |
182 { | |
183 global $context, $txt, $sourcedir, $smcFunc; | |
184 | |
185 // Load the permission profiles. | |
186 require_once($sourcedir . '/ManagePermissions.php'); | |
187 loadLanguage('ManagePermissions'); | |
188 loadPermissionProfiles(); | |
189 | |
190 // Get every moderator. | |
191 $request = $smcFunc['db_query']('', ' | |
192 SELECT mods.id_board, mods.id_member, mem.real_name | |
193 FROM {db_prefix}moderators AS mods | |
194 INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)', | |
195 array( | |
196 ) | |
197 ); | |
198 $moderators = array(); | |
199 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
200 $moderators[$row['id_board']][] = $row['real_name']; | |
201 $smcFunc['db_free_result']($request); | |
202 | |
203 // Get all the possible membergroups! | |
204 $request = $smcFunc['db_query']('', ' | |
205 SELECT id_group, group_name, online_color | |
206 FROM {db_prefix}membergroups', | |
207 array( | |
208 ) | |
209 ); | |
210 $groups = array(-1 => $txt['guest_title'], 0 => $txt['full_member']); | |
211 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
212 $groups[$row['id_group']] = empty($row['online_color']) ? $row['group_name'] : '<span style="color: ' . $row['online_color'] . '">' . $row['group_name'] . '</span>'; | |
213 $smcFunc['db_free_result']($request); | |
214 | |
215 // All the fields we'll show. | |
216 $boardSettings = array( | |
217 'category' => $txt['board_category'], | |
218 'parent' => $txt['board_parent'], | |
219 'num_topics' => $txt['board_num_topics'], | |
220 'num_posts' => $txt['board_num_posts'], | |
221 'count_posts' => $txt['board_count_posts'], | |
222 'theme' => $txt['board_theme'], | |
223 'override_theme' => $txt['board_override_theme'], | |
224 'profile' => $txt['board_profile'], | |
225 'moderators' => $txt['board_moderators'], | |
226 'groups' => $txt['board_groups'], | |
227 ); | |
228 | |
229 // Do it in columns, it's just easier. | |
230 setKeys('cols'); | |
231 | |
232 // Go through each board! | |
233 $request = $smcFunc['db_query']('order_by_board_order', ' | |
234 SELECT b.id_board, b.name, b.num_posts, b.num_topics, b.count_posts, b.member_groups, b.override_theme, b.id_profile, | |
235 c.name AS cat_name, IFNULL(par.name, {string:text_none}) AS parent_name, IFNULL(th.value, {string:text_none}) AS theme_name | |
236 FROM {db_prefix}boards AS b | |
237 LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) | |
238 LEFT JOIN {db_prefix}boards AS par ON (par.id_board = b.id_parent) | |
239 LEFT JOIN {db_prefix}themes AS th ON (th.id_theme = b.id_theme AND th.variable = {string:name})', | |
240 array( | |
241 'name' => 'name', | |
242 'text_none' => $txt['none'], | |
243 ) | |
244 ); | |
245 $boards = array(0 => array('name' => $txt['global_boards'])); | |
246 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
247 { | |
248 // Each board has it's own table. | |
249 newTable($row['name'], '', 'left', 'auto', 'left', 200, 'left'); | |
250 | |
251 // First off, add in the side key. | |
252 addData($boardSettings); | |
253 | |
254 // Format the profile name. | |
255 $profile_name = $context['profiles'][$row['id_profile']]['name']; | |
256 | |
257 // Create the main data array. | |
258 $boardData = array( | |
259 'category' => $row['cat_name'], | |
260 'parent' => $row['parent_name'], | |
261 'num_posts' => $row['num_posts'], | |
262 'num_topics' => $row['num_topics'], | |
263 'count_posts' => empty($row['count_posts']) ? $txt['yes'] : $txt['no'], | |
264 'theme' => $row['theme_name'], | |
265 'profile' => $profile_name, | |
266 'override_theme' => $row['override_theme'] ? $txt['yes'] : $txt['no'], | |
267 'moderators' => empty($moderators[$row['id_board']]) ? $txt['none'] : implode(', ', $moderators[$row['id_board']]), | |
268 ); | |
269 | |
270 // Work out the membergroups who can access it. | |
271 $allowedGroups = explode(',', $row['member_groups']); | |
272 foreach ($allowedGroups as $key => $group) | |
273 { | |
274 if (isset($groups[$group])) | |
275 $allowedGroups[$key] = $groups[$group]; | |
276 else | |
277 unset($allowedGroups[$key]); | |
278 } | |
279 $boardData['groups'] = implode(', ', $allowedGroups); | |
280 | |
281 // Next add the main data. | |
282 addData($boardData); | |
283 } | |
284 $smcFunc['db_free_result']($request); | |
285 } | |
286 | |
287 // Generate a report on the current permissions by board and membergroup. | |
288 function BoardPermissionsReport() | |
289 { | |
290 global $context, $txt, $modSettings, $smcFunc; | |
291 | |
292 // Get as much memory as possible as this can be big. | |
293 @ini_set('memory_limit', '256M'); | |
294 | |
295 if (isset($_REQUEST['boards'])) | |
296 { | |
297 if (!is_array($_REQUEST['boards'])) | |
298 $_REQUEST['boards'] = explode(',', $_REQUEST['boards']); | |
299 foreach ($_REQUEST['boards'] as $k => $dummy) | |
300 $_REQUEST['boards'][$k] = (int) $dummy; | |
301 | |
302 $board_clause = 'id_board IN ({array_int:boards})'; | |
303 } | |
304 else | |
305 $board_clause = '1=1'; | |
306 | |
307 if (isset($_REQUEST['groups'])) | |
308 { | |
309 if (!is_array($_REQUEST['groups'])) | |
310 $_REQUEST['groups'] = explode(',', $_REQUEST['groups']); | |
311 foreach ($_REQUEST['groups'] as $k => $dummy) | |
312 $_REQUEST['groups'][$k] = (int) $dummy; | |
313 | |
314 $group_clause = 'id_group IN ({array_int:groups})'; | |
315 } | |
316 else | |
317 $group_clause = '1=1'; | |
318 | |
319 // Fetch all the board names. | |
320 $request = $smcFunc['db_query']('', ' | |
321 SELECT id_board, name, id_profile | |
322 FROM {db_prefix}boards | |
323 WHERE ' . $board_clause . ' | |
324 ORDER BY id_board', | |
325 array( | |
326 'boards' => isset($_REQUEST['boards']) ? $_REQUEST['boards'] : array(), | |
327 ) | |
328 ); | |
329 $profiles = array(); | |
330 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
331 { | |
332 $boards[$row['id_board']] = array( | |
333 'name' => $row['name'], | |
334 'profile' => $row['id_profile'], | |
335 ); | |
336 $profiles[] = $row['id_profile']; | |
337 } | |
338 $smcFunc['db_free_result']($request); | |
339 | |
340 // Get all the possible membergroups, except admin! | |
341 $request = $smcFunc['db_query']('', ' | |
342 SELECT id_group, group_name | |
343 FROM {db_prefix}membergroups | |
344 WHERE ' . $group_clause . ' | |
345 AND id_group != {int:admin_group}' . (empty($modSettings['permission_enable_postgroups']) ? ' | |
346 AND min_posts = {int:min_posts}' : '') . ' | |
347 ORDER BY min_posts, CASE WHEN id_group < {int:newbie_group} THEN id_group ELSE 4 END, group_name', | |
348 array( | |
349 'admin_group' => 1, | |
350 'min_posts' => -1, | |
351 'newbie_group' => 4, | |
352 'groups' => isset($_REQUEST['groups']) ? $_REQUEST['groups'] : array(), | |
353 ) | |
354 ); | |
355 if (!isset($_REQUEST['groups']) || in_array(-1, $_REQUEST['groups']) || in_array(0, $_REQUEST['groups'])) | |
356 $member_groups = array('col' => '', -1 => $txt['membergroups_guests'], 0 => $txt['membergroups_members']); | |
357 else | |
358 $member_groups = array('col' => ''); | |
359 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
360 $member_groups[$row['id_group']] = $row['group_name']; | |
361 $smcFunc['db_free_result']($request); | |
362 | |
363 // Make sure that every group is represented - plus in rows! | |
364 setKeys('rows', $member_groups); | |
365 | |
366 // Cache every permission setting, to make sure we don't miss any allows. | |
367 $permissions = array(); | |
368 $board_permissions = array(); | |
369 $request = $smcFunc['db_query']('', ' | |
370 SELECT id_profile, id_group, add_deny, permission | |
371 FROM {db_prefix}board_permissions | |
372 WHERE id_profile IN ({array_int:profile_list}) | |
373 AND ' . $group_clause . (empty($modSettings['permission_enable_deny']) ? ' | |
374 AND add_deny = {int:not_deny}' : '') . ' | |
375 ORDER BY id_profile, permission', | |
376 array( | |
377 'profile_list' => $profiles, | |
378 'not_deny' => 1, | |
379 'groups' => isset($_REQUEST['groups']) ? $_REQUEST['groups'] : array(), | |
380 ) | |
381 ); | |
382 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
383 { | |
384 foreach ($boards as $id => $board) | |
385 if ($board['profile'] == $row['id_profile']) | |
386 $board_permissions[$id][$row['id_group']][$row['permission']] = $row['add_deny']; | |
387 | |
388 // Make sure we get every permission. | |
389 if (!isset($permissions[$row['permission']])) | |
390 { | |
391 // This will be reused on other boards. | |
392 $permissions[$row['permission']] = array( | |
393 'title' => isset($txt['board_perms_name_' . $row['permission']]) ? $txt['board_perms_name_' . $row['permission']] : $row['permission'], | |
394 ); | |
395 } | |
396 } | |
397 $smcFunc['db_free_result']($request); | |
398 | |
399 // Now cycle through the board permissions array... lots to do ;) | |
400 foreach ($board_permissions as $board => $groups) | |
401 { | |
402 // Create the table for this board first. | |
403 newTable($boards[$board]['name'], 'x', 'all', 100, 'center', 200, 'left'); | |
404 | |
405 // Add the header row - shows all the membergroups. | |
406 addData($member_groups); | |
407 | |
408 // Add the separator. | |
409 addSeparator($txt['board_perms_permission']); | |
410 | |
411 // Here cycle through all the detected permissions. | |
412 foreach ($permissions as $ID_PERM => $perm_info) | |
413 { | |
414 // Is this identical to the global? | |
415 $identicalGlobal = $board == 0 ? false : true; | |
416 | |
417 // Default data for this row. | |
418 $curData = array('col' => $perm_info['title']); | |
419 | |
420 // Now cycle each membergroup in this set of permissions. | |
421 foreach ($member_groups as $id_group => $name) | |
422 { | |
423 // Don't overwrite the key column! | |
424 if ($id_group === 'col') | |
425 continue; | |
426 | |
427 $group_permissions = isset($groups[$id_group]) ? $groups[$id_group] : array(); | |
428 | |
429 // Do we have any data for this group? | |
430 if (isset($group_permissions[$ID_PERM])) | |
431 { | |
432 // Set the data for this group to be the local permission. | |
433 $curData[$id_group] = $group_permissions[$ID_PERM]; | |
434 } | |
435 // Otherwise means it's set to disallow.. | |
436 else | |
437 { | |
438 $curData[$id_group] = 'x'; | |
439 } | |
440 | |
441 // Now actually make the data for the group look right. | |
442 if (empty($curData[$id_group])) | |
443 $curData[$id_group] = '<span style="color: red;">' . $txt['board_perms_deny'] . '</span>'; | |
444 elseif ($curData[$id_group] == 1) | |
445 $curData[$id_group] = '<span style="color: darkgreen;">' . $txt['board_perms_allow'] . '</span>'; | |
446 else | |
447 $curData[$id_group] = 'x'; | |
448 | |
449 // Embolden those permissions different from global (makes it a lot easier!) | |
450 if (@$board_permissions[0][$id_group][$ID_PERM] != @$group_permissions[$ID_PERM]) | |
451 $curData[$id_group] = '<strong>' . $curData[$id_group] . '</strong>'; | |
452 } | |
453 | |
454 // Now add the data for this permission. | |
455 addData($curData); | |
456 } | |
457 } | |
458 } | |
459 | |
460 // Show what the membergroups are made of. | |
461 function MemberGroupsReport() | |
462 { | |
463 global $context, $txt, $settings, $modSettings, $smcFunc; | |
464 | |
465 // Fetch all the board names. | |
466 $request = $smcFunc['db_query']('', ' | |
467 SELECT id_board, name, member_groups, id_profile | |
468 FROM {db_prefix}boards', | |
469 array( | |
470 ) | |
471 ); | |
472 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
473 { | |
474 if (trim($row['member_groups']) == '') | |
475 $groups = array(1); | |
476 else | |
477 $groups = array_merge(array(1), explode(',', $row['member_groups'])); | |
478 | |
479 $boards[$row['id_board']] = array( | |
480 'id' => $row['id_board'], | |
481 'name' => $row['name'], | |
482 'profile' => $row['id_profile'], | |
483 'groups' => $groups, | |
484 ); | |
485 } | |
486 $smcFunc['db_free_result']($request); | |
487 | |
488 // Standard settings. | |
489 $mgSettings = array( | |
490 'name' => '', | |
491 '#sep#1' => $txt['member_group_settings'], | |
492 'color' => $txt['member_group_color'], | |
493 'min_posts' => $txt['member_group_min_posts'], | |
494 'max_messages' => $txt['member_group_max_messages'], | |
495 'stars' => $txt['member_group_stars'], | |
496 '#sep#2' => $txt['member_group_access'], | |
497 ); | |
498 | |
499 // Add on the boards! | |
500 foreach ($boards as $board) | |
501 $mgSettings['board_' . $board['id']] = $board['name']; | |
502 | |
503 // Add all the membergroup settings, plus we'll be adding in columns! | |
504 setKeys('cols', $mgSettings); | |
505 | |
506 // Only one table this time! | |
507 newTable($txt['gr_type_member_groups'], '-', 'all', 100, 'center', 200, 'left'); | |
508 | |
509 // Get the shaded column in. | |
510 addData($mgSettings); | |
511 | |
512 // Now start cycling the membergroups! | |
513 $request = $smcFunc['db_query']('', ' | |
514 SELECT mg.id_group, mg.group_name, mg.online_color, mg.min_posts, mg.max_messages, mg.stars, | |
515 CASE WHEN bp.permission IS NOT NULL OR mg.id_group = {int:admin_group} THEN 1 ELSE 0 END AS can_moderate | |
516 FROM {db_prefix}membergroups AS mg | |
517 LEFT JOIN {db_prefix}board_permissions AS bp ON (bp.id_group = mg.id_group AND bp.id_profile = {int:default_profile} AND bp.permission = {string:moderate_board}) | |
518 ORDER BY mg.min_posts, CASE WHEN mg.id_group < {int:newbie_group} THEN mg.id_group ELSE 4 END, mg.group_name', | |
519 array( | |
520 'admin_group' => 1, | |
521 'default_profile' => 1, | |
522 'newbie_group' => 4, | |
523 'moderate_board' => 'moderate_board', | |
524 ) | |
525 ); | |
526 | |
527 // Cache them so we get regular members too. | |
528 $rows = array( | |
529 array( | |
530 'id_group' => -1, | |
531 'group_name' => $txt['membergroups_guests'], | |
532 'online_color' => '', | |
533 'min_posts' => -1, | |
534 'max_messages' => null, | |
535 'stars' => '' | |
536 ), | |
537 array( | |
538 'id_group' => 0, | |
539 'group_name' => $txt['membergroups_members'], | |
540 'online_color' => '', | |
541 'min_posts' => -1, | |
542 'max_messages' => null, | |
543 'stars' => '' | |
544 ), | |
545 ); | |
546 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
547 $rows[] = $row; | |
548 $smcFunc['db_free_result']($request); | |
549 | |
550 foreach ($rows as $row) | |
551 { | |
552 $row['stars'] = explode('#', $row['stars']); | |
553 | |
554 $group = array( | |
555 'name' => $row['group_name'], | |
556 'color' => empty($row['online_color']) ? '-' : '<span style="color: ' . $row['online_color'] . ';">' . $row['online_color'] . '</span>', | |
557 'min_posts' => $row['min_posts'] == -1 ? 'N/A' : $row['min_posts'], | |
558 'max_messages' => $row['max_messages'], | |
559 'stars' => !empty($row['stars'][0]) && !empty($row['stars'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/' . $row['stars'][1] . '" alt="*" />', $row['stars'][0]) : '', | |
560 ); | |
561 | |
562 // Board permissions. | |
563 foreach ($boards as $board) | |
564 $group['board_' . $board['id']] = in_array($row['id_group'], $board['groups']) ? '<span style="color: darkgreen;">' . $txt['board_perms_allow'] . '</span>' : 'x'; | |
565 | |
566 addData($group); | |
567 } | |
568 } | |
569 | |
570 // Show the large variety of group permissions assigned to each membergroup. | |
571 function GroupPermissionsReport() | |
572 { | |
573 global $context, $txt, $modSettings, $smcFunc; | |
574 | |
575 if (isset($_REQUEST['groups'])) | |
576 { | |
577 if (!is_array($_REQUEST['groups'])) | |
578 $_REQUEST['groups'] = explode(',', $_REQUEST['groups']); | |
579 foreach ($_REQUEST['groups'] as $k => $dummy) | |
580 $_REQUEST['groups'][$k] = (int) $dummy; | |
581 $_REQUEST['groups'] = array_diff($_REQUEST['groups'], array(3)); | |
582 | |
583 $clause = 'id_group IN ({array_int:groups})'; | |
584 } | |
585 else | |
586 $clause = 'id_group != {int:moderator_group}'; | |
587 | |
588 // Get all the possible membergroups, except admin! | |
589 $request = $smcFunc['db_query']('', ' | |
590 SELECT id_group, group_name | |
591 FROM {db_prefix}membergroups | |
592 WHERE ' . $clause . ' | |
593 AND id_group != {int:admin_group}' . (empty($modSettings['permission_enable_postgroups']) ? ' | |
594 AND min_posts = {int:min_posts}' : '') . ' | |
595 ORDER BY min_posts, CASE WHEN id_group < {int:newbie_group} THEN id_group ELSE 4 END, group_name', | |
596 array( | |
597 'admin_group' => 1, | |
598 'min_posts' => -1, | |
599 'newbie_group' => 4, | |
600 'moderator_group' => 3, | |
601 'groups' => isset($_REQUEST['groups']) ? $_REQUEST['groups'] : array(), | |
602 ) | |
603 ); | |
604 if (!isset($_REQUEST['groups']) || in_array(-1, $_REQUEST['groups']) || in_array(0, $_REQUEST['groups'])) | |
605 $groups = array('col' => '', -1 => $txt['membergroups_guests'], 0 => $txt['membergroups_members']); | |
606 else | |
607 $groups = array('col' => ''); | |
608 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
609 $groups[$row['id_group']] = $row['group_name']; | |
610 $smcFunc['db_free_result']($request); | |
611 | |
612 // Make sure that every group is represented! | |
613 setKeys('rows', $groups); | |
614 | |
615 // Create the table first. | |
616 newTable($txt['gr_type_group_perms'], '-', 'all', 100, 'center', 200, 'left'); | |
617 | |
618 // Show all the groups | |
619 addData($groups); | |
620 | |
621 // Add a separator | |
622 addSeparator($txt['board_perms_permission']); | |
623 | |
624 // Now the big permission fetch! | |
625 $request = $smcFunc['db_query']('', ' | |
626 SELECT id_group, add_deny, permission | |
627 FROM {db_prefix}permissions | |
628 WHERE ' . $clause . (empty($modSettings['permission_enable_deny']) ? ' | |
629 AND add_deny = {int:not_denied}' : '') . ' | |
630 ORDER BY permission', | |
631 array( | |
632 'not_denied' => 1, | |
633 'moderator_group' => 3, | |
634 'groups' => isset($_REQUEST['groups']) ? $_REQUEST['groups'] : array(), | |
635 ) | |
636 ); | |
637 $lastPermission = null; | |
638 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
639 { | |
640 // If this is a new permission flush the last row. | |
641 if ($row['permission'] != $lastPermission) | |
642 { | |
643 // Send the data! | |
644 if ($lastPermission !== null) | |
645 addData($curData); | |
646 | |
647 // Add the permission name in the left column. | |
648 $curData = array('col' => isset($txt['group_perms_name_' . $row['permission']]) ? $txt['group_perms_name_' . $row['permission']] : $row['permission']); | |
649 | |
650 $lastPermission = $row['permission']; | |
651 } | |
652 | |
653 // Good stuff - add the permission to the list! | |
654 if ($row['add_deny']) | |
655 $curData[$row['id_group']] = '<span style="color: darkgreen;">' . $txt['board_perms_allow'] . '</span>'; | |
656 else | |
657 $curData[$row['id_group']] = '<span style="color: red;">' . $txt['board_perms_deny'] . '</span>'; | |
658 } | |
659 $smcFunc['db_free_result']($request); | |
660 | |
661 // Flush the last data! | |
662 addData($curData); | |
663 } | |
664 | |
665 // Report for showing all the forum staff members - quite a feat! | |
666 function StaffReport() | |
667 { | |
668 global $sourcedir, $context, $txt, $smcFunc; | |
669 | |
670 require_once($sourcedir . '/Subs-Members.php'); | |
671 | |
672 // Fetch all the board names. | |
673 $request = $smcFunc['db_query']('', ' | |
674 SELECT id_board, name | |
675 FROM {db_prefix}boards', | |
676 array( | |
677 ) | |
678 ); | |
679 $boards = array(); | |
680 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
681 $boards[$row['id_board']] = $row['name']; | |
682 $smcFunc['db_free_result']($request); | |
683 | |
684 // Get every moderator. | |
685 $request = $smcFunc['db_query']('', ' | |
686 SELECT mods.id_board, mods.id_member | |
687 FROM {db_prefix}moderators AS mods', | |
688 array( | |
689 ) | |
690 ); | |
691 $moderators = array(); | |
692 $local_mods = array(); | |
693 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
694 { | |
695 $moderators[$row['id_member']][] = $row['id_board']; | |
696 $local_mods[$row['id_member']] = $row['id_member']; | |
697 } | |
698 $smcFunc['db_free_result']($request); | |
699 | |
700 // Get a list of global moderators (i.e. members with moderation powers). | |
701 $global_mods = array_intersect(membersAllowedTo('moderate_board', 0), membersAllowedTo('approve_posts', 0), membersAllowedTo('remove_any', 0), membersAllowedTo('modify_any', 0)); | |
702 | |
703 // How about anyone else who is special? | |
704 $allStaff = array_merge(membersAllowedTo('admin_forum'), membersAllowedTo('manage_membergroups'), membersAllowedTo('manage_permissions'), $local_mods, $global_mods); | |
705 | |
706 // Make sure everyone is there once - no admin less important than any other! | |
707 $allStaff = array_unique($allStaff); | |
708 | |
709 // This is a bit of a cop out - but we're protecting their forum, really! | |
710 if (count($allStaff) > 300) | |
711 fatal_lang_error('report_error_too_many_staff'); | |
712 | |
713 // Get all the possible membergroups! | |
714 $request = $smcFunc['db_query']('', ' | |
715 SELECT id_group, group_name, online_color | |
716 FROM {db_prefix}membergroups', | |
717 array( | |
718 ) | |
719 ); | |
720 $groups = array(0 => $txt['full_member']); | |
721 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
722 $groups[$row['id_group']] = empty($row['online_color']) ? $row['group_name'] : '<span style="color: ' . $row['online_color'] . '">' . $row['group_name'] . '</span>'; | |
723 $smcFunc['db_free_result']($request); | |
724 | |
725 // All the fields we'll show. | |
726 $staffSettings = array( | |
727 'position' => $txt['report_staff_position'], | |
728 'moderates' => $txt['report_staff_moderates'], | |
729 'posts' => $txt['report_staff_posts'], | |
730 'last_login' => $txt['report_staff_last_login'], | |
731 ); | |
732 | |
733 // Do it in columns, it's just easier. | |
734 setKeys('cols'); | |
735 | |
736 // Get each member! | |
737 $request = $smcFunc['db_query']('', ' | |
738 SELECT id_member, real_name, id_group, posts, last_login | |
739 FROM {db_prefix}members | |
740 WHERE id_member IN ({array_int:staff_list}) | |
741 ORDER BY real_name', | |
742 array( | |
743 'staff_list' => $allStaff, | |
744 ) | |
745 ); | |
746 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
747 { | |
748 // Each member gets their own table!. | |
749 newTable($row['real_name'], '', 'left', 'auto', 'left', 200, 'center'); | |
750 | |
751 // First off, add in the side key. | |
752 addData($staffSettings); | |
753 | |
754 // Create the main data array. | |
755 $staffData = array( | |
756 'position' => isset($groups[$row['id_group']]) ? $groups[$row['id_group']] : $groups[0], | |
757 'posts' => $row['posts'], | |
758 'last_login' => timeformat($row['last_login']), | |
759 'moderates' => array(), | |
760 ); | |
761 | |
762 // What do they moderate? | |
763 if (in_array($row['id_member'], $global_mods)) | |
764 $staffData['moderates'] = '<em>' . $txt['report_staff_all_boards'] . '</em>'; | |
765 elseif (isset($moderators[$row['id_member']])) | |
766 { | |
767 // Get the names | |
768 foreach ($moderators[$row['id_member']] as $board) | |
769 if (isset($boards[$board])) | |
770 $staffData['moderates'][] = $boards[$board]; | |
771 | |
772 $staffData['moderates'] = implode(', ', $staffData['moderates']); | |
773 } | |
774 else | |
775 $staffData['moderates'] = '<em>' . $txt['report_staff_no_boards'] . '</em>'; | |
776 | |
777 // Next add the main data. | |
778 addData($staffData); | |
779 } | |
780 $smcFunc['db_free_result']($request); | |
781 } | |
782 | |
783 // This function creates a new table of data, most functions will only use it once. | |
784 function newTable($title = '', $default_value = '', $shading = 'all', $width_normal = 'auto', $align_normal = 'center', $width_shaded = 'auto', $align_shaded = 'auto') | |
785 { | |
786 global $context; | |
787 | |
788 // Set the table count if needed. | |
789 if (empty($context['table_count'])) | |
790 $context['table_count'] = 0; | |
791 | |
792 // Create the table! | |
793 $context['tables'][$context['table_count']] = array( | |
794 'title' => $title, | |
795 'default_value' => $default_value, | |
796 'shading' => array( | |
797 'left' => $shading == 'all' || $shading == 'left', | |
798 'top' => $shading == 'all' || $shading == 'top', | |
799 ), | |
800 'width' => array( | |
801 'normal' => $width_normal, | |
802 'shaded' => $width_shaded, | |
803 ), | |
804 'align' => array( | |
805 'normal' => $align_normal, | |
806 'shaded' => $align_shaded, | |
807 ), | |
808 'data' => array(), | |
809 ); | |
810 | |
811 $context['current_table'] = $context['table_count']; | |
812 | |
813 // Increment the count... | |
814 $context['table_count']++; | |
815 } | |
816 | |
817 // Add an extra slice of data to the table | |
818 function addData($inc_data, $custom_table = null) | |
819 { | |
820 global $context; | |
821 | |
822 // No tables? Create one even though we are probably already in a bad state! | |
823 if (empty($context['table_count'])) | |
824 newTable(); | |
825 | |
826 // Specific table? | |
827 if ($custom_table !== null && !isset($context['tables'][$custom_table])) | |
828 return false; | |
829 elseif ($custom_table !== null) | |
830 $table = $custom_table; | |
831 else | |
832 $table = $context['current_table']; | |
833 | |
834 // If we have keys, sanitise the data... | |
835 if (!empty($context['keys'])) | |
836 { | |
837 // Basically, check every key exists! | |
838 foreach ($context['keys'] as $key => $dummy) | |
839 { | |
840 $data[$key] = array( | |
841 'v' => empty($inc_data[$key]) ? $context['tables'][$table]['default_value'] : $inc_data[$key], | |
842 ); | |
843 // Special "hack" the adding separators when doing data by column. | |
844 if (substr($key, 0, 5) == '#sep#') | |
845 $data[$key]['separator'] = true; | |
846 } | |
847 } | |
848 else | |
849 { | |
850 $data = $inc_data; | |
851 foreach ($data as $key => $value) | |
852 { | |
853 $data[$key] = array( | |
854 'v' => $value, | |
855 ); | |
856 if (substr($key, 0, 5) == '#sep#') | |
857 $data[$key]['separator'] = true; | |
858 } | |
859 } | |
860 | |
861 // Is it by row? | |
862 if (empty($context['key_method']) || $context['key_method'] == 'rows') | |
863 { | |
864 // Add the data! | |
865 $context['tables'][$table]['data'][] = $data; | |
866 } | |
867 // Otherwise, tricky! | |
868 else | |
869 { | |
870 foreach ($data as $key => $item) | |
871 $context['tables'][$table]['data'][$key][] = $item; | |
872 } | |
873 } | |
874 | |
875 // Add a separator row, only really used when adding data by rows. | |
876 function addSeparator($title = '', $custom_table = null) | |
877 { | |
878 global $context; | |
879 | |
880 // No tables - return? | |
881 if (empty($context['table_count'])) | |
882 return; | |
883 | |
884 // Specific table? | |
885 if ($custom_table !== null && !isset($context['tables'][$table])) | |
886 return false; | |
887 elseif ($custom_table !== null) | |
888 $table = $custom_table; | |
889 else | |
890 $table = $context['current_table']; | |
891 | |
892 // Plumb in the separator | |
893 $context['tables'][$table]['data'][] = array(0 => array( | |
894 'separator' => true, | |
895 'v' => $title | |
896 )); | |
897 } | |
898 | |
899 // This does the necessary count of table data before displaying them. | |
900 function finishTables() | |
901 { | |
902 global $context; | |
903 | |
904 if (empty($context['tables'])) | |
905 return; | |
906 | |
907 // Loop through each table counting up some basic values, to help with the templating. | |
908 foreach ($context['tables'] as $id => $table) | |
909 { | |
910 $context['tables'][$id]['id'] = $id; | |
911 $context['tables'][$id]['row_count'] = count($table['data']); | |
912 $curElement = current($table['data']); | |
913 $context['tables'][$id]['column_count'] = count($curElement); | |
914 | |
915 // Work out the rough width - for templates like the print template. Without this we might get funny tables. | |
916 if ($table['shading']['left'] && $table['width']['shaded'] != 'auto' && $table['width']['normal'] != 'auto') | |
917 $context['tables'][$id]['max_width'] = $table['width']['shaded'] + ($context['tables'][$id]['column_count'] - 1) * $table['width']['normal']; | |
918 elseif ($table['width']['normal'] != 'auto') | |
919 $context['tables'][$id]['max_width'] = $context['tables'][$id]['column_count'] * $table['width']['normal']; | |
920 else | |
921 $context['tables'][$id]['max_width'] = 'auto'; | |
922 } | |
923 } | |
924 | |
925 // Set the keys in use by the tables - these ensure entries MUST exist if the data isn't sent. | |
926 function setKeys($method = 'rows', $keys = array(), $reverse = false) | |
927 { | |
928 global $context; | |
929 | |
930 // Do we want to use the keys of the keys as the keys? :P | |
931 if ($reverse) | |
932 $context['keys'] = array_flip($keys); | |
933 else | |
934 $context['keys'] = $keys; | |
935 | |
936 // Rows or columns? | |
937 $context['key_method'] = $method == 'rows' ? 'rows' : 'cols'; | |
938 } | |
939 | |
940 ?> |