ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilStudyProgrammeMembersTableGUI.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 2015 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */
4
9{
10 const COLUMNS = [
11 //column, langvar, optional, if_lp_children, if_no_lp_children
12 ['name', 'name', false, true, true],
13 ['login', 'login', false, true, true],
14 ['prg_orgus', 'prg_orgus', true, true, true],
15 ['prg_status', 'prg_status', false, true, true],
16 ['prg_completion_date', 'prg_completion_date', true, true, true],
17 ['prg_completion_by', 'prg_completion_by', true, true, true],
18 ['points', 'prg_points_reachable', false, true, false],
19 ['points', 'prg_points_required', false, false, true],
20 ['points_current', 'prg_points_current', false, false, true],
21 ['prg_custom_plan', 'prg_custom_plan', true, true, true],
22 ['prg_belongs_to', 'prg_belongs_to', true, true, true],
23 ['prg_assign_date', 'prg_assign_date', false, true, true],
24 ['prg_assigned_by', 'prg_assigned_by', true, true, true],
25 ['prg_deadline', 'prg_deadline', true, true, true],
26 ['prg_expiry_date', 'prg_expiry_date', true, true, true],
27 ['prg_validity', 'prg_validity', true, true, true],
28 [null, 'action', false, true, true]
29 ];
30
31 const OPTION_ALL = -1;
34
38 protected $prg_obj_id;
39
43 protected $prg_ref_id;
44
49
53 protected $db;
54
58 protected $ui_factory;
59
63 protected $ui_renderer;
64
69
73 protected $prg;
74
78 protected $permissions;
79
84
89
90 public function __construct(
91 int $prg_obj_id,
92 int $prg_ref_id,
94 string $parent_cmd = '',
95 string $template_context = '',
98 \ILIAS\Data\Factory $data_factory
99 ) {
100 $this->setId("sp_member_list");
101 parent::__construct($parent_obj, $parent_cmd, $template_context);
102
103 $this->prg_obj_id = $prg_obj_id;
104 $this->prg_ref_id = $prg_ref_id;
105 $this->data_factory = $data_factory;
106 $this->permissions = $permissions;
107 $this->may_edit_anything = $this->permissions->mayAnyOf([ilOrgUnitOperation::OP_EDIT_INDIVIDUAL_PLAN, ilOrgUnitOperation::OP_MANAGE_MEMBERS]);
108 $this->user_ids_viewer_may_read_learning_progress_of = $this->permissions->getUserIdsSusceptibleTo(ilOrgUnitOperation::OP_READ_LEARNING_PROGRESS);
109
111 $this->prg_has_lp_children = $parent_obj->getStudyProgramme()->hasLPChildren();
112
113 global $DIC;
114 $this->db = $DIC['ilDB'];
115 $this->ui_factory = $DIC['ui.factory'];
116 $this->ui_renderer = $DIC['ui.renderer'];
117
118 $this->setEnableTitle(true);
119 $this->setTopCommands(false);
120 $this->setEnableHeader(true);
121 $this->setExternalSorting(true);
122 $this->setExternalSegmentation(true);
123 $this->setRowTemplate("tpl.members_table_row.html", "Modules/StudyProgramme");
124 $this->setShowRowsSelector(false);
125 $this->setFormAction($this->ctrl->getFormAction($parent_obj, "view"));
126 $this->addColumn("", "", "1", true);
127 $this->setEnableAllCommand(true);
128 $this->addMultiCommands();
129 $this->setDefaultOrderField('prgrs_id');
130 $this->setDefaultOrderDirection('ASC');
131
132 if ($this->may_edit_anything) {
133 $this->setSelectAllCheckbox($parent_obj::F_SELECTED_PROGRESS_IDS . '[]');
134 }
135
136 $selected = $this->getSelectedColumns();
137 foreach (self::COLUMNS as $column) {
138 list($col, $lng_var, $optional, $lp, $no_lp) = $column;
139
140 $show_by_lp = ($this->prg_has_lp_children && $lp) || (!$this->prg_has_lp_children && $no_lp);
141 $show_optional = !$optional || ($optional && array_key_exists($col, $selected));
142
143 if ($show_by_lp && $show_optional) {
144 $this->addColumn($this->lng->txt($lng_var), $col);
145 }
146 }
147
148 $this->sp_user_progress_db = $sp_user_progress_db;
149
150 $this->initFilter();
151 $filter_values = $this->getFilterValues();
152
154 $this->determineLimit();
155
156
157 $members_list = $this->fetchData(
158 $prg_obj_id,
159 $this->getLimit(),
160 $this->getOffset(),
161 $filter_values
162 );
163
164 $progress_ids = array_map(
165 function ($row) {
166 return (int) $row['prgrs_id'];
167 },
168 $members_list
169 );
170 $this->addHiddenInput(
171 $parent_obj::F_ALL_PROGRESS_IDS,
172 implode(',', $progress_ids)
173 );
174
175 $this->setMaxCount($this->countFetchData($prg_obj_id, $filter_values));
176 $this->setData(
177 $this->postOrder(
178 $members_list,
179 $this->getOrdering()
180 )
181 );
182 }
183
184
186 'prg_status' => 'status',
187 'prg_custom_plan' => 'custom_plan',
188 'prg_belongs_to' => 'belongs_to',
189 'prg_expiry_date' => 'vq_date',
190 'prg_orgus' => 'orgus',
191 'prg_completion_by' => 'completion_by',
192 'prg_completion_date' => 'completion_date',
193 ];
194
195 protected function postOrder(array $list, \ILIAS\Data\Order $order) : array
196 {
197 list($aspect, $direction) = $order->join('', function ($i, $k, $v) {
198 return [$k, $v];
199 });
200
201 if (array_key_exists($aspect, self::ORDER_MAPPING)) {
202 $aspect = self::ORDER_MAPPING[$aspect];
203 }
204
205 usort($list, function ($a, $b) use ($aspect) {
206 if (is_numeric($a[$aspect])) {
207 return $a[$aspect] > $b[$aspect];
208 }
209 return strcmp($a[$aspect], $b[$aspect]);
210 });
211
212 if ($direction === $order::DESC) {
213 $list = array_reverse($list);
214 }
215 return $list;
216 }
217
218 protected function getOrdering() : \ILIAS\Data\Order
219 {
220 $field = $this->getOrderField();
221 if (!$field) {
222 $field = $this->getDefaultOrderField();
223 }
224 $direction = $this->getOrderDirection();
225 if (!$direction) {
226 $direction = $this->getDefaultOrderDirection();
227 }
228
229 return $this->data_factory->order($field, strtoupper($direction));
230 }
231
232 protected function getUserDateFormat() : string
233 {
234 return ilCalendarUtil::getUserDateFormat(false, true);
235 }
236
237 protected function fillRow($a_set) : void
238 {
239 $usr_id = (int) $a_set['usr_id'];
240 if ($this->may_edit_anything) {
241 $this->tpl->setCurrentBlock("checkb");
242 $this->tpl->setVariable("ID", $a_set["prgrs_id"]);
243 $this->tpl->parseCurrentBlock();
244 }
245
246 $this->tpl->setVariable("FIRSTNAME", $a_set["firstname"]);
247 $this->tpl->setVariable("LASTNAME", $a_set["lastname"]);
248 $this->tpl->setVariable("LOGIN", $a_set["login"]);
249 $this->tpl->setVariable(
250 "STATUS",
252 in_array($usr_id, $this->user_ids_viewer_may_read_learning_progress_of),
253 $this->prg->statusToRepr($a_set["status"])
254 )
255 );
256 $this->tpl->setVariable("ASSIGN_DATE", $a_set["prg_assign_date"]);
257
258
259 $this->tpl->setVariable("POINTS_REQUIRED", $a_set["points_required"]);
260
261 if (!$this->prg_has_lp_children) {
262 $this->tpl->setCurrentBlock("points_current");
263 $this->tpl->setVariable(
264 "POINTS_CURRENT",
266 in_array($usr_id, $this->user_ids_viewer_may_read_learning_progress_of),
267 $a_set['points_current']
268 )
269 );
270 $this->tpl->parseCurrentBlock();
271 }
272
273
274 foreach ($this->getSelectedColumns() as $column) {
275 switch ($column) {
276 case "prg_orgus":
277 $this->tpl->setVariable("ORGUS", $a_set["orgus"]);
278 break;
279 case "prg_completion_date":
280 $completion_date = '';
281 if (in_array($usr_id, $this->user_ids_viewer_may_read_learning_progress_of)) {
282 $completion_date = $a_set["completion_date"];
283 }
284 $this->tpl->setVariable("COMPLETION_DATE", $completion_date);
285 break;
286
287 case "prg_completion_by":
288 if (is_null($a_set["completion_by"])) {
289 $this->tpl->touchBlock("comp_by");
290 } else {
291 $this->tpl->setVariable(
292 "COMPLETION_BY",
294 in_array($usr_id, $this->user_ids_viewer_may_read_learning_progress_of),
295 $a_set["completion_by"]
296 )
297 );
298 }
299
300 break;
301 case "prg_custom_plan":
302 $individual = $this->lng->txt("no");
303 if ($a_set["individual"]) {
304 $individual = $this->lng->txt("yes");
305 }
306
307 $this->tpl->setVariable(
308 "CUSTOM_PLAN",
309 $individual
310 );
311 break;
312
313 case "prg_belongs_to":
314 $this->tpl->setVariable("BELONGS_TO", $a_set["belongs_to"]);
315 break;
316 case "prg_expiry_date":
317 $this->tpl->setVariable(
318 "EXPIRY_DATE",
320 in_array($usr_id, $this->user_ids_viewer_may_read_learning_progress_of),
321 $a_set["vq_date"]
322 )
323 );
324 break;
325 case "prg_assigned_by":
326 $assigned_by = $a_set["prg_assigned_by"];
327 if (is_null($assigned_by)) {
329 $assignment_src = (int) $a_set['prg_assignment_origin'];
330 $assigned_by = $this->lng->txt('prg_autoassignment')
331 . ' ' . $this->lng->txt($srcs[$assignment_src]);
332 }
333 $this->tpl->setVariable("ASSIGNED_BY", $assigned_by);
334 break;
335 case "prg_deadline":
336 if (is_null($a_set["prg_deadline"])) {
337 $this->tpl->touchBlock("deadline");
338 } else {
339 $this->tpl->setVariable(
340 "DEADLINE",
342 in_array($usr_id, $this->user_ids_viewer_may_read_learning_progress_of),
343 $a_set["prg_deadline"]
344 )
345 );
346 }
347 break;
348 case "prg_validity":
349 $this->tpl->setVariable(
350 "VALIDITY",
352 in_array($usr_id, $this->user_ids_viewer_may_read_learning_progress_of),
353 $a_set['prg_validity']
354 )
355 );
356 break;
357
358 }
359 }
360 $this->tpl->setVariable(
361 "ACTIONS",
362 $this->buildActionDropDown(
363 $a_set["actions"],
364 $a_set["prgrs_id"],
365 $a_set["assignment_id"],
366 $usr_id
367 )
368 );
369 }
370
371 protected function getValueOrEmptyString(string $condition, string $value) : string
372 {
373 if ($condition) {
374 return $value;
375 }
376
377 return '';
378 }
379
383 protected function buildActionDropDown(
384 array $actions,
385 int $prgrs_id,
386 int $ass_id,
387 int $usr_id
388 ) : string {
389 $parent = $this->getParentObject();
391
392 $view_individual_plan = $this->permissions->may(ilOrgUnitOperation::OP_VIEW_INDIVIDUAL_PLAN);
393 $edit_individual_plan = $this->permissions->may(ilOrgUnitOperation::OP_EDIT_INDIVIDUAL_PLAN);
394 $addremove_users = $this->permissions->may(ilOrgUnitOperation::OP_MANAGE_MEMBERS);
395
396 foreach ($actions as $action) {
397 switch ($action) {
400 if (!$edit_individual_plan) {
401 continue 2;
402 }
403 break;
405 if (!$view_individual_plan) {
406 continue 2;
407 }
408 break;
409
411 if (!$addremove_users) {
412 continue 2;
413 }
414 break;
415 }
416
417 $target = $this->getLinkTargetForAction($action, $prgrs_id, $ass_id);
418 $l->addItem($this->lng->txt("prg_$action"), $action, $target);
419 }
420
421 return $l->getHTML();
422 }
423
427 protected function getLinkTargetForAction(string $action, int $prgrs_id, int $ass_id) : string
428 {
429 return $this->getParentObject()->getLinkTargetForAction($action, $prgrs_id, $ass_id);
430 }
431
432 protected function getCompletionLink(int $target_obj_id, int $target_ref_id) : string
433 {
434 $link = '?';
435 if (ilObject::_exists($target_ref_id, true) &&
436 is_null(ilObject::_lookupDeletedDate($target_ref_id))
437 ) {
438 $title = ilObject::_lookupTitle($target_obj_id);
439 $url = ilLink::_getStaticLink($target_ref_id, "crs");
440 $link = $this->ui_renderer->render($this->ui_factory->link()->standard($title, $url));
441 } else {
442 $del_data = \ilObjectDataDeletionLog::get($target_obj_id);
443 if ($del_data) {
444 $link = $del_data['title'];
445 }
446 }
447 return $link;
448 }
449
453 protected function fetchData(
454 int $prg_id,
455 int $limit = null,
456 int $offset = null,
457 array $filter = []
458 ) : array {
459 // TODO: Reimplement this in terms of ActiveRecord when innerjoin
460 // supports the required rename functionality
461
462 $accredited = $this->db->quote(ilStudyProgrammeProgress::STATUS_ACCREDITED, 'integer');
463
464 $sql =
465 "SELECT" . PHP_EOL
466 . "prgrs.id AS prgrs_id," . PHP_EOL
467 . "pcp.firstname," . PHP_EOL
468 . "pcp.lastname," . PHP_EOL
469 . "pcp.login," . PHP_EOL
470 . "pcp.usr_id," . PHP_EOL
471 . "prgrs.usr_id," . PHP_EOL
472 . "prgrs.points," . PHP_EOL
473 . "prgrs.points_cur * ABS(prgrs.status - $accredited) /" . PHP_EOL
474 . " (GREATEST(ABS(prgrs.status - $accredited),1))" . PHP_EOL
475 . "+ prgrs.points * (1 - ABS(prgrs.status - $accredited) /" . PHP_EOL
476 . " (GREATEST(ABS(prgrs.status - $accredited),1))) AS points_current," . PHP_EOL
477 . "prgrs.last_change_by," . PHP_EOL
478 . "prgrs.status," . PHP_EOL
479 . "prgrs.individual," . PHP_EOL
480 . "blngs.title AS belongs_to," . PHP_EOL
481 . "cmpl_usr.login AS accredited_by," . PHP_EOL
482 . "cmpl_obj.title AS completion_by," . PHP_EOL
483 . "cmpl_obj.type AS completion_by_type," . PHP_EOL
484 . "prgrs.completion_by AS completion_by_id," . PHP_EOL
485 . "prgrs.assignment_id AS assignment_id," . PHP_EOL
486 . "prgrs.completion_date," . PHP_EOL
487 . "prgrs.vq_date," . PHP_EOL
488 . "prgrs.deadline AS prg_deadline," . PHP_EOL
489 . "ass.root_prg_id AS root_prg_id," . PHP_EOL
490 . "ass.last_change AS prg_assign_date," . PHP_EOL
491 . "ass.last_change_by AS prg_assingment_origin," . PHP_EOL
492 . "ass_usr.login AS prg_assigned_by," . PHP_EOL
493 . "CONCAT(pcp.firstname, pcp.lastname) AS name," . PHP_EOL
494 . "prgrs.individual AS custom_plan" . PHP_EOL
495 ;
496
497 $sql .= $this->getFrom();
498 $sql .= $this->getWhere($prg_id);
499 $sql .= $this->getFilterWhere($filter);
500 $sql .= $this->getOrguValidUsersFilter();
501
502 if ($limit !== null) {
503 $this->db->setLimit($limit, $offset !== null ? $offset : 0);
504 }
505
506 $res = $this->db->query($sql);
507 $now = new DateTimeImmutable();
508 $members_list = array();
509
510 while ($rec = $this->db->fetchAssoc($res)) {
511 $progress_id = (int) $rec['prgrs_id'];
512 $progress = $this->sp_user_progress_db->get($progress_id);
513
514 $rec["actions"] = $this->getPossibleActions(
515 $prg_id,
516 $rec["root_prg_id"],
517 $rec["status"]
518 );
519
520 $prg = ilObjStudyProgramme::getInstanceByObjId($progress->getNodeId());
521
522 $rec['points_required'] = number_format($progress->getAmountOfPoints());
523 $rec['points_current'] = number_format($progress->getCurrentAmountOfPoints());
524
525 if ($rec["status"] == ilStudyProgrammeProgress::STATUS_COMPLETED) {
526 //If the status completed is set by crs reference
527 //use crs title
528 if ($rec["completion_by_type"] == "crsr") {
529 $completion_id = $rec["completion_by_id"];
530 $obj_id = ilContainerReference::_lookupTargetId($completion_id);
531 $ref_id = ilContainerReference::_lookupTargetRefId($completion_id);
532 $rec["completion_by"] = $this->getCompletionLink($obj_id, $ref_id);
533 }
534
535 // If the status completed and there is a non-null completion_by field
536 // in the set, this means the completion was achieved by some leaf in
537 // the program tree.
538 if (!$rec["completion_by"]) {
539 $prgrs = $this->sp_user_progress_db->getByPrgIdAndAssignmentId(
540 $this->prg_obj_id,
541 $rec["assignment_id"]
542 );
543 $prg = ilObjStudyProgramme::getInstanceByObjId($this->prg_obj_id);
544
545 $links = [];
546 $successful_children = $prg->getIdsOfSuccessfulChildren((int) $rec["assignment_id"]);
547 foreach ($successful_children as $entry) {
548 list($obj_id, $ref_id) = $entry;
549 $links[] = $this->getCompletionLink($obj_id, $ref_id);
550 }
551 $rec["completion_by"] = implode(", ", $links);
552 }
553 // This case should only occur if the status completed is set
554 // by an already deleted crs.
555 if (!$rec["completion_by"]) {
556 $title = ilObjectDataDeletionLog::get($rec["completion_by_id"]);
557 if (!is_null($title["title"])) {
558 $rec["completion_by"] = $title["title"];
559 }
560 }
561 } elseif ($rec["status"] == ilStudyProgrammeProgress::STATUS_ACCREDITED) {
562 $rec["completion_by"] = $rec["accredited_by"];
563 }
564
565 if (!$rec['completion_date']) {
566 $rec['completion_date'] = '';
567 }
568
569 $rec['vq_date'] = '';
570 if (!is_null($progress->getValidityOfQualification())
571 ) {
572 $rec['vq_date'] = $progress->getValidityOfQualification()->format($this->getUserDateFormat());
573 }
574
575 $rec['prg_validity'] = '-';
576 if (!is_null($progress->hasValidQualification($now))) {
577 $rec['prg_validity'] = $this->lng->txt('prg_not_valid');
578 if ($progress->hasValidQualification($now)) {
579 $rec['prg_validity'] = $this->lng->txt('prg_still_valid');
580 }
581 }
582
583 $rec['prg_deadline'] = null;
584 if ($progress->isSuccessful() === false
585 && !is_null($progress->getDeadline())
586 ) {
587 $rec['prg_deadline'] = $progress->getDeadline()->format($this->getUserDateFormat());
588 }
589
590 $usr_id = (int) $rec['usr_id'];
591 $rec["orgus"] = ilObjUser::lookupOrgUnitsRepresentation($usr_id);
592 $members_list[] = $rec;
593 }
594
595 return $members_list;
596 }
597
601 protected function countFetchData(int $prg_id, array $filter = []) : int
602 {
603 // TODO: Reimplement this in terms of ActiveRecord when innerjoin
604 // supports the required rename functionality
605 $query = "SELECT count(prgrs.id) as cnt" . PHP_EOL;
606 $query .= $this->getFrom();
607 $query .= $this->getWhere($prg_id);
608 $query .= $this->getFilterWhere($filter);
609
610 $res = $this->db->query($query);
611 $rec = $this->db->fetchAssoc($res);
612
613 return $rec["cnt"];
614 }
615
616 protected function getFrom() : string
617 {
618 return
619 "FROM " . ilStudyProgrammeProgressDBRepository::TABLE . " prgrs" . PHP_EOL
620 . "JOIN usr_data pcp ON pcp.usr_id = prgrs.usr_id" . PHP_EOL
621 . "JOIN " . ilStudyProgrammeAssignmentDBRepository::TABLE . " ass" . PHP_EOL
622 . " ON ass.id = prgrs.assignment_id" . PHP_EOL
623 . "JOIN object_data blngs ON blngs.obj_id = ass.root_prg_id" . PHP_EOL
624 . "LEFT JOIN usr_data ass_usr ON ass_usr.usr_id = ass.last_change_by" . PHP_EOL
625 . "LEFT JOIN usr_data cmpl_usr ON cmpl_usr.usr_id = prgrs.completion_by" . PHP_EOL
626 . "LEFT JOIN object_data cmpl_obj ON cmpl_obj.obj_id = prgrs.completion_by" . PHP_EOL
627 ;
628 }
629
633 protected function getWhere(int $prg_id) : string
634 {
635 $q = "WHERE prgrs.prg_id = " . $this->db->quote($prg_id, "integer") . PHP_EOL;
636
637 //get all potentially visible users:
638 $visible = [];
639 foreach ($this->permissions::ORGU_OPERATIONS as $op) {
640 $visible = array_merge(
641 $visible,
642 $this->permissions->getUserIdsSusceptibleTo($op)
643 );
644 }
645
646 if (count($visible) > 0) {
647 $q .= " AND " . $this->db->in("prgrs.usr_id", $visible, false, "integer") . PHP_EOL;
648 } else {
649 $q .= " AND FALSE" . PHP_EOL;
650 }
651 return $q;
652 }
653
657 public function getSelectableColumns() : array
658 {
659 $cols = [];
660 foreach (self::COLUMNS as $column) {
661 list($col, $lng_var, $optional, $lp, $no_lp) = $column;
662 if ($optional) {
663 $cols[$col] = ["txt" => $this->lng->txt($lng_var)];
664 }
665 }
666
667 return $cols;
668 }
669
673 protected function addMultiCommands() : void
674 {
675 foreach ($this->getMultiCommands() as $cmd => $caption) {
676 $this->addMultiCommand($cmd, $caption);
677 }
678 }
679
685 protected function getMultiCommands() : array
686 {
687 $permissions_for_edit_individual_plan = [
688 'updateFromCurrentPlanMulti' => $this->lng->txt('prg_multi_update_from_current_plan'),
689 'markRelevantMulti' => $this->lng->txt('prg_multi_mark_relevant'),
690 'markNotRelevantMulti' => $this->lng->txt('prg_multi_unmark_relevant'),
691 'changeDeadlineMulti' => $this->lng->txt('prg_multi_change_deadline'),
692 'changeExpireDateMulti' => $this->lng->txt('prg_multi_change_expire_date'),
693 'markAccreditedMulti' => $this->lng->txt('prg_multi_mark_accredited'),
694 'unmarkAccreditedMulti' => $this->lng->txt('prg_multi_unmark_accredited')
695 ];
696
697 $permissions_for_manage = [
698 'removeUserMulti' => $this->lng->txt('prg_multi_remove_user')
699 ];
700
701 $perms = [];
702
703 if ($this->permissions->may(ilOrgUnitOperation::OP_EDIT_INDIVIDUAL_PLAN)) {
704 $perms = array_merge($perms, $permissions_for_edit_individual_plan);
705 }
706
707 if ($this->permissions->may(ilOrgUnitOperation::OP_MANAGE_MEMBERS)) {
708 $perms = array_merge($perms, $permissions_for_manage);
709 }
710
711 return $perms;
712 }
713
719 protected function getPossibleActions(
720 int $node_id,
721 int $root_prg_id,
722 int $status
723 ) : array {
724 $actions = array();
725
726 if ($node_id == $root_prg_id) {
729 }
730
733 }
736 }
737
738 return $actions;
739 }
740
744 protected function getValidityOptions() : array
745 {
746 return [
747 self::VALIDITY_OPTION_VALID => $this->lng->txt("prg_still_valid"),
748 self::VALIDITY_OPTION_INVALID => $this->lng->txt("prg_not_valid")
749 ];
750 }
751
755 protected function getStatusOptions() : array
756 {
757 return [
758 ilStudyProgrammeProgress::STATUS_IN_PROGRESS => $this->lng->txt("prg_status_in_progress"),
759 ilStudyProgrammeProgress::STATUS_COMPLETED => $this->lng->txt("prg_status_completed"),
760 ilStudyProgrammeProgress::STATUS_ACCREDITED => $this->lng->txt("prg_status_accredited"),
761 ilStudyProgrammeProgress::STATUS_NOT_RELEVANT => $this->lng->txt("prg_status_not_relevant"),
762 ilStudyProgrammeProgress::STATUS_FAILED => $this->lng->txt("prg_status_failed")
763 ];
764 }
765
769 public function initFilter() : void
770 {
771 $item = $this->addFilterItemByMetaType('prg_validity', self::FILTER_SELECT);
772 $item->setOptions(
773 [self::OPTION_ALL => $this->lng->txt("all")] + $this->getValidityOptions()
774 );
775
776 $item = $this->addFilterItemByMetaType('prg_status', self::FILTER_SELECT);
777 $item->setOptions(
778 [self::OPTION_ALL => $this->lng->txt("all")] + $this->getStatusOptions()
779 );
780
781 $this->addFilterItemByMetaType('name', self::FILTER_TEXT);
782 $this->addFilterItemByMetaType('prg_expiry_date', self::FILTER_DATE_RANGE);
783 }
784
788 protected function getFilterValues() : array
789 {
790 $f = [];
791 foreach ($this->filters as $item) {
792 $f[$item->getFieldId()] = $this->getFilterValue($item);
793 }
794 return $f;
795 }
796
800 protected function getFilterWhere(array $filter) : string
801 {
802 $buf = [''];
803
804 if (strlen($filter['name']) > 0) {
805 $name = substr($this->db->quote($filter['name'], "text"), 1, -1);
806 $name_filter =
807 'AND (' . PHP_EOL
808 . 'pcp.firstname LIKE \'%' . $name . '%\' OR' . PHP_EOL
809 . 'pcp.lastname LIKE \'%' . $name . '%\' OR' . PHP_EOL
810 . 'pcp.login LIKE \'%' . $name . '%\'' . PHP_EOL
811 . ')' . PHP_EOL
812 ;
813
814 $buf[] = $name_filter;
815 }
816
817 if ($filter['prg_status'] && (int) $filter['prg_status'] !== self::OPTION_ALL) {
818 $buf[] = 'AND prgrs.status = ' . $this->db->quote($filter['prg_status'], "integer");
819 }
820
821 $filter_success = 'prgrs.status IN ('
823 . ','
825 . ') ';
826
827 if ($filter['prg_validity'] && (int) $filter['prg_validity'] !== self::OPTION_ALL) {
828 if ((int) $filter['prg_validity'] === self::VALIDITY_OPTION_VALID) {
829 $filter_validity = 'AND (prgrs.vq_date >= NOW() OR prgrs.vq_date IS NULL)';
830 }
831 if ((int) $filter['prg_validity'] === self::VALIDITY_OPTION_INVALID) {
832 $filter_validity = 'AND prgrs.vq_date < NOW()';
833 }
834
835 $buf[] = 'AND ('
836 . $filter_success
837 . $filter_validity
838 . ')';
839 }
840
841 $exp_from = $filter['prg_expiry_date']['from'];
842 if (!is_null($exp_from)) {
843 $dat = $exp_from->get(IL_CAL_DATE);
844 $buf[] = 'AND ('
845 . $filter_success
846 . 'AND prgrs.vq_date >= \'' . $dat . ' 00:00:00\''
847 . ')';
848 }
849
850 $exp_to = $filter['prg_expiry_date']['to'];
851 if (!is_null($exp_to)) {
852 $dat = $exp_to->get(IL_CAL_DATE);
853 $buf[] = 'AND ('
854 . $filter_success
855 . 'AND prgrs.vq_date <= \'' . $dat . ' 23:59:59\''
856 . ')';
857 }
858
859 $conditions = implode(PHP_EOL, $buf);
860
861 return $conditions;
862 }
863
864
866 {
867 return $this->prg->getPositionSettingsIsActiveForPrg();
868 }
869
870 protected function getOrguValidUsersFilter() : string
871 {
872 if ($this->permissions->may($this->permissions::ROLEPERM_MANAGE_MEMBERS)) {
873 return '';
874 }
875 $valid_user_ids = $this->permissions->getUserIdsSusceptibleTo(ilOrgUnitOperation::OP_VIEW_MEMBERS);
876
877 if (count($valid_user_ids) < 1) {
878 return ' AND false';
879 }
880
881 $valid_user_ids[] = $this->getParentObject()->user->getId();
882 return ' AND pcp.usr_id in ('
883 . implode(',', $valid_user_ids)
884 . ')';
885 }
886}
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_DATE
User interface class for advanced drop-down selection lists.
static getUserDateFormat($a_add_time=false, $a_for_parsing=false)
Parse current user setting into date/time format.
static _lookupTargetId($a_obj_id)
lookup target id
static _lookupTargetRefId($a_obj_id)
Lookup target ref_id.
@ilCtrl_Calls ilObjStudyProgrammeMembersGUI: ilStudyProgrammeRepositorySearchGUI @ilCtrl_Calls ilObjS...
static getInstanceByRefId($a_ref_id)
static lookupOrgUnitsRepresentation($a_usr_id)
lokup org unit representation
static _lookupTitle($a_id)
lookup object title
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data@access public
static _lookupDeletedDate($a_ref_id)
only called in ilObjectGUI::insertSavedNodes
Both role and OrgU-based permissions are relevant in many places of the PRG.
Class ilObjStudyProgrammeMembersTableGUI.
buildActionDropDown(array $actions, int $prgrs_id, int $ass_id, int $usr_id)
Builds the action menu for each row of the table.
getLinkTargetForAction(string $action, int $prgrs_id, int $ass_id)
Get ilias link for action.
fetchData(int $prg_id, int $limit=null, int $offset=null, array $filter=[])
Get data for table.
fillRow($a_set)
Standard Version of Fill Row.
getFilterWhere(array $filter)
Get the additional sql WHERE-part for filters.
initFilter()
Init filter.Overwrite this to initialize all filter input property objects.
getCompletionLink(int $target_obj_id, int $target_ref_id)
getValueOrEmptyString(string $condition, string $value)
getValidityOptions()
Get options of filter "validity".
getPossibleActions(int $node_id, int $root_prg_id, int $status)
Get a list with possible actions on a progress record.
__construct(int $prg_obj_id, int $prg_ref_id, ilObjStudyProgrammeMembersGUI $parent_obj, string $parent_cmd='', string $template_context='', ilStudyProgrammeProgressRepository $sp_user_progress_db, ilPRGPermissionsHelper $permissions, \ILIAS\Data\Factory $data_factory)
postOrder(array $list, \ILIAS\Data\Order $order)
countFetchData(int $prg_id, array $filter=[])
Get maximum number of rows the table could have.
Class ilStudyProgrammeProgress.
Class ilTable2GUI.
addHiddenInput($a_name, $a_value)
Add Hidden Input field.
getSelectedColumns()
Get selected columns.
setTopCommands($a_val)
Set top commands (display command buttons on top of table, too)
setEnableHeader($a_enableheader)
Set Enable Header.
setExternalSorting($a_val)
Set external sorting.
setShowRowsSelector($a_value)
Toggle rows-per-page selector.
getParentObject()
Get parent object.
determineOffsetAndOrder($a_omit_offset=false)
Determine offset and order.
setSelectAllCheckbox($a_select_all_checkbox, $a_select_all_on_top=false)
Set the name of the checkbox that should be toggled with a select all button.
setEnableAllCommand($a_value)
Enable actions for all entries in current result.
setData($a_data)
set table data @access public
setEnableTitle($a_enabletitle)
Set Enable Title.
getDefaultOrderDirection()
Get Default order direction.
getLimit()
Get limit.
setRowTemplate($a_template, $a_template_dir="")
Set row template.
setDefaultOrderField($a_defaultorderfield)
Set Default order field.
addColumn( $a_text, $a_sort_field="", $a_width="", $a_is_checkbox_action_column=false, $a_class="", $a_tooltip="", $a_tooltip_with_html=false)
Add a column to the header.
getOffset()
Get offset.
setExternalSegmentation($a_val)
Set external segmentation.
setId($a_val)
Set id.
setFormAction($a_form_action, $a_multipart=false)
Set Form action parameter.
determineLimit()
Determine the limit.
setDefaultOrderDirection($a_defaultorderdirection)
Set Default order direction.
getDefaultOrderField()
Get Default order field.
getOrderDirection()
Get order direction.
setMaxCount($a_max_count)
set max.
global $DIC
Definition: goto.php:24
Covers the persistence of settings belonging to a study programme (SP).
if($format !==null) $name
Definition: metadata.php:230
$i
Definition: metadata.php:24
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Class ChatMainBarProvider \MainMenu\Provider.
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$query
$url
foreach($_POST as $key=> $value) $res
$cols
Definition: xhr_table.php:11