ILIAS  release_8 Revision v8.24
class.ilStudyProgrammeUserTable.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
27{
28 public const OPTION_ALL = -1;
29 public const VALIDITY_OPTION_VALID = 1;
30 public const VALIDITY_OPTION_INVALID = 3;
31 public const OPTION_USR_ACTIVE = 1;
32 public const OPTION_USR_INACTIVE = 2;
33
34 public const PRG_COLS = [
35 ['name', 'name', false, true, true],
36 ['login', 'login', false, true, true],
37 ['prg_orgus', 'prg_orgus', true, true, true],
38 ['prg_status', 'prg_status', false, true, true],
39 ['prg_completion_date', 'prg_completion_date', true, true, true],
40 ['prg_completion_by', 'prg_completion_by', true, true, true],
41 ['points', 'prg_points_reachable', false, true, false],
42 ['points_required', 'prg_points_required', false, false, true],
43 ['points_current', 'prg_points_current', false, false, true],
44 ['prg_custom_plan', 'prg_custom_plan', true, true, true],
45 ['prg_belongs_to', 'prg_belongs_to', true, true, true],
46 ['prg_assign_date', 'prg_assign_date', false, true, true],
47 ['prg_assigned_by', 'prg_assigned_by', true, true, true],
48 ['prg_deadline', 'prg_deadline', true, true, true],
49 ['prg_expiry_date', 'prg_expiry_date', true, true, true],
50 ['prg_validity', 'prg_validity', true, true, true]
51 ];
52
53 private const ORDER_MAPPING = [
54 'prg_status' => 'status',
55 'prg_custom_plan' => 'custom_plan',
56 'prg_belongs_to' => 'belongs_to',
57 'prg_validity' => 'validity',
58 'prg_orgus' => 'orgus',
59 'prg_completion_by' => 'completion_by',
60 'prg_completion_date' => 'completion_date',
61 'prg_assign_date' => 'assign_date',
62 'prg_assigned_by' => 'assigned_by',
63 'prg_deadline' => 'deadline',
64 'prg_expiry_date' => 'expiry_date',
65 'pgs_id' => 'prgrs_id'
66 ];
67
68 protected ilDBInterface $db;
70 protected ilLanguage $lng;
74
75 public function __construct(
81 ) {
82 $this->db = $db;
83 $this->export_fields_info = $export_fields_info;
84 $this->assignment_repo = $assignment_repo;
85 $this->lng = $lng;
86 $this->permissions = $permissions;
87 $this->user_ids_viewer_may_read_learning_progress_of = $this->permissions->getUserIdsSusceptibleTo(
89 );
90
91 $this->lng->loadLanguageModule("prg");
92 }
93
94 protected function getUserDataColumns(int $prg_id): array
95 {
96 $cols = [];
97 $user_data_cols = $this->export_fields_info->getSelectableFieldsInfo($prg_id);
98 foreach ($user_data_cols as $k => $column_definition) {
99 $cols[$k] = [$k, $column_definition['txt'], true, true, true];
100 }
101 return $cols;
102 }
103
104 protected function getPrgColumns(): array
105 {
106 $cols = [];
107 foreach (self::PRG_COLS as $k) {
108 $k[1] = $this->lng->txt($k[1]);
109 $cols[$k[0]] = $k;
110 }
111 return $cols;
112 }
113
114 public function getColumns(int $prg_id, bool $add_active_column = false): array
115 {
116 $columns = array_merge(
117 $this->getPrgColumns(),
118 $this->getUserDataColumns($prg_id)
119 );
120
121 if ($add_active_column) {
122 $columns["active"] = ["active", $this->lng->txt("active"), true, true, true];
123 }
124 return $columns;
125 }
126
127
128 public function countFetchData(int $prg_id, ?array $valid_user_ids, ilPRGAssignmentFilter $custom_filters): int
129 {
130 return $this->assignment_repo->countAllForNodeIsContained($prg_id, $valid_user_ids, $custom_filters);
131 }
132
137 public function fetchData(
138 int $prg_id,
139 ?array $valid_user_ids,
140 Order $order,
141 ilPRGAssignmentFilter $custom_filters = null,
142 int $limit = null,
143 int $offset = null
144 ): array {
145 $data = $this->assignment_repo->getAllForNodeIsContained(
146 $prg_id,
147 $valid_user_ids,
148 $custom_filters
149 );
150 $rows = array_map(fn ($ass) => $this->toRow($ass, $prg_id), $data);
151 $rows = $this->postOrder($rows, $order);
152 if ($limit) {
153 $offset = $offset ?? 0;
154 $rows = array_slice($rows, $offset, $limit);
155 }
156 return $rows;
157 }
158
159 public function fetchSingleUserRootAssignments(int $usr_id): array
160 {
161 $data = $this->assignment_repo->getForUser($usr_id);
162 $row = array_map(fn ($ass) => $this->toRow($ass, $ass->getRootId()), $data);
163 return $row;
164 }
165
166
167 protected $skip_perm_check_on_user = false;
168 public function disablePermissionCheck($flag = false): void
169 {
170 $this->skip_perm_check_on_user = $flag;
171 }
172
173 protected function includeLearningProgress(int $usr_id): bool
174 {
175 return
176 in_array($usr_id, $this->user_ids_viewer_may_read_learning_progress_of)
177 || $this->skip_perm_check_on_user;
178 }
179
180 protected function toRow(ilPRGAssignment $ass, int $node_id): ilStudyProgrammeUserTableRow
181 {
182 $pgs = $ass->getProgressForNode($node_id);
184 $ass->getId(),
185 $ass->getUserId(),
186 $node_id,
187 $ass->getRootId() === $node_id
188 );
189
190 $show_lp = $this->includeLearningProgress($ass->getUserId());
191
192 $prg_node = ilObjStudyProgramme::getInstanceByObjId($node_id);
193 $points_reachable = (string) $pgs->getPossiblePointsOfRelevantChildren();
194 if ($prg_node->getLPMode() === ilStudyProgrammeSettings::MODE_LP_COMPLETED) {
195 $points_reachable = (string) $pgs->getAmountOfPoints();
196 }
197
198 $row = $row
199 ->withUserActiveRaw($ass->getUserInformation()->isActive())
200 ->withUserActive($this->activeToRepresent($ass->getUserInformation()->isActive()))
201 ->withFirstname($ass->getUserInformation()->getFirstname())
202 ->withLastname($ass->getUserInformation()->getLastname())
203 ->withLogin($ass->getUserInformation()->getLogin())
204 ->withOrgUs($ass->getUserInformation()->getOrguRepresentation())
205 ->withUDF($ass->getUserInformation()->getAllUdf())
206 ->withGender($this->lng->txt('gender_' . $ass->getUserInformation()->getUdf('gender')))
207 ->withStatus($show_lp ? $this->statusToRepresent($pgs->getStatus()) : '')
208 ->withStatusRaw($pgs->getStatus())
209 ->withCompletionDate(
210 $show_lp && $pgs->getCompletionDate() ? $pgs->getCompletionDate()->format($this->getUserDateFormat()) : ''
211 )
212 ->withCompletionBy(
213 $show_lp && $pgs->getCompletionBy() ? $this->completionByToRepresent($pgs) : ''
214 )
215 ->withCompletionByObjIds(
216 $show_lp && $pgs->getCompletionBy() ? $this->completionByToCollection($pgs) : null
217 )
218 ->withPointsReachable($points_reachable)
219 ->withPointsRequired((string) $pgs->getAmountOfPoints())
220 ->withPointsCurrent($show_lp ? (string) $pgs->getCurrentAmountOfPoints() : '')
221 ->withCustomPlan($this->boolToRepresent($pgs->hasIndividualModifications()))
222 ->withBelongsTo($this::lookupTitle($ass->getRootId()))
223 ->withAssignmentDate($pgs->getAssignmentDate()->format($this->getUserDateFormat()))
224 ->withAssignmentBy(
225 $this->assignmentSourceToRepresent(
226 $ass->isManuallyAssigned(),
227 $ass->getLastChangeBy()
228 )
229 )
230 ->withDeadline(
231 $show_lp && $pgs->getDeadline() && !$pgs->isSuccessful() ? $pgs->getDeadline()->format($this->getUserDateFormat()) : ''
232 )
233 ->withExpiryDate(
234 $show_lp && $pgs->getValidityOfQualification() ? $pgs->getValidityOfQualification()->format($this->getUserDateFormat()) : ''
235 )
236 ->withValidity($show_lp ? $this->validToRepresent($pgs) : '')
237 ->withRestartDate($ass->getRestartDate() ? $ass->getRestartDate()->format($this->getUserDateFormat()) : '')
238 ;
239 return $row;
240 }
241
242 protected function getUserDateFormat(): string
243 {
244 return ilCalendarUtil::getUserDateFormat(0, true);
245 }
246
250 public function statusToRepresent($a_status): string
251 {
252 if ($a_status == ilPRGProgress::STATUS_IN_PROGRESS) {
253 return $this->lng->txt("prg_status_in_progress");
254 }
255 if ($a_status == ilPRGProgress::STATUS_COMPLETED) {
256 return $this->lng->txt("prg_status_completed");
257 }
258 if ($a_status == ilPRGProgress::STATUS_ACCREDITED) {
259 return $this->lng->txt("prg_status_accredited");
260 }
261 if ($a_status == ilPRGProgress::STATUS_NOT_RELEVANT) {
262 return $this->lng->txt("prg_status_not_relevant");
263 }
264 if ($a_status == ilPRGProgress::STATUS_FAILED) {
265 return $this->lng->txt("prg_status_failed");
266 }
267 throw new ilException("Unknown status: '$a_status'");
268 }
269
270 public function boolToRepresent(bool $value): string
271 {
272 return ($value) ? $this->lng->txt("yes") : $this->lng->txt("no");
273 }
274
275 public function validToRepresent(ilPRGProgress $pgs): string
276 {
277 if (!$pgs->isSuccessful()) {
278 return '-';
279 }
280 return $pgs->isInvalidated() ? $this->lng->txt("prg_not_valid") : $this->lng->txt("prg_still_valid");
281 }
282
283 public function activeToRepresent(bool $value): string
284 {
285 return $value ? $this->lng->txt('active') : $this->lng->txt('inactive');
286 }
287
288 public function assignmentSourceToRepresent(bool $manually, int $assignment_src): string
289 {
291 if ($manually || ! in_array($assignment_src, $srcs)) {
292 return $this::lookupTitle($assignment_src);
293 }
294 return implode(' ', [
295 $this->lng->txt('prg_autoassignment'),
296 $this->lng->txt($srcs[$assignment_src])
297 ]);
298 }
299
300 public function completionByToRepresent(ilPRGProgress $progress): string
301 {
302 $completion_by = $progress->getCompletionBy();
303 if ($completion_by !== ilPRGProgress::COMPLETED_BY_SUBNODES) {
304 return $this::lookupTitle($completion_by);
305 }
306
307 $out = array_map(
308 fn (int $node_obj_id): string => self::lookupTitle($node_obj_id),
309 $this->completionByToCollection($progress)
310 );
311
312 return implode(', ', $out);
313 }
314
315 protected function completionByToCollection(ilPRGProgress $progress): array
316 {
317 $completion_by = $progress->getCompletionBy();
318 if ($completion_by !== ilPRGProgress::COMPLETED_BY_SUBNODES) {
319 return [$completion_by];
320 }
321 $successful_subnodes = array_filter(
322 $progress->getSubnodes(),
323 static fn (ilPRGProgress $pgs): bool => $pgs->isSuccessful()
324 );
325 return array_map(
326 static fn (ilPRGProgress $pgs): int => $pgs->getNodeId(),
327 $successful_subnodes
328 );
329 }
330
331 public static function lookupTitle(int $obj_id): string
332 {
333 $type = ilObject::_lookupType($obj_id);
334 switch ($type) {
335 case 'usr':
336 case 'prg':
337 return ilObject::_lookupTitle($obj_id);
338 case 'prg':
339 $title = ilObject::_lookupTitle($obj_id);
341 return sprintf('(%s)', $title);
342 }
343 return $title;
344 case 'crs':
345 $title = ilObject::_lookupTitle($obj_id);
346 $refs = ilObject::_getAllReferences($obj_id);
347 $target_ref_id = array_shift($refs) ?? null;
348 if($target_ref_id === null || ilObject::_isInTrash($target_ref_id)) {
349 return sprintf('(%s)', $title);
350 }
351 return $title;
352 }
353
354 if ($del = ilObjectDataDeletionLog::get($obj_id)) {
355 return sprintf('(%s)', $del['title']);
356 }
357 return 'object id ' . $obj_id;
358 }
359
360 protected function postOrder(array $list, \ILIAS\Data\Order $order): array
361 {
362 [$aspect, $direction] = $order->join('', function ($i, $k, $v) {
363 return [$k, $v];
364 });
365
366 if (array_key_exists($aspect, self::ORDER_MAPPING)) {
367 $aspect = self::ORDER_MAPPING[$aspect];
368 }
369
370 usort($list, static function (ilStudyProgrammeUserTableRow $a, ilStudyProgrammeUserTableRow $b) use ($aspect): int {
371 $a = $a->toArray();
372 $b = $b->toArray();
373
374 if (is_numeric($a[$aspect])) {
375 return $a[$aspect] <=> $b[$aspect];
376 }
377 return strcmp($a[$aspect], $b[$aspect]);
378 });
379
380 if ($direction === $order::DESC) {
381 $list = array_reverse($list);
382 }
383 return $list;
384 }
385}
$out
Definition: buildRTE.php:24
Both the subject and the direction need to be specified when expressing an order.
Definition: Order.php:13
static getUserDateFormat(int $a_add_time=0, bool $a_for_parsing=false)
Parse current user setting into date/time format.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
language handling
static getInstanceByObjId(int $obj_id)
static getRefIdFor(int $obj_id)
static _lookupType(int $id, bool $reference=false)
static _getAllReferences(int $id)
get all reference ids for object ID
static _isInTrash(int $ref_id)
static _lookupTitle(int $obj_id)
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...
Assignments are relations of users to a PRG; They hold progress-information for (sub-)nodes of the PR...
getProgressForNode(int $node_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getUserIdsSusceptibleTo(string $operation)
A Progress is the status of a user on a single node of an assignment; it is unique by assignment_id:u...
ilStudyProgrammeUserTable provides a flattened list of progresses at a programme-node.
ilStudyProgrammeUserTable provides a flattened list of progresses at a programme-node.
fetchData(int $prg_id, ?array $valid_user_ids, Order $order, ilPRGAssignmentFilter $custom_filters=null, int $limit=null, int $offset=null)
completionByToRepresent(ilPRGProgress $progress)
completionByToCollection(ilPRGProgress $progress)
getColumns(int $prg_id, bool $add_active_column=false)
postOrder(array $list, \ILIAS\Data\Order $order)
assignmentSourceToRepresent(bool $manually, int $assignment_src)
countFetchData(int $prg_id, ?array $valid_user_ids, ilPRGAssignmentFilter $custom_filters)
ilPRGAssignmentDBRepository $assignment_repo
__construct(ilDBInterface $db, ilExportFieldsInfo $export_fields_info, ilPRGAssignmentDBRepository $assignment_repo, ilLanguage $lng, ilPRGPermissionsHelper $permissions)
toRow(ilPRGAssignment $ass, int $node_id)
Interface ilDBInterface.
$i
Definition: metadata.php:41
Class ChatMainBarProvider \MainMenu\Provider.
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$type
$cols
Definition: xhr_table.php:11
$rows
Definition: xhr_table.php:10