ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
class.ilBadgeUserTableGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21namespace ILIAS\Badge;
22
27use ilLanguage;
30use Psr\Http\Message\ServerRequestInterface;
31use Psr\Http\Message\RequestInterface;
33use Generator;
36use ilObject;
37use ilBadge;
39use ilUserQuery;
40use DateTimeImmutable;
43use ilTree;
45use ilObjUser;
49
51{
52 private readonly Factory $factory;
53 private readonly Renderer $renderer;
54 private readonly ServerRequestInterface|RequestInterface $request;
55 private readonly ilLanguage $lng;
57 private readonly ilTree $tree;
58 private readonly ilObjUser $user;
60 private bool $is_container_context = false;
74 private ?array $cached_records = null;
75
76 public function __construct(
77 private readonly ?int $parent_ref_id = null,
78 private readonly ?ilBadge $award_badge = null,
79 private readonly ?int $parent_obj_id = null,
80 private readonly ?int $restrict_badge_id = null
81 ) {
82 global $DIC;
83
84 $this->lng = $DIC->language();
85 $this->tpl = $DIC->ui()->mainTemplate();
86 $this->factory = $DIC->ui()->factory();
87 $this->renderer = $DIC->ui()->renderer();
88 $this->request = $DIC->http()->request();
89 $this->tree = $DIC->repositoryTree();
90 $this->user = $DIC->user();
91
92 if ($this->parent_ref_id) {
93 $parent_type = ilObject::_lookupType($this->parent_ref_id, true);
94 if (\in_array($parent_type, ['grp', 'crs'], true)) {
95 $this->is_container_context = $this->parent_obj_id === null && $this->award_badge === null;
96 }
97 }
98 }
99
113 private function getRecords(): array
114 {
115 if ($this->cached_records !== null) {
117 }
118
120 $assignments = [];
121 $user_ids = [];
122 $rows = [];
123 $badges = [];
124
125 $parent_obj_id = $this->parent_obj_id;
126 if (!$parent_obj_id && $this->parent_ref_id) {
127 $parent_obj_id = ilObject::_lookupObjId($this->parent_ref_id);
128 }
129
130 if ($this->parent_ref_id) {
131 $user_ids = ilBadgeHandler::getInstance()->getUserIds($this->parent_ref_id, $parent_obj_id);
132 }
133
134 $obj_ids = [$parent_obj_id];
135 if ($this->is_container_context) {
136 foreach ($this->tree->getSubTree($this->tree->getNodeData($this->parent_ref_id)) as $node) {
137 $obj_ids[] = (int) $node['obj_id'];
138 }
139 $obj_ids = array_unique($obj_ids);
140 }
141
142 foreach ($obj_ids as $obj_id) {
143 foreach (ilBadge::getInstancesByParentId($obj_id) as $badge) {
144 $badges[$badge->getId()] = $badge;
145 }
146
147 foreach (ilBadgeAssignment::getInstancesByParentId($obj_id) as $ass) {
148 if ($this->restrict_badge_id && $this->restrict_badge_id !== $ass->getBadgeId()) {
149 continue;
150 }
151
152 if ($this->award_badge instanceof ilBadge &&
153 $ass->getBadgeId() !== $this->award_badge->getId()) {
154 continue;
155 }
156
157 $assignments[$ass->getUserId()][] = $ass;
158 }
159 }
160
161 if (!$user_ids) {
162 $user_ids = array_keys($assignments);
163 }
164
165 $tmp['set'] = [];
166 if (\count($user_ids) > 0) {
167 $uquery = new ilUserQuery();
168 $uquery->setLimit(9999);
169 $uquery->setUserFilter($user_ids);
170 $tmp = $uquery->query();
171 }
172
173 foreach ($tmp['set'] as $user) {
174 if (\array_key_exists($user['usr_id'], $assignments)) {
175 foreach ($assignments[$user['usr_id']] as $user_ass) {
176 $idx = $user_ass->getBadgeId() . '_' . $user_ass->getUserId();
177
178 $badge = $badges[$user_ass->getBadgeId()];
179
180 $parent = null;
181 $paren_sortable = null;
182 if ($this->is_container_context) {
183 $parent_metadata = $badge->getParentMeta();
184
185 $parent = implode(' ', [
186 $this->renderer->render(
187 $this->factory->symbol()->icon()->custom(
188 ilObject::_getIcon($parent_metadata['id'], 'big', $parent_metadata['type']),
189 $this->lng->txt('obj_' . $parent_metadata['type'])
190 )
191 ),
192 $parent_metadata['title']
193 ]);
194 $paren_sortable = $parent_metadata['title'];
195 }
196
197 $rows[] = [
198 'id' => $idx,
199 'name' => $user['lastname'] . ', ' . $user['firstname'],
200 'login' => $user['login'],
201 'type' => ilBadge::getExtendedTypeCaption($badge->getTypeInstance()),
202 'title' => $badge->getTitle(),
203 'issued' => (new DateTimeImmutable())
204 ->setTimestamp($user_ass->getTimestamp())
205 ->setTimezone(new \DateTimeZone($this->user->getTimeZone()))
206 ->format($this->date_format->toString()),
207 'issued_sortable' => (new DateTimeImmutable())
208 ->setTimestamp($user_ass->getTimestamp())
209 ->setTimezone(new \DateTimeZone($this->user->getTimeZone())),
210 'parent' => $parent,
211 'parent_sortable' => $paren_sortable,
212 ];
213 }
214 } elseif ($this->award_badge) {
215 $idx = $this->award_badge->getId() . '_' . $user['usr_id'];
216
217 $rows[] = [
218 'id' => $idx,
219 'name' => $user['lastname'] . ', ' . $user['firstname'],
220 'login' => $user['login'],
221 'type' => '',
222 'title' => '',
223 'issued' => null,
224 'issued_sortable' => null,
225 'parent' => null,
226 'parent_sortable' => null,
227 ];
228 }
229 }
230
231 $this->cached_records = $rows;
232
233 return $rows;
234 }
235
236 public function getRows(
237 DataRowBuilder $row_builder,
238 array $visible_column_ids,
240 Order $order,
241 mixed $additional_viewcontrol_data,
242 mixed $filter_data,
243 mixed $additional_parameters
244 ): Generator {
245 $records = $this->getRecords();
246
247 if ($order) {
248 [$order_field, $order_direction] = $order->join(
249 [],
250 fn($ret, $key, $value) => [$key, $value]
251 );
252 usort($records, static function (array $left, array $right) use ($order_field): int {
253 if (\in_array($order_field, ['name', 'login', 'type', 'title', 'parent'], true)) {
254 if ($order_field === 'parent') {
255 $order_field .= '_sortable';
256 }
257
258 return \ilStr::strCmp(
259 $left[$order_field] ?? '',
260 $right[$order_field] ?? ''
261 );
262 }
263
264 if ($order_field === 'issued') {
265 $order_field .= '_sortable';
266 return $left[$order_field] <=> $right[$order_field];
267 }
268
269 return $left[$order_field] <=> $right[$order_field];
270 });
271
272 if ($order_direction === ORDER::DESC) {
273 $records = array_reverse($records);
274 }
275 }
276
277 if ($range) {
278 $records = \array_slice($records, $range->getStart(), $range->getLength());
279 }
280
281 foreach ($records as $record) {
282 yield $row_builder->buildDataRow($record['id'], $record)->withDisabledAction(
283 'badge_award_badge',
284 $record['issued'] === null
285 )->withDisabledAction(
286 'badge_revoke_badge',
287 $record['issued'] !== null
288 );
289 }
290 }
291
292 public function getTotalRowCount(
293 mixed $additional_viewcontrol_data,
294 mixed $filter_data,
295 mixed $additional_parameters
296 ): ?int {
297 return \count($this->getRecords());
298 }
299
303 public function getColumns(): array
304 {
305 $columns = [
306 'name' => $this->factory->table()->column()->text($this->lng->txt('name')),
307 'login' => $this->factory->table()->column()->text($this->lng->txt('login')),
308 'type' => $this->factory->table()->column()->text($this->lng->txt('type')),
309 'title' => $this->factory->table()->column()->text($this->lng->txt('title')),
310 // Cannot be a date column, because when awarding/revoking badges for uses, the list items may contain NULL values for `issued`
311 'issued' => $this->factory->table()->column()->text($this->lng->txt('badge_issued_on'))
312 ];
313
314 if ($this->is_container_context) {
315 $columns['parent'] = $this->factory->table()->column()->text($this->lng->txt('object'));
316 }
317
318 return $columns;
319 }
320
324 private function getActions(
325 URLBuilder $url_builder,
326 URLBuilderToken $action_parameter_token,
327 URLBuilderToken $row_id_token,
328 ): array {
329 return ($this->award_badge instanceof ilBadge) ? [
330 'badge_award_badge' =>
331 $this->factory->table()->action()->multi(
332 $this->lng->txt('badge_award_badge'),
333 $url_builder->withParameter($action_parameter_token, 'assignBadge'),
334 $row_id_token
335 ),
336 'badge_revoke_badge' =>
337 $this->factory->table()->action()->multi(
338 $this->lng->txt('badge_remove_badge'),
339 $url_builder->withParameter($action_parameter_token, 'revokeBadge'),
340 $row_id_token
341 )
342 ] : [];
343 }
344
345 public function renderTable(string $url): void
346 {
347 $df = new \ILIAS\Data\Factory();
348 $this->date_format = $this->user->getDateTimeFormat();
349
350 $table_uri = $df->uri($url);
351 $url_builder = new URLBuilder($table_uri);
352 $query_params_namespace = ['tid'];
353
354 [$url_builder, $action_parameter_token, $row_id_token] = $url_builder->acquireParameters(
355 $query_params_namespace,
356 'table_action',
357 'id',
358 );
359
360 if ($this->award_badge instanceof ilBadge) {
361 $title = $this->lng->txt('badge_award_badge') . ': ' . $this->award_badge->getTitle();
362 } else {
363 $parent = '';
364 if ($this->parent_obj_id) {
365 $title = ilObject::_lookupTitle($this->parent_obj_id);
366 if (!$title) {
367 $title = ilObjectDataDeletionLog::get($this->parent_obj_id);
368 if ($title) {
369 $title = $title['title'];
370 }
371 }
372
373 if ($this->restrict_badge_id) {
374 $badge = new ilBadge($this->restrict_badge_id);
375 $title .= ' - ' . $badge->getTitle();
376 }
377
378 $parent = $title . ': ';
379 }
380 $title = $parent . $this->lng->txt('users');
381 }
382
383 $table = $this->factory
384 ->table()
385 ->data($this, $title, $this->getColumns())
386 ->withId(self::class . '_' . $this->parent_ref_id)
387 ->withOrder(new Order('name', Order::ASC))
388 ->withActions($this->getActions($url_builder, $action_parameter_token, $row_id_token))
389 ->withRequest($this->request);
390
391 $out = [$table];
392
393 $this->tpl->setContent($this->renderer->render($out));
394 }
395}
renderer()
factory()
$out
Definition: buildRTE.php:24
getTotalRowCount(mixed $additional_viewcontrol_data, mixed $filter_data, mixed $additional_parameters)
Mainly for the purpose of pagination-support, it is important to know about the total number of recor...
__construct(private readonly ?int $parent_ref_id=null, private readonly ?ilBadge $award_badge=null, private readonly ?int $parent_obj_id=null, private readonly ?int $restrict_badge_id=null)
readonly ilGlobalTemplateInterface $tpl
getRows(DataRowBuilder $row_builder, array $visible_column_ids, Range $range, Order $order, mixed $additional_viewcontrol_data, mixed $filter_data, mixed $additional_parameters)
This is called by the table to retrieve rows; map data-records to rows using the $row_builder e....
getActions(URLBuilder $url_builder, URLBuilderToken $action_parameter_token, URLBuilderToken $row_id_token,)
readonly ServerRequestInterface RequestInterface $request
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
A Date Format provides a format definition akin to PHP's date formatting options, but stores the sing...
Definition: DateFormat.php:27
Both the subject and the direction need to be specified when expressing an order.
Definition: Order.php:29
join($init, callable $fn)
Definition: Order.php:75
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:29
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstancesByParentId(int $a_parent_obj_id)
Class ilBadgeHandler.
static getExtendedTypeCaption(ilBadgeType $a_type)
static getInstancesByParentId(int $a_parent_id, ?array $a_filter=null)
Stores all calendar relevant settings.
language handling
User class.
Class ilObject Basic functions for all objects.
static _lookupType(int $id, bool $reference=false)
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
User query class.
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
A Column describes the form of presentation for a certain aspect of data, i.e.
Definition: Column.php:28
buildDataRow(string $id, array $record)
This is how the factory for UI elements looks.
Definition: Factory.php:38
An entity that renders components to a string output.
Definition: Renderer.php:31
global $DIC
Definition: shib_login.php:26
$url
Definition: shib_logout.php:68