ILIAS  release_8 Revision v8.24
class.ilExAssignmentTeam.php
Go to the documentation of this file.
1<?php
2
26{
27 public const TEAM_LOG_CREATE_TEAM = 1;
28 public const TEAM_LOG_ADD_MEMBER = 2;
29 public const TEAM_LOG_REMOVE_MEMBER = 3;
30 public const TEAM_LOG_ADD_FILE = 4;
31 public const TEAM_LOG_REMOVE_FILE = 5;
32
33 protected ilDBInterface $db;
34 protected ilObjUser $user;
35 protected ?int $id = null;
36 protected int $assignment_id;
37 protected array $members = array();
38
39 public function __construct(?int $a_id = null)
40 {
41 global $DIC;
42
43 $this->db = $DIC->database();
44 $this->user = $DIC->user();
45 if ($a_id) {
46 $this->read($a_id);
47 }
48 }
49
50 public static function getInstanceByUserId(
51 int $a_assignment_id,
52 int $a_user_id,
53 bool $a_create_on_demand = false
54 ): self {
55 $id = self::getTeamId($a_assignment_id, $a_user_id, $a_create_on_demand);
56 return new self($id);
57 }
58
59 public static function getInstancesFromMap(int $a_assignment_id): array
60 {
61 $teams = array();
62 foreach (self::getAssignmentTeamMap($a_assignment_id) as $user_id => $team_id) {
63 $teams[$team_id][] = $user_id;
64 }
65
66 $res = array();
67 foreach ($teams as $team_id => $members) {
68 $team = new self();
69 $team->id = $team_id;
70 $team->assignment_id = $a_assignment_id;
71 $team->members = $members;
72 $res[$team_id] = $team;
73 }
74
75 return $res;
76 }
77
78 public function getId(): ?int
79 {
80 return $this->id;
81 }
82
83 private function setId(?int $a_id): void
84 {
85 $this->id = $a_id;
86 }
87
88 protected function read(int $a_id): void
89 {
90 $ilDB = $this->db;
91
92 // #18094
93 $this->members = array();
94
95 $sql = "SELECT * FROM il_exc_team" .
96 " WHERE id = " . $ilDB->quote($a_id, "integer");
97 $set = $ilDB->query($sql);
98 if ($ilDB->numRows($set)) {
99 $this->setId($a_id);
100
101 while ($row = $ilDB->fetchAssoc($set)) {
102 $this->assignment_id = $row["ass_id"];
103 $this->members[] = $row["user_id"];
104 }
105 }
106 }
107
108 // Get team id for member id
109 public static function getTeamId(
110 int $a_assignment_id,
111 int $a_user_id,
112 bool $a_create_on_demand = false
113 ): ?int {
114 global $DIC;
115
116 $ilDB = $DIC->database();
117
118 $sql = "SELECT id FROM il_exc_team" .
119 " WHERE ass_id = " . $ilDB->quote($a_assignment_id, "integer") .
120 " AND user_id = " . $ilDB->quote($a_user_id, "integer");
121 $set = $ilDB->query($sql);
122 $id = null;
123 if ($row = $ilDB->fetchAssoc($set)) {
124 $id = $row["id"];
125 }
126
127 if (!$id && $a_create_on_demand) {
128 $id = $ilDB->nextId("il_exc_team");
129
130 // get starting timestamp (relative deadlines) from individual deadline
131 $idl = ilExcIndividualDeadline::getInstance($a_assignment_id, $a_user_id);
132
133 $fields = array("id" => array("integer", $id),
134 "ass_id" => array("integer", $a_assignment_id),
135 "user_id" => array("integer", $a_user_id));
136 $ilDB->insert("il_exc_team", $fields);
137
138 // set starting timestamp for created team
139 if ($idl->getStartingTimestamp() > 0) {
140 $idl_team = ilExcIndividualDeadline::getInstance($a_assignment_id, $id, true);
141 $idl_team->setStartingTimestamp($idl->getStartingTimestamp());
142 $idl_team->save();
143 }
144
145 self::writeTeamLog($id, self::TEAM_LOG_CREATE_TEAM);
146 self::writeTeamLog(
147 $id,
148 self::TEAM_LOG_ADD_MEMBER,
150 );
151 }
152
153 return $id;
154 }
155
156 public function createTeam(
157 int $a_assignment_id,
158 int $a_user_id
159 ): int {
160 $ilDB = $this->db;
161 $id = $ilDB->nextId("il_exc_team");
162 $fields = array("id" => array("integer", $id),
163 "ass_id" => array("integer", $a_assignment_id),
164 "user_id" => array("integer", $a_user_id));
165 $ilDB->insert("il_exc_team", $fields);
166 self::writeTeamLog($id, self::TEAM_LOG_CREATE_TEAM);
167 self::writeTeamLog(
168 $id,
169 self::TEAM_LOG_ADD_MEMBER,
171 );
172 return $id;
173 }
174
175 // Get members of assignment team
176 public function getMembers(): array
177 {
178 return $this->members;
179 }
180
185 public function getMembersOfAllTeams(): array
186 {
187 $ilDB = $this->db;
188
189 $ids = array();
190
191 $sql = "SELECT user_id" .
192 " FROM il_exc_team" .
193 " WHERE ass_id = " . $ilDB->quote($this->assignment_id, "integer");
194 $set = $ilDB->query($sql);
195 while ($row = $ilDB->fetchAssoc($set)) {
196 $ids[] = $row["user_id"];
197 }
198
199 return $ids;
200 }
201
202 // Add new member to team
203
207 public function addTeamMember(
208 int $a_user_id,
209 ?int $a_exc_ref_id = null
210 ): bool {
211 $ilDB = $this->db;
212
213 if (!$this->id) {
214 return false;
215 }
216
217 // must not be in any team already
218 if (!in_array($a_user_id, $this->getMembersOfAllTeams())) {
219 $fields = array("id" => array("integer", $this->id),
220 "ass_id" => array("integer", $this->assignment_id),
221 "user_id" => array("integer", $a_user_id));
222 $ilDB->insert("il_exc_team", $fields);
223
224 if ($a_exc_ref_id) {
225 $this->sendNotification($a_exc_ref_id, $a_user_id, "add");
226 }
227
228 $this->writeLog(
229 self::TEAM_LOG_ADD_MEMBER,
231 );
232
233 $this->read($this->id);
234
235 return true;
236 }
237
238 return false;
239 }
240
244 public function removeTeamMember(
245 int $a_user_id,
246 ?int $a_exc_ref_id = null
247 ): void {
248 $ilDB = $this->db;
249
250 if (!$this->id) {
251 return;
252 }
253
254 $sql = "DELETE FROM il_exc_team" .
255 " WHERE ass_id = " . $ilDB->quote($this->assignment_id, "integer") .
256 " AND id = " . $ilDB->quote($this->id, "integer") .
257 " AND user_id = " . $ilDB->quote($a_user_id, "integer");
258 $ilDB->manipulate($sql);
259
260 if ($a_exc_ref_id) {
261 $this->sendNotification($a_exc_ref_id, $a_user_id, "rmv");
262 }
263
264 $this->writeLog(
265 self::TEAM_LOG_REMOVE_MEMBER,
267 );
268
269 $this->read($this->id);
270 }
271
272 // Get team structure for assignment
273 public static function getAssignmentTeamMap(int $a_ass_id): array
274 {
275 global $DIC;
276
277 $ilDB = $DIC->database();
278
279 $map = array();
280
281 $sql = "SELECT * FROM il_exc_team" .
282 " WHERE ass_id = " . $ilDB->quote($a_ass_id, "integer");
283 $set = $ilDB->query($sql);
284 while ($row = $ilDB->fetchAssoc($set)) {
285 $map[$row["user_id"]] = $row["id"];
286 }
287
288 return $map;
289 }
290
291 public function writeLog(
292 string $a_action,
293 string $a_details = null
294 ): void {
295 self::writeTeamLog($this->id, $a_action, $a_details);
296 }
297
301 public static function writeTeamLog(
302 int $a_team_id,
303 string $a_action,
304 string $a_details = null
305 ): void {
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
324 // Get all log entries for team
325 public function getLog(): array
326 {
327 $ilDB = $this->db;
328
329 $this->cleanLog();
330
331 $res = array();
332
333 $sql = "SELECT * FROM il_exc_team_log" .
334 " WHERE team_id = " . $ilDB->quote($this->id, "integer") .
335 " ORDER BY tstamp DESC";
336 $set = $ilDB->query($sql);
337 while ($row = $ilDB->fetchAssoc($set)) {
338 $res[] = $row;
339 }
340 return $res;
341 }
342
348 protected function cleanLog(): void
349 {
350 $ilDB = $this->db;
351
352 // #18179
353
354 // see also #31565
355 $obsolete_teams = [];
356 $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;");
357 while ($row = $ilDB->fetchAssoc($set)) {
358 $obsolete_teams[] = $row["id"];
359 }
360
361 if (count($obsolete_teams) > 0) {
362 $q = "DELETE FROM il_exc_team_log" .
363 " WHERE " . $ilDB->in("team_id", $obsolete_teams, false, "integer");
364 $ilDB->manipulate($q);
365 }
366 }
367
372 public function sendNotification(
373 int $a_exc_ref_id,
374 int $a_user_id,
375 string $a_action
376 ): void {
377 $ilUser = $this->user;
378
379 // no need to notify current user
380 if (!$a_exc_ref_id ||
381 $ilUser->getId() == $a_user_id) {
382 return;
383 }
384 $ass = new ilExAssignment($this->assignment_id);
385
386 $ntf = new ilSystemNotification();
387 $ntf->setLangModules(array("exc"));
388 $ntf->setRefId($a_exc_ref_id);
389 $ntf->setChangedByUserId($ilUser->getId());
390 $ntf->setSubjectLangId('exc_team_notification_subject_' . $a_action);
391 $ntf->setIntroductionLangId('exc_team_notification_body_' . $a_action);
392 $ntf->addAdditionalInfo("exc_assignment", $ass->getTitle());
393 $ntf->setGotoLangId('exc_team_notification_link');
394 $ntf->setReasonLangId('exc_team_notification_reason');
395 $ntf->sendMailAndReturnRecipients(array($a_user_id));
396 }
397
398
399 public static function getAdoptableTeamAssignments(
400 int $a_exercise_id,
401 int $a_exclude_ass_id = null,
402 int $a_user_id = null
403 ): array {
404 $res = array();
405
407 foreach ($data as $row) {
408 if ($a_exclude_ass_id && $row["id"] == $a_exclude_ass_id) {
409 continue;
410 }
411
412 if ($row["type"] == ilExAssignment::TYPE_UPLOAD_TEAM) {
413 $map = self::getAssignmentTeamMap($row["id"]);
414
415 if ($a_user_id && !array_key_exists($a_user_id, $map)) {
416 continue;
417 }
418
419 if ($map !== []) {
420 $user_team = null;
421 if ($a_user_id) {
422 $user_team_id = $map[$a_user_id];
423 $user_team = array();
424 foreach ($map as $user_id => $team_id) {
425 if ($user_id != $a_user_id &&
426 $user_team_id == $team_id) {
427 $user_team[] = $user_id;
428 }
429 }
430 }
431
432 if (!$a_user_id ||
433 count($user_team)) {
434 $res[$row["id"]] = array(
435 "title" => $row["title"],
436 "teams" => count(array_flip($map)),
437 );
438
439 if ($a_user_id) {
440 $res[$row["id"]]["user_team"] = $user_team;
441 }
442 }
443 }
444 }
445 }
446
447 return ilArrayUtil::sortArray($res, "title", "asc", false, true);
448 }
449
453 public static function adoptTeams(
454 int $a_source_ass_id,
455 int $a_target_ass_id,
456 int $a_user_id = null,
457 int $a_exc_ref_id = null
458 ): void {
459 $teams = array();
460
461 $old_team = null;
462 foreach (self::getAssignmentTeamMap($a_source_ass_id) as $user_id => $team_id) {
463 $teams[$team_id][] = $user_id;
464
465 if ($a_user_id && $user_id == $a_user_id) {
466 $old_team = $team_id;
467 }
468 }
469
470 if ($a_user_id) {
471 // no existing team (in source) or user already in team (in current)
472 if (!$old_team ||
473 self::getInstanceByUserId($a_target_ass_id, $a_user_id)->getId()) {
474 return;
475 }
476 }
477
478 $current_map = self::getAssignmentTeamMap($a_target_ass_id);
479
480 foreach ($teams as $team_id => $user_ids) {
481 if (!$old_team || $team_id == $old_team) {
482 // only not assigned users
483 $missing = array();
484 foreach ($user_ids as $user_id) {
485 if (!array_key_exists($user_id, $current_map)) {
486 $missing[] = $user_id;
487 }
488 }
489
490 if ($missing !== []) {
491 // create new team
492 $first = array_shift($missing);
493 $new_team = self::getInstanceByUserId($a_target_ass_id, $first, true);
494
495 // give new team starting time of original user
496 if ($a_user_id > 0 && $old_team > 0) {
497 $idl = ilExcIndividualDeadline::getInstance($a_target_ass_id, $a_user_id);
498 if ($idl->getStartingTimestamp()) {
499 $idl_team = ilExcIndividualDeadline::getInstance($a_target_ass_id, $new_team->getId(), true);
500 $idl_team->setStartingTimestamp($idl->getStartingTimestamp());
501 $idl_team->save();
502 }
503 }
504
505 if ($a_exc_ref_id) {
506 // getTeamId() does NOT send notification
507 $new_team->sendNotification($a_exc_ref_id, $first, "add");
508 }
509
510 foreach ($missing as $user_id) {
511 $new_team->addTeamMember($user_id, $a_exc_ref_id);
512 }
513 }
514 }
515 }
516 }
517
518 //
519 // GROUPS
520 //
521
526 public static function getAdoptableGroups(int $a_exc_ref_id): array
527 {
528 global $DIC;
529
530 $tree = $DIC->repositoryTree();
531
532 $res = array();
533
534 $parent_ref_id = $tree->getParentId($a_exc_ref_id);
535 if ($parent_ref_id) {
536 foreach ($tree->getChildsByType($parent_ref_id, "grp") as $group) {
537 $res[] = $group["obj_id"];
538 }
539 }
540
541 return $res;
542 }
543
544 public static function getGroupMembersMap(int $a_exc_ref_id): array
545 {
546 $res = array();
547
548 foreach (self::getAdoptableGroups($a_exc_ref_id) as $grp_obj_id) {
549 $members_obj = new ilGroupParticipants($grp_obj_id);
550
551 $res[$grp_obj_id] = array(
552 "title" => ilObject::_lookupTitle($grp_obj_id)
553 ,"members" => $members_obj->getMembers()
554 );
555 }
556
557 return ilArrayUtil::sortArray($res, "title", "asc", false, true);
558 }
559
571 public function createRandomTeams(
572 int $a_exercise_id,
573 int $a_assignment_id,
574 int $a_number_teams,
575 int $a_min_participants
576 ): void {
577 //just in case...
578 if (count(self::getAssignmentTeamMap($a_assignment_id))) {
579 return;
580 }
581 $exercise = new ilObjExercise($a_exercise_id, false);
582 $obj_exc_members = new ilExerciseMembers($exercise);
583 $members = $obj_exc_members->getMembers();
584 $total_exc_members = count($members);
585 $number_of_teams = $a_number_teams;
586 if (!$number_of_teams) {
587 if ($a_min_participants) {
588 $number_of_teams = round($total_exc_members / $a_min_participants);
589 } else {
590 $number_of_teams = random_int(1, $total_exc_members);
591 }
592 }
593 $members_per_team = round($total_exc_members / $number_of_teams);
594 shuffle($members);
595 for ($i = 0;$i < $number_of_teams;$i++) {
596 $members_counter = 0;
597 while (!empty($members) && $members_counter < $members_per_team) {
598 $member_id = array_pop($members);
599 if ($members_counter == 0) {
600 $team_id = $this->createTeam($a_assignment_id, $member_id);
601 $this->setId($team_id);
602 $this->assignment_id = $a_assignment_id;
603 } else {
604 $this->addTeamMember($member_id);
605 }
606 $members_counter++;
607 }
608 }
609 //get the new teams, remove duplicates.
610 $teams = array_unique(array_values(self::getAssignmentTeamMap($a_assignment_id)));
611 shuffle($teams);
612 while (!empty($members)) {
613 $member_id = array_pop($members);
614 $team_id = array_pop($teams);
615 $this->setId($team_id);
616 $this->addTeamMember($member_id);
617 }
618 }
619}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
writeLog(string $a_action, string $a_details=null)
static writeTeamLog(int $a_team_id, string $a_action, string $a_details=null)
Add entry to team log.
static adoptTeams(int $a_source_ass_id, int $a_target_ass_id, int $a_user_id=null, int $a_exc_ref_id=null)
static getAssignmentTeamMap(int $a_ass_id)
static getAdoptableGroups(int $a_exc_ref_id)
addTeamMember(int $a_user_id, ?int $a_exc_ref_id=null)
getMembersOfAllTeams()
Get members for all teams of assignment.
createTeam(int $a_assignment_id, int $a_user_id)
static getAdoptableTeamAssignments(int $a_exercise_id, int $a_exclude_ass_id=null, int $a_user_id=null)
sendNotification(int $a_exc_ref_id, int $a_user_id, string $a_action)
Send notification about team status.
static getInstanceByUserId(int $a_assignment_id, int $a_user_id, bool $a_create_on_demand=false)
static getTeamId(int $a_assignment_id, int $a_user_id, bool $a_create_on_demand=false)
removeTeamMember(int $a_user_id, ?int $a_exc_ref_id=null)
static getInstancesFromMap(int $a_assignment_id)
static getGroupMembersMap(int $a_exc_ref_id)
cleanLog()
Remove obsolete log entries.
createRandomTeams(int $a_exercise_id, int $a_assignment_id, int $a_number_teams, int $a_min_participants)
Create random teams for assignment type "team upload" following specific rules.
Exercise assignment.
static getAssignmentDataOfExercise(int $a_exc_id)
static getInstance(int $a_ass_id, int $a_participant_id, bool $a_is_team=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilObjExercise.
User class.
static _lookupFullname(int $a_user_id)
static _lookupTitle(int $obj_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
global $DIC
Definition: feed.php:28
$ilUser
Definition: imgupload.php:34
Interface ilDBInterface.
$res
Definition: ltiservices.php:69
$i
Definition: metadata.php:41