ILIAS  trunk Revision v13.0_alpha-52-g21c366bbdd4
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;
44use ilObjUser;
48
50{
51 private readonly Factory $factory;
52 private readonly Renderer $renderer;
53 private readonly ServerRequestInterface|RequestInterface $request;
54 private readonly ilLanguage $lng;
56 private readonly ilTree $tree;
57 private readonly ilObjUser $user;
59 private bool $is_container_context = false;
73 private ?array $cached_records = null;
74
75 public function __construct(
76 private readonly ?int $parent_ref_id = null,
77 private readonly ?ilBadge $award_badge = null,
78 private readonly ?int $parent_obj_id = null,
79 private readonly ?int $restrict_badge_id = null
80 ) {
81 global $DIC;
82
83 $this->lng = $DIC->language();
84 $this->tpl = $DIC->ui()->mainTemplate();
85 $this->factory = $DIC->ui()->factory();
86 $this->renderer = $DIC->ui()->renderer();
87 $this->request = $DIC->http()->request();
88 $this->tree = $DIC->repositoryTree();
89 $this->user = $DIC->user();
90
91 if ($this->parent_ref_id) {
92 $parent_type = ilObject::_lookupType($this->parent_ref_id, true);
93 if (\in_array($parent_type, ['grp', 'crs'], true)) {
94 $this->is_container_context = $this->parent_obj_id === null && $this->award_badge === null;
95 }
96 }
97 }
98
112 private function getRecords(): array
113 {
114 if ($this->cached_records !== null) {
116 }
117
119 $assignments = [];
120 $user_ids = [];
121 $rows = [];
122 $badges = [];
123
124 $parent_obj_id = $this->parent_obj_id;
125 if (!$parent_obj_id && $this->parent_ref_id) {
126 $parent_obj_id = ilObject::_lookupObjId($this->parent_ref_id);
127 }
128
129 if ($this->parent_ref_id) {
130 $user_ids = ilBadgeHandler::getInstance()->getUserIds($this->parent_ref_id, $parent_obj_id);
131 }
132
133 $obj_ids = [$parent_obj_id];
134 if ($this->is_container_context) {
135 foreach ($this->tree->getSubTree($this->tree->getNodeData($this->parent_ref_id)) as $node) {
136 $obj_ids[] = (int) $node['obj_id'];
137 }
138 $obj_ids = array_unique($obj_ids);
139 }
140
141 foreach ($obj_ids as $obj_id) {
142 foreach (ilBadge::getInstancesByParentId($obj_id) as $badge) {
143 $badges[$badge->getId()] = $badge;
144 }
145
146 foreach (ilBadgeAssignment::getInstancesByParentId($obj_id) as $ass) {
147 if ($this->restrict_badge_id && $this->restrict_badge_id !== $ass->getBadgeId()) {
148 continue;
149 }
150
151 if ($this->award_badge instanceof ilBadge &&
152 $ass->getBadgeId() !== $this->award_badge->getId()) {
153 continue;
154 }
155
156 $assignments[$ass->getUserId()][] = $ass;
157 }
158 }
159
160 if (!$user_ids) {
161 $user_ids = array_keys($assignments);
162 }
163
164 $tmp['set'] = [];
165 if (\count($user_ids) > 0) {
166 $uquery = new ilUserQuery();
167 $uquery->setLimit(9999);
168 $uquery->setUserFilter($user_ids);
169 $tmp = $uquery->query();
170 }
171
172 foreach ($tmp['set'] as $user) {
173 if (\array_key_exists($user['usr_id'], $assignments)) {
174 foreach ($assignments[$user['usr_id']] as $user_ass) {
175 $idx = $user_ass->getBadgeId() . '_' . $user_ass->getUserId();
176
177 $badge = $badges[$user_ass->getBadgeId()];
178
179 $parent = null;
180 $paren_sortable = null;
181 if ($this->is_container_context) {
182 $parent_metadata = $badge->getParentMeta();
183
184 $parent = implode(' ', [
185 $this->renderer->render(
186 $this->factory->symbol()->icon()->custom(
187 ilObject::_getIcon($parent_metadata['id'], 'big', $parent_metadata['type']),
188 $this->lng->txt('obj_' . $parent_metadata['type'])
189 )
190 ),
191 $parent_metadata['title']
192 ]);
193 $paren_sortable = $parent_metadata['title'];
194 }
195
196 $rows[] = [
197 'id' => $idx,
198 'name' => $user['lastname'] . ', ' . $user['firstname'],
199 'login' => $user['login'],
200 'type' => ilBadge::getExtendedTypeCaption($badge->getTypeInstance()),
201 'title' => $badge->getTitle(),
202 'issued' => (new DateTimeImmutable())
203 ->setTimestamp($user_ass->getTimestamp())
204 ->setTimezone(new \DateTimeZone($this->user->getTimeZone()))
205 ->format($this->date_format->toString()),
206 'issued_sortable' => (new DateTimeImmutable())
207 ->setTimestamp($user_ass->getTimestamp())
208 ->setTimezone(new \DateTimeZone($this->user->getTimeZone())),
209 'parent' => $parent,
210 'parent_sortable' => $paren_sortable,
211 ];
212 }
213 } elseif ($this->award_badge) {
214 $idx = $this->award_badge->getId() . '_' . $user['usr_id'];
215
216 $rows[] = [
217 'id' => $idx,
218 'name' => $user['lastname'] . ', ' . $user['firstname'],
219 'login' => $user['login'],
220 'type' => '',
221 'title' => '',
222 'issued' => null,
223 'issued_sortable' => null,
224 'parent' => null,
225 'parent_sortable' => null,
226 ];
227 }
228 }
229
230 $this->cached_records = $rows;
231
232 return $rows;
233 }
234
235 public function getRows(
236 DataRowBuilder $row_builder,
237 array $visible_column_ids,
239 Order $order,
240 mixed $additional_viewcontrol_data,
241 mixed $filter_data,
242 mixed $additional_parameters
243 ): Generator {
244 $records = $this->getRecords();
245
246 if ($order) {
247 [$order_field, $order_direction] = $order->join(
248 [],
249 fn($ret, $key, $value) => [$key, $value]
250 );
251 usort($records, static function (array $left, array $right) use ($order_field): int {
252 if (\in_array($order_field, ['name', 'login', 'type', 'title', 'parent'], true)) {
253 if ($order_field === 'parent') {
254 $order_field .= '_sortable';
255 }
256
257 return \ilStr::strCmp(
258 $left[$order_field] ?? '',
259 $right[$order_field] ?? ''
260 );
261 }
262
263 if ($order_field === 'issued') {
264 $order_field .= '_sortable';
265 return $left[$order_field] <=> $right[$order_field];
266 }
267
268 return $left[$order_field] <=> $right[$order_field];
269 });
270
271 if ($order_direction === ORDER::DESC) {
272 $records = array_reverse($records);
273 }
274 }
275
276 if ($range) {
277 $records = \array_slice($records, $range->getStart(), $range->getLength());
278 }
279
280 foreach ($records as $record) {
281 yield $row_builder->buildDataRow($record['id'], $record)->withDisabledAction(
282 'badge_award_badge',
283 $record['issued'] === null
284 )->withDisabledAction(
285 'badge_revoke_badge',
286 $record['issued'] !== null
287 );
288 }
289 }
290
291 public function getTotalRowCount(
292 mixed $additional_viewcontrol_data,
293 mixed $filter_data,
294 mixed $additional_parameters
295 ): ?int {
296 return \count($this->getRecords());
297 }
298
302 public function getColumns(): array
303 {
304 $columns = [
305 'name' => $this->factory->table()->column()->text($this->lng->txt('name')),
306 'login' => $this->factory->table()->column()->text($this->lng->txt('login')),
307 'type' => $this->factory->table()->column()->text($this->lng->txt('type')),
308 'title' => $this->factory->table()->column()->text($this->lng->txt('title')),
309 // Cannot be a date column, because when awarding/revoking badges for uses, the list items may contain NULL values for `issued`
310 'issued' => $this->factory->table()->column()->text($this->lng->txt('badge_issued_on'))
311 ];
312
313 if ($this->is_container_context) {
314 $columns['parent'] = $this->factory->table()->column()->text($this->lng->txt('object'));
315 }
316
317 return $columns;
318 }
319
323 private function getActions(
324 URLBuilder $url_builder,
325 URLBuilderToken $action_parameter_token,
326 URLBuilderToken $row_id_token,
327 ): array {
328 return ($this->award_badge instanceof ilBadge) ? [
329 'badge_award_badge' =>
330 $this->factory->table()->action()->multi(
331 $this->lng->txt('badge_award_badge'),
332 $url_builder->withParameter($action_parameter_token, 'assignBadge'),
333 $row_id_token
334 ),
335 'badge_revoke_badge' =>
336 $this->factory->table()->action()->multi(
337 $this->lng->txt('badge_remove_badge'),
338 $url_builder->withParameter($action_parameter_token, 'revokeBadge'),
339 $row_id_token
340 )
341 ] : [];
342 }
343
344 public function renderTable(string $url): void
345 {
346 $df = new \ILIAS\Data\Factory();
347 $this->date_format = $this->user->getDateTimeFormat();
348
349 $table_uri = $df->uri($url);
350 $url_builder = new URLBuilder($table_uri);
351 $query_params_namespace = ['tid'];
352
353 [$url_builder, $action_parameter_token, $row_id_token] = $url_builder->acquireParameters(
354 $query_params_namespace,
355 'table_action',
356 'id',
357 );
358
359 if ($this->award_badge instanceof ilBadge) {
360 $title = $this->lng->txt('badge_award_badge') . ': ' . $this->award_badge->getTitle();
361 } else {
362 $parent = '';
363 if ($this->parent_obj_id) {
364 $title = ilObject::_lookupTitle($this->parent_obj_id);
365 if (!$title) {
366 $title = ilObjectDataDeletionLog::get($this->parent_obj_id);
367 if ($title) {
368 $title = $title['title'];
369 }
370 }
371
372 if ($this->restrict_badge_id) {
373 $badge = new ilBadge($this->restrict_badge_id);
374 $title .= ' - ' . $badge->getTitle();
375 }
376
377 $parent = $title . ': ';
378 }
379 $title = $parent . $this->lng->txt('users');
380 }
381
382 $table = $this->factory
383 ->table()
384 ->data($this, $title, $this->getColumns())
385 ->withId(str_replace('\\', '', self::class) . '_' . $this->parent_ref_id)
386 ->withOrder(new Order('name', Order::ASC))
387 ->withRange(new Range(0, 100))
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:28
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)
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['3gp', '7z', 'ai', 'aif', 'aifc', 'aiff', 'au', 'arw', 'avi', 'backup', 'bak', 'bas', 'bpmn', 'bpmn2', 'bmp', 'bib', 'bibtex', 'bz', 'bz2', 'c', 'c++', 'cc', 'cct', 'cdf', 'cer', 'class', 'cls', 'conf', 'cpp', 'crt', 'crs', 'crw', 'cr2', 'css', 'cst', 'csv', 'cur', 'db', 'dcr', 'des', 'dng', 'doc', 'docx', 'dot', 'dotx', 'dtd', 'dvi', 'el', 'eps', 'epub', 'f', 'f77', 'f90', 'flv', 'for', 'g3', 'gif', 'gl', 'gan', 'ggb', 'gsd', 'gsm', 'gtar', 'gz', 'gzip', 'h', 'hpp', 'htm', 'html', 'htmls', 'ibooks', 'ico', 'ics', 'ini', 'ipynb', 'java', 'jbf', 'jpeg', 'jpg', 'js', 'jsf', 'jso', 'json', 'latex', 'lang', 'less', 'log', 'lsp', 'ltx', 'm1v', 'm2a', 'm2v', 'm3u', 'm4a', 'm4v', 'markdown', 'm', 'mat', 'md', 'mdl', 'mdown', 'mid', 'min', 'midi', 'mobi', 'mod', 'mov', 'movie', 'mp2', 'mp3', 'mp4', 'mpa', 'mpeg', 'mpg', 'mph', 'mpga', 'mpp', 'mpt', 'mpv', 'mpx', 'mv', 'mw', 'mv4', 'nb', 'nbp', 'nef', 'nif', 'niff', 'obj', 'obm', 'odt', 'ods', 'odp', 'odg', 'odf', 'oga', 'ogg', 'ogv', 'old', 'p', 'pas', 'pbm', 'pcl', 'pct', 'pcx', 'pdf', 'pgm', 'pic', 'pict', 'png', 'por', 'pov', 'project', 'properties', 'ppa', 'ppm', 'pps', 'ppsx', 'ppt', 'pptx', 'ppz', 'ps', 'psd', 'pwz', 'qt', 'qtc', 'qti', 'qtif', 'r', 'ra', 'ram', 'rar', 'rast', 'rda', 'rev', 'rexx', 'ris', 'rf', 'rgb', 'rm', 'rmd', 'rmi', 'rmm', 'rmp', 'rt', 'rtf', 'rtx', 'rv', 's', 's3m', 'sav', 'sbs', 'sec', 'sdml', 'sgm', 'sgml', 'smi', 'smil', 'srt', 'sps', 'spv', 'stl', 'svg', 'swa', 'swf', 'swz', 'tar', 'tex', 'texi', 'texinfo', 'text', 'tgz', 'tif', 'tiff', 'ttf', 'txt', 'tmp', 'uvproj', 'vdf', 'vimeo', 'viv', 'vivo', 'vrml', 'vsdx', 'vtt', 'wav', 'webm', 'wmv', 'wmx', 'wmz', 'woff', 'wwd', 'xhtml', 'xif', 'xls', 'xlsx', 'xmind', 'xml', 'xsl', 'xsd', 'zip']
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