Subs-Membergroups.php 25 KB

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