Subs-Membergroups.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. <?php
  2. /**
  3. * This file contains functions regarding manipulation of and information about membergroups.
  4. *
  5. * Simple Machines Forum (SMF)
  6. *
  7. * @package SMF
  8. * @author Simple Machines http://www.simplemachines.org
  9. * @copyright 2012 Simple Machines
  10. * @license http://www.simplemachines.org/about/smf/license.php BSD
  11. *
  12. * @version 2.1 Alpha 1
  13. */
  14. if (!defined('SMF'))
  15. die('No direct access...');
  16. /**
  17. * Delete one of more membergroups.
  18. * Requires the manage_membergroups permission.
  19. * Returns true on success or false on failure.
  20. * Has protection against deletion of protected membergroups.
  21. * Deletes the permissions linked to the membergroup.
  22. * Takes members out of the deleted membergroups.
  23. * @param array $groups
  24. * @return boolean
  25. */
  26. function deleteMembergroups($groups)
  27. {
  28. global $sourcedir, $smcFunc, $modSettings;
  29. // Make sure it's an array.
  30. if (!is_array($groups))
  31. $groups = array((int) $groups);
  32. else
  33. {
  34. $groups = array_unique($groups);
  35. // Make sure all groups are integer.
  36. foreach ($groups as $key => $value)
  37. $groups[$key] = (int) $value;
  38. }
  39. // Some groups are protected (guests, administrators, moderators, newbies).
  40. $protected_groups = array(-1, 0, 1, 3, 4);
  41. // There maybe some others as well.
  42. if (!allowedTo('admin_forum'))
  43. {
  44. $request = $smcFunc['db_query']('', '
  45. SELECT id_group
  46. FROM {db_prefix}membergroups
  47. WHERE group_type = {int:is_protected}',
  48. array(
  49. 'is_protected' => 1,
  50. )
  51. );
  52. while ($row = $smcFunc['db_fetch_assoc']($request))
  53. $protected_groups[] = $row['id_group'];
  54. $smcFunc['db_free_result']($request);
  55. }
  56. // Make sure they don't delete protected groups!
  57. $groups = array_diff($groups, array_unique($protected_groups));
  58. if (empty($groups))
  59. return false;
  60. // Log the deletion.
  61. $request = $smcFunc['db_query']('', '
  62. SELECT group_name
  63. FROM {db_prefix}membergroups
  64. WHERE id_group IN ({array_int:group_list})',
  65. array(
  66. 'group_list' => $groups,
  67. )
  68. );
  69. while ($row = $smcFunc['db_fetch_assoc']($request))
  70. logAction('delete_group', array('group' => $row['group_name']), 'admin');
  71. $smcFunc['db_free_result']($request);
  72. call_integration_hook('integrate_delete_membergroups', array($groups));
  73. // Remove the membergroups themselves.
  74. $smcFunc['db_query']('', '
  75. DELETE FROM {db_prefix}membergroups
  76. WHERE id_group IN ({array_int:group_list})',
  77. array(
  78. 'group_list' => $groups,
  79. )
  80. );
  81. // Remove the permissions of the membergroups.
  82. $smcFunc['db_query']('', '
  83. DELETE FROM {db_prefix}permissions
  84. WHERE id_group IN ({array_int:group_list})',
  85. array(
  86. 'group_list' => $groups,
  87. )
  88. );
  89. $smcFunc['db_query']('', '
  90. DELETE FROM {db_prefix}board_permissions
  91. WHERE id_group IN ({array_int:group_list})',
  92. array(
  93. 'group_list' => $groups,
  94. )
  95. );
  96. $smcFunc['db_query']('', '
  97. DELETE FROM {db_prefix}group_moderators
  98. WHERE id_group IN ({array_int:group_list})',
  99. array(
  100. 'group_list' => $groups,
  101. )
  102. );
  103. // Delete any outstanding requests.
  104. $smcFunc['db_query']('', '
  105. DELETE FROM {db_prefix}log_group_requests
  106. WHERE id_group IN ({array_int:group_list})',
  107. array(
  108. 'group_list' => $groups,
  109. )
  110. );
  111. // Update the primary groups of members.
  112. $smcFunc['db_query']('', '
  113. UPDATE {db_prefix}members
  114. SET id_group = {int:regular_group}
  115. WHERE id_group IN ({array_int:group_list})',
  116. array(
  117. 'group_list' => $groups,
  118. 'regular_group' => 0,
  119. )
  120. );
  121. // Update any inherited groups (Lose inheritance).
  122. $smcFunc['db_query']('', '
  123. UPDATE {db_prefix}membergroups
  124. SET id_parent = {int:uninherited}
  125. WHERE id_parent IN ({array_int:group_list})',
  126. array(
  127. 'group_list' => $groups,
  128. 'uninherited' => -2,
  129. )
  130. );
  131. // Update the additional groups of members.
  132. $request = $smcFunc['db_query']('', '
  133. SELECT id_member, additional_groups
  134. FROM {db_prefix}members
  135. WHERE FIND_IN_SET({raw:additional_groups_explode}, additional_groups) != 0',
  136. array(
  137. 'additional_groups_explode' => implode(', additional_groups) != 0 OR FIND_IN_SET(', $groups),
  138. )
  139. );
  140. $updates = array();
  141. while ($row = $smcFunc['db_fetch_assoc']($request))
  142. $updates[$row['additional_groups']][] = $row['id_member'];
  143. $smcFunc['db_free_result']($request);
  144. foreach ($updates as $additional_groups => $memberArray)
  145. updateMemberData($memberArray, array('additional_groups' => implode(',', array_diff(explode(',', $additional_groups), $groups))));
  146. // No boards can provide access to these membergroups anymore.
  147. $request = $smcFunc['db_query']('', '
  148. SELECT id_board, member_groups
  149. FROM {db_prefix}boards
  150. WHERE FIND_IN_SET({raw:member_groups_explode}, member_groups) != 0',
  151. array(
  152. 'member_groups_explode' => implode(', member_groups) != 0 OR FIND_IN_SET(', $groups),
  153. )
  154. );
  155. $updates = array();
  156. while ($row = $smcFunc['db_fetch_assoc']($request))
  157. $updates[$row['member_groups']][] = $row['id_board'];
  158. $smcFunc['db_free_result']($request);
  159. foreach ($updates as $member_groups => $boardArray)
  160. $smcFunc['db_query']('', '
  161. UPDATE {db_prefix}boards
  162. SET member_groups = {string:member_groups}
  163. WHERE id_board IN ({array_int:board_lists})',
  164. array(
  165. 'board_lists' => $boardArray,
  166. 'member_groups' => implode(',', array_diff(explode(',', $member_groups), $groups)),
  167. )
  168. );
  169. // Recalculate the post groups, as they likely changed.
  170. updateStats('postgroups');
  171. // Make a note of the fact that the cache may be wrong.
  172. $settings_update = array('settings_updated' => time());
  173. // Have we deleted the spider group?
  174. if (isset($modSettings['spider_group']) && in_array($modSettings['spider_group'], $groups))
  175. $settings_update['spider_group'] = 0;
  176. updateSettings($settings_update);
  177. // It was a success.
  178. return true;
  179. }
  180. /**
  181. * Remove one or more members from one or more membergroups.
  182. * Requires the manage_membergroups permission.
  183. * Function includes a protection against removing from implicit groups.
  184. * Non-admins are not able to remove members from the admin group.
  185. * @param array $members
  186. * @param array $groups = null if groups is null, the specified members are stripped from all their membergroups.
  187. * @param bool $permissionCheckDone = false
  188. * @param bool $ignoreProtected = false
  189. * @return boolean
  190. */
  191. function removeMembersFromGroups($members, $groups = null, $permissionCheckDone = false, $ignoreProtected = false)
  192. {
  193. global $smcFunc, $user_info, $modSettings, $sourcedir;
  194. // You're getting nowhere without this permission, unless of course you are the group's moderator.
  195. if (!$permissionCheckDone)
  196. isAllowedTo('manage_membergroups');
  197. // Assume something will happen.
  198. updateSettings(array('settings_updated' => time()));
  199. // Cleaning the input.
  200. if (!is_array($members))
  201. $members = array((int) $members);
  202. else
  203. {
  204. $members = array_unique($members);
  205. // Cast the members to integer.
  206. foreach ($members as $key => $value)
  207. $members[$key] = (int) $value;
  208. }
  209. // Before we get started, let's check we won't leave the admin group empty!
  210. if ($groups === null || $groups == 1 || (is_array($groups) && in_array(1, $groups)))
  211. {
  212. $admins = array();
  213. listMembergroupMembers_Href($admins, 1);
  214. // Remove any admins if there are too many.
  215. $non_changing_admins = array_diff(array_keys($admins), $members);
  216. if (empty($non_changing_admins))
  217. $members = array_diff($members, array_keys($admins));
  218. }
  219. // Just in case.
  220. if (empty($members))
  221. return false;
  222. elseif ($groups === null)
  223. {
  224. // Wanna remove all groups from these members? That's easy.
  225. $smcFunc['db_query']('', '
  226. UPDATE {db_prefix}members
  227. SET
  228. id_group = {int:regular_member},
  229. additional_groups = {string:blank_string}
  230. WHERE id_member IN ({array_int:member_list})' . (allowedTo('admin_forum') ? '' : '
  231. AND id_group != {int:admin_group}
  232. AND FIND_IN_SET({int:admin_group}, additional_groups) = 0'),
  233. array(
  234. 'member_list' => $members,
  235. 'regular_member' => 0,
  236. 'admin_group' => 1,
  237. 'blank_string' => '',
  238. )
  239. );
  240. updateStats('postgroups', $members);
  241. // Log what just happened.
  242. foreach ($members as $member)
  243. logAction('removed_all_groups', array('member' => $member), 'admin');
  244. return true;
  245. }
  246. elseif (!is_array($groups))
  247. $groups = array((int) $groups);
  248. else
  249. {
  250. $groups = array_unique($groups);
  251. // Make sure all groups are integer.
  252. foreach ($groups as $key => $value)
  253. $groups[$key] = (int) $value;
  254. }
  255. // Fetch a list of groups members cannot be assigned to explicitely, and the group names of the ones we want.
  256. $implicitGroups = array(-1, 0, 3);
  257. $request = $smcFunc['db_query']('', '
  258. SELECT id_group, group_name, min_posts
  259. FROM {db_prefix}membergroups
  260. WHERE id_group IN ({array_int:group_list})',
  261. array(
  262. 'group_list' => $groups,
  263. )
  264. );
  265. $group_names = array();
  266. while ($row = $smcFunc['db_fetch_assoc']($request))
  267. {
  268. if ($row['min_posts'] != -1)
  269. $implicitGroups[] = $row['id_group'];
  270. else
  271. $group_names[$row['id_group']] = $row['group_name'];
  272. }
  273. $smcFunc['db_free_result']($request);
  274. // Now get rid of those groups.
  275. $groups = array_diff($groups, $implicitGroups);
  276. // Don't forget the protected groups.
  277. if (!allowedTo('admin_forum') && !$ignoreProtected)
  278. {
  279. $request = $smcFunc['db_query']('', '
  280. SELECT id_group
  281. FROM {db_prefix}membergroups
  282. WHERE group_type = {int:is_protected}',
  283. array(
  284. 'is_protected' => 1,
  285. )
  286. );
  287. $protected_groups = array(1);
  288. while ($row = $smcFunc['db_fetch_assoc']($request))
  289. $protected_groups[] = $row['id_group'];
  290. $smcFunc['db_free_result']($request);
  291. // If you're not an admin yourself, you can't touch protected groups!
  292. $groups = array_diff($groups, array_unique($protected_groups));
  293. }
  294. // Only continue if there are still groups and members left.
  295. if (empty($groups) || empty($members))
  296. return false;
  297. // First, reset those who have this as their primary group - this is the easy one.
  298. $log_inserts = array();
  299. $request = $smcFunc['db_query']('', '
  300. SELECT id_member, id_group
  301. FROM {db_prefix}members AS members
  302. WHERE id_group IN ({array_int:group_list})
  303. AND id_member IN ({array_int:member_list})',
  304. array(
  305. 'group_list' => $groups,
  306. 'member_list' => $members,
  307. )
  308. );
  309. while ($row = $smcFunc['db_fetch_assoc']($request))
  310. $log_inserts[] = array('group' => $group_names[$row['id_group']], 'member' => $row['id_member']);
  311. $smcFunc['db_free_result']($request);
  312. $smcFunc['db_query']('', '
  313. UPDATE {db_prefix}members
  314. SET id_group = {int:regular_member}
  315. WHERE id_group IN ({array_int:group_list})
  316. AND id_member IN ({array_int:member_list})',
  317. array(
  318. 'group_list' => $groups,
  319. 'member_list' => $members,
  320. 'regular_member' => 0,
  321. )
  322. );
  323. // Those who have it as part of their additional group must be updated the long way... sadly.
  324. $request = $smcFunc['db_query']('', '
  325. SELECT id_member, additional_groups
  326. FROM {db_prefix}members
  327. WHERE (FIND_IN_SET({raw:additional_groups_implode}, additional_groups) != 0)
  328. AND id_member IN ({array_int:member_list})
  329. LIMIT ' . count($members),
  330. array(
  331. 'member_list' => $members,
  332. 'additional_groups_implode' => implode(', additional_groups) != 0 OR FIND_IN_SET(', $groups),
  333. )
  334. );
  335. $updates = array();
  336. while ($row = $smcFunc['db_fetch_assoc']($request))
  337. {
  338. // What log entries must we make for this one, eh?
  339. foreach (explode(',', $row['additional_groups']) as $group)
  340. if (in_array($group, $groups))
  341. $log_inserts[] = array('group' => $group_names[$group], 'member' => $row['id_member']);
  342. $updates[$row['additional_groups']][] = $row['id_member'];
  343. }
  344. $smcFunc['db_free_result']($request);
  345. foreach ($updates as $additional_groups => $memberArray)
  346. $smcFunc['db_query']('', '
  347. UPDATE {db_prefix}members
  348. SET additional_groups = {string:additional_groups}
  349. WHERE id_member IN ({array_int:member_list})',
  350. array(
  351. 'member_list' => $memberArray,
  352. 'additional_groups' => implode(',', array_diff(explode(',', $additional_groups), $groups)),
  353. )
  354. );
  355. // Their post groups may have changed now...
  356. updateStats('postgroups', $members);
  357. // Do the log.
  358. if (!empty($log_inserts) && !empty($modSettings['modlog_enabled']))
  359. {
  360. require_once($sourcedir . '/Logging.php');
  361. foreach ($log_inserts as $extra)
  362. logAction('removed_from_group', $extra, 'admin');
  363. }
  364. // Mission successful.
  365. return true;
  366. }
  367. /**
  368. * Add one or more members to a membergroup
  369. *
  370. * Requires the manage_membergroups permission.
  371. * Function has protection against adding members to implicit groups.
  372. * Non-admins are not able to add members to the admin group.
  373. *
  374. * @param string|array $members
  375. * @param int $group
  376. * @param string $type = 'auto' specifies whether the group is added as primary or as additional group.
  377. * Supported types:
  378. * - only_primary - Assigns a membergroup as primary membergroup, but only
  379. * if a member has not yet a primary membergroup assigned,
  380. * unless the member is already part of the membergroup.
  381. * - only_additional - Assigns a membergroup to the additional membergroups,
  382. * unless the member is already part of the membergroup.
  383. * - force_primary - Assigns a membergroup as primary membergroup no matter
  384. * what the previous primary membergroup was.
  385. * - auto - Assigns a membergroup to the primary group if it's still
  386. * available. If not, assign it to the additional group.
  387. * @param bool $permissionCheckDone
  388. * @param bool $ignoreProtected
  389. * @return boolean success or failure
  390. */
  391. function addMembersToGroup($members, $group, $type = 'auto', $permissionCheckDone = false, $ignoreProtected = false)
  392. {
  393. global $smcFunc, $user_info, $modSettings, $sourcedir;
  394. // Show your licence, but only if it hasn't been done yet.
  395. if (!$permissionCheckDone)
  396. isAllowedTo('manage_membergroups');
  397. // Make sure we don't keep old stuff cached.
  398. updateSettings(array('settings_updated' => time()));
  399. if (!is_array($members))
  400. $members = array((int) $members);
  401. else
  402. {
  403. $members = array_unique($members);
  404. // Make sure all members are integer.
  405. foreach ($members as $key => $value)
  406. $members[$key] = (int) $value;
  407. }
  408. $group = (int) $group;
  409. // Some groups just don't like explicitly having members.
  410. $implicitGroups = array(-1, 0, 3);
  411. $request = $smcFunc['db_query']('', '
  412. SELECT id_group, group_name, min_posts
  413. FROM {db_prefix}membergroups
  414. WHERE id_group = {int:current_group}',
  415. array(
  416. 'current_group' => $group,
  417. )
  418. );
  419. $group_names = array();
  420. while ($row = $smcFunc['db_fetch_assoc']($request))
  421. {
  422. if ($row['min_posts'] != -1)
  423. $implicitGroups[] = $row['id_group'];
  424. else
  425. $group_names[$row['id_group']] = $row['group_name'];
  426. }
  427. $smcFunc['db_free_result']($request);
  428. // Sorry, you can't join an implicit group.
  429. if (in_array($group, $implicitGroups) || empty($members))
  430. return false;
  431. // Only admins can add admins...
  432. if (!allowedTo('admin_forum') && $group == 1)
  433. return false;
  434. // ... and assign protected groups!
  435. elseif (!allowedTo('admin_forum') && !$ignoreProtected)
  436. {
  437. $request = $smcFunc['db_query']('', '
  438. SELECT group_type
  439. FROM {db_prefix}membergroups
  440. WHERE id_group = {int:current_group}
  441. LIMIT {int:limit}',
  442. array(
  443. 'current_group' => $group,
  444. 'limit' => 1,
  445. )
  446. );
  447. list ($is_protected) = $smcFunc['db_fetch_row']($request);
  448. $smcFunc['db_free_result']($request);
  449. // Is it protected?
  450. if ($is_protected == 1)
  451. return false;
  452. }
  453. // Do the actual updates.
  454. if ($type == 'only_additional')
  455. $smcFunc['db_query']('', '
  456. UPDATE {db_prefix}members
  457. SET additional_groups = CASE WHEN additional_groups = {string:blank_string} THEN {string:id_group_string} ELSE CONCAT(additional_groups, {string:id_group_string_extend}) END
  458. WHERE id_member IN ({array_int:member_list})
  459. AND id_group != {int:id_group}
  460. AND FIND_IN_SET({int:id_group}, additional_groups) = 0',
  461. array(
  462. 'member_list' => $members,
  463. 'id_group' => $group,
  464. 'id_group_string' => (string) $group,
  465. 'id_group_string_extend' => ',' . $group,
  466. 'blank_string' => '',
  467. )
  468. );
  469. elseif ($type == 'only_primary' || $type == 'force_primary')
  470. $smcFunc['db_query']('', '
  471. UPDATE {db_prefix}members
  472. SET id_group = {int:id_group}
  473. WHERE id_member IN ({array_int:member_list})' . ($type == 'force_primary' ? '' : '
  474. AND id_group = {int:regular_group}
  475. AND FIND_IN_SET({int:id_group}, additional_groups) = 0'),
  476. array(
  477. 'member_list' => $members,
  478. 'id_group' => $group,
  479. 'regular_group' => 0,
  480. )
  481. );
  482. elseif ($type == 'auto')
  483. $smcFunc['db_query']('', '
  484. UPDATE {db_prefix}members
  485. SET
  486. id_group = CASE WHEN id_group = {int:regular_group} THEN {int:id_group} ELSE id_group END,
  487. additional_groups = CASE WHEN id_group = {int:id_group} THEN additional_groups
  488. WHEN additional_groups = {string:blank_string} THEN {string:id_group_string}
  489. ELSE CONCAT(additional_groups, {string:id_group_string_extend}) END
  490. WHERE id_member IN ({array_int:member_list})
  491. AND id_group != {int:id_group}
  492. AND FIND_IN_SET({int:id_group}, additional_groups) = 0',
  493. array(
  494. 'member_list' => $members,
  495. 'regular_group' => 0,
  496. 'id_group' => $group,
  497. 'blank_string' => '',
  498. 'id_group_string' => (string) $group,
  499. 'id_group_string_extend' => ',' . $group,
  500. )
  501. );
  502. // Ack!!? What happened?
  503. else
  504. trigger_error('addMembersToGroup(): Unknown type \'' . $type . '\'', E_USER_WARNING);
  505. call_integration_hook('integrate_add_members_to_group', array($members, $group, &$group_names));
  506. // Update their postgroup statistics.
  507. updateStats('postgroups', $members);
  508. // Log the data.
  509. require_once($sourcedir . '/Logging.php');
  510. foreach ($members as $member)
  511. logAction('added_to_group', array('group' => $group_names[$group], 'member' => $member), 'admin');
  512. return true;
  513. }
  514. /**
  515. * Gets the members of a supplied membergroup
  516. * Returns them as a link for display
  517. *
  518. * @param array &$members
  519. * @param int $membergroup
  520. * @param int $limit = null
  521. * @return boolean
  522. */
  523. function listMembergroupMembers_Href(&$members, $membergroup, $limit = null)
  524. {
  525. global $scripturl, $txt, $smcFunc;
  526. $request = $smcFunc['db_query']('', '
  527. SELECT id_member, real_name
  528. FROM {db_prefix}members
  529. WHERE id_group = {int:id_group} OR FIND_IN_SET({int:id_group}, additional_groups) != 0' . ($limit === null ? '' : '
  530. LIMIT ' . ($limit + 1)),
  531. array(
  532. 'id_group' => $membergroup,
  533. )
  534. );
  535. $members = array();
  536. while ($row = $smcFunc['db_fetch_assoc']($request))
  537. $members[$row['id_member']] = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
  538. $smcFunc['db_free_result']($request);
  539. // If there are more than $limit members, add a 'more' link.
  540. if ($limit !== null && count($members) > $limit)
  541. {
  542. array_pop($members);
  543. return true;
  544. }
  545. else
  546. return false;
  547. }
  548. /**
  549. * Retrieve a list of (visible) membergroups used by the cache.
  550. *
  551. * @global type $scripturl
  552. * @global type $smcFunc
  553. * @return type
  554. */
  555. function cache_getMembergroupList()
  556. {
  557. global $scripturl, $smcFunc;
  558. $request = $smcFunc['db_query']('', '
  559. SELECT id_group, group_name, online_color
  560. FROM {db_prefix}membergroups
  561. WHERE min_posts = {int:min_posts}
  562. AND hidden = {int:not_hidden}
  563. AND id_group != {int:mod_group}
  564. AND online_color != {string:blank_string}
  565. ORDER BY group_name',
  566. array(
  567. 'min_posts' => -1,
  568. 'not_hidden' => 0,
  569. 'mod_group' => 3,
  570. 'blank_string' => '',
  571. )
  572. );
  573. $groupCache = array();
  574. while ($row = $smcFunc['db_fetch_assoc']($request))
  575. $groupCache[] = '<a href="' . $scripturl . '?action=groups;sa=members;group=' . $row['id_group'] . '" ' . ($row['online_color'] ? 'style="color: ' . $row['online_color'] . '"' : '') . '>' . $row['group_name'] . '</a>';
  576. $smcFunc['db_free_result']($request);
  577. return array(
  578. 'data' => $groupCache,
  579. 'expires' => time() + 3600,
  580. 'refresh_eval' => 'return $GLOBALS[\'modSettings\'][\'settings_updated\'] > ' . time() . ';',
  581. );
  582. }
  583. /**
  584. * Helper function to generate a list of membergroups for display
  585. *
  586. * @param type $start
  587. * @param type $items_per_page
  588. * @param type $sort
  589. * @param type $membergroup_type
  590. * @return type
  591. */
  592. function list_getMembergroups($start, $items_per_page, $sort, $membergroup_type)
  593. {
  594. global $txt, $scripturl, $context, $settings, $smcFunc, $user_info;
  595. $groups = array();
  596. $request = $smcFunc['db_query']('substring_membergroups', '
  597. SELECT mg.id_group, mg.group_name, mg.min_posts, mg.description, mg.group_type, mg.online_color, mg.hidden,
  598. mg.icons, IFNULL(gm.id_member, 0) AS can_moderate, 0 AS num_members
  599. FROM {db_prefix}membergroups AS mg
  600. LEFT JOIN {db_prefix}group_moderators AS gm ON (gm.id_group = mg.id_group AND gm.id_member = {int:current_member})
  601. WHERE mg.min_posts {raw:min_posts}' . (allowedTo('admin_forum') ? '' : '
  602. AND mg.id_group != {int:mod_group}') . '
  603. ORDER BY {raw:sort}',
  604. array(
  605. 'current_member' => $user_info['id'],
  606. 'min_posts' => ($membergroup_type === 'post_count' ? '!= ' : '= ') . -1,
  607. 'mod_group' => 3,
  608. 'sort' => $sort,
  609. )
  610. );
  611. // Start collecting the data.
  612. $groups = array();
  613. $group_ids = array();
  614. $context['can_moderate'] = allowedTo('manage_membergroups');
  615. while ($row = $smcFunc['db_fetch_assoc']($request))
  616. {
  617. // We only list the groups they can see.
  618. if ($row['hidden'] && !$row['can_moderate'] && !allowedTo('manage_membergroups'))
  619. continue;
  620. $row['icons'] = explode('#', $row['icons']);
  621. $groups[$row['id_group']] = array(
  622. 'id_group' => $row['id_group'],
  623. 'group_name' => $row['group_name'],
  624. 'min_posts' => $row['min_posts'],
  625. 'desc' => $row['description'],
  626. 'online_color' => $row['online_color'],
  627. 'type' => $row['group_type'],
  628. 'num_members' => $row['num_members'],
  629. 'moderators' => array(),
  630. 'icons' => !empty($row['icons'][0]) && !empty($row['icons'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/membericons/' . $row['icons'][1] . '" alt="*" />', $row['icons'][0]) : '',
  631. );
  632. $context['can_moderate'] |= $row['can_moderate'];
  633. $group_ids[] = $row['id_group'];
  634. }
  635. $smcFunc['db_free_result']($request);
  636. // If we found any membergroups, get the amount of members in them.
  637. if (!empty($group_ids))
  638. {
  639. if ($membergroup_type === 'post_count')
  640. {
  641. $query = $smcFunc['db_query']('', '
  642. SELECT id_post_group AS id_group, COUNT(*) AS num_members
  643. FROM {db_prefix}members
  644. WHERE id_post_group IN ({array_int:group_list})
  645. GROUP BY id_post_group',
  646. array(
  647. 'group_list' => $group_ids,
  648. )
  649. );
  650. while ($row = $smcFunc['db_fetch_assoc']($query))
  651. $groups[$row['id_group']]['num_members'] += $row['num_members'];
  652. $smcFunc['db_free_result']($query);
  653. }
  654. else
  655. {
  656. $query = $smcFunc['db_query']('', '
  657. SELECT id_group, COUNT(*) AS num_members
  658. FROM {db_prefix}members
  659. WHERE id_group IN ({array_int:group_list})
  660. GROUP BY id_group',
  661. array(
  662. 'group_list' => $group_ids,
  663. )
  664. );
  665. while ($row = $smcFunc['db_fetch_assoc']($query))
  666. $groups[$row['id_group']]['num_members'] += $row['num_members'];
  667. $smcFunc['db_free_result']($query);
  668. // Only do additional groups if we can moderate...
  669. if ($context['can_moderate'])
  670. {
  671. $query = $smcFunc['db_query']('', '
  672. SELECT mg.id_group, COUNT(*) AS num_members
  673. FROM {db_prefix}membergroups AS mg
  674. INNER JOIN {db_prefix}members AS mem ON (mem.additional_groups != {string:blank_string}
  675. AND mem.id_group != mg.id_group
  676. AND FIND_IN_SET(mg.id_group, mem.additional_groups) != 0)
  677. WHERE mg.id_group IN ({array_int:group_list})
  678. GROUP BY mg.id_group',
  679. array(
  680. 'group_list' => $group_ids,
  681. 'blank_string' => '',
  682. )
  683. );
  684. while ($row = $smcFunc['db_fetch_assoc']($query))
  685. $groups[$row['id_group']]['num_members'] += $row['num_members'];
  686. $smcFunc['db_free_result']($query);
  687. }
  688. }
  689. $query = $smcFunc['db_query']('', '
  690. SELECT mods.id_group, mods.id_member, mem.member_name, mem.real_name
  691. FROM {db_prefix}group_moderators AS mods
  692. INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)
  693. WHERE mods.id_group IN ({array_int:group_list})',
  694. array(
  695. 'group_list' => $group_ids,
  696. )
  697. );
  698. while ($row = $smcFunc['db_fetch_assoc']($query))
  699. $groups[$row['id_group']]['moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
  700. $smcFunc['db_free_result']($query);
  701. }
  702. // Apply manual sorting if the 'number of members' column is selected.
  703. if (substr($sort, 0, 1) == '1' || strpos($sort, ', 1') !== false)
  704. {
  705. $sort_ascending = strpos($sort, 'DESC') === false;
  706. foreach ($groups as $group)
  707. $sort_array[] = $group['id_group'] != 3 ? (int) $group['num_members'] : -1;
  708. array_multisort($sort_array, $sort_ascending ? SORT_ASC : SORT_DESC, SORT_REGULAR, $groups);
  709. }
  710. return $groups;
  711. }
  712. ?>