Subs-Membergroups.php 24 KB

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