ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilExAssignmentTeam.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
11{
15 protected $db;
16
20 protected $user;
21
22 protected $id; // [int]
23 protected $assignment_id; // [int]
24 protected $members = array(); // [array]
25
31
32 public function __construct($a_id = null)
33 {
34 global $DIC;
35
36 $this->db = $DIC->database();
37 $this->user = $DIC->user();
38 if ($a_id) {
39 $this->read($a_id);
40 }
41 }
42
43 public static function getInstanceByUserId($a_assignment_id, $a_user_id, $a_create_on_demand = false)
44 {
45 $id = self::getTeamId($a_assignment_id, $a_user_id, $a_create_on_demand);
46 return new self($id);
47 }
48
49 public static function getInstancesFromMap($a_assignment_id)
50 {
51 $teams = array();
52 foreach (self::getAssignmentTeamMap($a_assignment_id) as $user_id => $team_id) {
53 $teams[$team_id][] = $user_id;
54 }
55
56 $res = array();
57 foreach ($teams as $team_id => $members) {
58 $team = new self();
59 $team->id = $team_id;
60 $team->assignment_id = $a_assignment_id;
61 $team->members = $members;
62 $res[$team_id] = $team;
63 }
64
65 return $res;
66 }
67
68 public function getId()
69 {
70 return $this->id;
71 }
72
73 private function setId($a_id)
74 {
75 $this->id = $a_id;
76 }
77
78 protected function read($a_id)
79 {
81
82 // #18094
83 $this->members = array();
84
85 $sql = "SELECT * FROM il_exc_team" .
86 " WHERE id = " . $ilDB->quote($a_id, "integer");
87 $set = $ilDB->query($sql);
88 if ($ilDB->numRows($set)) {
89 $this->setId($a_id);
90
91 while ($row = $ilDB->fetchAssoc($set)) {
92 $this->assignment_id = $row["ass_id"];
93 $this->members[] = $row["user_id"];
94 }
95 }
96 }
97
107 public static function getTeamId($a_assignment_id, $a_user_id, $a_create_on_demand = false)
108 {
109 global $DIC;
110
111 $ilDB = $DIC->database();
112
113 $sql = "SELECT id FROM il_exc_team" .
114 " WHERE ass_id = " . $ilDB->quote($a_assignment_id, "integer") .
115 " AND user_id = " . $ilDB->quote($a_user_id, "integer");
116 $set = $ilDB->query($sql);
117 $row = $ilDB->fetchAssoc($set);
118 $id = $row["id"];
119
120 if (!$id && $a_create_on_demand) {
121 $id = $ilDB->nextId("il_exc_team");
122
123 // get starting timestamp (relative deadlines) from individual deadline
124 $idl = ilExcIndividualDeadline::getInstance($a_assignment_id, $a_user_id);
125
126 $fields = array("id" => array("integer", $id),
127 "ass_id" => array("integer", $a_assignment_id),
128 "user_id" => array("integer", $a_user_id));
129 $ilDB->insert("il_exc_team", $fields);
130
131 // set starting timestamp for created team
132 if ($idl->getStartingTimestamp() > 0) {
133 $idl_team = ilExcIndividualDeadline::getInstance($a_assignment_id, $id, true);
134 $idl_team->setStartingTimestamp($idl->getStartingTimestamp());
135 $idl_team->save();
136 }
137
138 self::writeTeamLog($id, self::TEAM_LOG_CREATE_TEAM);
140 $id,
141 self::TEAM_LOG_ADD_MEMBER,
143 );
144 }
145
146 return $id;
147 }
148
149 public function createTeam($a_assignment_id, $a_user_id)
150 {
152 $id = $ilDB->nextId("il_exc_team");
153 $fields = array("id" => array("integer", $id),
154 "ass_id" => array("integer", $a_assignment_id),
155 "user_id" => array("integer", $a_user_id));
156 $ilDB->insert("il_exc_team", $fields);
157 self::writeTeamLog($id, self::TEAM_LOG_CREATE_TEAM);
159 $id,
160 self::TEAM_LOG_ADD_MEMBER,
162 );
163 return $id;
164 }
165
171 public function getMembers()
172 {
173 return $this->members;
174 }
175
181 public function getMembersOfAllTeams()
182 {
184
185 $ids = array();
186
187 $sql = "SELECT user_id" .
188 " FROM il_exc_team" .
189 " WHERE ass_id = " . $ilDB->quote($this->assignment_id, "integer");
190 $set = $ilDB->query($sql);
191 while ($row = $ilDB->fetchAssoc($set)) {
192 $ids[] = $row["user_id"];
193 }
194
195 return $ids;
196 }
197
204 public function addTeamMember($a_user_id, $a_exc_ref_id = null)
205 {
207
208 if (!$this->id) {
209 return false;
210 }
211
212 // must not be in any team already
213 if (!in_array($a_user_id, $this->getMembersOfAllTeams())) {
214 $fields = array("id" => array("integer", $this->id),
215 "ass_id" => array("integer", $this->assignment_id),
216 "user_id" => array("integer", $a_user_id));
217 $ilDB->insert("il_exc_team", $fields);
218
219 if ($a_exc_ref_id) {
220 $this->sendNotification($a_exc_ref_id, $a_user_id, "add");
221 }
222
223 $this->writeLog(
224 self::TEAM_LOG_ADD_MEMBER,
226 );
227
228 $this->read($this->id);
229
230 return true;
231 }
232
233 return false;
234 }
235
242 public function removeTeamMember($a_user_id, $a_exc_ref_id = null)
243 {
245
246 if (!$this->id) {
247 return;
248 }
249
250 $sql = "DELETE FROM il_exc_team" .
251 " WHERE ass_id = " . $ilDB->quote($this->assignment_id, "integer") .
252 " AND id = " . $ilDB->quote($this->id, "integer") .
253 " AND user_id = " . $ilDB->quote($a_user_id, "integer");
254 $ilDB->manipulate($sql);
255
256 if ($a_exc_ref_id) {
257 $this->sendNotification($a_exc_ref_id, $a_user_id, "rmv");
258 }
259
260 $this->writeLog(
261 self::TEAM_LOG_REMOVE_MEMBER,
263 );
264
265 $this->read($this->id);
266 }
267
274 public static function getAssignmentTeamMap($a_ass_id)
275 {
276 global $DIC;
277
278 $ilDB = $DIC->database();
279
280 $map = array();
281
282 $sql = "SELECT * FROM il_exc_team" .
283 " WHERE ass_id = " . $ilDB->quote($a_ass_id, "integer");
284 $set = $ilDB->query($sql);
285 while ($row = $ilDB->fetchAssoc($set)) {
286 $map[$row["user_id"]] = $row["id"];
287 }
288
289 return $map;
290 }
291
292 public function writeLog($a_action, $a_details = null)
293 {
294 self::writeTeamLog($this->id, $a_action, $a_details);
295 }
296
304 public static function writeTeamLog($a_team_id, $a_action, $a_details = null)
305 {
306 global $DIC;
307
308 $ilDB = $DIC->database();
309 $ilUser = $DIC->user();
310 $id = $ilDB->nextId('il_exc_team_log');
311
312 $fields = array(
313 "log_id" => array("integer", $id),
314 "team_id" => array("integer", $a_team_id),
315 "user_id" => array("integer", $ilUser->getId()),
316 "action" => array("integer", $a_action),
317 "details" => array("text", $a_details),
318 "tstamp" => array("integer", time())
319 );
320
321 $ilDB->insert("il_exc_team_log", $fields);
322 }
323
330 public function getLog()
331 {
333
334 $this->cleanLog();
335
336 $res = array();
337
338 $sql = "SELECT * FROM il_exc_team_log" .
339 " WHERE team_id = " . $ilDB->quote($this->id, "integer") .
340 " ORDER BY tstamp DESC";
341 $set = $ilDB->query($sql);
342 while ($row = $ilDB->fetchAssoc($set)) {
343 $res[] = $row;
344 }
345 return $res;
346 }
347
353 protected function cleanLog()
354 {
356
357 // #18179
358
359 // see also #31565
360 $obsolete_teams = [];
361 $set = $ilDB->query("SELECT DISTINCT l.team_id as id FROM il_exc_team_log as l LEFT JOIN il_exc_team as t ON (l.team_id = t.id) WHERE t.id IS NULL;");
362 while ($row = $ilDB->fetchAssoc($set)) {
363 $obsolete_teams[] = $row["id"];
364 }
365
366 if (count($obsolete_teams) > 0) {
367 $q = "DELETE FROM il_exc_team_log" .
368 " WHERE " . $ilDB->in("team_id", $obsolete_teams, false, "integer");
369 $ilDB->manipulate($q);
370 }
371 }
372
380 public function sendNotification($a_exc_ref_id, $a_user_id, $a_action)
381 {
383
384 // no need to notify current user
385 if (!$a_exc_ref_id ||
386 $ilUser->getId() == $a_user_id) {
387 return;
388 }
389
390 $ass = new ilExAssignment($this->assignment_id);
391
392 $ntf = new ilSystemNotification();
393 $ntf->setLangModules(array("exc"));
394 $ntf->setRefId($a_exc_ref_id);
395 $ntf->setChangedByUserId($ilUser->getId());
396 $ntf->setSubjectLangId('exc_team_notification_subject_' . $a_action);
397 $ntf->setIntroductionLangId('exc_team_notification_body_' . $a_action);
398 $ntf->addAdditionalInfo("exc_assignment", $ass->getTitle());
399 $ntf->setGotoLangId('exc_team_notification_link');
400 $ntf->setReasonLangId('exc_team_notification_reason');
401 $ntf->sendMail(array($a_user_id));
402 }
403
404
405 public static function getAdoptableTeamAssignments($a_exercise_id, $a_exclude_ass_id = null, $a_user_id = null)
406 {
407 $res = array();
408
410 foreach ($data as $row) {
411 if ($a_exclude_ass_id && $row["id"] == $a_exclude_ass_id) {
412 continue;
413 }
414
415 if ($row["type"] == ilExAssignment::TYPE_UPLOAD_TEAM) {
416 $map = self::getAssignmentTeamMap($row["id"]);
417
418 if ($a_user_id && !array_key_exists($a_user_id, $map)) {
419 continue;
420 }
421
422 if (sizeof($map)) {
423 $user_team = null;
424 if ($a_user_id) {
425 $user_team_id = $map[$a_user_id];
426 $user_team = array();
427 foreach ($map as $user_id => $team_id) {
428 if ($user_id != $a_user_id &&
429 $user_team_id == $team_id) {
430 $user_team[] = $user_id;
431 }
432 }
433 }
434
435 if (!$a_user_id ||
436 sizeof($user_team)) {
437 $res[$row["id"]] = array(
438 "title" => $row["title"],
439 "teams" => sizeof(array_flip($map)),
440 );
441
442 if ($a_user_id) {
443 $res[$row["id"]]["user_team"] = $user_team;
444 }
445 }
446 }
447 }
448 }
449
450 return ilUtil::sortArray($res, "title", "asc", false, true);
451 }
452
453 public static function adoptTeams($a_source_ass_id, $a_target_ass_id, $a_user_id = null, $a_exc_ref_id = null)
454 {
455 $teams = array();
456
457 $old_team = null;
458 foreach (self::getAssignmentTeamMap($a_source_ass_id) as $user_id => $team_id) {
459 $teams[$team_id][] = $user_id;
460
461 if ($a_user_id && $user_id == $a_user_id) {
462 $old_team = $team_id;
463 }
464 }
465
466 if ($a_user_id) {
467 // no existing team (in source) or user already in team (in current)
468 if (!$old_team ||
469 self::getInstanceByUserId($a_target_ass_id, $a_user_id)->getId()) {
470 return;
471 }
472 }
473
474 $current_map = self::getAssignmentTeamMap($a_target_ass_id);
475
476 foreach ($teams as $team_id => $user_ids) {
477 if (!$old_team || $team_id == $old_team) {
478 // only not assigned users
479 $missing = array();
480 foreach ($user_ids as $user_id) {
481 if (!array_key_exists($user_id, $current_map)) {
482 $missing[] = $user_id;
483 }
484 }
485
486 if (sizeof($missing)) {
487 // create new team
488 $first = array_shift($missing);
489 $new_team = self::getInstanceByUserId($a_target_ass_id, $first, true);
490
491 // give new team starting time of original user
492 if ($a_user_id > 0 && $old_team > 0) {
493 $idl = ilExcIndividualDeadline::getInstance($a_target_ass_id, $a_user_id);
494 if ($idl->getStartingTimestamp()) {
495 $idl_team = ilExcIndividualDeadline::getInstance($a_target_ass_id, $new_team->getId(), true);
496 $idl_team->setStartingTimestamp($idl->getStartingTimestamp());
497 $idl_team->save();
498 }
499 }
500
501 if ($a_exc_ref_id) {
502 // getTeamId() does NOT send notification
503 $new_team->sendNotification($a_exc_ref_id, $first, "add");
504 }
505
506 foreach ($missing as $user_id) {
507 $new_team->addTeamMember($user_id, $a_exc_ref_id);
508 }
509 }
510 }
511 }
512 }
513
514 //
515 // GROUPS
516 //
517
518 public static function getAdoptableGroups($a_exc_ref_id)
519 {
520 global $DIC;
521
522 $tree = $DIC->repositoryTree();
523
524 $res = array();
525
526 $parent_ref_id = $tree->getParentId($a_exc_ref_id);
527 if ($parent_ref_id) {
528 foreach ($tree->getChildsByType($parent_ref_id, "grp") as $group) {
529 $res[] = $group["obj_id"];
530 }
531 }
532
533 return $res;
534 }
535
536 public static function getGroupMembersMap($a_exc_ref_id)
537 {
538 $res = array();
539
540 foreach (self::getAdoptableGroups($a_exc_ref_id) as $grp_obj_id) {
541 $members_obj = new ilGroupParticipants($grp_obj_id);
542
543 $res[$grp_obj_id] = array(
544 "title" => ilObject::_lookupTitle($grp_obj_id)
545 ,"members" => $members_obj->getMembers()
546 );
547 }
548
549 return ilUtil::sortArray($res, "title", "asc", false, true);
550 }
551
566 public function createRandomTeams($a_exercise_id, $a_assignment_id, $a_number_teams, $a_min_participants)
567 {
568 //just in case...
569 if (count(self::getAssignmentTeamMap($a_assignment_id))) {
570 return false;
571 }
572 $exercise = new ilObjExercise($a_exercise_id, false);
573 $obj_exc_members = new ilExerciseMembers($exercise);
574 $members = $obj_exc_members->getMembers();
575 $total_exc_members = count($members);
576 $number_of_teams = $a_number_teams;
577 if (!$number_of_teams) {
578 if ($a_min_participants) {
579 $number_of_teams = round($total_exc_members / $a_min_participants);
580 } else {
581 $number_of_teams = random_int(1, $total_exc_members);
582 }
583 }
584 $members_per_team = round($total_exc_members / $number_of_teams);
585 shuffle($members);
586 for ($i = 0;$i < $number_of_teams;$i++) {
587 $members_counter = 0;
588 while (!empty($members) && $members_counter < $members_per_team) {
589 $member_id = array_pop($members);
590 if ($members_counter == 0) {
591 $team_id = $this->createTeam($a_assignment_id, $member_id);
592 $this->setId($team_id);
593 $this->assignment_id = $a_assignment_id;
594 } else {
595 $this->addTeamMember($member_id);
596 }
597 $members_counter++;
598 }
599 }
600 //get the new teams, remove duplicates.
601 $teams = array_unique(array_values(self::getAssignmentTeamMap($a_assignment_id)));
602 shuffle($teams);
603 while (!empty($members)) {
604 $member_id = array_pop($members);
605 $team_id = array_pop($teams);
606 $this->setId($team_id);
607 $this->addTeamMember($member_id);
608 }
609 return true;
610 }
611}
user()
Definition: user.php:4
An exception for terminatinating execution or to throw for unit testing.
Exercise assignment team.
sendNotification($a_exc_ref_id, $a_user_id, $a_action)
Send notification about team status.
getMembers()
Get members of assignment team.
addTeamMember($a_user_id, $a_exc_ref_id=null)
Add new member to team.
createTeam($a_assignment_id, $a_user_id)
static getAdoptableGroups($a_exc_ref_id)
createRandomTeams($a_exercise_id, $a_assignment_id, $a_number_teams, $a_min_participants)
Create random teams for assignment type "team upload" following specific rules.
getMembersOfAllTeams()
Get members for all teams of assignment.
getLog()
Get all log entries for team.
writeLog($a_action, $a_details=null)
static getGroupMembersMap($a_exc_ref_id)
removeTeamMember($a_user_id, $a_exc_ref_id=null)
Remove member from team.
static getAssignmentTeamMap($a_ass_id)
Get team structure for assignment.
static getInstanceByUserId($a_assignment_id, $a_user_id, $a_create_on_demand=false)
static getInstancesFromMap($a_assignment_id)
static getTeamId($a_assignment_id, $a_user_id, $a_create_on_demand=false)
Get team id for member id.
static getAdoptableTeamAssignments($a_exercise_id, $a_exclude_ass_id=null, $a_user_id=null)
static writeTeamLog($a_team_id, $a_action, $a_details=null)
Add entry to team log.
cleanLog()
Remove obsolete log entries.
static adoptTeams($a_source_ass_id, $a_target_ass_id, $a_user_id=null, $a_exc_ref_id=null)
Exercise assignment.
static getAssignmentDataOfExercise($a_exc_id)
Get assignments data of an exercise in an array.
static getInstance($a_ass_id, $a_participant_id, $a_is_team=false)
Get instance.
Class ilExerciseMembers.
Class ilObjExercise.
static _lookupFullname($a_user_id)
Lookup Full Name.
static _lookupTitle($a_id)
lookup object title
Wrapper classes for system notifications.
static sortArray( $array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
global $DIC
Definition: goto.php:24
$ilUser
Definition: imgupload.php:18
$i
Definition: metadata.php:24
foreach($_POST as $key=> $value) $res
global $ilDB
$data
Definition: storeScorm.php:23