groupmanager.lib.php 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. *
  5. * @package chamilo.library
  6. */
  7. /**
  8. * Code
  9. */
  10. require_once 'fileManage.lib.php';
  11. require_once 'fileUpload.lib.php';
  12. require_once 'document.lib.php';
  13. /**
  14. * This library contains some functions for group-management.
  15. * @author Bart Mollet
  16. * @package chamilo.library
  17. * @todo Add $course_code parameter to all functions. So this GroupManager can
  18. * be used outside a session.
  19. */
  20. class GroupManager {
  21. //- VIRTUAL_COURSE_CATEGORY: in this category groups are created based on the virtual course of a course
  22. CONST VIRTUAL_COURSE_CATEGORY = 1;
  23. //DEFAULT_GROUP_CATEGORY: When group categories aren't available (platform-setting), all groups are created in this 'dummy'-category
  24. CONST DEFAULT_GROUP_CATEGORY = 2;
  25. /**
  26. * infinite
  27. */
  28. CONST INFINITE = 99999;
  29. /**
  30. * No limit on the number of users in a group
  31. */
  32. CONST MEMBER_PER_GROUP_NO_LIMIT = 0;
  33. /**
  34. * No limit on the number of groups per user
  35. */
  36. CONST GROUP_PER_MEMBER_NO_LIMIT = 0;
  37. /**
  38. * The tools of a group can have 3 states
  39. * - not available
  40. * - public
  41. * - private
  42. */
  43. CONST TOOL_NOT_AVAILABLE = 0;
  44. CONST TOOL_PUBLIC = 1;
  45. CONST TOOL_PRIVATE = 2;
  46. /**
  47. * Constants for the available group tools
  48. */
  49. CONST GROUP_TOOL_FORUM = 0;
  50. CONST GROUP_TOOL_DOCUMENTS = 1;
  51. CONST GROUP_TOOL_CALENDAR = 2;
  52. CONST GROUP_TOOL_ANNOUNCEMENT = 3;
  53. CONST GROUP_TOOL_WORK = 4;
  54. CONST GROUP_TOOL_WIKI = 5;
  55. CONST GROUP_TOOL_CHAT = 6;
  56. //GROUP FUNCTIONS
  57. private function __construct() {
  58. }
  59. public static function get_groups() {
  60. $table_group = Database :: get_course_table(TABLE_GROUP);
  61. $course_id = api_get_course_int_id();
  62. $sql = "SELECT * FROM $table_group WHERE c_id = $course_id ";
  63. $result = Database::query($sql);
  64. return Database::store_result($result, 'ASSOC');
  65. }
  66. /**
  67. * Get list of groups for current course.
  68. * @param int $category The id of the category from which the groups are
  69. * requested
  70. * @param string $course_code Default is current course
  71. * @return array An array with all information about the groups.
  72. */
  73. public static function get_group_list ($category = null, $course_code = null) {
  74. $my_user_id = api_get_user_id();
  75. /*
  76. if ($course_code != null) {
  77. $course_info = Database :: get_course_info($course_code);
  78. $course_db = $course_info['database'];
  79. } else {
  80. $my_course_code=api_get_course_id();
  81. }
  82. */
  83. $course_info = api_get_course_info($course_code);
  84. $course_id = $course_info['real_id'];
  85. $table_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  86. $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
  87. $table_group = Database :: get_course_table(TABLE_GROUP);
  88. //condition for the session
  89. $session_id = api_get_session_id();
  90. $my_status_of_user_in_course = CourseManager::get_user_in_course_status($my_user_id, $course_info['code']);
  91. $is_student_in_session = false;
  92. if (is_null($my_status_of_user_in_course) || $my_status_of_user_in_course=='') {//into session
  93. if ($session_id>0) {
  94. $is_student_in_session=true;
  95. }
  96. }
  97. //COURSEMANAGER or STUDENT
  98. if ($my_status_of_user_in_course == COURSEMANAGER || api_is_allowed_to_edit(null, true) || api_is_drh()) {
  99. $sql = "SELECT g.id ,
  100. g.name ,
  101. g.description ,
  102. g.category_id,
  103. g.max_student maximum_number_of_members,
  104. g.secret_directory,
  105. g.self_registration_allowed,
  106. g.self_unregistration_allowed,
  107. g.session_id,
  108. ug.user_id is_member,
  109. COUNT(ug2.id) number_of_members
  110. FROM ".$table_group." g
  111. LEFT JOIN ".$table_group_user." ug
  112. ON ug.group_id = g.id AND ug.user_id = '".api_get_user_id()."' AND ug.c_id = $course_id
  113. LEFT JOIN ".$table_group_user." ug2
  114. ON ug2.group_id = g.id AND ug2.c_id = $course_id";
  115. } elseif ($my_status_of_user_in_course==STUDENT || $is_student_in_session===true || $_SESSION['studentview'] == 'studentview') {
  116. $sql = "SELECT g.id,
  117. g.name,
  118. g.description,
  119. g.category_id,
  120. g.max_student maximum_number_of_members,
  121. g.secret_directory,
  122. g.self_registration_allowed,
  123. g.self_unregistration_allowed,
  124. g.session_id,
  125. ug.user_id is_member,
  126. COUNT(ug2.id) number_of_members
  127. FROM ".$table_group." g
  128. LEFT JOIN ".$table_group_user." ug
  129. ON ug.group_id = g.id AND ug.user_id = '".api_get_user_id()."' AND ug.c_id = $course_id
  130. LEFT JOIN ".$table_group_user." ug2
  131. ON ug2.group_id = g.id AND ug2.c_id = $course_id";
  132. }
  133. $sql .= " WHERE 1=1 ";
  134. if ($category != null) {
  135. $sql .= " AND g.category_id = '".Database::escape_string($category)."' ";
  136. $session_condition = api_get_session_condition($session_id);
  137. if(!empty($session_condition))
  138. $sql .= $session_condition;
  139. } else {
  140. $session_condition = api_get_session_condition($session_id, true);
  141. }
  142. $sql .= " AND g.c_id = $course_id ";
  143. if(!empty($session_condition))
  144. $sql .= $session_condition;
  145. $sql .= " GROUP BY g.id ORDER BY UPPER(g.name)";
  146. if (!api_is_anonymous()) {
  147. $groupList = Database::query($sql);
  148. } else {
  149. return array();
  150. }
  151. $groups = array ();
  152. $thisGroup= array();
  153. while ($thisGroup = Database::fetch_array($groupList)) {
  154. if ($thisGroup['category_id'] == self::VIRTUAL_COURSE_CATEGORY) {
  155. $sql = "SELECT title FROM $table_course WHERE code = '".$thisGroup['name']."'";
  156. $obj = Database::fetch_object(Database::query($sql));
  157. $thisGroup['name'] = $obj->title;
  158. }
  159. if($thisGroup['session_id']!=0) {
  160. $sql_session = 'SELECT name FROM '.Database::get_main_table(TABLE_MAIN_SESSION).' WHERE id='.$thisGroup['session_id'];
  161. $rs_session = Database::query($sql_session);
  162. if (Database::num_rows($rs_session)>0) {
  163. $thisGroup['session_name'] = Database::result($rs_session,0,0);
  164. } else {
  165. //the session has probably been removed, so the group is now orphaned
  166. }
  167. }
  168. $groups[] = $thisGroup;
  169. }
  170. return $groups;
  171. }
  172. /**
  173. * Create a group
  174. * @param string $name The name for this group
  175. * @param int $tutor The user-id of the group's tutor
  176. * @param int $places How many people can subscribe to the new group
  177. */
  178. public static function create_group ($name, $category_id, $tutor, $places) {
  179. global $_course;
  180. $table_group = Database :: get_course_table(TABLE_GROUP);
  181. $session_id = api_get_session_id();
  182. $course_id = api_get_course_int_id();
  183. $currentCourseRepository = $_course['path'];
  184. $category = self :: get_category($category_id);
  185. if (intval($places) == 0) {
  186. //if the amount of users per group is not filled in, use the setting from the category
  187. $places = $category['max_student'];
  188. }
  189. $sql = "INSERT INTO ".$table_group." SET
  190. c_id = $course_id ,
  191. category_id='".Database::escape_string($category_id)."',
  192. max_student = '".$places."',
  193. doc_state = '".$category['doc_state']."',
  194. calendar_state = '".$category['calendar_state']."',
  195. work_state = '".$category['work_state']."',
  196. announcements_state = '".$category['announcements_state']."',
  197. forum_state = '".$category['forum_state']."',
  198. wiki_state = '".$category['wiki_state']."',
  199. chat_state = '".$category['chat_state']."',
  200. self_registration_allowed = '".$category['self_reg_allowed']."',
  201. self_unregistration_allowed = '".$category['self_unreg_allowed']."',
  202. session_id='".Database::escape_string($session_id)."'";
  203. Database::query($sql);
  204. $lastId = Database::insert_id();
  205. if ($lastId) {
  206. $desired_dir_name= '/'.replace_dangerous_char($name,'strict').'_groupdocs';
  207. $my_path = api_get_path(SYS_COURSE_PATH).$currentCourseRepository.'/document';
  208. $unique_name = create_unexisting_directory($_course, api_get_user_id(), $session_id, $lastId, NULL, $my_path, $desired_dir_name);
  209. /* Stores the directory path into the group table */
  210. $sql = "UPDATE ".$table_group." SET name = '".Database::escape_string($name)."', secret_directory = '".$unique_name."'
  211. WHERE c_id = $course_id AND id ='".$lastId."'";
  212. Database::query($sql);
  213. // create a forum if needed
  214. if ($category['forum_state'] >= 0) {
  215. require_once api_get_path(SYS_CODE_PATH).'forum/forumconfig.inc.php';
  216. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  217. $forum_categories = get_forum_categories();
  218. $values = array();
  219. $values['forum_title'] = $name;
  220. $values['group_id'] = $lastId;
  221. $counter = 0;
  222. foreach ($forum_categories as $key=>$value) {
  223. if ($counter==0) {
  224. $forum_category_id = $key;
  225. }
  226. $counter++;
  227. }
  228. // A sanity check.
  229. if (empty($forum_category_id)) {
  230. $forum_category_id = 0;
  231. }
  232. $values['forum_category'] = $forum_category_id;
  233. $values['allow_anonymous_group']['allow_anonymous'] = 0;
  234. $values['students_can_edit_group']['students_can_edit'] = 0;
  235. $values['approval_direct_group']['approval_direct'] = 0;
  236. $values['allow_attachments_group']['allow_attachments'] = 1;
  237. $values['allow_new_threads_group']['allow_new_threads'] = 1;
  238. $values['default_view_type_group']['default_view_type']=api_get_setting('default_forum_view');
  239. $values['group_forum'] = $lastId;
  240. if ($category['forum_state'] == '1') {
  241. $values['public_private_group_forum_group']['public_private_group_forum']='public';
  242. } elseif ($category['forum_state'] == '2') {
  243. $values['public_private_group_forum_group']['public_private_group_forum']='private';
  244. } elseif ($category['forum_state'] == '0') {
  245. $values['public_private_group_forum_group']['public_private_group_forum']='unavailable';
  246. }
  247. store_forum($values);
  248. }
  249. }
  250. return $lastId;
  251. }
  252. /**
  253. * Create subgroups.
  254. * This function creates new groups based on an existing group. It will
  255. * create the specified number of groups and fill those groups with users
  256. * from the base group
  257. * @param int $group_id The group from which subgroups have to be created.
  258. * @param int $number_of_groups The number of groups that have to be created
  259. */
  260. public static function create_subgroups ($group_id, $number_of_groups) {
  261. $course_id = api_get_course_int_id();
  262. $table_group = Database :: get_course_table(TABLE_GROUP);
  263. $category_id = self :: create_category('Subgroups', '', GroupManager::TOOL_PRIVATE, GroupManager::TOOL_PRIVATE, 0, 0, 1, 1);
  264. $users = self :: get_users($group_id);
  265. $group_ids = array ();
  266. for ($group_nr = 1; $group_nr <= $number_of_groups; $group_nr ++)
  267. {
  268. $group_ids[] = self :: create_group('SUBGROUP '.$group_nr, $category_id, 0, 0);
  269. }
  270. $members = array ();
  271. foreach ($users as $index => $user_id) {
  272. self :: subscribe_users($user_id, $group_ids[$index % $number_of_groups]);
  273. $members[$group_ids[$index % $number_of_groups]]++;
  274. }
  275. foreach ($members as $group_id => $places) {
  276. $sql = "UPDATE $table_group SET max_student = $places WHERE c_id = $course_id AND id = $group_id";
  277. Database::query($sql);
  278. }
  279. }
  280. /**
  281. * Create groups from all virtual courses in the given course.
  282. */
  283. public static function create_groups_from_virtual_courses() {
  284. self :: delete_category(self::VIRTUAL_COURSE_CATEGORY);
  285. $id = self :: create_category(get_lang('GroupsFromVirtualCourses'), '', GroupManager::TOOL_NOT_AVAILABLE, GroupManager::TOOL_NOT_AVAILABLE, 0, 0, 1, 1);
  286. $table_group_cat = Database :: get_course_table(TABLE_GROUP_CATEGORY);
  287. $course_id = api_get_course_int_id();
  288. $sql = "UPDATE ".$table_group_cat." SET id=".self::VIRTUAL_COURSE_CATEGORY." WHERE c_id = $course_id AND id=$id";
  289. Database::query($sql);
  290. $course = api_get_course_info();
  291. $course['code'] = $course['sysCode'];
  292. $course['title'] = $course['name'];
  293. $virtual_courses = CourseManager :: get_virtual_courses_linked_to_real_course($course['sysCode']);
  294. $group_courses = $virtual_courses;
  295. $group_courses[] = $course;
  296. $ids = array ();
  297. foreach ($group_courses as $index => $group_course) {
  298. $users = CourseManager :: get_user_list_from_course_code($group_course['code']);
  299. $members = array ();
  300. foreach ($users as $index => $user) {
  301. if ($user['status'] == 5 && $user['tutor_id'] == 0) {
  302. $members[] = $user['user_id'];
  303. }
  304. }
  305. $id = self :: create_group($group_course['code'], self::VIRTUAL_COURSE_CATEGORY, 0, count($members));
  306. self :: subscribe_users($members, $id);
  307. $ids[] = $id;
  308. }
  309. return $ids;
  310. }
  311. /**
  312. * Create a group for every class subscribed to the current course
  313. * @param int $category_id The category in which the groups should be
  314. * created
  315. */
  316. public static function create_class_groups ($category_id) {
  317. global $_course;
  318. $classes = ClassManager::get_classes_in_course($_course['sysCode']);
  319. $group_ids = array();
  320. foreach($classes as $index => $class)
  321. {
  322. $users = ClassManager::get_users($class['id']);
  323. $group_id = self::create_group($class['name'],$category_id,0,count($users));
  324. $user_ids = array();
  325. foreach($users as $index_user => $user)
  326. {
  327. $user_ids[] = $user['user_id'];
  328. }
  329. self::subscribe_users($user_ids,$group_id);
  330. $group_ids[] = $group_id;
  331. }
  332. return $group_ids;
  333. }
  334. /**
  335. * deletes groups and their data.
  336. * @author Christophe Gesche <christophe.gesche@claroline.net>
  337. * @author Hugues Peeters <hugues.peeters@claroline.net>
  338. * @author Bart Mollet
  339. * @param mixed $groupIdList - group(s) to delete. It can be a single id
  340. * (int) or a list of id (array).
  341. * @param string $course_code Default is current course
  342. * @return integer - number of groups deleted.
  343. */
  344. public static function delete_groups($group_ids, $course_code = null) {
  345. $course_info = api_get_course_info($course_code);
  346. $course_id = $course_info['real_id'];
  347. // Database table definitions
  348. $group_table = Database :: get_course_table(TABLE_GROUP);
  349. $forum_table = Database :: get_course_table(TABLE_FORUM);
  350. $group_ids = is_array($group_ids) ? $group_ids : array ($group_ids);
  351. $group_ids = array_map('intval',$group_ids);
  352. if (api_is_course_coach()) {
  353. //a coach can only delete courses from his session
  354. for($i=0 ; $i<count($group_ids) ; $i++) {
  355. if(!api_is_element_in_the_session(TOOL_GROUP,$group_ids[$i])) {
  356. array_splice($group_ids,$i,1);
  357. $i--;
  358. }
  359. }
  360. if(count($group_ids)==0)
  361. return 0;
  362. }
  363. // Unsubscribe all users
  364. self :: unsubscribe_all_users($group_ids);
  365. $sql = "SELECT id, secret_directory, session_id FROM $group_table WHERE c_id = $course_id AND id IN (".implode(' , ', $group_ids).")";
  366. $db_result = Database::query($sql);
  367. $forum_ids = array ();
  368. while ($group = Database::fetch_object($db_result)) {
  369. // move group-documents to garbage
  370. //$source_directory = api_get_path(SYS_COURSE_PATH).$course['path']."/group/".$group->secret_directory;
  371. $source_directory = api_get_path(SYS_COURSE_PATH).$course['path']."/document".$group->secret_directory;
  372. //File to renamed
  373. $destination_dir = api_get_path(SYS_COURSE_PATH).$course['path']."/document".$group->secret_directory.'_DELETED_'.$group->id;
  374. if (!empty($group->secret_directory)) {
  375. //Deleting from document tool
  376. DocumentManager::delete_document($course, $group->secret_directory, $source_directory);
  377. if (file_exists($source_directory)) {
  378. if (api_get_setting('permanently_remove_deleted_files') == 'true') {
  379. //Delete
  380. my_delete($source_directory);
  381. } else {
  382. //Rename
  383. rename($source_directory, $destination_dir);
  384. }
  385. }
  386. }
  387. //$forum_ids[] = $group->forum_id;
  388. }
  389. // delete the groups
  390. $sql = "DELETE FROM ".$group_table." WHERE c_id = $course_id AND id IN ('".implode("' , '", $group_ids)."')";
  391. Database::query($sql);
  392. $sql2 = "DELETE FROM ".$forum_table." WHERE c_id = $course_id AND forum_of_group IN ('".implode("' , '", $group_ids)."')";
  393. Database::query($sql2);
  394. return Database::affected_rows();
  395. }
  396. /**
  397. * Get group properties
  398. * @param int $group_id The group from which properties are requested.
  399. * @return array All properties. Array-keys are name, tutor_id, description, maximum_number_of_students, directory and visibility of tools
  400. */
  401. public static function get_group_properties($group_id) {
  402. $course_id = api_get_course_int_id();
  403. if (empty($group_id) or !is_integer(intval($group_id)) ) {
  404. return null;
  405. }
  406. $result = array();
  407. $table_group = Database :: get_course_table(TABLE_GROUP);
  408. $sql = "SELECT * FROM $table_group WHERE c_id = $course_id AND id = ".intval($group_id);
  409. $db_result = Database::query($sql);
  410. $db_object = Database::fetch_object($db_result);
  411. $result['id'] = $db_object->id;
  412. $result['name'] = $db_object->name;
  413. $result['tutor_id'] = isset($db_object->tutor_id)?$db_object->tutor_id:null;
  414. $result['description'] = $db_object->description;
  415. $result['maximum_number_of_students'] = $db_object->max_student;
  416. $result['doc_state'] = $db_object->doc_state;
  417. $result['work_state'] = $db_object->work_state;
  418. $result['calendar_state'] = $db_object->calendar_state;
  419. $result['announcements_state'] = $db_object->announcements_state;
  420. $result['forum_state'] = $db_object->forum_state;
  421. $result['wiki_state'] = $db_object->wiki_state;
  422. $result['chat_state'] = $db_object->chat_state;
  423. $result['directory'] = $db_object->secret_directory;
  424. $result['self_registration_allowed'] = $db_object->self_registration_allowed;
  425. $result['self_unregistration_allowed'] = $db_object->self_unregistration_allowed;
  426. $result['count_users'] = count(self::get_subscribed_users($group_id));
  427. $result['count_tutor'] = count(self::get_subscribed_tutors($group_id));
  428. $result['count_all'] = $result['count_users'] + $result['count_tutor'];
  429. return $result;
  430. }
  431. /**
  432. * Set group properties
  433. * Changes the group's properties.
  434. * @param int Group Id
  435. * @param string Group name
  436. * @param string Group description
  437. * @param int Max number of students in group
  438. * @param int Document tool's visibility (0=none,1=private,2=public)
  439. * @param int Work tool's visibility (0=none,1=private,2=public)
  440. * @param int Calendar tool's visibility (0=none,1=private,2=public)
  441. * @param int Announcement tool's visibility (0=none,1=private,2=public)
  442. * @param int Forum tool's visibility (0=none,1=private,2=public)
  443. * @param int Wiki tool's visibility (0=none,1=private,2=public)
  444. * @param int Chat tool's visibility (0=none,1=private,2=public)
  445. * @param bool Whether self registration is allowed or not
  446. * @param bool Whether self unregistration is allowed or not
  447. * @return bool TRUE if properties are successfully changed, false otherwise
  448. */
  449. public static function set_group_properties ($group_id, $name, $description, $maximum_number_of_students, $doc_state, $work_state, $calendar_state, $announcements_state, $forum_state, $wiki_state, $chat_state, $self_registration_allowed, $self_unregistration_allowed) {
  450. $table_group = Database :: get_course_table(TABLE_GROUP);
  451. $table_forum = Database :: get_course_table(TABLE_FORUM);
  452. //$forum_id = get_forums_of_group($group_id);
  453. $group_id = Database::escape_string($group_id);
  454. $course_id = api_get_course_int_id();
  455. $sql = "UPDATE ".$table_group."
  456. SET name='".Database::escape_string(trim($name))."',
  457. doc_state = '".Database::escape_string($doc_state)."',
  458. work_state = '".Database::escape_string($work_state)."',
  459. calendar_state = '".Database::escape_string($calendar_state)."',
  460. announcements_state = '".Database::escape_string($announcements_state)."',
  461. forum_state = '".Database::escape_string($forum_state)."',
  462. wiki_state = '".Database::escape_string($wiki_state)."',
  463. chat_state = '".Database::escape_string($chat_state)."',
  464. description='".Database::escape_string(trim($description))."',
  465. max_student=".Database::escape_string($maximum_number_of_students).",
  466. self_registration_allowed='".Database::escape_string($self_registration_allowed)."',
  467. self_unregistration_allowed='".Database::escape_string($self_unregistration_allowed)."'
  468. WHERE c_id = $course_id AND id=".$group_id;
  469. $result = Database::query($sql);
  470. //Here we are updating a field in the table forum_forum that perhaps duplicates the table group_info.forum_state cvargas
  471. $forum_state = (int) $forum_state;
  472. $sql2 = "UPDATE ".$table_forum." SET ";
  473. if ($forum_state===1) {
  474. $sql2 .= " forum_group_public_private='public' ";
  475. } elseif ($forum_state===2) {
  476. $sql2 .= " forum_group_public_private='private' ";
  477. } elseif ($forum_state===0) {
  478. $sql2 .= " forum_group_public_private='unavailable' ";
  479. }
  480. $sql2 .=" WHERE c_id = $course_id AND forum_of_group=".$group_id;
  481. $result2 = Database::query($sql2);
  482. return $result;
  483. }
  484. /**
  485. * Get the total number of groups for the current course.
  486. * @return int The number of groups for the current course.
  487. */
  488. public static function get_number_of_groups() {
  489. $course_id = api_get_course_int_id();
  490. $table_group = Database :: get_course_table(TABLE_GROUP);
  491. $res = Database::query("SELECT COUNT(id) AS number_of_groups FROM $table_group WHERE c_id = $course_id ");
  492. $obj = Database::fetch_object($res);
  493. return $obj->number_of_groups;
  494. }
  495. //GROUPCATEGORY FUNCTIONS
  496. /**
  497. * Get all categories
  498. * @param string $course_code The cours (default = current course)
  499. */
  500. public static function get_categories ($course_code = null) {
  501. $course_info = api_get_course_info($course_code);
  502. $course_id = $course_info['real_id'];
  503. $table_group_cat = Database :: get_course_table(TABLE_GROUP_CATEGORY);
  504. $sql = "SELECT * FROM $table_group_cat WHERE c_id = $course_id ORDER BY display_order";
  505. $res = Database::query($sql);
  506. $cats = array ();
  507. while ($cat = Database::fetch_array($res)) {
  508. $cats[] = $cat;
  509. }
  510. return $cats;
  511. }
  512. /**
  513. * Get a group category
  514. * @param int $id The category id
  515. * @param string $course_code The course (default = current course)
  516. */
  517. public static function get_category ($id, $course_code = null) {
  518. if (empty($id)) {
  519. return array();
  520. }
  521. $course_info = api_get_course_info($course_code);
  522. $course_id = $course_info['real_id'];
  523. $id = Database::escape_string($id);
  524. $table_group_cat = Database :: get_course_table(TABLE_GROUP_CATEGORY);
  525. $sql = "SELECT * FROM $table_group_cat WHERE c_id = $course_id AND id = $id LIMIT 1";
  526. $res = Database::query($sql);
  527. return Database::fetch_array($res);
  528. }
  529. /**
  530. * Get the unique category of a given group
  531. * @param int $group_id The id of the group
  532. * @param string $course_code The course in which the group is (default =
  533. * current course)
  534. * @return array The category
  535. */
  536. public static function get_category_from_group ($group_id, $course_code = null) {
  537. $table_group = Database :: get_course_table(TABLE_GROUP);
  538. $table_group_cat = Database :: get_course_table(TABLE_GROUP_CATEGORY);
  539. if (empty($group_id)) {
  540. return array();
  541. }
  542. $course_info = api_get_course_info($course_code);
  543. $course_id = $course_info['real_id'];
  544. $group_id = Database::escape_string($group_id);
  545. $sql = "SELECT gc.* FROM $table_group_cat gc, $table_group g
  546. WHERE gc.c_id = $course_id AND
  547. g.c_id = $course_id AND
  548. gc.id = g.category_id AND g.id= $group_id LIMIT 1";
  549. $res = Database::query($sql);
  550. $cat = array();
  551. if (Database::num_rows($res)) {
  552. $cat = Database::fetch_array($res);
  553. }
  554. return $cat;
  555. }
  556. /**
  557. * Delete a group category
  558. * @param int $cat_id The id of the category to delete
  559. * @param string $course_code The code in which the category should be
  560. * deleted (default = current course)
  561. */
  562. public static function delete_category ($cat_id, $course_code = null) {
  563. $course_info = api_get_course_info($course_code);
  564. $course_id = $course_info['real_id'];
  565. $table_group = Database :: get_course_table(TABLE_GROUP);
  566. $table_group_cat = Database :: get_course_table(TABLE_GROUP_CATEGORY);
  567. $cat_id = Database::escape_string($cat_id);
  568. $sql = "SELECT id FROM $table_group WHERE c_id = $course_id AND category_id='".$cat_id."'";
  569. $res = Database::query($sql);
  570. if (Database::num_rows($res) > 0) {
  571. $groups_to_delete = array ();
  572. while ($group = Database::fetch_object($res)) {
  573. $groups_to_delete[] = $group->id;
  574. }
  575. self :: delete_groups($groups_to_delete);
  576. }
  577. $sql = "DELETE FROM $table_group_cat WHERE c_id = $course_id AND id='".$cat_id."'";
  578. Database::query($sql);
  579. }
  580. /**
  581. * Create group category
  582. * @param string $title The title of the new category
  583. * @param string $description The description of the new category
  584. * @param bool $self_registration_allowed
  585. * @param bool $self_unregistration_allowed
  586. * @param int $max_number_of_students
  587. * @param int $groups_per_user
  588. */
  589. public static function create_category ($title, $description, $doc_state, $work_state, $calendar_state, $announcements_state, $forum_state, $wiki_state,
  590. $chat_state = 1, $self_registration_allowed = 0, $self_unregistration_allowed = 0, $maximum_number_of_students = 8, $groups_per_user = 0) {
  591. $table_group_category = Database :: get_course_table(TABLE_GROUP_CATEGORY);
  592. $course_id = api_get_course_int_id();
  593. $sql = "SELECT MAX(display_order)+1 as new_order FROM $table_group_category WHERE c_id = $course_id ";
  594. $res = Database::query($sql);
  595. $obj = Database::fetch_object($res);
  596. if (!isset ($obj->new_order)) {
  597. $obj->new_order = 1;
  598. }
  599. $sql = "INSERT INTO ".$table_group_category." SET
  600. c_id = $course_id ,
  601. title='".Database::escape_string($title)."',
  602. display_order ='".$obj->new_order."',
  603. description='".Database::escape_string($description)."',
  604. doc_state = '".Database::escape_string($doc_state)."',
  605. work_state = '".Database::escape_string($work_state)."',
  606. calendar_state = '".Database::escape_string($calendar_state)."',
  607. announcements_state = '".Database::escape_string($announcements_state)."',
  608. forum_state = '".Database::escape_string($forum_state)."',
  609. wiki_state = '".Database::escape_string($wiki_state)."',
  610. chat_state = '".Database::escape_string($chat_state)."',
  611. groups_per_user = '".Database::escape_string($groups_per_user)."',
  612. self_reg_allowed = '".Database::escape_string($self_registration_allowed)."',
  613. self_unreg_allowed = '".Database::escape_string($self_unregistration_allowed)."',
  614. max_student = '".Database::escape_string($maximum_number_of_students)."' ";
  615. Database::query($sql);
  616. $id = Database::insert_id();
  617. if ($id == self::VIRTUAL_COURSE_CATEGORY) {
  618. $sql = "UPDATE ".$table_group_category." SET id = ". ($id +1)." WHERE c_id = $course_id AND id = $id";
  619. Database::query($sql);
  620. return $id +1;
  621. }
  622. return $id;
  623. }
  624. /**
  625. * Update group category
  626. * @param int $id The id of the category
  627. * @param string $title The title of the new category
  628. * @param string $description The description of the new category
  629. * @param bool $self_registration_allowed
  630. * @param bool $self_unregistration_allowed
  631. * @param int $max_number_of_students
  632. * @param int $groups_per_user
  633. */
  634. public static function update_category ($id, $title, $description, $doc_state, $work_state, $calendar_state, $announcements_state, $forum_state, $wiki_state, $chat_state, $self_registration_allowed, $self_unregistration_allowed, $maximum_number_of_students, $groups_per_user) {
  635. $table_group_category = Database :: get_course_table(TABLE_GROUP_CATEGORY);
  636. $id = Database::escape_string($id);
  637. $course_id = api_get_course_int_id();
  638. $sql = "UPDATE ".$table_group_category."
  639. SET title='".Database::escape_string($title)."',
  640. description='".Database::escape_string($description)."',
  641. doc_state = '".Database::escape_string($doc_state)."',
  642. work_state = '".Database::escape_string($work_state)."',
  643. calendar_state = '".Database::escape_string($calendar_state)."',
  644. announcements_state = '".Database::escape_string($announcements_state)."',
  645. forum_state = '".Database::escape_string($forum_state)."',
  646. wiki_state = '".Database::escape_string($wiki_state)."',
  647. chat_state = '".Database::escape_string($chat_state)."',
  648. groups_per_user = ".Database::escape_string($groups_per_user).",
  649. self_reg_allowed = '".Database::escape_string($self_registration_allowed)."',
  650. self_unreg_allowed = '".Database::escape_string($self_unregistration_allowed)."',
  651. max_student = ".Database::escape_string($maximum_number_of_students)."
  652. WHERE c_id = $course_id AND id=$id";
  653. Database::query($sql);
  654. }
  655. /**
  656. * Returns the number of groups of the user with the greatest number of
  657. * subscribtions in the given category
  658. */
  659. public static function get_current_max_groups_per_user ($category_id = null, $course_code = null) {
  660. $course_info = api_get_course_info ($course_code);
  661. $group_table = Database :: get_course_table(TABLE_GROUP);
  662. $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
  663. $sql = 'SELECT COUNT(gu.group_id) AS current_max FROM '.$group_user_table.' gu, '.$group_table.' g
  664. WHERE g.c_id = '.$course_info['real_id'].' AND gu.group_id = g.id ';
  665. if ($category_id != null) {
  666. $category_id = Database::escape_string($category_id);
  667. $sql .= ' AND g.category_id = '.$category_id;
  668. }
  669. $sql .= ' GROUP BY gu.user_id ORDER BY current_max DESC LIMIT 1';
  670. $res = Database::query($sql);
  671. $obj = Database::fetch_object($res);
  672. return $obj->current_max;
  673. }
  674. /**
  675. * Swaps the display-order of two categories
  676. * @param int $id1 The id of the first category
  677. * @param int $id2 The id of the second category
  678. */
  679. public static function swap_category_order ($id1, $id2) {
  680. $table_group_cat = Database :: get_course_table(TABLE_GROUP_CATEGORY);
  681. $id1 = Database::escape_string($id1);
  682. $id2 = Database::escape_string($id2);
  683. $course_id = api_get_course_int_id();
  684. $sql = "SELECT id,display_order FROM $table_group_cat WHERE id IN ($id1,$id2) AND c_id = $course_id ";
  685. $res = Database::query($sql);
  686. $cat1 = Database::fetch_object($res);
  687. $cat2 = Database::fetch_object($res);
  688. $sql = "UPDATE $table_group_cat SET display_order=$cat2->display_order WHERE id = $cat1->id AND c_id = $course_id ";
  689. Database::query($sql);
  690. $sql = "UPDATE $table_group_cat SET display_order=$cat1->display_order WHERE id = $cat2->id AND c_id = $course_id ";
  691. Database::query($sql);
  692. }
  693. //GROUP USERS FUNCTIONS
  694. /**
  695. * Get all users from a given group
  696. * @param int $group_id The group
  697. * @return array list of user id
  698. */
  699. public static function get_users ($group_id, $load_extra_info = false) {
  700. $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
  701. $group_id = Database::escape_string($group_id);
  702. $course_id = api_get_course_int_id();
  703. $sql = "SELECT user_id FROM $group_user_table WHERE c_id = $course_id AND group_id = $group_id";
  704. $res = Database::query($sql);
  705. $users = array ();
  706. while ($obj = Database::fetch_object($res)) {
  707. if ($load_extra_info) {
  708. $users[] = api_get_user_info($obj->user_id);
  709. } else {
  710. $users[] = $obj->user_id;
  711. }
  712. }
  713. return $users;
  714. }
  715. public function get_members_and_tutors($group_id) {
  716. $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
  717. $tutor_user_table = Database :: get_course_table(TABLE_GROUP_TUTOR);
  718. $course_id = api_get_course_int_id();
  719. $group_id = intval($group_id);
  720. $sql = "SELECT user_id FROM $group_user_table WHERE c_id = $course_id AND group_id = $group_id";
  721. $res = Database::query($sql);
  722. $users = array();
  723. while ($obj = Database::fetch_object($res)) {
  724. $users[] = api_get_user_info($obj->user_id);
  725. }
  726. $sql = "SELECT user_id FROM $tutor_user_table WHERE c_id = $course_id AND group_id = $group_id";
  727. $res = Database::query($sql);
  728. while ($obj = Database::fetch_object($res)) {
  729. $users[] = api_get_user_info($obj->user_id);
  730. }
  731. return $users;
  732. }
  733. /**
  734. * Returns users belonging to any of the group
  735. *
  736. * @param array $groups list of group ids
  737. * @return array list of user ids
  738. */
  739. public static function get_groups_users($groups = array()) {
  740. $result = array();
  741. $tbl_group_user = Database::get_course_table(TABLE_GROUP_USER);
  742. $course_id = api_get_course_int_id();
  743. $groups = array_map('intval', $groups);
  744. $groups = implode(', ', $groups); //protect individual elements with surrounding quotes
  745. $sql = "SELECT DISTINCT user_id
  746. FROM $tbl_group_user gu
  747. WHERE c_id = $course_id AND gu.group_id IN ($groups)";
  748. $rs = Database::query($sql);
  749. while ($row = Database::fetch_array($rs)) {
  750. $result[] = $row['user_id'];
  751. }
  752. return $result;
  753. }
  754. /**
  755. * Fill the groups with students.
  756. * The algorithm takes care to first fill the groups with the least # of users.
  757. * Analysis
  758. * There was a problem with the "ALL" setting.
  759. * When max # of groups is set to all, the value is sometimes NULL and sometimes ALL
  760. * and in both cased the query does not work as expected.
  761. * Stupid solution (currently implemented: set ALL to a big number (INFINITE) and things are solved :)
  762. * Better solution: that's up to you.
  763. *
  764. * Note
  765. * Throughout Dokeos there is some confusion about "course id" and "course code"
  766. * The code is e.g. TEST101, but sometimes a variable that is called courseID also contains a course code string.
  767. * However, there is also a integer course_id that uniquely identifies the course.
  768. * ywarnier:> Now the course_id has been removed (25/1/2005)
  769. * The databases are als very inconsistent in this.
  770. *
  771. * @author Chrisptophe Gesche <christophe.geshe@claroline.net>,
  772. * Hugues Peeters <hugues.peeters@claroline.net> - original version
  773. * @author Roan Embrechts - virtual course support, code cleaning
  774. * @author Bart Mollet - code cleaning, use other GroupManager-functions
  775. * @return void
  776. */
  777. public static function fill_groups ($group_ids) {
  778. global $_course;
  779. $group_ids = is_array($group_ids) ? $group_ids : array ($group_ids);
  780. $group_ids = array_map('intval', $group_ids);
  781. if (api_is_course_coach()) {
  782. for ($i=0 ; $i< count($group_ids) ; $i++) {
  783. if (!api_is_element_in_the_session(TOOL_GROUP, $group_ids[$i])){
  784. array_splice($group_ids,$i,1);
  785. $i--;
  786. }
  787. }
  788. if (count($group_ids)==0) {
  789. return false;
  790. }
  791. }
  792. $category = self::get_category_from_group($group_ids[0]);
  793. $groups_per_user = $category['groups_per_user'];
  794. $group_table = Database :: get_course_table(TABLE_GROUP);
  795. $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
  796. $session_id = api_get_session_id();
  797. $complete_user_list = CourseManager :: get_real_and_linked_user_list($_course['code'], true, $session_id);
  798. $number_groups_per_user = ($groups_per_user == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $groups_per_user);
  799. /*
  800. * Retrieve all the groups where enrollment is still allowed
  801. * (reverse) ordered by the number of place available
  802. */
  803. $course_id = api_get_course_int_id();
  804. $sql = "SELECT g.id gid, g.max_student-count(ug.user_id) nbPlaces, g.max_student
  805. FROM ".$group_table." g
  806. LEFT JOIN ".$group_user_table." ug ON
  807. g.c_id = $course_id AND ug.c_id = $course_id AND g.id = ug.group_id
  808. WHERE
  809. g.id IN (".implode(',', $group_ids).")
  810. GROUP BY (g.id)
  811. HAVING (nbPlaces > 0 OR g.max_student = ".GroupManager::MEMBER_PER_GROUP_NO_LIMIT.")
  812. ORDER BY nbPlaces DESC";
  813. $sql_result = Database::query($sql);
  814. $group_available_place = array ();
  815. while ($group = Database::fetch_array($sql_result, 'ASSOC')) {
  816. $group_available_place[$group['gid']] = $group['nbPlaces'];
  817. }
  818. /*
  819. * Retrieve course users (reverse) ordered by the number
  820. * of group they are already enrolled
  821. */
  822. for ($i = 0; $i < count($complete_user_list); $i ++) {
  823. //find # of groups the user is enrolled in
  824. $number_of_groups = self :: user_in_number_of_groups($complete_user_list[$i]["user_id"], $category['id']);
  825. //add # of groups to user list
  826. $complete_user_list[$i]['number_groups_left'] = $number_groups_per_user - $number_of_groups;
  827. }
  828. //first sort by user_id to filter out duplicates
  829. $complete_user_list = TableSort :: sort_table($complete_user_list, 'user_id');
  830. $complete_user_list = self :: filter_duplicates($complete_user_list, 'user_id');
  831. $complete_user_list = self :: filter_only_students($complete_user_list);
  832. //now sort by # of group left
  833. $complete_user_list = TableSort :: sort_table($complete_user_list, 'number_groups_left', SORT_DESC);
  834. $userToken = array ();
  835. foreach ($complete_user_list as $this_user) {
  836. if ($this_user['number_groups_left'] > 0) {
  837. $userToken[$this_user['user_id']] = $this_user['number_groups_left'];
  838. }
  839. }
  840. $changed = true;
  841. while ($changed) {
  842. $changed = false;
  843. reset($group_available_place);
  844. arsort($group_available_place);
  845. reset($userToken);
  846. arsort($userToken);
  847. foreach ($group_available_place as $group_id => $place) {
  848. foreach ($userToken as $user_id => $places) {
  849. if (self :: can_user_subscribe($user_id, $group_id)) {
  850. self :: subscribe_users($user_id, $group_id);
  851. $group_available_place[$group_id]--;
  852. //$userToken[$user_id]--;
  853. unset($userToken[$user_id]);
  854. $changed = true;
  855. break;
  856. }
  857. }
  858. if ($changed) {
  859. break;
  860. }
  861. }
  862. }
  863. }
  864. /**
  865. * Get the number of students in a group.
  866. * @param int $group_id
  867. * @return int Number of students in the given group.
  868. */
  869. public static function number_of_students ($group_id, $course_id = null) {
  870. $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
  871. $group_id = Database::escape_string($group_id);
  872. if (empty($course_id)) {
  873. $course_id = api_get_course_int_id();
  874. } else {
  875. $course_id = intval($course_id);
  876. }
  877. $sql = "SELECT COUNT(*) AS number_of_students FROM $table_group_user WHERE c_id = $course_id AND group_id = $group_id";
  878. $db_result = Database::query($sql);
  879. $db_object = Database::fetch_object($db_result);
  880. return $db_object->number_of_students;
  881. }
  882. /**
  883. * Maximum number of students in a group
  884. * @param int $group_id
  885. * @return int Maximum number of students in the given group.
  886. */
  887. public static function maximum_number_of_students ($group_id) {
  888. $table_group = Database :: get_course_table(TABLE_GROUP);
  889. $group_id = Database::escape_string($group_id);
  890. $course_id = api_get_course_int_id();
  891. $db_result = Database::query("SELECT max_student FROM $table_group WHERE c_id = $course_id AND id = $group_id");
  892. $db_object = Database::fetch_object($db_result);
  893. if ($db_object->max_student == 0) {
  894. return self::INFINITE;
  895. }
  896. return $db_object->max_student;
  897. }
  898. /**
  899. * Number of groups of a user
  900. * @param int $user_id
  901. * @return int The number of groups the user is subscribed in.
  902. */
  903. public static function user_in_number_of_groups ($user_id, $cat_id = null) {
  904. $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
  905. $table_group = Database :: get_course_table(TABLE_GROUP);
  906. $user_id = Database::escape_string($user_id);
  907. $cat_id = Database::escape_string($cat_id);
  908. $course_id = api_get_course_int_id();
  909. $cat_condition = '';
  910. if (!empty($cat_id)) {
  911. $cat_condition = " AND g.category_id = $cat_id ";
  912. }
  913. $sql = "SELECT COUNT(*) AS number_of_groups FROM $table_group_user gu, $table_group g
  914. WHERE gu.c_id = $course_id AND
  915. g.c_id = $course_id AND
  916. gu.user_id = $user_id AND
  917. g.id = gu.group_id $cat_condition";
  918. $db_result = Database::query($sql);
  919. $db_object = Database::fetch_object($db_result);
  920. return $db_object->number_of_groups;
  921. }
  922. /**
  923. * Is sef-registration allowed?
  924. * @param int $user_id
  925. * @param int $group_id
  926. * @return bool TRUE if self-registration is allowed in the given group.
  927. */
  928. public static function is_self_registration_allowed ($user_id, $group_id) {
  929. $course_id = api_get_course_int_id();
  930. if (!$user_id > 0)
  931. return false;
  932. $table_group = Database :: get_course_table(TABLE_GROUP);
  933. $group_id= intval($group_id);
  934. if (isset($group_id)) {
  935. $sql = "SELECT self_registration_allowed FROM $table_group WHERE c_id = $course_id AND id = $group_id";
  936. $db_result = Database::query($sql);
  937. $db_object = Database::fetch_object($db_result);
  938. return $db_object->self_registration_allowed == 1 && self :: can_user_subscribe($user_id, $group_id);
  939. } else {
  940. return false;
  941. }
  942. }
  943. /**
  944. * Is sef-unregistration allowed?
  945. * @param int $user_id
  946. * @param int $group_id
  947. * @return bool TRUE if self-unregistration is allowed in the given group.
  948. */
  949. public static function is_self_unregistration_allowed ($user_id, $group_id) {
  950. if (!$user_id > 0)
  951. return false;
  952. $table_group = Database :: get_course_table(TABLE_GROUP);
  953. $group_id = Database::escape_string($group_id);
  954. $course_id = api_get_course_int_id();
  955. $db_result = Database::query('SELECT self_unregistration_allowed FROM '.$table_group.' WHERE c_id = '.$course_id.' AND id = '.$group_id);
  956. $db_object = Database::fetch_object($db_result);
  957. return $db_object->self_unregistration_allowed == 1 && self :: can_user_unsubscribe($user_id, $group_id);
  958. }
  959. /**
  960. * Is user subscribed in group?
  961. * @param int $user_id
  962. * @param int $group_id
  963. * @return bool TRUE if given user is subscribed in given group
  964. */
  965. public static function is_subscribed ($user_id, $group_id) {
  966. if(empty($user_id) or empty($group_id)){return false;}
  967. $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
  968. $group_id = Database::escape_string($group_id);
  969. $user_id = Database::escape_string($user_id);
  970. $course_id = api_get_course_int_id();
  971. $sql = 'SELECT 1 FROM '.$table_group_user.' WHERE c_id = '.$course_id.' AND group_id = '.$group_id.' AND user_id = '.$user_id;
  972. $db_result = Database::query($sql);
  973. return Database::num_rows($db_result) > 0;
  974. }
  975. /**
  976. * Can a user subscribe to a specified group in a course
  977. * @param int $user_id
  978. * @param int $group_id
  979. * @return bool TRUE if given user can be subscribed in given group
  980. */
  981. public static function can_user_subscribe ($user_id, $group_id) {
  982. global $_course;
  983. $course_code = $_course['sysCode'];
  984. $category = self :: get_category_from_group($group_id);
  985. $result = CourseManager :: is_user_subscribed_in_real_or_linked_course($user_id, $course_code);
  986. $result = !self :: is_subscribed($user_id, $group_id);
  987. $result &= (self :: number_of_students($group_id) < self :: maximum_number_of_students($group_id));
  988. if ($category['groups_per_user'] == self::GROUP_PER_MEMBER_NO_LIMIT) {
  989. $category['groups_per_user'] = self::INFINITE;
  990. }
  991. $result &= (self :: user_in_number_of_groups($user_id, $category['id']) < $category['groups_per_user']);
  992. $result &= !self :: is_tutor_of_group($user_id, $group_id);
  993. return $result;
  994. }
  995. /**
  996. * Can a user unsubscribe to a specified group in a course
  997. * @param int $user_id
  998. * @param int $group_id
  999. * @return bool TRUE if given user can be unsubscribed from given group
  1000. * @internal for now, same as GroupManager::is_subscribed($user_id,$group_id)
  1001. */
  1002. public static function can_user_unsubscribe ($user_id, $group_id) {
  1003. $result = self :: is_subscribed($user_id, $group_id);
  1004. return $result;
  1005. }
  1006. /**
  1007. * Get all subscribed users from a group
  1008. * @param int $group_id
  1009. * @return array An array with information of all users from the given group.
  1010. * (user_id, firstname, lastname, email)
  1011. */
  1012. public static function get_subscribed_users($group_id) {
  1013. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  1014. $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
  1015. $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
  1016. if (empty($group_id)) {
  1017. return array();
  1018. }
  1019. $group_id = intval($group_id);
  1020. $course_id = api_get_course_int_id();
  1021. $sql = "SELECT ug.id, u.user_id, u.lastname, u.firstname, u.email, u.username
  1022. FROM $table_user u INNER JOIN $table_group_user ug ON (ug.user_id = u.user_id)
  1023. WHERE ug.c_id = $course_id AND
  1024. ug.group_id = $group_id
  1025. $order_clause";
  1026. $db_result = Database::query($sql);
  1027. $users = array();
  1028. while ($user = Database::fetch_object($db_result)) {
  1029. $member['user_id'] = $user->user_id;
  1030. $member['firstname'] = $user->firstname;
  1031. $member['lastname'] = $user->lastname;
  1032. $member['email'] = $user->email;
  1033. $member['username'] = $user->username;
  1034. $users[$member['user_id']] = $member;
  1035. }
  1036. return $users;
  1037. }
  1038. /**
  1039. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1040. * Get all subscribed tutors of a group
  1041. * @param int $group_id
  1042. * @return array An array with information of all users from the given group.
  1043. * (user_id, firstname, lastname, email)
  1044. */
  1045. public static function get_subscribed_tutors ($group_id,$id_only=false) {
  1046. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  1047. $table_group_tutor = Database :: get_course_table(TABLE_GROUP_TUTOR);
  1048. $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
  1049. $group_id = Database::escape_string($group_id);
  1050. $course_id = api_get_course_int_id();
  1051. $sql = "SELECT tg.id, u.user_id, u.lastname, u.firstname, u.email
  1052. FROM ".$table_user." u, ".$table_group_tutor." tg
  1053. WHERE tg.c_id = $course_id AND
  1054. tg.group_id='".$group_id."' AND
  1055. tg.user_id=u.user_id".$order_clause;
  1056. $db_result = Database::query($sql);
  1057. $users = array ();
  1058. while ($user = Database::fetch_object($db_result)) {
  1059. if (!$id_only) {
  1060. $member['user_id'] = $user->user_id;
  1061. $member['firstname'] = $user->firstname;
  1062. $member['lastname'] = $user->lastname;
  1063. $member['email'] = $user->email;
  1064. $users[] = $member;
  1065. } else {
  1066. $users[]=$user->user_id;
  1067. }
  1068. }
  1069. return $users;
  1070. }
  1071. /**
  1072. * Subscribe user(s) to a specified group in current course
  1073. * @param mixed $user_ids Can be an array with user-id's or a single user-id
  1074. * @param int $group_id
  1075. * @return bool TRUE if successfull
  1076. */
  1077. public static function subscribe_users ($user_ids, $group_id) {
  1078. $user_ids = is_array($user_ids) ? $user_ids : array ($user_ids);
  1079. $result = true;
  1080. $course_id = api_get_course_int_id();
  1081. $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
  1082. if (!empty($user_ids)) {
  1083. foreach ($user_ids as $index => $user_id) {
  1084. $user_id = Database::escape_string($user_id);
  1085. $group_id = Database::escape_string($group_id);
  1086. $sql = "INSERT INTO ".$table_group_user." (c_id, user_id, group_id) VALUES ('$course_id', '".$user_id."', '".$group_id."')";
  1087. $result &= Database::query($sql);
  1088. }
  1089. }
  1090. return $result;
  1091. }
  1092. /**
  1093. * Subscribe tutor(s) to a specified group in current course
  1094. * @param mixed $user_ids Can be an array with user-id's or a single user-id
  1095. * @param int $group_id
  1096. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1097. * @see subscribe_users. This function is almost an exact copy of that function.
  1098. * @return bool TRUE if successfull
  1099. */
  1100. public static function subscribe_tutors ($user_ids, $group_id) {
  1101. $user_ids = is_array($user_ids) ? $user_ids : array ($user_ids);
  1102. $result = true;
  1103. $course_id = api_get_course_int_id();
  1104. $table_group_tutor = Database :: get_course_table(TABLE_GROUP_TUTOR);
  1105. foreach ($user_ids as $index => $user_id) {
  1106. $user_id = Database::escape_string($user_id);
  1107. $group_id = Database::escape_string($group_id);
  1108. $sql = "INSERT INTO ".$table_group_tutor." (c_id, user_id, group_id) VALUES ('$course_id', '".$user_id."', '".$group_id."')";
  1109. $result &= Database::query($sql);
  1110. }
  1111. return $result;
  1112. }
  1113. /**
  1114. * Unsubscribe user(s) from a specified group in current course
  1115. * @param mixed $user_ids Can be an array with user-id's or a single user-id
  1116. * @param int $group_id
  1117. * @return bool TRUE if successfull
  1118. */
  1119. public static function unsubscribe_users ($user_ids, $group_id) {
  1120. $user_ids = is_array($user_ids) ? $user_ids : array ($user_ids);
  1121. $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
  1122. $group_id = Database::escape_string($group_id);
  1123. $course_id = api_get_course_int_id();
  1124. $result &= Database::query('DELETE FROM '.$table_group_user.' WHERE c_id = '.$course_id.' AND group_id = '.$group_id.' AND user_id IN ('.implode(',', $user_ids).')');
  1125. }
  1126. /**
  1127. * Unsubscribe all users from one or more groups
  1128. * @param mixed $group_id Can be an array with group-id's or a single group-id
  1129. * @return bool TRUE if successfull
  1130. */
  1131. public static function unsubscribe_all_users ($group_ids) {
  1132. $course_id = api_get_course_int_id();
  1133. $group_ids = is_array($group_ids) ? $group_ids : array ($group_ids);
  1134. $group_ids = array_map('intval',$group_ids);
  1135. if( count($group_ids) > 0) {
  1136. if(api_is_course_coach()) {
  1137. for($i=0 ; $i<count($group_ids) ; $i++) {
  1138. if(!api_is_element_in_the_session(TOOL_GROUP,$group_ids[$i])) {
  1139. array_splice($group_ids,$i,1);
  1140. $i--;
  1141. }
  1142. }
  1143. if(count($group_ids)==0) {
  1144. return false;
  1145. }
  1146. }
  1147. $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
  1148. $sql = 'DELETE FROM '.$table_group_user.' WHERE group_id IN ('.implode(',', $group_ids).') AND c_id = '.$course_id;
  1149. $result = Database::query($sql);
  1150. return $result;
  1151. }
  1152. return true;
  1153. }
  1154. /**
  1155. * Unsubscribe all tutors from one or more groups
  1156. * @param mixed $group_id Can be an array with group-id's or a single group-id
  1157. * @see unsubscribe_all_users. This function is almost an exact copy of that function.
  1158. * @return bool TRUE if successfull
  1159. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1160. */
  1161. public static function unsubscribe_all_tutors ($group_ids) {
  1162. $course_id = api_get_course_int_id();
  1163. $group_ids = is_array($group_ids) ? $group_ids : array ($group_ids);
  1164. if( count($group_ids) > 0) {
  1165. $table_group_tutor = Database :: get_course_table(TABLE_GROUP_TUTOR);
  1166. $sql = 'DELETE FROM '.$table_group_tutor.' WHERE group_id IN ('.implode(',', $group_ids).') AND c_id = '.$course_id;
  1167. $result = Database::query($sql);
  1168. return $result;
  1169. }
  1170. return true;
  1171. }
  1172. /**
  1173. * Is the user a tutor of this group?
  1174. * @param $user_id the id of the user
  1175. * @param $group_id the id of the group
  1176. * @return boolean true/false
  1177. * @todo use the function user_has_access that includes this function
  1178. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1179. */
  1180. public static function is_tutor_of_group ($user_id,$group_id) {
  1181. global $_course;
  1182. $table_group_tutor = Database :: get_course_table(TABLE_GROUP_TUTOR);
  1183. $user_id = Database::escape_string($user_id);
  1184. $group_id = Database::escape_string($group_id);
  1185. $course_id = api_get_course_int_id();
  1186. $sql = "SELECT * FROM ".$table_group_tutor." WHERE c_id = $course_id AND user_id='".$user_id."' AND group_id='".$group_id."'";
  1187. $result = Database::query($sql);
  1188. if (Database::num_rows($result)>0) {
  1189. return true;
  1190. } else {
  1191. return false;
  1192. }
  1193. }
  1194. /**
  1195. * Is the user part of this group? This can be a tutor or a normal member
  1196. * you should use this function if the access to a tool or functionality is restricted to the people who are actually in the group
  1197. * before you had to check if the user was 1. a member of the group OR 2. a tutor of the group. This function combines both
  1198. * @param $user_id the id of the user
  1199. * @param $group_id the id of the group
  1200. * @return boolean true/false
  1201. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1202. */
  1203. public static function is_user_in_group ($user_id, $group_id) {
  1204. $member = self :: is_subscribed($user_id,$group_id);
  1205. $tutor = self :: is_tutor_of_group($user_id,$group_id);
  1206. if ($member OR $tutor) {
  1207. return true;
  1208. } else {
  1209. return false;
  1210. }
  1211. }
  1212. /**
  1213. * Get all tutors for the current course.
  1214. * @return array An array with firstname, lastname and user_id for all
  1215. * tutors in the current course.
  1216. * @deprecated this function uses the old tutor implementation
  1217. */
  1218. public static function get_all_tutors() {
  1219. global $_course;
  1220. $course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1221. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  1222. $sql = "SELECT user.user_id AS user_id, user.lastname AS lastname, user.firstname AS firstname
  1223. FROM ".$user_table." user, ".$course_user_table." cu
  1224. WHERE cu.user_id=user.user_id
  1225. AND cu.tutor_id='1'
  1226. AND cu.course_code='".$_course['sysCode']."'";
  1227. $resultTutor = Database::query($sql);
  1228. $tutors = array ();
  1229. while ($tutor = Database::fetch_array($resultTutor))
  1230. {
  1231. $tutors[] = $tutor;
  1232. }
  1233. return $tutors;
  1234. }
  1235. /**
  1236. * Is user a tutor in current course
  1237. * @param int $user_id
  1238. * @return bool TRUE if given user is a tutor in the current course.
  1239. * @deprecated this function uses the old tutor implementation
  1240. */
  1241. public static function is_tutor ($user_id) {
  1242. global $_course;
  1243. $course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  1244. $user_id = Database::escape_string($user_id);
  1245. $sql = "SELECT tutor_id FROM ".$course_user_table."
  1246. WHERE user_id='".$user_id."' AND course_code='".$_course['code']."'"."AND tutor_id=1";
  1247. $db_result = Database::query($sql);
  1248. $result = (Database::num_rows($db_result) > 0);
  1249. return $result;
  1250. }
  1251. /**
  1252. * Get all group's from a given course in which a given user is unsubscribed
  1253. * @author Patrick Cool
  1254. * @param int course id
  1255. * retrieve the groups for
  1256. * @param integer $user_id: the ID of the user you want to know all its
  1257. * group memberships
  1258. */
  1259. public static function get_group_ids ($course_id, $user_id) {
  1260. $groups = array();
  1261. $tbl_group = Database::get_course_table(TABLE_GROUP_USER);
  1262. $tbl_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
  1263. $user_id = intval($user_id);
  1264. $course_id = intval($course_id);
  1265. $sql = "SELECT group_id FROM $tbl_group WHERE c_id = $course_id AND user_id = '$user_id'";
  1266. $groupres = Database::query($sql);
  1267. if ($groupres) {
  1268. while ($myrow= Database::fetch_array($groupres))
  1269. $groups[]=$myrow['group_id'];
  1270. }
  1271. //Also loading if i'm the tutor
  1272. $sql = "SELECT group_id FROM $tbl_group_tutor WHERE c_id = $course_id AND user_id = '$user_id'";
  1273. $groupres = Database::query($sql);
  1274. if ($groupres) {
  1275. while ($myrow= Database::fetch_array($groupres)) {
  1276. $groups[]=$myrow['group_id'];
  1277. }
  1278. }
  1279. if (!empty($groups)) {
  1280. array_filter($groups);
  1281. }
  1282. return $groups;
  1283. }
  1284. /*
  1285. Group functions - these take virtual/linked courses into account when necessary
  1286. */
  1287. /**
  1288. * Get a combined list of all users of the real course $course_code
  1289. * and all users in virtual courses linked to this course $course_code
  1290. * Filter user list: remove duplicate users; plus
  1291. * remove users that
  1292. * - are already in the current group $group_id;
  1293. * - do not have student status in these courses;
  1294. * - are not appointed as tutor (group assistent) for this group;
  1295. * - have already reached their maximum # of groups in this course.
  1296. *
  1297. * Originally to get the correct list of users a big SQL statement was used,
  1298. * but this has become more complicated now there is not just one real course but many virtual courses.
  1299. * Still, that could have worked as well.
  1300. *
  1301. * @version 1.1.3
  1302. * @author Roan Embrechts
  1303. */
  1304. public static function get_complete_list_of_users_that_can_be_added_to_group ($course_code, $group_id) {
  1305. global $_course, $_user;
  1306. $category = self :: get_category_from_group($group_id, $course_code);
  1307. $number_of_groups_limit = $category['groups_per_user'] == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $category['groups_per_user'];
  1308. $real_course_code = $_course['sysCode'];
  1309. $real_course_info = Database :: get_course_info($real_course_code);
  1310. $real_course_user_list = CourseManager :: get_user_list_from_course_code($real_course_code);
  1311. //get list of all virtual courses
  1312. $user_subscribed_course_list = CourseManager :: get_list_of_virtual_courses_for_specific_user_and_real_course($_user['user_id'], $real_course_code);
  1313. //add real course to the list
  1314. $user_subscribed_course_list[] = $real_course_info;
  1315. if (!is_array($user_subscribed_course_list)) {
  1316. return;
  1317. }
  1318. //for all courses...
  1319. foreach ($user_subscribed_course_list as $this_course) {
  1320. $this_course_code = $this_course['code'];
  1321. $course_user_list = CourseManager :: get_user_list_from_course_code($this_course_code);
  1322. //for all users in the course
  1323. foreach ($course_user_list as $this_user) {
  1324. $user_id = $this_user['user_id'];
  1325. $loginname = $this_user['username'];
  1326. $lastname = $this_user['lastname'];
  1327. $firstname = $this_user['firstname'];
  1328. $status = $this_user['status'];
  1329. //$role = $this_user['role'];
  1330. $tutor_id = $this_user['tutor_id'];
  1331. $full_name = api_get_person_name($firstname, $lastname);
  1332. if ($lastname == "" || $firstname == '') {
  1333. $full_name = $loginname;
  1334. }
  1335. $complete_user['user_id'] = $user_id;
  1336. $complete_user['full_name'] = $full_name;
  1337. $complete_user['firstname'] = $firstname;
  1338. $complete_user['lastname'] = $lastname;
  1339. $complete_user['status'] = $status;
  1340. $complete_user['tutor_id'] = $tutor_id;
  1341. $student_number_of_groups = self :: user_in_number_of_groups($user_id, $category['id']);
  1342. //filter: only add users that have not exceeded their maximum amount of groups
  1343. if ($student_number_of_groups < $number_of_groups_limit) {
  1344. $complete_user_list[] = $complete_user;
  1345. }
  1346. }
  1347. }
  1348. if (is_array($complete_user_list)) {
  1349. //sort once, on array field "full_name"
  1350. $complete_user_list = TableSort :: sort_table($complete_user_list, "full_name");
  1351. //filter out duplicates, based on field "user_id"
  1352. $complete_user_list = self :: filter_duplicates($complete_user_list, "user_id");
  1353. $complete_user_list = self :: filter_users_already_in_group($complete_user_list, $group_id);
  1354. }
  1355. return $complete_user_list;
  1356. }
  1357. /**
  1358. * Filter out duplicates in a multidimensional array
  1359. * by comparing field $compare_field.
  1360. *
  1361. * @param $user_array_in list of users (must be sorted).
  1362. * @param string $compare_field, the field to be compared
  1363. */
  1364. public static function filter_duplicates ($user_array_in, $compare_field) {
  1365. $total_number = count($user_array_in);
  1366. $user_array_out[0] = $user_array_in[0];
  1367. $count_out = 0;
  1368. for ($count_in = 1; $count_in < $total_number; $count_in ++) {
  1369. if ($user_array_in[$count_in][$compare_field] != $user_array_out[$count_out][$compare_field]) {
  1370. $count_out ++;
  1371. $user_array_out[$count_out] = $user_array_in[$count_in];
  1372. }
  1373. }
  1374. return $user_array_out;
  1375. }
  1376. /**
  1377. * Filters from the array $user_array_in the users already in the group $group_id.
  1378. */
  1379. public static function filter_users_already_in_group ($user_array_in, $group_id) {
  1380. foreach ($user_array_in as $this_user) {
  1381. if (!self :: is_subscribed($this_user['user_id'], $group_id)) {
  1382. $user_array_out[] = $this_user;
  1383. }
  1384. }
  1385. return $user_array_out;
  1386. }
  1387. /**
  1388. * Remove all users that are not students and all users who have tutor status
  1389. * from the list.
  1390. */
  1391. public static function filter_only_students($user_array_in) {
  1392. $user_array_out = array ();
  1393. foreach ($user_array_in as $this_user) {
  1394. //if ($this_user['status_rel'] == STUDENT && $this_user['tutor_id'] == 0) {
  1395. if (api_get_session_id()) {
  1396. if ($this_user['status_session'] == 0) {
  1397. $user_array_out[] = $this_user;
  1398. }
  1399. } else {
  1400. if ($this_user['status_rel'] == STUDENT) {
  1401. $user_array_out[] = $this_user;
  1402. }
  1403. }
  1404. }
  1405. return $user_array_out;
  1406. }
  1407. /**
  1408. * Check if a user has access to a certain group tool
  1409. * @param int $user_id The user id
  1410. * @param int $group_id The group id
  1411. * @param constant $tool The tool to check the access rights. This should be
  1412. * one of constants: GROUP_TOOL_DOCUMENTS
  1413. * @return bool True if the given user has access to the given tool in the
  1414. * given course.
  1415. */
  1416. public static function user_has_access($user_id, $group_id, $tool) {
  1417. //Admin have access everywhere
  1418. if (api_is_platform_admin()) {
  1419. return true;
  1420. }
  1421. //Course admin also have access to everything
  1422. if (api_is_allowed_to_edit()) {
  1423. return true;
  1424. }
  1425. switch ($tool) {
  1426. case self::GROUP_TOOL_FORUM :
  1427. $state_key = 'forum_state';
  1428. break;
  1429. case self::GROUP_TOOL_DOCUMENTS :
  1430. $state_key = 'doc_state';
  1431. break;
  1432. case self::GROUP_TOOL_CALENDAR :
  1433. $state_key = 'calendar_state';
  1434. break;
  1435. case self::GROUP_TOOL_ANNOUNCEMENT :
  1436. $state_key = 'announcements_state';
  1437. break;
  1438. case self::GROUP_TOOL_WORK :
  1439. $state_key = 'work_state';
  1440. break;
  1441. case self::GROUP_TOOL_WIKI :
  1442. $state_key = 'wiki_state';
  1443. break;
  1444. case self::GROUP_TOOL_CHAT :
  1445. $state_key = 'chat_state';
  1446. break;
  1447. default:
  1448. return false;
  1449. }
  1450. $user_is_in_group = self :: is_user_in_group($user_id, $group_id);
  1451. //Check group properties
  1452. $group_info = self :: get_group_properties($group_id);
  1453. //Check group category if exists
  1454. $category_group_info = self::get_category_from_group($group_id);
  1455. if (!empty($category_group_info)) {
  1456. //if exists check the category group status first
  1457. if ($category_group_info[$state_key] == GroupManager::TOOL_NOT_AVAILABLE) {
  1458. return false;
  1459. } elseif($category_group_info[$state_key] == GroupManager::TOOL_PRIVATE && !$user_is_in_group) {
  1460. return false;
  1461. }
  1462. }
  1463. //is_user_in_group() is more complete that the is_subscribed() function
  1464. if ($group_info[$state_key] == GroupManager::TOOL_NOT_AVAILABLE) {
  1465. return false;
  1466. } elseif ($group_info[$state_key] == self::TOOL_PUBLIC) {
  1467. return true;
  1468. } elseif (api_is_allowed_to_edit(false,true)) {
  1469. return true;
  1470. } elseif($group_info['tutor_id'] == $user_id) { //this tutor implementation was dropped
  1471. return true;
  1472. } elseif($group_info[$state_key] == GroupManager::TOOL_PRIVATE && !$user_is_in_group) {
  1473. return false;
  1474. } else {
  1475. return $user_is_in_group;
  1476. }
  1477. }
  1478. /**
  1479. * Get all groups where a specific user is subscribed
  1480. */
  1481. public static function get_user_group_name ($user_id) {
  1482. $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
  1483. $table_group = Database::get_course_table(TABLE_GROUP);
  1484. $user_id = intval($user_id);
  1485. $course_id = api_get_course_int_id();
  1486. $sql_groups = "SELECT name FROM $table_group g INNER JOIN $table_group_user gu
  1487. ON (gu.group_id=g.id)
  1488. WHERE gu.c_id= $course_id AND
  1489. g.c_id= $course_id AND
  1490. gu.user_id = $user_id";
  1491. $res = Database::query($sql_groups);
  1492. $groups=array();
  1493. while ($group = Database::fetch_array($res)) {
  1494. $groups[] .= $group['name'];
  1495. }
  1496. return $groups;
  1497. }
  1498. /**
  1499. * fill_groups_list
  1500. *
  1501. * see : fill_groups
  1502. * Fill the groups with students.
  1503. *
  1504. * note :
  1505. * optimize fill_groups_list <--> fill_groups
  1506. *
  1507. */
  1508. public static function fill_groups_list ($group_ids) {
  1509. $group_ids = is_array($group_ids) ? $group_ids : array ($group_ids);
  1510. $group_ids = array_map('intval',$group_ids);
  1511. if (api_is_course_coach()) {
  1512. for($i=0 ; $i<count($group_ids) ; $i++) {
  1513. if(!api_is_element_in_the_session(TOOL_GROUP,$group_ids[$i])) {
  1514. array_splice($group_ids,$i,1);
  1515. $i--;
  1516. }
  1517. }
  1518. if (count($group_ids)==0){
  1519. return false;}
  1520. }
  1521. global $_course;
  1522. $category = self :: get_category_from_group($group_ids[0]);
  1523. $groups_per_user = $category['groups_per_user'];
  1524. $course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1525. $group_table = Database :: get_course_table(TABLE_GROUP);
  1526. $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
  1527. $session_id = api_get_session_id();
  1528. $complete_user_list = CourseManager :: get_real_and_linked_user_list($_course['sysCode'], true, $session_id);
  1529. $number_groups_per_user = ($groups_per_user == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $groups_per_user);
  1530. $course_id = api_get_course_int_id();
  1531. /*
  1532. * Retrieve all the groups where enrollment is still allowed
  1533. * (reverse) ordered by the number of place available
  1534. */
  1535. $sql = "SELECT g.id gid, g.max_student - count(ug.user_id) nbPlaces, g.max_student
  1536. FROM ".$group_table." g
  1537. LEFT JOIN ".$group_user_table." ug
  1538. ON g.id = ug.group_id
  1539. WHERE g.c_id = $course_id AND
  1540. ug.c_id = $course_id AND
  1541. g.id IN (".implode(',', $group_ids).")
  1542. GROUP BY (g.id)
  1543. HAVING (nbPlaces > 0 OR g.max_student = ".GroupManager::MEMBER_PER_GROUP_NO_LIMIT.")
  1544. ORDER BY nbPlaces DESC";
  1545. $sql_result = Database::query($sql);
  1546. $group_available_place = array ();
  1547. while ($group = Database::fetch_array($sql_result, 'ASSOC')) {
  1548. $group_available_place[$group['gid']] = $group['nbPlaces'];
  1549. }
  1550. /*
  1551. * Retrieve course users (reverse) ordered by the number
  1552. * of group they are already enrolled
  1553. */
  1554. for ($i = 0; $i < count($complete_user_list); $i ++) {
  1555. //find # of groups the user is enrolled in
  1556. $number_of_groups = self :: user_in_number_of_groups($complete_user_list[$i]["user_id"],$category['id']);
  1557. //add # of groups to user list
  1558. $complete_user_list[$i]['number_groups_left'] = $number_groups_per_user - $number_of_groups;
  1559. }
  1560. //first sort by user_id to filter out duplicates
  1561. $complete_user_list = TableSort :: sort_table($complete_user_list, 'user_id');
  1562. $complete_user_list = self :: filter_duplicates($complete_user_list, 'user_id');
  1563. //$complete_user_list = self :: filter_only_students($complete_user_list);
  1564. //now sort by # of group left
  1565. $complete_user_list = TableSort :: sort_table($complete_user_list, 'number_groups_left', SORT_DESC);
  1566. return $complete_user_list;
  1567. }
  1568. }