PageRenderTime 83ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 1ms

/htdocs/lib/group.php

https://gitlab.com/mahara-contrib/janrain-auth
PHP | 1476 lines | 1049 code | 145 blank | 282 comment | 158 complexity | d499ce78c570722782f7b2e076d4c3dc MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, MIT

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Mahara: Electronic portfolio, weblog, resume builder and social networking
  4. * Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
  5. * http://wiki.mahara.org/Contributors
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. * @package mahara
  21. * @subpackage core
  22. * @author Catalyst IT Ltd
  23. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL
  24. * @copyright (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
  25. *
  26. */
  27. defined('INTERNAL') || die();
  28. // Role related functions
  29. /**
  30. * Establishes what role a user has in a given group.
  31. *
  32. * If the user is not in the group, this returns false.
  33. *
  34. * @param mixed $groupid ID of the group to check
  35. * @param mixed $userid ID of the user to check. Defaults to the logged in
  36. * user.
  37. * @return mixed The role the user has in the group, or false if they
  38. * have no role in the group
  39. */
  40. function group_user_access($groupid, $userid=null, $refresh=null) {
  41. static $result;
  42. if (!is_logged_in()) {
  43. return false;
  44. }
  45. $groupid = group_param_groupid($groupid);
  46. $userid = group_param_userid($userid);
  47. if (isset($result[$groupid][$userid]) && !isset($refresh)) {
  48. return $result[$groupid][$userid];
  49. }
  50. return $result[$groupid][$userid] = get_field('group_member', 'role', 'group', $groupid, 'member', $userid);
  51. }
  52. /**
  53. * Returns whether the given user is the only administrator in the given group.
  54. *
  55. * If the user isn't in the group, or they're not an admin, or there is another admin, false
  56. * is returned.
  57. *
  58. * @param int $groupid The ID of the group to check
  59. * @param int $userid The ID of the user to check
  60. * @returns boolean
  61. */
  62. function group_is_only_admin($groupid, $userid=null) {
  63. static $result;
  64. $groupid = group_param_groupid($groupid);
  65. $userid = group_param_userid($userid);
  66. if (isset($result[$groupid][$userid])) {
  67. return $result[$groupid][$userid];
  68. }
  69. return $result[$groupid][$userid] = (group_user_access($groupid, $userid) == 'admin'
  70. && count_records('group_member', 'group', $groupid, 'role', 'admin') == 1);
  71. }
  72. /**
  73. * Returns whether the given user is allowed to change their role to the
  74. * requested role in the given group.
  75. *
  76. * This function is checking whether _role changes_ are allowed, not if a user
  77. * is allowed to be added to a group.
  78. *
  79. * @param int $groupid The ID of the group to check
  80. * @param int $userid The ID of the user to check
  81. * @param string $role The role the user wishes to switch to
  82. * @returns boolean
  83. */
  84. function group_can_change_role($groupid, $userid, $role) {
  85. $groupid = group_param_groupid($groupid);
  86. $userid = group_param_userid($userid);
  87. if (!group_user_access($groupid, $userid)) {
  88. return false;
  89. }
  90. // Sole remaining admins can never change their role
  91. if (group_is_only_admin($groupid, $userid)) {
  92. return false;
  93. }
  94. // admin role permissions check
  95. if ($role == 'admin') {
  96. $group = group_current_group();
  97. safe_require('grouptype', $group->grouptype);
  98. return call_static_method('GroupType' . $group->grouptype, 'can_become_admin', $userid);
  99. }
  100. return true;
  101. }
  102. /**
  103. * Changes a user role in a group, if this is allowed.
  104. *
  105. * @param int $groupid The ID of the group
  106. * @param int $userid The ID of the user whose role needs changing
  107. * @param string $role The role the user wishes to switch to
  108. * @throws AccessDeniedException If the specified role change is not allowed.
  109. * Check with group_can_change_role first if you
  110. * need to.
  111. */
  112. function group_change_role($groupid, $userid, $role) {
  113. // group_can_change_role checks whether the group and user parameters are valid
  114. if (!group_can_change_role($groupid, $userid, $role)) {
  115. throw new AccessDeniedException(get_string('usercannotchangetothisrole', 'group'));
  116. }
  117. set_field('group_member', 'role', $role, 'group', $groupid, 'member', $userid);
  118. }
  119. /**
  120. * Returns whether a user is allowed to edit views in a given group
  121. *
  122. * @param int $groupid The ID of the group
  123. * @param int $userid The ID of the user
  124. * @returns boolean
  125. */
  126. function group_user_can_edit_views($groupid, $userid=null) {
  127. // root user can always do whatever it wants
  128. $sysuser = get_record('usr', 'username', 'root');
  129. if ($sysuser->id == $userid) {
  130. return true;
  131. }
  132. if (!is_logged_in()) {
  133. return false;
  134. }
  135. $groupid = group_param_groupid($groupid);
  136. $userid = group_param_userid($userid);
  137. return get_field_sql('
  138. SELECT
  139. r.edit_views
  140. FROM
  141. {group_member} m
  142. INNER JOIN {group} g ON (m.group = g.id AND g.deleted = 0)
  143. INNER JOIN {grouptype_roles} r ON (g.grouptype = r.grouptype AND m.role = r.role)
  144. WHERE
  145. m.group = ?
  146. AND m.member = ?', array($groupid, $userid));
  147. }
  148. /**
  149. * Returns whether a user is allowed to assess views that have been submitted
  150. * to the given group.
  151. *
  152. * @param int $groupid ID of group
  153. * @param int $userid ID of user
  154. * @return boolean
  155. */
  156. function group_user_can_assess_submitted_views($groupid, $userid) {
  157. $groupid = group_param_groupid($groupid);
  158. $userid = group_param_userid($userid);
  159. return get_field_sql('
  160. SELECT
  161. r.see_submitted_views
  162. FROM
  163. {group_member} m
  164. INNER JOIN {group} g ON (m.group = g.id AND g.deleted = 0)
  165. INNER JOIN {grouptype_roles} r ON (g.grouptype = r.grouptype AND r.role = m.role)
  166. WHERE
  167. m.member = ?
  168. AND m.group = ?', array($userid, $groupid));
  169. }
  170. // Functions for creation/deletion of groups, and adding/removing users to groups
  171. /**
  172. * Creates a group.
  173. *
  174. * All group creation should be done through this function, as the
  175. * implementation of group creation may change over time.
  176. *
  177. * @param array $data Data required to create the group. The following
  178. * key/value pairs can be specified:
  179. *
  180. * - name: The group name [required, must be unique]
  181. * - description: The group description [optional, defaults to empty string]
  182. * - grouptype: The grouptype for the new group. Must be an installed grouptype.
  183. * - jointype: The jointype for the new group. One of 'open', 'invite',
  184. * 'request' or 'controlled'
  185. * - ctime: The unix timestamp of the time the group will be recorded as having
  186. * been created. Defaults to the current time.
  187. * - members: Array of users who should be in the group, structured like this:
  188. * array(
  189. * userid => role,
  190. * userid => role,
  191. * ...
  192. * )
  193. * @return int The ID of the created group
  194. */
  195. function group_create($data) {
  196. if (!is_array($data)) {
  197. throw new InvalidArgumentException("group_create: data must be an array, see the doc comment for this "
  198. . "function for details on its format");
  199. }
  200. if (!isset($data['name'])) {
  201. throw new InvalidArgumentException("group_create: must specify a name for the group");
  202. }
  203. if (!isset($data['grouptype']) || !in_array($data['grouptype'], group_get_grouptypes())) {
  204. throw new InvalidArgumentException("group_create: grouptype specified must be an installed grouptype");
  205. }
  206. safe_require('grouptype', $data['grouptype']);
  207. if (isset($data['jointype'])) {
  208. if (!in_array($data['jointype'], call_static_method('GroupType' . $data['grouptype'], 'allowed_join_types'))) {
  209. throw new InvalidArgumentException("group_create: jointype specified is not allowed by the grouptype specified");
  210. }
  211. }
  212. else {
  213. throw new InvalidArgumentException("group_create: jointype specified must be one of the valid join types");
  214. }
  215. if (!isset($data['ctime'])) {
  216. $data['ctime'] = time();
  217. }
  218. $data['ctime'] = db_format_timestamp($data['ctime']);
  219. if (!is_array($data['members']) || count($data['members']) == 0) {
  220. throw new InvalidArgumentException("group_create: at least one member must be specified for adding to the group");
  221. }
  222. $data['public'] = (isset($data['public'])) ? intval($data['public']) : 0;
  223. $data['usersautoadded'] = (isset($data['usersautoadded'])) ? intval($data['usersautoadded']) : 0;
  224. db_begin();
  225. $id = insert_record(
  226. 'group',
  227. (object) array(
  228. 'name' => $data['name'],
  229. 'description' => $data['description'],
  230. 'grouptype' => $data['grouptype'],
  231. 'category' => $data['category'],
  232. 'jointype' => $data['jointype'],
  233. 'ctime' => $data['ctime'],
  234. 'mtime' => $data['ctime'],
  235. 'public' => $data['public'],
  236. 'usersautoadded' => $data['usersautoadded'],
  237. ),
  238. 'id',
  239. true
  240. );
  241. foreach ($data['members'] as $userid => $role) {
  242. insert_record(
  243. 'group_member',
  244. (object) array(
  245. 'group' => $id,
  246. 'member' => $userid,
  247. 'role' => $role,
  248. 'ctime' => $data['ctime'],
  249. )
  250. );
  251. }
  252. // Copy views for the new group
  253. $templates = get_column('view_autocreate_grouptype', 'view', 'grouptype', $data['grouptype']);
  254. $templates = get_records_sql_array("
  255. SELECT v.id, v.title, v.description
  256. FROM {view} v
  257. INNER JOIN {view_autocreate_grouptype} vag ON vag.view = v.id
  258. WHERE vag.grouptype = 'standard'", array());
  259. if ($templates) {
  260. require_once(get_config('libroot') . 'view.php');
  261. foreach ($templates as $template) {
  262. list($view) = View::create_from_template(array(
  263. 'group' => $id,
  264. 'title' => $template->title,
  265. 'description' => $template->description,
  266. ), $template->id);
  267. $view->set_access(array(array(
  268. 'type' => 'group',
  269. 'id' => $id,
  270. 'startdate' => null,
  271. 'stopdate' => null,
  272. 'role' => null
  273. )));
  274. }
  275. }
  276. $data['id'] = $id;
  277. // install the homepage
  278. if ($t = get_record('view', 'type', 'grouphomepage', 'template', 1, 'owner', 0)) {
  279. require_once('view.php');
  280. $template = new View($t->id, (array)$t);
  281. list($homepage) = View::create_from_template(array(
  282. 'group' => $id,
  283. 'title' => $template->get('title'),
  284. 'description' => $template->get('description'),
  285. 'type' => 'grouphomepage',
  286. ), $t->id, 0, false);
  287. }
  288. insert_record('view_access', (object) array(
  289. 'view' => $homepage->get('id'),
  290. 'accesstype' => $data['public'] ? 'public' : 'loggedin',
  291. ));
  292. handle_event('creategroup', $data);
  293. db_commit();
  294. return $id;
  295. }
  296. /**
  297. * Deletes a group.
  298. *
  299. * All group deleting should be done through this function, even though it is
  300. * simple. What is required to perform group deletion may change over time.
  301. *
  302. * @param int $groupid The group to delete
  303. *
  304. * {{@internal Maybe later we can have a group_can_be_deleted function if
  305. * necessary}}
  306. */
  307. function group_delete($groupid) {
  308. $groupid = group_param_groupid($groupid);
  309. update_record('group',
  310. array(
  311. 'deleted' => 1,
  312. 'name' => get_field('group', 'name', 'id', $groupid) . '.deleted.' . time(),
  313. ),
  314. array(
  315. 'id' => $groupid,
  316. )
  317. );
  318. }
  319. /**
  320. * Adds a member to a group.
  321. *
  322. * Doesn't do any jointype checking, that should be handled by the caller.
  323. *
  324. * TODO: it should though. We should probably have group_user_can_be_added
  325. *
  326. * @param int $groupid
  327. * @param int $userid
  328. * @param string $role
  329. */
  330. function group_add_user($groupid, $userid, $role=null) {
  331. $groupid = group_param_groupid($groupid);
  332. $userid = group_param_userid($userid);
  333. $gm = new StdClass;
  334. $gm->member = $userid;
  335. $gm->group = $groupid;
  336. $gm->ctime = db_format_timestamp(time());
  337. if (!$role) {
  338. $role = get_field_sql('SELECT gt.defaultrole FROM {grouptype} gt, {group} g WHERE g.id = ? AND g.grouptype = gt.name', array($groupid));
  339. }
  340. $gm->role = $role;
  341. db_begin();
  342. insert_record('group_member', $gm);
  343. delete_records('group_member_request', 'group', $groupid, 'member', $userid);
  344. handle_event('userjoinsgroup', $gm);
  345. db_commit();
  346. }
  347. /**
  348. * Checks whether a user is allowed to leave a group.
  349. *
  350. * This checks things like if they're the owner and the group membership type
  351. *
  352. * @param mixed $group DB record or ID of group to check
  353. * @param int $userid (optional, will default to logged in user)
  354. */
  355. function group_user_can_leave($group, $userid=null) {
  356. global $USER;
  357. static $result;
  358. $userid = optional_userid($userid);
  359. if (is_numeric($group)) {
  360. if (!$group = get_record('group', 'id', $group, 'deleted', 0)) {
  361. return false;
  362. }
  363. }
  364. // Return cached value if we have it
  365. if (isset($result[$group->id][$userid])) {
  366. return $result[$group->id][$userid];
  367. }
  368. if ($group->jointype == 'controlled' && group_user_access($group->id, $USER->get('id')) != 'admin') {
  369. return ($result[$group->id][$userid] = false);
  370. }
  371. if (group_is_only_admin($group->id, $userid)) {
  372. return ($result[$group->id][$userid] = false);
  373. }
  374. return ($result[$group->id][$userid] = true);
  375. }
  376. /**
  377. * Removes a user from a group.
  378. *
  379. * @param int $groupid ID of group
  380. * @param int $userid ID of user to remove
  381. */
  382. function group_remove_user($groupid, $userid=null, $force=false) {
  383. // group_user_can_leave checks the validity of groupid and userid
  384. if (!$force && !group_user_can_leave($groupid, $userid)) {
  385. throw new AccessDeniedException(get_string('usercantleavegroup', 'group'));
  386. }
  387. delete_records('group_member', 'group', $groupid, 'member', $userid);
  388. require_once(get_config('docroot') . 'interaction/lib.php');
  389. $interactions = get_column('interaction_instance', 'id', 'group', $groupid);
  390. foreach ($interactions as $interaction) {
  391. interaction_instance_from_id($interaction)->interaction_remove_user($userid);
  392. }
  393. }
  394. /**
  395. * Invite a user to a group.
  396. *
  397. * @param object $group group
  398. * @param object $userid User to invite
  399. * @param object $userfrom User sending the invitation
  400. */
  401. function group_invite_user($group, $userid, $userfrom, $role='member', $delay=null) {
  402. $user = optional_userobj($userid);
  403. $data = new StdClass;
  404. $data->group = $group->id;
  405. $data->member= $user->id;
  406. $data->ctime = db_format_timestamp(time());
  407. $data->role = $role;
  408. ensure_record_exists('group_member_invite', $data, $data);
  409. $lang = get_user_language($user->id);
  410. require_once('activity.php');
  411. $activitydata = array(
  412. 'users' => array($user->id),
  413. 'subject' => get_string_from_language($lang, 'invitetogroupsubject', 'group'),
  414. 'message' => get_string_from_language($lang, 'invitetogroupmessage', 'group', display_name($userfrom, $user), $group->name),
  415. 'url' => get_config('wwwroot') . 'group/view.php?id=' . $group->id,
  416. 'urltext' => $group->name,
  417. );
  418. activity_occurred('maharamessage', $activitydata, null, null, $delay);
  419. }
  420. // Pieforms for various operations on groups
  421. /**
  422. * Form for users to join a given group
  423. */
  424. function group_get_join_form($name, $groupid, $returnto='view') {
  425. return pieform(array(
  426. 'name' => $name,
  427. 'successcallback' => 'joingroup_submit',
  428. 'autofocus' => false,
  429. 'elements' => array(
  430. 'join' => array(
  431. 'type' => 'submit',
  432. 'value' => get_string('joingroup', 'group')
  433. ),
  434. 'group' => array(
  435. 'type' => 'hidden',
  436. 'value' => $groupid
  437. ),
  438. 'returnto' => array(
  439. 'type' => 'hidden',
  440. 'value' => $returnto
  441. ),
  442. )
  443. ));
  444. }
  445. /**
  446. * Form for accepting/declining a group invite
  447. */
  448. function group_get_accept_form($name, $groupid, $returnto) {
  449. return pieform(array(
  450. 'name' => $name,
  451. 'renderer' => 'oneline',
  452. 'successcallback' => 'group_invite_submit',
  453. 'elements' => array(
  454. 'accept' => array(
  455. 'type' => 'submit',
  456. 'value' => get_string('acceptinvitegroup', 'group')
  457. ),
  458. 'decline' => array(
  459. 'type' => 'submit',
  460. 'value' => get_string('declineinvitegroup', 'group')
  461. ),
  462. 'group' => array(
  463. 'type' => 'hidden',
  464. 'value' => $groupid
  465. ),
  466. 'returnto' => array(
  467. 'type' => 'hidden',
  468. 'value' => $returnto
  469. )
  470. )
  471. ));
  472. }
  473. /**
  474. * Form for adding a user to a group
  475. */
  476. function group_get_adduser_form($userid, $groupid) {
  477. return pieform(array(
  478. 'name' => 'adduser' . $userid,
  479. 'successcallback' => 'group_adduser_submit',
  480. 'renderer' => 'div',
  481. 'elements' => array(
  482. 'group' => array(
  483. 'type' => 'hidden',
  484. 'value' => $groupid,
  485. ),
  486. 'member' => array(
  487. 'type' => 'hidden',
  488. 'value' => $userid,
  489. ),
  490. 'submit' => array(
  491. 'type' => 'submit',
  492. 'value' => get_string('add') . ' ' . display_name($userid),
  493. ),
  494. ),
  495. ));
  496. }
  497. /**
  498. * Form for removing a user from a group
  499. */
  500. function group_get_removeuser_form($userid, $groupid) {
  501. require_once('pieforms/pieform.php');
  502. return pieform(array(
  503. 'name' => 'removeuser' . $userid,
  504. 'validatecallback' => 'group_removeuser_validate',
  505. 'successcallback' => 'group_removeuser_submit',
  506. 'renderer' => 'oneline',
  507. 'elements' => array(
  508. 'group' => array(
  509. 'type' => 'hidden',
  510. 'value' => $groupid,
  511. ),
  512. 'member' => array(
  513. 'type' => 'hidden',
  514. 'value' => $userid,
  515. ),
  516. 'removeuser' => array(
  517. 'type' => 'submit',
  518. 'value' => get_string('removefromgroup', 'group'),
  519. ),
  520. ),
  521. ));
  522. }
  523. /**
  524. * Form for denying request (request jointype group)
  525. */
  526. function group_get_denyuser_form($userid, $groupid) {
  527. require_once('pieforms/pieform.php');
  528. return pieform(array(
  529. 'name' => 'denyuser' . $userid,
  530. 'successcallback' => 'group_denyuser_submit',
  531. 'renderer' => 'oneline',
  532. 'elements' => array(
  533. 'group' => array(
  534. 'type' => 'hidden',
  535. 'value' => $groupid,
  536. ),
  537. 'member' => array(
  538. 'type' => 'hidden',
  539. 'value' => $userid,
  540. ),
  541. 'denyuser' => array(
  542. 'type' => 'submit',
  543. 'value' => get_string('declinerequest', 'group'),
  544. ),
  545. ),
  546. ));
  547. }
  548. // Functions for handling submission of group related forms
  549. function joingroup_submit(Pieform $form, $values) {
  550. global $SESSION, $USER;
  551. group_add_user($values['group'], $USER->get('id'));
  552. $SESSION->add_ok_msg(get_string('joinedgroup', 'group'));
  553. if (substr($values['returnto'], 0, 1) == '/') {
  554. $next = $values['returnto'];
  555. }
  556. else {
  557. $next = '/group/view.php?id=' . $values['group'];
  558. }
  559. redirect($next);
  560. }
  561. function group_invite_submit(Pieform $form, $values) {
  562. global $SESSION, $USER;
  563. $inviterecord = get_record('group_member_invite', 'member', $USER->get('id'), 'group', $values['group']);
  564. if ($inviterecord) {
  565. delete_records('group_member_invite', 'group', $values['group'], 'member', $USER->get('id'));
  566. if (isset($values['accept'])) {
  567. group_add_user($values['group'], $USER->get('id'), $inviterecord->role);
  568. $SESSION->add_ok_msg(get_string('groupinviteaccepted', 'group'));
  569. if (substr($values['returnto'], 0, 1) == '/') {
  570. $next = $values['returnto'];
  571. }
  572. else {
  573. $next = '/group/view.php?id=' . $values['group'];
  574. }
  575. redirect($next);
  576. }
  577. else {
  578. $SESSION->add_ok_msg(get_string('groupinvitedeclined', 'group'));
  579. redirect($values['returnto'] == 'find' ? '/group/find.php' : '/group/mygroups.php');
  580. }
  581. }
  582. }
  583. function group_adduser_submit(Pieform $form, $values) {
  584. global $SESSION;
  585. $group = (int)$values['group'];
  586. if (group_user_access($group) != 'admin') {
  587. $SESSION->add_error_msg(get_string('accessdenied', 'error'));
  588. redirect('/group/members.php?id=' . $group . '&membershiptype=request');
  589. }
  590. group_add_user($group, $values['member']);
  591. $SESSION->add_ok_msg(get_string('useradded', 'group'));
  592. if (count_records('group_member_request', 'group', $group)) {
  593. redirect('/group/members.php?id=' . $group . '&membershiptype=request');
  594. }
  595. redirect('/group/members.php?id=' . $group);
  596. }
  597. /**
  598. * Denying request (request jointype group)
  599. */
  600. function group_denyuser_submit(Pieform $form, $values) {
  601. global $SESSION;
  602. $group = (int)$values['group'];
  603. if (group_user_access($group) != 'admin') {
  604. $SESSION->add_error_msg(get_string('accessdenied', 'error'));
  605. redirect('/group/members.php?id=' . $group . '&membershiptype=request');
  606. }
  607. delete_records('group_member_request', 'group', $values['group'], 'member', $values['member']);
  608. $SESSION->add_ok_msg(get_string('declinerequestsuccess', 'group'));
  609. if (count_records('group_member_request', 'group', $group)) {
  610. redirect('/group/members.php?id=' . $group . '&membershiptype=request');
  611. }
  612. redirect('/group/members.php?id=' . $group);
  613. }
  614. function group_removeuser_validate(Pieform $form, $values) {
  615. global $user, $group, $SESSION;
  616. if (!group_user_can_leave($values['group'], $values['member'])) {
  617. $form->set_error('submit', get_string('usercantleavegroup', 'group'));
  618. }
  619. }
  620. function group_removeuser_submit(Pieform $form, $values) {
  621. global $SESSION;
  622. $group = (int)$values['group'];
  623. if (group_user_access($group) != 'admin') {
  624. $SESSION->add_error_msg(get_string('accessdenied', 'error'));
  625. redirect('/group/members.php?id=' . $group);
  626. }
  627. group_remove_user($group, $values['member']);
  628. $SESSION->add_ok_msg(get_string('userremoved', 'group'));
  629. redirect('/group/members.php?id=' . $group);
  630. }
  631. /**
  632. * Form for submitting views to a group
  633. */
  634. function group_view_submission_form($groupid, $viewdata) {
  635. $options = array();
  636. foreach ($viewdata as $view) {
  637. if (empty($view->submittedgroup) && empty($view->submittedhost)) {
  638. $options[$view->id] = $view->title;
  639. }
  640. }
  641. if (empty($options)) {
  642. return;
  643. }
  644. return pieform(array(
  645. 'name' => 'group_view_submission_form_' . $groupid,
  646. 'method' => 'post',
  647. 'renderer' => 'oneline',
  648. 'autofocus' => false,
  649. 'successcallback' => 'group_view_submission_form_submit',
  650. 'elements' => array(
  651. 'text1' => array(
  652. 'type' => 'html', 'value' => get_string('submit', 'group') . ' ',
  653. ),
  654. 'options' => array(
  655. 'type' => 'select',
  656. 'collapseifoneoption' => false,
  657. 'options' => $options,
  658. ),
  659. 'text2' => array(
  660. 'type' => 'html',
  661. 'value' => get_string('forassessment', 'view'),
  662. ),
  663. 'submit' => array(
  664. 'type' => 'submit',
  665. 'value' => get_string('submit')
  666. ),
  667. 'group' => array(
  668. 'type' => 'hidden',
  669. 'value' => $groupid
  670. ),
  671. 'returnto' => array(
  672. 'type' => 'hidden',
  673. 'value' => get_config('wwwroot') . 'group/view.php?id=' . $groupid,
  674. ),
  675. ),
  676. ));
  677. }
  678. function group_view_submission_form_submit(Pieform $form, $values) {
  679. redirect('/view/submit.php?id=' . $values['options'] . '&group=' . $values['group'] . '&returnto=group');
  680. }
  681. // Miscellaneous group related functions
  682. /**
  683. * Returns a list of user IDs who are admins for a group
  684. *
  685. * @param int ID of group
  686. * @return array
  687. */
  688. function group_get_admin_ids($groupid) {
  689. return (array)get_column_sql("SELECT \"member\"
  690. FROM {group_member}
  691. WHERE \"group\" = ?
  692. AND \"role\" = 'admin'", $groupid);
  693. }
  694. /**
  695. * Gets information about what the roles in a given group are able to do
  696. *
  697. * @param int $groupid ID of group to get role information for
  698. * @return array
  699. */
  700. function group_get_role_info($groupid) {
  701. $roles = get_records_sql_assoc('SELECT "role", edit_views, see_submitted_views, gr.grouptype FROM {grouptype_roles} gr
  702. INNER JOIN {group} g ON g.grouptype = gr.grouptype
  703. WHERE g.id = ?', array($groupid));
  704. foreach ($roles as $role) {
  705. $role->display = get_string($role->role, 'grouptype.'.$role->grouptype);
  706. $role->name = $role->role;
  707. }
  708. return $roles;
  709. }
  710. function group_get_default_artefact_permissions($groupid) {
  711. $type = get_field('group', 'grouptype', 'id', $groupid);
  712. safe_require('grouptype', $type);
  713. return call_static_method('GroupType' . $type, 'default_artefact_rolepermissions');
  714. }
  715. /**
  716. * Sets up groups for display in mygroups.php and find.php
  717. *
  718. * @param array $groups Initial group data, including the current user's
  719. * membership type in each group. See mygroups.php for
  720. * the query to build this information.
  721. * @param string $returnto Where forms generated for display should be told to return to
  722. */
  723. function group_prepare_usergroups_for_display($groups, $returnto='mygroups') {
  724. if (!$groups) {
  725. return;
  726. }
  727. // Retrieve a list of all the group admins, for placing in each $group object
  728. $groupadmins = array();
  729. $groupids = array_map(create_function('$a', 'return $a->id;'), $groups);
  730. if ($groupids) {
  731. $groupadmins = get_records_sql_array('SELECT "group", "member"
  732. FROM {group_member}
  733. WHERE "group" IN (' . implode(',', db_array_to_ph($groupids)) . ")
  734. AND \"role\" = 'admin'", $groupids);
  735. if (!$groupadmins) {
  736. $groupadmins = array();
  737. }
  738. }
  739. $i = 0;
  740. foreach ($groups as $group) {
  741. $group->admins = array();
  742. foreach ($groupadmins as $admin) {
  743. if ($admin->group == $group->id) {
  744. $group->admins[] = $admin->member;
  745. }
  746. }
  747. if ($group->membershiptype == 'member') {
  748. $group->canleave = group_user_can_leave($group->id);
  749. }
  750. else if ($group->jointype == 'open') {
  751. $group->groupjoin = group_get_join_form('joingroup' . $i++, $group->id);
  752. }
  753. else if ($group->membershiptype == 'invite') {
  754. $group->invite = group_get_accept_form('invite' . $i++, $group->id, $returnto);
  755. }
  756. $group->settingsdescription = group_display_settings($group);
  757. }
  758. }
  759. /*
  760. * Used by admin/groups/groups.php and admin/groups/groups.json.php for listing groups.
  761. */
  762. function build_grouplist_html($query, $limit, $offset, &$count=null) {
  763. $groups = search_group($query, $limit, $offset, 'all');
  764. $count = $groups['count'];
  765. if ($ids = array_map(create_function('$a', 'return intval($a->id);'), $groups['data'])) {
  766. $sumsql = "(m.role = 'admin')";
  767. if (is_postgres()) {
  768. $sumsql .= '::int';
  769. }
  770. // Member & admin counts
  771. $ids = join(',', $ids);
  772. $counts = get_records_sql_assoc("
  773. SELECT m.group, COUNT(m.member) AS members, SUM($sumsql) AS admins
  774. FROM {group_member} m
  775. WHERE m.group IN ($ids)
  776. GROUP BY m.group",
  777. array()
  778. );
  779. }
  780. foreach ($groups['data'] as &$group) {
  781. $group->visibility = $group->public ? get_string('Public', 'group') : get_string('Members', 'group');
  782. $group->admins = empty($counts[$group->id]->admins) ? 0 : $counts[$group->id]->admins;
  783. $group->members = empty($counts[$group->id]->members) ? 0 : $counts[$group->id]->members;
  784. if (get_config('allowgroupcategories')) {
  785. $group->categorytitle = ($group->category) ? get_field('group_category', 'title', 'id', $group->category) : '';
  786. }
  787. }
  788. $smarty = smarty_core();
  789. $smarty->assign('groups', $groups['data']);
  790. $data = array();
  791. $data['tablerows'] = $smarty->fetch('admin/groups/groupsresults.tpl');
  792. $pagination = build_pagination(array(
  793. 'id' => 'admgroupslist_pagination',
  794. 'datatable' => 'admgroupslist',
  795. 'url' => get_config('wwwroot') . 'admin/groups/groups.php' . (!empty($query) ? '?query=' . urlencode($query) : ''),
  796. 'jsonscript' => 'admin/groups/groups.json.php',
  797. 'count' => $count,
  798. 'limit' => $limit,
  799. 'offset' => $offset,
  800. 'resultcounttextsingular' => get_string('group', 'group'),
  801. 'resultcounttextplural' => get_string('groups', 'group'),
  802. ));
  803. $data['pagination'] = $pagination['html'];
  804. $data['pagination_js'] = $pagination['javascript'];
  805. return $data;
  806. }
  807. function group_get_membersearch_data($results, $group, $query, $membershiptype) {
  808. global $USER;
  809. $params = array();
  810. if (!empty($query)) {
  811. $params[] = 'query=' . $query;
  812. }
  813. $params[] = 'limit=' . $results['limit'];
  814. if (!empty($membershiptype)) {
  815. $params[] = 'membershiptype=' . $membershiptype;
  816. }
  817. $searchurl = get_config('wwwroot') . 'group/members.php?id=' . $group . '&amp;' . join('&amp;', $params);
  818. $smarty = smarty_core();
  819. $role = group_user_access($group);
  820. $userid = $USER->get('id');
  821. foreach ($results['data'] as &$r) {
  822. if ($role == 'admin' && ($r['id'] != $userid || group_user_can_leave($group, $r['id']))) {
  823. $r['removeform'] = group_get_removeuser_form($r['id'], $group);
  824. }
  825. // NOTE: this is a quick approximation. We should really check whether,
  826. // for each role in the group, that the user can change to it (using
  827. // group_can_change_role). This only controls whether the 'change
  828. // role' link appears though, so it doesn't matter too much. If the
  829. // user clicks on this link, changerole.php does the full check and
  830. // sends them back here saying that the user has no roles they can
  831. // change to anyway.
  832. $r['canchangerole'] = !group_is_only_admin($group, $r['id']);
  833. }
  834. if (!empty($membershiptype)) {
  835. if ($membershiptype == 'request') {
  836. foreach ($results['data'] as &$r) {
  837. $r['addform'] = group_get_adduser_form($r['id'], $group);
  838. $r['denyform'] = group_get_denyuser_form($r['id'], $group);
  839. // TODO: this will suck when there's quite a few on the page,
  840. // would be better to grab all the reasons in one go
  841. $r['reason'] = get_field('group_member_request', 'reason', 'group', $group, 'member', $r['id']);
  842. }
  843. }
  844. $smarty->assign('membershiptype', $membershiptype);
  845. }
  846. $results['cdata'] = array_chunk($results['data'], 2);
  847. $results['roles'] = group_get_role_info($group);
  848. $smarty->assign_by_ref('results', $results);
  849. $smarty->assign('searchurl', $searchurl);
  850. $smarty->assign('pagebaseurl', $searchurl);
  851. $smarty->assign('caneditroles', group_user_access($group) == 'admin');
  852. $smarty->assign('group', $group);
  853. $html = $smarty->fetch('group/membersearchresults.tpl');
  854. $pagination = build_pagination(array(
  855. 'id' => 'member_pagination',
  856. 'class' => 'center',
  857. 'url' => $searchurl,
  858. 'count' => $results['count'],
  859. 'limit' => $results['limit'],
  860. 'offset' => $results['offset'],
  861. 'datatable' => 'membersearchresults',
  862. 'jsonscript' => 'group/membersearchresults.json.php',
  863. 'firsttext' => '',
  864. 'previoustext' => '',
  865. 'nexttext' => '',
  866. 'lasttext' => '',
  867. 'numbersincludefirstlast' => false,
  868. 'resultcounttextsingular' => get_string('member', 'group'),
  869. 'resultcounttextplural' => get_string('members', 'group'),
  870. ));
  871. return array($html, $pagination, $results['count'], $results['offset'], $membershiptype);
  872. }
  873. /**
  874. * Returns a list of available grouptypes
  875. *
  876. * @return array
  877. */
  878. function group_get_grouptypes() {
  879. static $grouptypes = null;
  880. if (is_null($grouptypes)) {
  881. $grouptypes = get_column('grouptype', 'name');
  882. }
  883. return $grouptypes;
  884. }
  885. /**
  886. * Returns a list of grouptype & jointype options to be used in create
  887. * group/edit group drop-downs.
  888. *
  889. * If there is more than one group type with the same join type,
  890. * prefix the join types with the group type for display.
  891. */
  892. function group_get_grouptype_options($currentgrouptype=null) {
  893. $groupoptions = array();
  894. $jointypecount = array('open' => 0, 'invite' => 0, 'request' => 0, 'controlled' => 0);
  895. $grouptypes = group_get_grouptypes();
  896. $enabled = array_map(create_function('$a', 'return $a->name;'), plugins_installed('grouptype'));
  897. if (is_null($currentgrouptype) || in_array($currentgrouptype, $enabled)) {
  898. $grouptypes = array_intersect($enabled, $grouptypes);
  899. }
  900. foreach ($grouptypes as $grouptype) {
  901. safe_require('grouptype', $grouptype);
  902. if (call_static_method('GroupType' . $grouptype, 'can_be_created_by_user')) {
  903. $grouptypename = get_string('name', 'grouptype.' . $grouptype);
  904. foreach (call_static_method('GroupType' . $grouptype, 'allowed_join_types') as $jointype) {
  905. $jointypecount[$jointype]++;
  906. $groupoptions['jointype']["$grouptype.$jointype"] = get_string('membershiptype.'.$jointype, 'group');
  907. $groupoptions['grouptype']["$grouptype.$jointype"] = $grouptypename . ': ' . get_string('membershiptype.'.$jointype, 'group');
  908. }
  909. }
  910. }
  911. $duplicates = array_reduce($jointypecount, create_function('$a, $b', 'return $a || $b > 1;'));
  912. if ($duplicates) {
  913. return $groupoptions['grouptype'];
  914. }
  915. return $groupoptions['jointype'];
  916. }
  917. /**
  918. * Returns a datastructure describing the tabs that appear on a group page
  919. *
  920. * @param object $group Database record of group to get tabs for
  921. * @return array
  922. */
  923. function group_get_menu_tabs() {
  924. static $menu;
  925. $group = group_current_group();
  926. if (!$group) {
  927. return null;
  928. }
  929. $menu = array(
  930. 'info' => array(
  931. 'path' => 'groups/info',
  932. 'url' => 'group/view.php?id='.$group->id,
  933. 'title' => get_string('About', 'group'),
  934. 'weight' => 20
  935. ),
  936. 'members' => array(
  937. 'path' => 'groups/members',
  938. 'url' => 'group/members.php?id='.$group->id,
  939. 'title' => get_string('Members', 'group'),
  940. 'weight' => 30
  941. ),
  942. );
  943. if ($group->public || group_user_access($group->id)) {
  944. $menu['forums'] = array( // @todo: get this from a function in the interaction plugin (or better, make forums an artefact plugin)
  945. 'path' => 'groups/forums',
  946. 'url' => 'interaction/forum/index.php?group='.$group->id,
  947. 'title' => get_string('nameplural', 'interaction.forum'),
  948. 'weight' => 40,
  949. );
  950. }
  951. $menu['views'] = array(
  952. 'path' => 'groups/views',
  953. 'url' => 'view/groupviews.php?group='.$group->id,
  954. 'title' => get_string('Views', 'group'),
  955. 'weight' => 50,
  956. );
  957. $menu['share'] = array(
  958. 'path' => 'groups/share',
  959. 'url' => 'group/shareviews.php?group='.$group->id,
  960. 'title' => get_string('share', 'view'),
  961. 'weight' => 60,
  962. );
  963. if (group_user_access($group->id)) {
  964. safe_require('grouptype', $group->grouptype);
  965. $artefactplugins = call_static_method('GroupType' . $group->grouptype, 'get_group_artefact_plugins');
  966. if ($plugins = get_records_array('artefact_installed', 'active', 1)) {
  967. foreach ($plugins as &$plugin) {
  968. if (!in_array($plugin->name, $artefactplugins)) {
  969. continue;
  970. }
  971. safe_require('artefact', $plugin->name);
  972. $plugin_menu = call_static_method(generate_class_name('artefact',$plugin->name), 'group_tabs', $group->id);
  973. $menu = array_merge($menu, $plugin_menu);
  974. }
  975. }
  976. }
  977. if (defined('MENUITEM')) {
  978. $key = substr(MENUITEM, strlen('groups/'));
  979. if ($key && isset($menu[$key])) {
  980. $menu[$key]['selected'] = true;
  981. }
  982. }
  983. return $menu;
  984. }
  985. /**
  986. * Used by this file to perform validation of group ID function arguments
  987. *
  988. * @param int $groupid
  989. * @return int
  990. * @throws InvalidArgumentException
  991. */
  992. function group_param_groupid($groupid) {
  993. $groupid = (int)$groupid;
  994. if ($groupid == 0) {
  995. throw new InvalidArgumentException("group_user_access: group argument should be an integer");
  996. }
  997. return $groupid;
  998. }
  999. /**
  1000. * Used by this file to perform validation of user ID function arguments
  1001. *
  1002. * @param int $userid
  1003. * @return int
  1004. * @throws InvalidArgumentException
  1005. */
  1006. function group_param_userid($userid) {
  1007. if (is_null($userid)) {
  1008. global $USER;
  1009. $userid = (int)$USER->get('id');
  1010. }
  1011. else {
  1012. $userid = (int)$userid;
  1013. }
  1014. if ($userid == 0) {
  1015. throw new InvalidArgumentException("group_user_access: user argument should be an integer");
  1016. }
  1017. return $userid;
  1018. }
  1019. function group_current_group() {
  1020. static $group;
  1021. // This function sometimes gets called by the smarty function
  1022. // during the execution of a GroupNotFound exception. This
  1023. // variable prevents a 2nd exception from being thrown. Perhaps
  1024. // better achieved with a global in the exception handler?
  1025. static $dying;
  1026. if (defined('GROUP') && !$dying) {
  1027. $group = get_record_select('group', 'id = ? AND deleted = 0', array(GROUP), '*, ' . db_format_tsfield('ctime'));
  1028. if (!$group) {
  1029. $dying = 1;
  1030. throw new GroupNotFoundException(get_string('groupnotfound', 'group', GROUP));
  1031. }
  1032. }
  1033. else {
  1034. $group = null;
  1035. }
  1036. return $group;
  1037. }
  1038. /**
  1039. * creates the group sideblock
  1040. */
  1041. function group_sideblock() {
  1042. require_once('group.php');
  1043. $data['group'] = group_current_group();
  1044. if (!$data['group']) {
  1045. return null;
  1046. }
  1047. $data['menu'] = group_get_menu_tabs();
  1048. // @todo either: remove this if interactions become group
  1049. // artefacts, or: do this in interaction/lib.php if we leave them
  1050. // as interactions
  1051. $data['forums'] = get_records_select_array(
  1052. 'interaction_instance',
  1053. '"group" = ? AND deleted = ? AND plugin = ?',
  1054. array(GROUP, 0, 'forum'),
  1055. 'ctime',
  1056. 'id, plugin, title'
  1057. );
  1058. if (!$data['forums']) {
  1059. $data['forums'] = array();
  1060. }
  1061. else {
  1062. safe_require('interaction', 'forum');
  1063. $data['forums'] = PluginInteractionForum::sideblock_sort($data['forums']);
  1064. }
  1065. return $data;
  1066. }
  1067. function group_get_associated_groups($userid, $filter='all', $limit=20, $offset=0, $category='') {
  1068. // Strangely, casting is only needed for invite, request and admin and only in
  1069. // postgres
  1070. if (is_mysql()) {
  1071. $invitesql = "'invite'";
  1072. $requestsql = "'request'";
  1073. $adminsql = "'admin'";
  1074. $empty = "''";
  1075. }
  1076. else {
  1077. $invitesql = "CAST('invite' AS TEXT)";
  1078. $requestsql = "CAST('request' AS TEXT)";
  1079. $adminsql = "CAST('admin' AS TEXT)";
  1080. $empty = "CAST('' AS TEXT)";
  1081. }
  1082. // TODO: make it work on other databases?
  1083. // Different filters join on the different kinds of association
  1084. if ($filter == 'admin') {
  1085. $sql = "
  1086. INNER JOIN (
  1087. SELECT g.id, $adminsql AS membershiptype, $empty AS reason, $adminsql AS role
  1088. FROM {group} g
  1089. INNER JOIN {group_member} gm ON (gm.group = g.id AND gm.member = ? AND gm.role = 'admin')
  1090. ) t ON t.id = g.id";
  1091. $values = array($userid);
  1092. }
  1093. else if ($filter == 'member') {
  1094. $sql = "
  1095. INNER JOIN (
  1096. SELECT g.id, 'admin' AS membershiptype, $empty AS reason, $adminsql AS role
  1097. FROM {group} g
  1098. INNER JOIN {group_member} gm ON (gm.group = g.id AND gm.member = ? AND gm.role = 'admin')
  1099. UNION
  1100. SELECT g.id, 'member' AS type, $empty AS reason, gm.role AS role
  1101. FROM {group} g
  1102. INNER JOIN {group_member} gm ON (gm.group = g.id AND gm.member = ? AND gm.role != 'admin')
  1103. ) t ON t.id = g.id";
  1104. $values = array($userid, $userid);
  1105. }
  1106. else if ($filter == 'invite') {
  1107. $sql = "
  1108. INNER JOIN (
  1109. SELECT g.id, $invitesql AS membershiptype, gmi.reason, gmi.role
  1110. FROM {group} g
  1111. INNER JOIN {group_member_invite} gmi ON (gmi.group = g.id AND gmi.member = ?)
  1112. ) t ON t.id = g.id";
  1113. $values = array($userid);
  1114. }
  1115. else if ($filter == 'request') {
  1116. $sql = "
  1117. INNER JOIN (
  1118. SELECT g.id, $requestsql AS membershiptype, gmr.reason, $empty AS role
  1119. FROM {group} g
  1120. INNER JOIN {group_member_request} gmr ON (gmr.group = g.id AND gmr.member = ?)
  1121. ) t ON t.id = g.id";
  1122. $values = array($userid);
  1123. }
  1124. else { // all or some other text
  1125. $filter = 'all';
  1126. $sql = "
  1127. INNER JOIN (
  1128. SELECT g.id, 'admin' AS membershiptype, '' AS reason, 'admin' AS role
  1129. FROM {group} g
  1130. INNER JOIN {group_member} gm ON (gm.group = g.id AND gm.member = ? AND gm.role = 'admin')
  1131. UNION
  1132. SELECT g.id, 'member' AS membershiptype, '' AS reason, gm.role AS role
  1133. FROM {group} g
  1134. INNER JOIN {group_member} gm ON (g.id = gm.group AND gm.member = ? AND gm.role != 'admin')
  1135. UNION
  1136. SELECT g.id, 'invite' AS membershiptype, gmi.reason, gmi.role
  1137. FROM {group} g
  1138. INNER JOIN {group_member_invite} gmi ON (gmi.group = g.id AND gmi.member = ?)
  1139. UNION SELECT g.id, 'request' AS membershiptype, gmr.reason, '' AS role
  1140. FROM {group} g
  1141. INNER JOIN {group_member_request} gmr ON (gmr.group = g.id AND gmr.member = ?)
  1142. ) t ON t.id = g.id";
  1143. $values = array($userid, $userid, $userid, $userid);
  1144. }
  1145. $values[] = 0;
  1146. $catsql = '';
  1147. if (!empty($category)) {
  1148. if ($category == -1) { //find unassigned groups
  1149. $catsql = ' AND g.category IS NULL';
  1150. } else {
  1151. $catsql = ' AND g.category = ?';
  1152. $values[] = $category;
  1153. }
  1154. }
  1155. $count = count_records_sql('SELECT COUNT(*) FROM {group} g ' . $sql . ' WHERE g.deleted = ?'.$catsql, $values);
  1156. // almost the same as query used in find - common parts should probably be pulled out
  1157. // gets the groups filtered by above
  1158. // and the first three members by id
  1159. $sql = 'SELECT g1.id, g1.name, g1.description, g1.public, g1.jointype, g1.grouptype, g1.membershiptype, g1.reason, g1.role, g1.membercount, COUNT(gmr.member) AS requests
  1160. FROM (
  1161. SELECT g.id, g.name, g.description, g.public, g.jointype, g.grouptype, t.membershiptype, t.reason, t.role, COUNT(gm.member) AS membercount
  1162. FROM {group} g
  1163. LEFT JOIN {group_member} gm ON (gm.group = g.id)' .
  1164. $sql . '
  1165. WHERE g.deleted = ?' .
  1166. $catsql . '
  1167. GROUP BY g.id, g.name, g.description, g.public, g.jointype, g.grouptype, t.membershiptype, t.reason, t.role
  1168. ORDER BY g.name
  1169. ) g1
  1170. LEFT JOIN {group_member_request} gmr ON (gmr.group = g1.id)
  1171. GROUP BY g1.id, g1.name, g1.description, g1.public, g1.jointype, g1.grouptype, g1.membershiptype, g1.reason, g1.role, g1.membercount';
  1172. $groups = get_records_sql_array($sql, $values, $offset, $limit);
  1173. return array('groups' => $groups ? $groups : array(), 'count' => $count);
  1174. }
  1175. function group_get_user_groups($userid=null, $roles=null) {
  1176. static $usergroups = array();
  1177. if (is_null($userid)) {
  1178. global $USER;
  1179. $userid = $USER->get('id');
  1180. }
  1181. if (empty($roles) && isset($usergroups[$userid])) {
  1182. return $usergroups[$userid];
  1183. }
  1184. if (!$groups = get_records_sql_array(
  1185. "SELECT g.id, g.name, gm.role, g.jointype, g.grouptype, gtr.see_submitted_views, g.category
  1186. FROM {group} g
  1187. JOIN {group_member} gm ON (gm.group = g.id)
  1188. JOIN {grouptype_roles} gtr ON (g.grouptype = gtr.grouptype AND gm.role = gtr.role)
  1189. WHERE gm.member = ?
  1190. AND g.deleted = 0 " . (is_array($roles) ? (' AND gm.role IN (' . join(',', array_map('db_quote', $roles)) . ')') : '') . "
  1191. ORDER BY gm.role = 'admin' DESC, gm.role, g.id", array($userid))) {
  1192. $groups = array();
  1193. }
  1194. if (empty($roles)) {
  1195. $usergroups[$userid] = $groups;
  1196. }
  1197. return $groups;
  1198. }
  1199. function group_get_member_ids($group, $roles=null) {
  1200. $rolesql = is_null($roles) ? '' : (' AND gm.role IN (' . join(',', array_map('db_quote', $roles)) . ')');
  1201. return get_column_sql('
  1202. SELECT gm.member
  1203. FROM {group_member} gm INNER JOIN {group} g ON gm.group = g.id
  1204. WHERE g.deleted = 0 AND g.id = ?' . $rolesql,
  1205. array($group)
  1206. );
  1207. }
  1208. function group_can_create_groups() {
  1209. global $USER;
  1210. $creators = get_config('creategroups');
  1211. if ($creators == 'all') {
  1212. return true;
  1213. }
  1214. if ($USER->get('admin') || $USER->is_institutional_admin()) {
  1215. return true;
  1216. }
  1217. return $creators == 'staff' && ($USER->get('staff') || $USER->is_institutional_staff());
  1218. }
  1219. function group_get_user_course_groups($userid=null) {
  1220. if (is_null($userid)) {
  1221. global $USER;
  1222. $userid = $USER->get('id');
  1223. }
  1224. if ($groups = get_records_sql_array(
  1225. "SELECT g.id, g.name
  1226. FROM {group_member} u
  1227. INNER JOIN {group} g ON (u.group = g.id AND g.deleted = 0)
  1228. INNER JOIN {grouptype} t ON t.name = g.grouptype
  1229. WHERE u.member = ?
  1230. AND t.submittableto = 1
  1231. ORDER BY g.name
  1232. ", array($userid))) {
  1233. return $groups;
  1234. }
  1235. return array();
  1236. }
  1237. function group_allows_submission($grouptype) {
  1238. static $grouptypes = null;
  1239. if (is_null($grouptypes)) {
  1240. $grouptypes = get_records_assoc('grouptype');
  1241. }
  1242. return (bool) $grouptypes[$grouptype]->submittableto;
  1243. }
  1244. function group_display_settings($group) {
  1245. $string = get_string('membershiptype.'.$group->jointype, 'group');
  1246. if (group_allows_submission($group->grouptype)) {
  1247. $string .= ', ' . get_string('allowssubmissions', 'group');
  1248. }
  1249. if ($group->public) {
  1250. $string .= ', ' . get_string('publiclyvisible', 'group');
  1251. }
  1252. return $string;
  1253. }
  1254. /**
  1255. * Return the view object for this group's homepage view
  1256. *
  1257. * @param int $groupid the id of the group to fetch the view for
  1258. *
  1259. * @throws ViewNotFoundException
  1260. */
  1261. function group_get_homepage_view($groupid) {
  1262. $v = get_record('view', 'group', $groupid, 'type', 'grouphomepage');
  1263. return new View($v->id, (array)$v);
  1264. }
  1265. /**
  1266. * install the group homepage view
  1267. * This creates a template at system level
  1268. * which is subsequently copied to group hompages
  1269. *
  1270. * @return int the id of the new template
  1271. */
  1272. function install_system_grouphomepage_view() {
  1273. $dbtime = db_format_timestamp(time());
  1274. // create a system template for group homepage views
  1275. require_once(get_config('libroot') . 'view.php');
  1276. $viewdata = (object) array(
  1277. 'type' => 'grouphomepage',
  1278. 'owner' => 0,
  1279. 'numcolumns' => 1,
  1280. 'template' => 1,
  1281. 'title' => get_string('grouphomepage', 'view'),
  1282. 'ctime' => $dbtime,
  1283. 'atime' => $dbtime,
  1284. 'mtime' => $dbtime,
  1285. );
  1286. $id = insert_record('view', $viewdata, 'id', true);
  1287. $accessdata = (object) array('view' => $id, 'accesstype' => 'loggedin');
  1288. insert_record('view_access', $accessdata);
  1289. $blocktypes = array(
  1290. array(
  1291. 'blocktype' => 'groupinfo',
  1292. 'title' => '',
  1293. 'column' => 1,
  1294. 'config' => null,
  1295. ),
  1296. array(
  1297. 'blocktype' => 'recentforumposts',
  1298. 'title' => get_string('latestforumposts', 'interaction.forum'),
  1299. 'column' => 1,
  1300. 'config' => null,
  1301. ),
  1302. array(
  1303. 'blo…

Large files files are truncated, but you can click here to view the full file