ILIAS  trunk Revision v13.0_alpha-52-g21c366bbdd4
class.ilObjectBadgeTableGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21namespace ILIAS\Badge;
22
23use ilStr;
24use ilLink;
25use ilBadge;
26use ilObject;
27use Generator;
28use ilLanguage;
42use Psr\Http\Message\RequestInterface;
48use Psr\Http\Message\ServerRequestInterface;
50
51use function count;
52use function in_array;
53use function is_array;
54use function array_slice;
55
57{
58 private const RECORD_RAW = '__raw__';
59 private readonly Factory $factory;
60 private readonly Renderer $renderer;
61 private readonly \ILIAS\Refinery\Factory $refinery;
62 private readonly ServerRequestInterface|RequestInterface $request;
63 private readonly Services $http;
64 private readonly ilLanguage $lng;
67 private readonly ilAccessHandler $access;
68 private readonly \ILIAS\ResourceStorage\Services $irss;
70
83 private ?array $cached_records = null;
84
86 private array $has_access_by_parent_cache = [];
87
90
91 public function __construct(
93 protected bool $has_write = false
94 ) {
95 global $DIC;
96
97 $this->lng = $DIC->language();
98 $this->tpl = $DIC->ui()->mainTemplate();
99 $this->factory = $DIC->ui()->factory();
100 $this->renderer = $DIC->ui()->renderer();
101 $this->refinery = $DIC->refinery();
102 $this->request = $DIC->http()->request();
103 $this->http = $DIC->http();
104 $this->access = $DIC->access();
105 $this->parent_obj = $parentObj;
106 $this->irss = $DIC->resourceStorage();
107 $this->badge_image_service = new ilBadgeImage(
108 $this->irss,
109 $DIC->upload(),
110 $DIC->ui()->mainTemplate()
111 );
112 }
113
114 public function getRows(
115 DataRowBuilder $row_builder,
116 array $visible_column_ids,
118 Order $order,
119 mixed $additional_viewcontrol_data,
120 mixed $filter_data,
121 mixed $additional_parameters
122 ): Generator {
123 $records = $this->getRecords();
124
125 if ($order) {
126 [$order_field, $order_direction] = $order->join(
127 [],
128 fn($ret, $key, $value) => [$key, $value]
129 );
130
131 usort($records, static function (array $left, array $right) use ($order_field): int {
132 if (in_array($order_field, ['container', 'title', 'type'], true)) {
133 if (in_array($order_field, ['container', 'title'], true)) {
134 $order_field .= '_sortable';
135 }
136
137 return ilStr::strCmp(
138 $left[$order_field],
139 $right[$order_field]
140 );
141 }
142
143 if ($order_field === 'active') {
144 return $right[$order_field] <=> $left[$order_field];
145 }
146
147 return $left[$order_field] <=> $right[$order_field];
148 });
149
150 if ($order_direction === Order::DESC) {
151 $records = array_reverse($records);
152 }
153 }
154
155 if ($range) {
156 $records = array_slice($records, $range->getStart(), $range->getLength());
157 }
158
159 $identifications = [];
160 foreach ($records as $record) {
161 $image_rid = $record[self::RECORD_RAW]['image_rid'] ?? null;
162 if (is_string($image_rid) && $image_rid !== '' && $image_rid !== '-') {
163 $identifications[] = $image_rid;
164 }
165 }
166
167 $this->irss->preload($identifications);
168
169 $modal_container = new ModalBuilder();
170 $container_deleted_title_part = '<span class="il_ItemAlertProperty">' . $this->lng->txt('deleted') . '</span>';
171 foreach ($records as $record) {
172 yield $row_builder->buildDataRow(
173 (string) $record['id'],
174 $this->enrichRecord($modal_container, $container_deleted_title_part, $record)
175 );
176 }
177 }
178
179 public function getTotalRowCount(
180 mixed $additional_viewcontrol_data,
181 mixed $filter_data,
182 mixed $additional_parameters
183 ): ?int {
184 return count($this->getRecords());
185 }
186
221 private function enrichRecord(
222 ModalBuilder $modal_builder,
223 string $container_deleted_title_part,
224 array $record
225 ): array {
226 $badge_item = $record[self::RECORD_RAW];
227
228 $badge = new ilBadge(0);
229 $badge->setId($badge_item['id']);
230 $badge->setImageRid($badge_item['image_rid']);
231
232 $images = [
233 'rendered' => null,
234 'large' => null,
235 ];
236 $image_src = $this->badge_image_service->getImageFromResourceId($badge);
237 if ($image_src !== '') {
238 $images['rendered'] = $this->renderer->render(
239 $this->factory->image()->responsive(
240 $image_src,
241 $badge_item['title']
242 )
243 );
244
245 $image_src_large = $this->badge_image_service->getImageFromResourceId(
246 $badge,
247 ilBadgeImage::IMAGE_SIZE_XL
248 );
249 if ($image_src_large !== '') {
250 $images['large'] = $this->factory->image()->responsive(
251 $image_src_large,
252 $badge_item['title']
253 );
254 }
255 }
256
257 $container_title_parts = [
258 'icon' => $this->renderer->render(
259 $this->factory->symbol()->icon()->custom(
260 ilObject::_getIcon($badge_item['parent_id'], 'big', $badge_item['parent_type'] ?? ''),
261 $this->lng->txt('obj_' . ($badge_item['parent_type'] ?? ''))
262 )
263 ),
264 'title' => $badge_item['parent_title'] ?? '',
265 ];
266
267 $sortable_container_title_parts = [
268 'title' => $badge_item['parent_title'] ?? ''
269 ];
270 if ($badge_item['deleted']) {
271 $container_title_parts['suffix'] = $container_deleted_title_part;
272 $sortable_container_title_parts['suffix'] = $container_deleted_title_part;
273 } else {
274 if (isset($this->has_access_by_parent_cache[$badge_item['parent_id']])) {
275 $has_access = $this->has_access_by_parent_cache[$badge_item['parent_id']] ?? false;
276 $ref_id = $this->first_ref_id_for_parent_cache[$badge_item['parent_id']] ?? null;
277 } else {
278 $ref_ids = ilObject::_getAllReferences($badge_item['parent_id']);
279 $ref_id = array_shift($ref_ids);
280 $this->first_ref_id_for_parent_cache[$badge_item['parent_id']] = $ref_id;
281 $has_access = $ref_id && $this->access->checkAccess('read', '', $ref_id);
282 $this->has_access_by_parent_cache[$badge_item['parent_id']] = $has_access;
283 }
284
285 if ($has_access) {
286 $container_title_parts['title'] = $this->renderer->render(
287 new Standard(
288 $container_title_parts['title'],
289 (string) new URI(
290 ilLink::_getLink(
291 $ref_id,
292 $badge_item['parent_type'] ?? ''
293 )
294 )
295 )
296 );
297 } else {
298 $container_title_parts['suffix'] = $container_deleted_title_part;
299 $sortable_container_title_parts['suffix'] = $container_deleted_title_part;
300 }
301 }
302
303 $modal = $modal_builder->constructModal(
304 $images['large'],
305 $badge_item['title'],
306 [
307 'active' => $badge_item['active'] ? $this->lng->txt('yes') : $this->lng->txt('no'),
308 'type' => $record['type'],
309 'container' => implode(' ', array_slice($container_title_parts, 1, null, true)),
310 ],
311 true
312 );
313
314 return [
315 'id' => $badge_item['id'],
316 'active' => (bool) $badge_item['active'],
317 'type' => $record['type'],
318 'image' => $images['rendered'] ? ($modal_builder->renderShyButton(
319 $images['rendered'],
320 $modal
321 ) . ' ') : '',
322 'title' => implode('', [
323 $modal_builder->renderShyButton($badge_item['title'], $modal),
324 $modal_builder->renderModal($modal)
325 ]),
326 'title_sortable' => $badge_item['title'],
327 'container' => implode(' ', $container_title_parts),
328 'container_sortable' => implode(' ', $sortable_container_title_parts),
329 ];
330 }
331
356 private function getRecords(): array
357 {
358 if ($this->cached_records !== null) {
359 return $this->cached_records;
360 }
361
362 // A filter is not implemented, yet
363 $filter = [
364 'type' => '',
365 'title' => '',
366 'object' => ''
367 ];
368
369 $types = ilBadgeHandler::getInstance()->getAvailableTypes(false);
370 $raw_records = ilBadge::getObjectInstances($filter);
371
372 $sortable_rows = array_map(function (array $badge_item) use ($types) {
373 return [
374 'id' => $badge_item['id'],
375 'active' => (bool) $badge_item['active'],
376 'type' => ilBadge::getExtendedTypeCaption($types[$badge_item['type_id']]),
377 'title_sortable' => $badge_item['title'],
378 'container_sortable' => ($badge_item['parent_title'] ?? '') .
379 ($badge_item['deleted'] ? ' ' . $this->lng->txt('deleted') : ''),
380 self::RECORD_RAW => $badge_item
381 ];
382 }, $raw_records);
383
384 $this->cached_records = $sortable_rows;
385
386 return $this->cached_records;
387 }
388
392 public function getColumns(): array
393 {
394 return [
395 'image' => $this->factory->table()->column()->text($this->lng->txt('image'))->withIsSortable(false),
396 'title' => $this->factory->table()->column()->text($this->lng->txt('title')),
397 'type' => $this->factory->table()->column()->text($this->lng->txt('type')),
398 'container' => $this->factory->table()->column()->text($this->lng->txt('object')),
399 'active' => $this->factory->table()->column()->boolean(
400 $this->lng->txt('active'),
401 $this->lng->txt('yes'),
402 $this->lng->txt('no')
403 )->withOrderingLabels(
404 $this->lng->txt('badge_sort_active_badges_first'),
405 $this->lng->txt('badge_sort_active_badges_last')
406 )
407 ];
408 }
409
413 private function getActions(
414 URLBuilder $url_builder,
415 URLBuilderToken $action_parameter_token,
416 URLBuilderToken $row_id_token
417 ): array {
418 return $this->has_write ? [
419 'obj_badge_activate' => $this->factory->table()->action()->multi(
420 $this->lng->txt('activate'),
421 $url_builder->withParameter($action_parameter_token, 'obj_badge_activate'),
422 $row_id_token
423 ),
424 'obj_badge_deactivate' => $this->factory->table()->action()->multi(
425 $this->lng->txt('deactivate'),
426 $url_builder->withParameter($action_parameter_token, 'obj_badge_deactivate'),
427 $row_id_token
428 ),
429 'obj_badge_delete' => $this->factory->table()->action()->multi(
430 $this->lng->txt('delete'),
431 $url_builder->withParameter($action_parameter_token, 'obj_badge_delete'),
432 $row_id_token
433 ),
434 'obj_badge_show_users' => $this->factory->table()->action()->single(
435 $this->lng->txt('user'),
436 $url_builder->withParameter($action_parameter_token, 'obj_badge_show_users'),
437 $row_id_token
438 )
439 ] : [];
440 }
441
442 public function renderTable(string $url): void
443 {
444 $df = new \ILIAS\Data\Factory();
445
446 $table_uri = $df->uri($url);
447 $url_builder = new URLBuilder($table_uri);
448 $query_params_namespace = ['tid'];
449
450 [$url_builder, $action_parameter_token, $row_id_token] = $url_builder->acquireParameters(
451 $query_params_namespace,
452 'table_action',
453 'id',
454 );
455
456 $table = $this->factory
457 ->table()
458 ->data($this, $this->lng->txt('badge_object_badges'), $this->getColumns())
459 ->withId(str_replace('\\', '', self::class))
460 ->withOrder(new Order('title', Order::ASC))
461 ->withRange(new Range(0, 100))
462 ->withActions($this->getActions($url_builder, $action_parameter_token, $row_id_token))
463 ->withRequest($this->request);
464
465 $query = $this->http->wrapper()->query();
466 if ($query->has($action_parameter_token->getName())) {
467 $action = $query->retrieve($action_parameter_token->getName(), $this->refinery->kindlyTo()->string());
468 $ids = $query->retrieve($row_id_token->getName(), $this->refinery->custom()->transformation(fn($v) => $v));
469
470 if ($action === 'obj_badge_delete') {
471 $items = [];
472 if (is_array($ids) && count($ids) > 0) {
473 if ($ids === ['ALL_OBJECTS']) {
474 $filter = [
475 'type' => '',
476 'title' => '',
477 'object' => ''
478 ];
479 $ids = [];
480 foreach (ilBadge::getObjectInstances($filter) as $badge_item) {
481 $ids[] = $badge_item['id'];
482 }
483 }
484
485 foreach ($ids as $id) {
486 $badge = new ilBadge((int) $id);
487 $items[] = $this->factory->modal()->interruptiveItem()->keyValue(
488 (string) $id,
489 (string) $badge->getId(),
490 $badge->getTitle()
491 );
492 }
493
494 $this->http->saveResponse(
495 $this->http
496 ->response()
497 ->withBody(
498 Streams::ofString($this->renderer->renderAsync([
499 $this->factory->modal()->interruptive(
500 $this->lng->txt('badge_deletion'),
501 $this->lng->txt('badge_deletion_confirmation'),
502 '#'
503 )->withAffectedItems($items)
504 ]))
505 )
506 );
507 $this->http->sendResponse();
508 $this->http->close();
509 }
510 }
511 }
512
513 $content_wrapper = new TableContentWrapper($this->renderer, $this->factory);
514 $this->tpl->setContent($this->renderer->render(
515 $content_wrapper->wrap(
516 $table
517 )
518 ));
519 }
520}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
renderer()
factory()
renderShyButton(string $label, Modal $modal)
renderModal(Modal $modal)
constructModal(?Image $badge_image, string $badge_title, array $badge_properties=[], bool $enclose_in_div=false)
This class provides a central helper method to wrap the content of a KS/UI > Table > Data into a spec...
readonly ilGlobalTemplateInterface $tpl
readonly ilObjBadgeAdministrationGUI $parent_obj
readonly ServerRequestInterface RequestInterface $request
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...
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 ILIAS ResourceStorage Services $irss
enrichRecord(ModalBuilder $modal_builder, string $container_deleted_title_part, array $record)
readonly ILIAS Refinery Factory $refinery
__construct(ilObjBadgeAdministrationGUI $parentObj, protected bool $has_write=false)
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
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
const DESC
Definition: Order.php:31
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:29
The scope of this class is split ilias-conform URI's into components.
Definition: URI.php:35
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Definition: Streams.php:32
Class Services.
Definition: Services.php:43
Class ilBadgeHandler.
static getExtendedTypeCaption(ilBadgeType $a_type)
static getObjectInstances(?array $filter=null)
language handling
@ilCtrl_Calls ilObjBadgeAdministrationGUI: ilPermissionGUI, ilBadgeManagementGUI @ilCtrl_IsCalledBy i...
Class ilObject Basic functions for all objects.
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
static _getAllReferences(int $id)
get all reference ids for object ID
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: class.ilStr.php:20
static strCmp(string $a, string $b)
Definition: class.ilStr.php:87
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
Combines all available interfaces which can be called via global $ilAccess.
static http()
Fetches the global http state from ILIAS.
global $DIC
Definition: shib_login.php:26