albertlast /
SMF2.1
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * This file currently just shows group info, and allows certain priviledged members to add/remove members. |
||
| 5 | * |
||
| 6 | * Simple Machines Forum (SMF) |
||
| 7 | * |
||
| 8 | * @package SMF |
||
| 9 | * @author Simple Machines http://www.simplemachines.org |
||
| 10 | * @copyright 2017 Simple Machines and individual contributors |
||
| 11 | * @license http://www.simplemachines.org/about/smf/license.php BSD |
||
| 12 | * |
||
| 13 | * @version 2.1 Beta 4 |
||
| 14 | */ |
||
| 15 | |||
| 16 | if (!defined('SMF')) |
||
| 17 | die('No direct access...'); |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Entry point function, permission checks, admin bars, etc. |
||
| 21 | * It allows moderators and users to access the group showing functions. |
||
| 22 | * It handles permission checks, and puts the moderation bar on as required. |
||
| 23 | */ |
||
| 24 | function Groups() |
||
| 25 | { |
||
| 26 | global $context, $txt, $scripturl, $sourcedir, $user_info; |
||
| 27 | |||
| 28 | // The sub-actions that we can do. Format "Function Name, Mod Bar Index if appropriate". |
||
| 29 | $subActions = array( |
||
| 30 | 'index' => array('GroupList', 'view_groups'), |
||
| 31 | 'members' => array('MembergroupMembers', 'view_groups'), |
||
| 32 | 'requests' => array('GroupRequests', 'group_requests'), |
||
| 33 | ); |
||
| 34 | |||
| 35 | // Default to sub action 'index'. |
||
| 36 | $_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'index'; |
||
| 37 | |||
| 38 | // Get the template stuff up and running. |
||
| 39 | loadLanguage('ManageMembers'); |
||
| 40 | loadLanguage('ModerationCenter'); |
||
| 41 | loadTemplate('ManageMembergroups'); |
||
| 42 | |||
| 43 | // If we can see the moderation center, and this has a mod bar entry, add the mod center bar. |
||
| 44 | if (allowedTo('access_mod_center') || $user_info['mod_cache']['bq'] != '0=1' || $user_info['mod_cache']['gq'] != '0=1' || allowedTo('manage_membergroups')) |
||
| 45 | { |
||
| 46 | require_once($sourcedir . '/ModerationCenter.php'); |
||
| 47 | $_GET['area'] = $_REQUEST['sa'] == 'requests' ? 'groups' : 'viewgroups'; |
||
| 48 | ModerationMain(true); |
||
| 49 | } |
||
| 50 | // Otherwise add something to the link tree, for normal people. |
||
| 51 | else |
||
| 52 | { |
||
| 53 | isAllowedTo('view_mlist'); |
||
| 54 | |||
| 55 | $context['linktree'][] = array( |
||
| 56 | 'url' => $scripturl . '?action=groups', |
||
| 57 | 'name' => $txt['groups'], |
||
| 58 | ); |
||
| 59 | } |
||
| 60 | |||
| 61 | // CRUD $subActions as needed. |
||
| 62 | call_integration_hook('integrate_manage_groups', array(&$subActions)); |
||
| 63 | |||
| 64 | // Call the actual function. |
||
| 65 | call_helper($subActions[$_REQUEST['sa']][0]); |
||
| 66 | } |
||
| 67 | |||
| 68 | /** |
||
| 69 | * This very simply lists the groups, nothing snazy. |
||
| 70 | */ |
||
| 71 | function GroupList() |
||
| 72 | { |
||
| 73 | global $txt, $context, $sourcedir, $scripturl; |
||
| 74 | |||
| 75 | $context['page_title'] = $txt['viewing_groups']; |
||
| 76 | |||
| 77 | // Making a list is not hard with this beauty. |
||
| 78 | require_once($sourcedir . '/Subs-List.php'); |
||
| 79 | |||
| 80 | // Use the standard templates for showing this. |
||
| 81 | $listOptions = array( |
||
| 82 | 'id' => 'group_lists', |
||
| 83 | 'title' => $context['page_title'], |
||
| 84 | 'base_href' => $scripturl . '?action=moderate;area=viewgroups;sa=view', |
||
| 85 | 'default_sort_col' => 'group', |
||
| 86 | 'get_items' => array( |
||
| 87 | 'file' => $sourcedir . '/Subs-Membergroups.php', |
||
| 88 | 'function' => 'list_getMembergroups', |
||
| 89 | 'params' => array( |
||
| 90 | 'regular', |
||
| 91 | ), |
||
| 92 | ), |
||
| 93 | 'columns' => array( |
||
| 94 | 'group' => array( |
||
| 95 | 'header' => array( |
||
| 96 | 'value' => $txt['name'], |
||
| 97 | ), |
||
| 98 | 'data' => array( |
||
| 99 | 'function' => function($rowData) use ($scripturl) |
||
| 100 | { |
||
| 101 | // Since the moderator group has no explicit members, no link is needed. |
||
| 102 | if ($rowData['id_group'] == 3) |
||
| 103 | $group_name = $rowData['group_name']; |
||
| 104 | else |
||
| 105 | { |
||
| 106 | $color_style = empty($rowData['online_color']) ? '' : sprintf(' style="color: %1$s;"', $rowData['online_color']); |
||
| 107 | |||
| 108 | View Code Duplication | if (allowedTo('manage_membergroups')) |
|
|
0 ignored issues
–
show
|
|||
| 109 | { |
||
| 110 | $group_name = sprintf('<a href="%1$s?action=admin;area=membergroups;sa=members;group=%2$d"%3$s>%4$s</a>', $scripturl, $rowData['id_group'], $color_style, $rowData['group_name']); |
||
| 111 | } |
||
| 112 | else |
||
| 113 | { |
||
| 114 | $group_name = sprintf('<a href="%1$s?action=groups;sa=members;group=%2$d"%3$s>%4$s</a>', $scripturl, $rowData['id_group'], $color_style, $rowData['group_name']); |
||
| 115 | } |
||
| 116 | } |
||
| 117 | |||
| 118 | // Add a help option for moderator and administrator. |
||
| 119 | View Code Duplication | if ($rowData['id_group'] == 1) |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 120 | $group_name .= sprintf(' (<a href="%1$s?action=helpadmin;help=membergroup_administrator" onclick="return reqOverlayDiv(this.href);">?</a>)', $scripturl); |
||
| 121 | elseif ($rowData['id_group'] == 3) |
||
| 122 | $group_name .= sprintf(' (<a href="%1$s?action=helpadmin;help=membergroup_moderator" onclick="return reqOverlayDiv(this.href);">?</a>)', $scripturl); |
||
| 123 | |||
| 124 | return $group_name; |
||
| 125 | }, |
||
| 126 | ), |
||
| 127 | 'sort' => array( |
||
| 128 | 'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, mg.group_name', |
||
| 129 | 'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, mg.group_name DESC', |
||
| 130 | ), |
||
| 131 | ), |
||
| 132 | 'icons' => array( |
||
| 133 | 'header' => array( |
||
| 134 | 'value' => $txt['membergroups_icons'], |
||
| 135 | ), |
||
| 136 | 'data' => array( |
||
| 137 | 'db' => 'icons', |
||
| 138 | ), |
||
| 139 | 'sort' => array( |
||
| 140 | 'default' => 'mg.icons', |
||
| 141 | 'reverse' => 'mg.icons DESC', |
||
| 142 | ) |
||
| 143 | ), |
||
| 144 | 'moderators' => array( |
||
| 145 | 'header' => array( |
||
| 146 | 'value' => $txt['moderators'], |
||
| 147 | ), |
||
| 148 | 'data' => array( |
||
| 149 | 'function' => function($group) use ($txt) |
||
| 150 | { |
||
| 151 | return empty($group['moderators']) ? '<em>' . $txt['membergroups_new_copy_none'] . '</em>' : implode(', ', $group['moderators']); |
||
| 152 | }, |
||
| 153 | ), |
||
| 154 | ), |
||
| 155 | 'members' => array( |
||
| 156 | 'header' => array( |
||
| 157 | 'value' => $txt['membergroups_members_top'], |
||
| 158 | ), |
||
| 159 | 'data' => array( |
||
| 160 | View Code Duplication | 'function' => function($rowData) use ($txt) |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 161 | { |
||
| 162 | // No explicit members for the moderator group. |
||
| 163 | return $rowData['id_group'] == 3 ? $txt['membergroups_guests_na'] : comma_format($rowData['num_members']); |
||
| 164 | }, |
||
| 165 | 'class' => 'centercol', |
||
| 166 | ), |
||
| 167 | 'sort' => array( |
||
| 168 | 'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, 1', |
||
| 169 | 'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, 1 DESC', |
||
| 170 | ), |
||
| 171 | ), |
||
| 172 | ), |
||
| 173 | ); |
||
| 174 | |||
| 175 | // Create the request list. |
||
| 176 | createList($listOptions); |
||
| 177 | |||
| 178 | $context['sub_template'] = 'show_list'; |
||
| 179 | $context['default_list'] = 'group_lists'; |
||
| 180 | } |
||
| 181 | |||
| 182 | /** |
||
| 183 | * Display members of a group, and allow adding of members to a group. Silly function name though ;) |
||
| 184 | * It can be called from ManageMembergroups if it needs templating within the admin environment. |
||
| 185 | * It shows a list of members that are part of a given membergroup. |
||
| 186 | * It is called by ?action=moderate;area=viewgroups;sa=members;group=x |
||
| 187 | * It requires the manage_membergroups permission. |
||
| 188 | * It allows to add and remove members from the selected membergroup. |
||
| 189 | * It allows sorting on several columns. |
||
| 190 | * It redirects to itself. |
||
| 191 | * @uses ManageMembergroups template, group_members sub template. |
||
| 192 | * @todo: use createList |
||
| 193 | */ |
||
| 194 | function MembergroupMembers() |
||
| 195 | { |
||
| 196 | global $txt, $scripturl, $context, $modSettings, $sourcedir, $user_info, $settings, $smcFunc; |
||
| 197 | |||
| 198 | $_REQUEST['group'] = isset($_REQUEST['group']) ? (int) $_REQUEST['group'] : 0; |
||
| 199 | |||
| 200 | // No browsing of guests, membergroup 0 or moderators. |
||
| 201 | if (in_array($_REQUEST['group'], array(-1, 0, 3))) |
||
| 202 | fatal_lang_error('membergroup_does_not_exist', false); |
||
| 203 | |||
| 204 | // Load up the group details. |
||
| 205 | $request = $smcFunc['db_query']('', ' |
||
| 206 | SELECT id_group AS id, group_name AS name, CASE WHEN min_posts = {int:min_posts} THEN 1 ELSE 0 END AS assignable, hidden, online_color, |
||
| 207 | icons, description, CASE WHEN min_posts != {int:min_posts} THEN 1 ELSE 0 END AS is_post_group, group_type |
||
| 208 | FROM {db_prefix}membergroups |
||
| 209 | WHERE id_group = {int:id_group} |
||
| 210 | LIMIT 1', |
||
| 211 | array( |
||
| 212 | 'min_posts' => -1, |
||
| 213 | 'id_group' => $_REQUEST['group'], |
||
| 214 | ) |
||
| 215 | ); |
||
| 216 | // Doesn't exist? |
||
| 217 | if ($smcFunc['db_num_rows']($request) == 0) |
||
| 218 | fatal_lang_error('membergroup_does_not_exist', false); |
||
| 219 | $context['group'] = $smcFunc['db_fetch_assoc']($request); |
||
| 220 | $smcFunc['db_free_result']($request); |
||
| 221 | |||
| 222 | // Fix the membergroup icons. |
||
| 223 | $context['group']['icons'] = explode('#', $context['group']['icons']); |
||
| 224 | $context['group']['icons'] = !empty($context['group']['icons'][0]) && !empty($context['group']['icons'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/membericons/' . $context['group']['icons'][1] . '" alt="*">', $context['group']['icons'][0]) : ''; |
||
| 225 | $context['group']['can_moderate'] = allowedTo('manage_membergroups') && (allowedTo('admin_forum') || $context['group']['group_type'] != 1); |
||
| 226 | |||
| 227 | $context['linktree'][] = array( |
||
| 228 | 'url' => $scripturl . '?action=groups;sa=members;group=' . $context['group']['id'], |
||
| 229 | 'name' => $context['group']['name'], |
||
| 230 | ); |
||
| 231 | $context['can_send_email'] = allowedTo('moderate_forum'); |
||
| 232 | |||
| 233 | // Load all the group moderators, for fun. |
||
| 234 | $request = $smcFunc['db_query']('', ' |
||
| 235 | SELECT mem.id_member, mem.real_name |
||
| 236 | FROM {db_prefix}group_moderators AS mods |
||
| 237 | INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member) |
||
| 238 | WHERE mods.id_group = {int:id_group}', |
||
| 239 | array( |
||
| 240 | 'id_group' => $_REQUEST['group'], |
||
| 241 | ) |
||
| 242 | ); |
||
| 243 | $context['group']['moderators'] = array(); |
||
| 244 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 245 | { |
||
| 246 | $context['group']['moderators'][] = array( |
||
| 247 | 'id' => $row['id_member'], |
||
| 248 | 'name' => $row['real_name'] |
||
| 249 | ); |
||
| 250 | |||
| 251 | if ($user_info['id'] == $row['id_member'] && $context['group']['group_type'] != 1) |
||
| 252 | $context['group']['can_moderate'] = true; |
||
| 253 | } |
||
| 254 | $smcFunc['db_free_result']($request); |
||
| 255 | |||
| 256 | // If this group is hidden then it can only "exists" if the user can moderate it! |
||
| 257 | if ($context['group']['hidden'] && !$context['group']['can_moderate']) |
||
| 258 | fatal_lang_error('membergroup_does_not_exist', false); |
||
| 259 | |||
| 260 | // You can only assign membership if you are the moderator and/or can manage groups! |
||
| 261 | if (!$context['group']['can_moderate']) |
||
| 262 | $context['group']['assignable'] = 0; |
||
| 263 | // Non-admins cannot assign admins. |
||
| 264 | elseif ($context['group']['id'] == 1 && !allowedTo('admin_forum')) |
||
| 265 | $context['group']['assignable'] = 0; |
||
| 266 | |||
| 267 | // Removing member from group? |
||
| 268 | if (isset($_POST['remove']) && !empty($_REQUEST['rem']) && is_array($_REQUEST['rem']) && $context['group']['assignable']) |
||
| 269 | { |
||
| 270 | checkSession(); |
||
| 271 | validateToken('mod-mgm'); |
||
| 272 | |||
| 273 | // Make sure we're dealing with integers only. |
||
| 274 | foreach ($_REQUEST['rem'] as $key => $group) |
||
| 275 | $_REQUEST['rem'][$key] = (int) $group; |
||
| 276 | |||
| 277 | require_once($sourcedir . '/Subs-Membergroups.php'); |
||
| 278 | removeMembersFromGroups($_REQUEST['rem'], $_REQUEST['group'], true); |
||
| 279 | } |
||
| 280 | // Must be adding new members to the group... |
||
| 281 | elseif (isset($_REQUEST['add']) && (!empty($_REQUEST['toAdd']) || !empty($_REQUEST['member_add'])) && $context['group']['assignable']) |
||
| 282 | { |
||
| 283 | checkSession(); |
||
| 284 | validateToken('mod-mgm'); |
||
| 285 | |||
| 286 | $member_query = array(); |
||
| 287 | $member_parameters = array(); |
||
| 288 | |||
| 289 | // Get all the members to be added... taking into account names can be quoted ;) |
||
| 290 | $_REQUEST['toAdd'] = strtr($smcFunc['htmlspecialchars']($_REQUEST['toAdd'], ENT_QUOTES), array('"' => '"')); |
||
| 291 | preg_match_all('~"([^"]+)"~', $_REQUEST['toAdd'], $matches); |
||
| 292 | $member_names = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_REQUEST['toAdd'])))); |
||
| 293 | |||
| 294 | foreach ($member_names as $index => $member_name) |
||
| 295 | { |
||
| 296 | $member_names[$index] = trim($smcFunc['strtolower']($member_names[$index])); |
||
| 297 | |||
| 298 | if (strlen($member_names[$index]) == 0) |
||
| 299 | unset($member_names[$index]); |
||
| 300 | } |
||
| 301 | |||
| 302 | // Any passed by ID? |
||
| 303 | $member_ids = array(); |
||
| 304 | if (!empty($_REQUEST['member_add'])) |
||
| 305 | foreach ($_REQUEST['member_add'] as $id) |
||
|
0 ignored issues
–
show
The expression
$_REQUEST['member_add'] of type integer|array|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
Loading history...
|
|||
| 306 | if ($id > 0) |
||
| 307 | $member_ids[] = (int) $id; |
||
| 308 | |||
| 309 | // Construct the query pelements. |
||
| 310 | if (!empty($member_ids)) |
||
| 311 | { |
||
| 312 | $member_query[] = 'id_member IN ({array_int:member_ids})'; |
||
| 313 | $member_parameters['member_ids'] = $member_ids; |
||
| 314 | } |
||
| 315 | if (!empty($member_names)) |
||
| 316 | { |
||
| 317 | $member_query[] = 'LOWER(member_name) IN ({array_string:member_names})'; |
||
| 318 | $member_query[] = 'LOWER(real_name) IN ({array_string:member_names})'; |
||
| 319 | $member_parameters['member_names'] = $member_names; |
||
| 320 | } |
||
| 321 | |||
| 322 | $members = array(); |
||
| 323 | if (!empty($member_query)) |
||
| 324 | { |
||
| 325 | $request = $smcFunc['db_query']('', ' |
||
| 326 | SELECT id_member |
||
| 327 | FROM {db_prefix}members |
||
| 328 | WHERE (' . implode(' OR ', $member_query) . ') |
||
| 329 | AND id_group != {int:id_group} |
||
| 330 | AND FIND_IN_SET({int:id_group}, additional_groups) = 0', |
||
| 331 | array_merge($member_parameters, array( |
||
| 332 | 'id_group' => $_REQUEST['group'], |
||
| 333 | )) |
||
| 334 | ); |
||
| 335 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 336 | $members[] = $row['id_member']; |
||
| 337 | $smcFunc['db_free_result']($request); |
||
| 338 | } |
||
| 339 | |||
| 340 | // @todo Add $_POST['additional'] to templates! |
||
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
36% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. Loading history...
|
|||
| 341 | |||
| 342 | // Do the updates... |
||
| 343 | if (!empty($members)) |
||
| 344 | { |
||
| 345 | require_once($sourcedir . '/Subs-Membergroups.php'); |
||
| 346 | addMembersToGroup($members, $_REQUEST['group'], isset($_POST['additional']) || $context['group']['hidden'] ? 'only_additional' : 'auto', true); |
||
| 347 | } |
||
| 348 | } |
||
| 349 | |||
| 350 | // Sort out the sorting! |
||
| 351 | $sort_methods = array( |
||
| 352 | 'name' => 'real_name', |
||
| 353 | 'email' => 'email_address', |
||
| 354 | 'active' => 'last_login', |
||
| 355 | 'registered' => 'date_registered', |
||
| 356 | 'posts' => 'posts', |
||
| 357 | ); |
||
| 358 | |||
| 359 | // They didn't pick one, default to by name.. |
||
| 360 | if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) |
||
| 361 | { |
||
| 362 | $context['sort_by'] = 'name'; |
||
| 363 | $querySort = 'real_name'; |
||
| 364 | } |
||
| 365 | // Otherwise default to ascending. |
||
| 366 | else |
||
| 367 | { |
||
| 368 | $context['sort_by'] = $_REQUEST['sort']; |
||
| 369 | $querySort = $sort_methods[$_REQUEST['sort']]; |
||
| 370 | } |
||
| 371 | |||
| 372 | $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up'; |
||
| 373 | |||
| 374 | // The where on the query is interesting. Non-moderators should only see people who are in this group as primary. |
||
| 375 | if ($context['group']['can_moderate']) |
||
| 376 | $where = $context['group']['is_post_group'] ? 'id_post_group = {int:group}' : 'id_group = {int:group} OR FIND_IN_SET({int:group}, additional_groups) != 0'; |
||
| 377 | else |
||
| 378 | $where = $context['group']['is_post_group'] ? 'id_post_group = {int:group}' : 'id_group = {int:group}'; |
||
| 379 | |||
| 380 | // Count members of the group. |
||
| 381 | $request = $smcFunc['db_query']('', ' |
||
| 382 | SELECT COUNT(*) |
||
| 383 | FROM {db_prefix}members |
||
| 384 | WHERE ' . $where, |
||
| 385 | array( |
||
| 386 | 'group' => $_REQUEST['group'], |
||
| 387 | ) |
||
| 388 | ); |
||
| 389 | list ($context['total_members']) = $smcFunc['db_fetch_row']($request); |
||
| 390 | $smcFunc['db_free_result']($request); |
||
| 391 | $context['total_members'] = comma_format($context['total_members']); |
||
| 392 | |||
| 393 | // Create the page index. |
||
| 394 | $context['page_index'] = constructPageIndex($scripturl . '?action=' . ($context['group']['can_moderate'] ? 'moderate;area=viewgroups' : 'groups') . ';sa=members;group=' . $_REQUEST['group'] . ';sort=' . $context['sort_by'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $context['total_members'], $modSettings['defaultMaxMembers']); |
||
| 395 | $context['start'] = $_REQUEST['start']; |
||
| 396 | $context['can_moderate_forum'] = allowedTo('moderate_forum'); |
||
| 397 | |||
| 398 | // Load up all members of this group. |
||
| 399 | $request = $smcFunc['db_query']('', ' |
||
| 400 | SELECT id_member, member_name, real_name, email_address, member_ip, date_registered, last_login, |
||
| 401 | posts, is_activated, real_name |
||
| 402 | FROM {db_prefix}members |
||
| 403 | WHERE ' . $where . ' |
||
| 404 | ORDER BY ' . $querySort . ' ' . ($context['sort_direction'] == 'down' ? 'DESC' : 'ASC') . ' |
||
| 405 | LIMIT {int:start}, {int:max}', |
||
| 406 | array( |
||
| 407 | 'group' => $_REQUEST['group'], |
||
| 408 | 'start' => $context['start'], |
||
| 409 | 'max' => $modSettings['defaultMaxMembers'], |
||
| 410 | ) |
||
| 411 | ); |
||
| 412 | $context['members'] = array(); |
||
| 413 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 414 | { |
||
| 415 | $row['member_ip'] = inet_dtop($row['member_ip']); |
||
| 416 | $last_online = empty($row['last_login']) ? $txt['never'] : timeformat($row['last_login']); |
||
| 417 | |||
| 418 | // Italicize the online note if they aren't activated. |
||
| 419 | if ($row['is_activated'] % 10 != 1) |
||
| 420 | $last_online = '<em title="' . $txt['not_activated'] . '">' . $last_online . '</em>'; |
||
| 421 | |||
| 422 | $context['members'][] = array( |
||
| 423 | 'id' => $row['id_member'], |
||
| 424 | 'name' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>', |
||
| 425 | 'email' => $row['email_address'], |
||
| 426 | 'ip' => '<a href="' . $scripturl . '?action=trackip;searchip=' . $row['member_ip'] . '">' . $row['member_ip'] . '</a>', |
||
| 427 | 'registered' => timeformat($row['date_registered']), |
||
| 428 | 'last_online' => $last_online, |
||
| 429 | 'posts' => comma_format($row['posts']), |
||
| 430 | 'is_activated' => $row['is_activated'] % 10 == 1, |
||
| 431 | ); |
||
| 432 | } |
||
| 433 | $smcFunc['db_free_result']($request); |
||
| 434 | |||
| 435 | // Select the template. |
||
| 436 | $context['sub_template'] = 'group_members'; |
||
| 437 | $context['page_title'] = $txt['membergroups_members_title'] . ': ' . $context['group']['name']; |
||
| 438 | createToken('mod-mgm'); |
||
| 439 | |||
| 440 | if ($context['group']['assignable']) |
||
| 441 | loadJavaScriptFile('suggest.js', array('defer' => false), 'smf_suggest'); |
||
| 442 | } |
||
| 443 | |||
| 444 | /** |
||
| 445 | * Show and manage all group requests. |
||
| 446 | */ |
||
| 447 | function GroupRequests() |
||
| 448 | { |
||
| 449 | global $txt, $context, $scripturl, $user_info, $sourcedir, $smcFunc, $modSettings; |
||
| 450 | |||
| 451 | // Set up the template stuff... |
||
| 452 | $context['page_title'] = $txt['mc_group_requests']; |
||
| 453 | $context['sub_template'] = 'show_list'; |
||
| 454 | |||
| 455 | // Verify we can be here. |
||
| 456 | if ($user_info['mod_cache']['gq'] == '0=1') |
||
| 457 | isAllowedTo('manage_membergroups'); |
||
| 458 | |||
| 459 | // Normally, we act normally... |
||
| 460 | $where = ($user_info['mod_cache']['gq'] == '1=1' || $user_info['mod_cache']['gq'] == '0=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq']); |
||
| 461 | |||
| 462 | if (isset($_GET['closed'])) |
||
| 463 | $where .= ' AND lgr.status != {int:status_open}'; |
||
| 464 | else |
||
| 465 | $where .= ' AND lgr.status = {int:status_open}'; |
||
| 466 | |||
| 467 | $where_parameters = array( |
||
| 468 | 'status_open' => 0, |
||
| 469 | ); |
||
| 470 | |||
| 471 | // We've submitted? |
||
| 472 | if (isset($_POST[$context['session_var']]) && !empty($_POST['groupr']) && !empty($_POST['req_action'])) |
||
| 473 | { |
||
| 474 | checkSession(); |
||
| 475 | validateToken('mod-gr'); |
||
| 476 | |||
| 477 | // Clean the values. |
||
| 478 | foreach ($_POST['groupr'] as $k => $request) |
||
| 479 | $_POST['groupr'][$k] = (int) $request; |
||
| 480 | |||
| 481 | $log_changes = array(); |
||
| 482 | |||
| 483 | // If we are giving a reason (And why shouldn't we?), then we don't actually do much. |
||
| 484 | if ($_POST['req_action'] == 'reason') |
||
| 485 | { |
||
| 486 | // Different sub template... |
||
| 487 | $context['sub_template'] = 'group_request_reason'; |
||
| 488 | // And a limitation. We don't care that the page number bit makes no sense, as we don't need it! |
||
| 489 | $where .= ' AND lgr.id_request IN ({array_int:request_ids})'; |
||
| 490 | $where_parameters['request_ids'] = $_POST['groupr']; |
||
| 491 | |||
| 492 | $context['group_requests'] = list_getGroupRequests(0, $modSettings['defaultMaxListItems'], 'lgr.id_request', $where, $where_parameters); |
||
|
0 ignored issues
–
show
$where_parameters is of type array<string,?,{"request_ids":"?"}>, but the function expects a string.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 493 | |||
| 494 | // Need to make another token for this. |
||
| 495 | createToken('mod-gr'); |
||
| 496 | |||
| 497 | // Let obExit etc sort things out. |
||
| 498 | obExit(); |
||
| 499 | } |
||
| 500 | // Otherwise we do something! |
||
| 501 | else |
||
| 502 | { |
||
| 503 | $request = $smcFunc['db_query']('', ' |
||
| 504 | SELECT lgr.id_request |
||
| 505 | FROM {db_prefix}log_group_requests AS lgr |
||
| 506 | WHERE ' . $where . ' |
||
| 507 | AND lgr.id_request IN ({array_int:request_list})', |
||
| 508 | array( |
||
| 509 | 'request_list' => $_POST['groupr'], |
||
| 510 | 'status_open' => 0, |
||
| 511 | ) |
||
| 512 | ); |
||
| 513 | $request_list = array(); |
||
| 514 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 515 | { |
||
| 516 | if (!isset($log_changes[$row['id_request']])) |
||
| 517 | $log_changes[$row['id_request']] = array( |
||
| 518 | 'id_request' => $row['id_request'], |
||
| 519 | 'status' => $_POST['req_action'] == 'approve' ? 1 : 2, // 1 = approved, 2 = rejected |
||
| 520 | 'id_member_acted' => $user_info['id'], |
||
| 521 | 'member_name_acted' => $user_info['name'], |
||
| 522 | 'time_acted' => time(), |
||
| 523 | 'act_reason' => $_POST['req_action'] != 'approve' && !empty($_POST['groupreason']) && !empty($_POST['groupreason'][$row['id_request']]) ? $smcFunc['htmlspecialchars']($_POST['groupreason'][$row['id_request']], ENT_QUOTES) : '', |
||
| 524 | ); |
||
| 525 | $request_list[] = $row['id_request']; |
||
| 526 | } |
||
| 527 | $smcFunc['db_free_result']($request); |
||
| 528 | |||
| 529 | // Add a background task to handle notifying people of this request |
||
| 530 | $data = json_encode(array('member_id' => $user_info['id'], 'member_ip' => $user_info['ip'], 'request_list' => $request_list, 'status' => $_POST['req_action'], 'reason' => isset($_POST['groupreason']) ? $_POST['groupreason'] : '', 'time' => time())); |
||
| 531 | $smcFunc['db_insert']('insert', '{db_prefix}background_tasks', |
||
| 532 | array('task_file' => 'string-255', 'task_class' => 'string-255', 'task_data' => 'string', 'claimed_time' => 'int'), |
||
| 533 | array('$sourcedir/tasks/GroupAct-Notify.php', 'GroupAct_Notify_Background', $data, 0), array() |
||
| 534 | ); |
||
| 535 | |||
| 536 | // Some changes to log? |
||
| 537 | if (!empty($log_changes)) |
||
| 538 | { |
||
| 539 | foreach ($log_changes as $id_request => $details) |
||
| 540 | { |
||
| 541 | $smcFunc['db_query']('', ' |
||
| 542 | UPDATE {db_prefix}log_group_requests |
||
| 543 | SET status = {int:status}, |
||
| 544 | id_member_acted = {int:id_member_acted}, |
||
| 545 | member_name_acted = {string:member_name_acted}, |
||
| 546 | time_acted = {int:time_acted}, |
||
| 547 | act_reason = {string:act_reason} |
||
| 548 | WHERE id_request = {int:id_request}', |
||
| 549 | $details |
||
| 550 | ); |
||
| 551 | } |
||
| 552 | } |
||
| 553 | } |
||
| 554 | } |
||
| 555 | |||
| 556 | // We're going to want this for making our list. |
||
| 557 | require_once($sourcedir . '/Subs-List.php'); |
||
| 558 | |||
| 559 | // This is all the information required for a group listing. |
||
| 560 | $listOptions = array( |
||
| 561 | 'id' => 'group_request_list', |
||
| 562 | 'width' => '100%', |
||
| 563 | 'items_per_page' => $modSettings['defaultMaxListItems'], |
||
| 564 | 'no_items_label' => $txt['mc_groupr_none_found'], |
||
| 565 | 'base_href' => $scripturl . '?action=groups;sa=requests', |
||
| 566 | 'default_sort_col' => 'member', |
||
| 567 | 'get_items' => array( |
||
| 568 | 'function' => 'list_getGroupRequests', |
||
| 569 | 'params' => array( |
||
| 570 | $where, |
||
| 571 | $where_parameters, |
||
| 572 | ), |
||
| 573 | ), |
||
| 574 | 'get_count' => array( |
||
| 575 | 'function' => 'list_getGroupRequestCount', |
||
| 576 | 'params' => array( |
||
| 577 | $where, |
||
| 578 | $where_parameters, |
||
| 579 | ), |
||
| 580 | ), |
||
| 581 | 'columns' => array( |
||
| 582 | 'member' => array( |
||
| 583 | 'header' => array( |
||
| 584 | 'value' => $txt['mc_groupr_member'], |
||
| 585 | ), |
||
| 586 | 'data' => array( |
||
| 587 | 'db' => 'member_link', |
||
| 588 | ), |
||
| 589 | 'sort' => array( |
||
| 590 | 'default' => 'mem.member_name', |
||
| 591 | 'reverse' => 'mem.member_name DESC', |
||
| 592 | ), |
||
| 593 | ), |
||
| 594 | 'group' => array( |
||
| 595 | 'header' => array( |
||
| 596 | 'value' => $txt['mc_groupr_group'], |
||
| 597 | ), |
||
| 598 | 'data' => array( |
||
| 599 | 'db' => 'group_link', |
||
| 600 | ), |
||
| 601 | 'sort' => array( |
||
| 602 | 'default' => 'mg.group_name', |
||
| 603 | 'reverse' => 'mg.group_name DESC', |
||
| 604 | ), |
||
| 605 | ), |
||
| 606 | 'reason' => array( |
||
| 607 | 'header' => array( |
||
| 608 | 'value' => $txt['mc_groupr_reason'], |
||
| 609 | ), |
||
| 610 | 'data' => array( |
||
| 611 | 'db' => 'reason', |
||
| 612 | ), |
||
| 613 | ), |
||
| 614 | 'date' => array( |
||
| 615 | 'header' => array( |
||
| 616 | 'value' => $txt['date'], |
||
| 617 | 'style' => 'width: 18%; white-space:nowrap;', |
||
| 618 | ), |
||
| 619 | 'data' => array( |
||
| 620 | 'db' => 'time_submitted', |
||
| 621 | ), |
||
| 622 | ), |
||
| 623 | 'action' => array( |
||
| 624 | 'header' => array( |
||
| 625 | 'value' => '<input type="checkbox" class="input_check" onclick="invertAll(this, this.form);">', |
||
| 626 | 'style' => 'width: 4%;', |
||
| 627 | 'class' => 'centercol', |
||
| 628 | ), |
||
| 629 | 'data' => array( |
||
| 630 | 'sprintf' => array( |
||
| 631 | 'format' => '<input type="checkbox" name="groupr[]" value="%1$d" class="input_check">', |
||
| 632 | 'params' => array( |
||
| 633 | 'id' => false, |
||
| 634 | ), |
||
| 635 | ), |
||
| 636 | 'class' => 'centercol', |
||
| 637 | ), |
||
| 638 | ), |
||
| 639 | ), |
||
| 640 | 'form' => array( |
||
| 641 | 'href' => $scripturl . '?action=groups;sa=requests', |
||
| 642 | 'include_sort' => true, |
||
| 643 | 'include_start' => true, |
||
| 644 | 'hidden_fields' => array( |
||
| 645 | $context['session_var'] => $context['session_id'], |
||
| 646 | ), |
||
| 647 | 'token' => 'mod-gr', |
||
| 648 | ), |
||
| 649 | 'additional_rows' => array( |
||
| 650 | array( |
||
| 651 | 'position' => 'bottom_of_list', |
||
| 652 | 'value' => ' |
||
| 653 | <select name="req_action" onchange="if (this.value != 0 && (this.value == \'reason\' || confirm(\'' . $txt['mc_groupr_warning'] . '\'))) this.form.submit();"> |
||
| 654 | <option value="0">' . $txt['with_selected'] . ':</option> |
||
| 655 | <option value="0" disabled>---------------------</option> |
||
| 656 | <option value="approve">' . $txt['mc_groupr_approve'] . '</option> |
||
| 657 | <option value="reject">' . $txt['mc_groupr_reject'] . '</option> |
||
| 658 | <option value="reason">' . $txt['mc_groupr_reject_w_reason'] . '</option> |
||
| 659 | </select> |
||
| 660 | <input type="submit" name="go" value="' . $txt['go'] . '" onclick="var sel = document.getElementById(\'req_action\'); if (sel.value != 0 && sel.value != \'reason\' && !confirm(\'' . $txt['mc_groupr_warning'] . '\')) return false;" class="button_submit">', |
||
| 661 | 'class' => 'floatright', |
||
| 662 | ), |
||
| 663 | ), |
||
| 664 | ); |
||
| 665 | |||
| 666 | if (isset($_GET['closed'])) |
||
| 667 | { |
||
| 668 | // Closed requests don't require interaction. |
||
| 669 | unset($listOptions['columns']['action'], $listOptions['form'], $listOptions['additional_rows'][0]); |
||
| 670 | $listOptions['base_href'] .= 'closed'; |
||
| 671 | } |
||
| 672 | |||
| 673 | // Create the request list. |
||
| 674 | createToken('mod-gr'); |
||
| 675 | createList($listOptions); |
||
| 676 | |||
| 677 | $context['default_list'] = 'group_request_list'; |
||
| 678 | $context[$context['moderation_menu_name']]['tab_data'] = array( |
||
| 679 | 'title' => $txt['mc_group_requests'], |
||
| 680 | ); |
||
| 681 | } |
||
| 682 | |||
| 683 | /** |
||
| 684 | * Callback function for createList(). |
||
| 685 | * |
||
| 686 | * @param string $where The WHERE clause for the query |
||
| 687 | * @param array $where_parameters The parameters for the WHERE clause |
||
| 688 | * @return int The number of group requests |
||
| 689 | */ |
||
| 690 | View Code Duplication | function list_getGroupRequestCount($where, $where_parameters) |
|
|
0 ignored issues
–
show
This function seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 691 | { |
||
| 692 | global $smcFunc; |
||
| 693 | |||
| 694 | $request = $smcFunc['db_query']('', ' |
||
| 695 | SELECT COUNT(*) |
||
| 696 | FROM {db_prefix}log_group_requests AS lgr |
||
| 697 | WHERE ' . $where, |
||
| 698 | array_merge($where_parameters, array( |
||
| 699 | )) |
||
| 700 | ); |
||
| 701 | list ($totalRequests) = $smcFunc['db_fetch_row']($request); |
||
| 702 | $smcFunc['db_free_result']($request); |
||
| 703 | |||
| 704 | return $totalRequests; |
||
| 705 | } |
||
| 706 | |||
| 707 | /** |
||
| 708 | * Callback function for createList() |
||
| 709 | * |
||
| 710 | * @param int $start The result to start with |
||
| 711 | * @param int $items_per_page The number of items per page |
||
| 712 | * @param string $sort An SQL sort expression (column/direction) |
||
| 713 | * @param string $where Data for the WHERE clause |
||
| 714 | * @param string $where_parameters Parameter values to be inserted into the WHERE clause |
||
| 715 | * @return array An array of group requests |
||
| 716 | * Each group request has: |
||
| 717 | * 'id' |
||
| 718 | * 'member_link' |
||
| 719 | * 'group_link' |
||
| 720 | * 'reason' |
||
| 721 | * 'time_submitted' |
||
| 722 | */ |
||
| 723 | function list_getGroupRequests($start, $items_per_page, $sort, $where, $where_parameters) |
||
| 724 | { |
||
| 725 | global $smcFunc, $scripturl, $txt; |
||
| 726 | |||
| 727 | $request = $smcFunc['db_query']('', ' |
||
| 728 | SELECT |
||
| 729 | lgr.id_request, lgr.id_member, lgr.id_group, lgr.time_applied, lgr.reason, |
||
| 730 | lgr.status, lgr.id_member_acted, lgr.member_name_acted, lgr.time_acted, lgr.act_reason, |
||
| 731 | mem.member_name, mg.group_name, mg.online_color, mem.real_name |
||
| 732 | FROM {db_prefix}log_group_requests AS lgr |
||
| 733 | INNER JOIN {db_prefix}members AS mem ON (mem.id_member = lgr.id_member) |
||
| 734 | INNER JOIN {db_prefix}membergroups AS mg ON (mg.id_group = lgr.id_group) |
||
| 735 | WHERE ' . $where . ' |
||
| 736 | ORDER BY {raw:sort} |
||
| 737 | LIMIT {int:start}, {int:max}', |
||
| 738 | array_merge($where_parameters, array( |
||
| 739 | 'sort' => $sort, |
||
| 740 | 'start' => $start, |
||
| 741 | 'max' => $items_per_page, |
||
| 742 | )) |
||
| 743 | ); |
||
| 744 | $group_requests = array(); |
||
| 745 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 746 | { |
||
| 747 | if (empty($row['reason'])) |
||
| 748 | $reason = '<em>(' . $txt['mc_groupr_no_reason'] . ')</em>'; |
||
| 749 | else |
||
| 750 | $reason = censorText($row['reason']); |
||
| 751 | |||
| 752 | if (isset($_GET['closed'])) |
||
| 753 | { |
||
| 754 | if ($row['status'] == 1) |
||
| 755 | $reason .= '<br><br><strong>' . $txt['mc_groupr_approved'] . '</strong>'; |
||
| 756 | elseif ($row['status'] == 2) |
||
| 757 | $reason .= '<br><br><strong>' . $txt['mc_groupr_rejected'] . '</strong>'; |
||
| 758 | |||
| 759 | $reason .= ' (' . timeformat($row['time_acted']) . ')'; |
||
| 760 | if (!empty($row['act_reason'])) |
||
| 761 | $reason .= '<br><br>' . censorText($row['act_reason']); |
||
| 762 | } |
||
| 763 | |||
| 764 | $group_requests[] = array( |
||
| 765 | 'id' => $row['id_request'], |
||
| 766 | 'member_link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>', |
||
| 767 | 'group_link' => '<span style="color: ' . $row['online_color'] . '">' . $row['group_name'] . '</span>', |
||
| 768 | 'reason' => $reason, |
||
| 769 | 'time_submitted' => timeformat($row['time_applied']), |
||
| 770 | ); |
||
| 771 | } |
||
| 772 | $smcFunc['db_free_result']($request); |
||
| 773 | |||
| 774 | return $group_requests; |
||
| 775 | } |
||
| 776 | |||
| 777 | ?> |
||
|
0 ignored issues
–
show
It is not recommended to use PHP's closing tag
?> in files other than templates.
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore. A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever. Loading history...
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.