ILIAS  trunk Revision v12.0_alpha-1227-g7ff6d300864
class.ilObjectBadgeTableGUI.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;
32use Psr\Http\Message\RequestInterface;
34use Generator;
37use ilBadge;
41use ilObject;
42use ilLink;
49
51{
52 private const RECORD_RAW = '__raw__';
53
54 private readonly Factory $factory;
55 private readonly Renderer $renderer;
56 private readonly \ILIAS\Refinery\Factory $refinery;
57 private readonly ServerRequestInterface|RequestInterface $request;
58 private readonly Services $http;
59 private readonly ilLanguage $lng;
62 private readonly ilAccessHandler $access;
63 private readonly \ILIAS\ResourceStorage\Services $irss;
77 private ?array $cached_records = null;
79 private array $has_access_by_parent_cache = [];
82
83 public function __construct(
85 protected bool $has_write = false
86 ) {
87 global $DIC;
88
89 $this->lng = $DIC->language();
90 $this->tpl = $DIC->ui()->mainTemplate();
91 $this->factory = $DIC->ui()->factory();
92 $this->renderer = $DIC->ui()->renderer();
93 $this->refinery = $DIC->refinery();
94 $this->request = $DIC->http()->request();
95 $this->http = $DIC->http();
96 $this->access = $DIC->access();
97 $this->parent_obj = $parentObj;
98 $this->irss = $DIC->resourceStorage();
99 $this->badge_image_service = new ilBadgeImage(
100 $this->irss,
101 $DIC->upload(),
102 $DIC->ui()->mainTemplate()
103 );
104 }
105
106 public function getRows(
107 DataRowBuilder $row_builder,
108 array $visible_column_ids,
110 Order $order,
111 mixed $additional_viewcontrol_data,
112 mixed $filter_data,
113 mixed $additional_parameters
114 ): Generator {
115 $records = $this->getRecords();
116
117 if ($order) {
118 [$order_field, $order_direction] = $order->join(
119 [],
120 fn($ret, $key, $value) => [$key, $value]
121 );
122
123 usort($records, static function (array $left, array $right) use ($order_field): int {
124 if (\in_array($order_field, ['container', 'title', 'type'], true)) {
125 if (\in_array($order_field, ['container', 'title'], true)) {
126 $order_field .= '_sortable';
127 }
128
129 return \ilStr::strCmp(
130 $left[$order_field],
131 $right[$order_field]
132 );
133 }
134
135 if ($order_field === 'active') {
136 return $right[$order_field] <=> $left[$order_field];
137 }
138
139 return $left[$order_field] <=> $right[$order_field];
140 });
141
142 if ($order_direction === Order::DESC) {
143 $records = array_reverse($records);
144 }
145 }
146
147 if ($range) {
148 $records = \array_slice($records, $range->getStart(), $range->getLength());
149 }
150
151 $identifications = [];
152 foreach ($records as $record) {
153 if (isset($record[self::RECORD_RAW]['image_rid']) && $record[self::RECORD_RAW]['image_rid'] !== '') {
154 $identifications[] = $record[self::RECORD_RAW]['image_rid'];
155 }
156 }
157
158 $this->irss->preload($identifications);
159
160 $modal_container = new ModalBuilder();
161 $container_deleted_title_part = '<span class="il_ItemAlertProperty">' . $this->lng->txt('deleted') . '</span>';
162 foreach ($records as $record) {
163 yield $row_builder->buildDataRow(
164 (string) $record['id'],
165 $this->enrichRecord($modal_container, $container_deleted_title_part, $record)
166 );
167 }
168 }
169
170 public function getTotalRowCount(
171 mixed $additional_viewcontrol_data,
172 mixed $filter_data,
173 mixed $additional_parameters
174 ): ?int {
175 return \count($this->getRecords());
176 }
177
213 private function enrichRecord(
214 ModalBuilder $modal_builder,
215 string $container_deleted_title_part,
216 array $record
217 ): array {
218 $badge_item = $record[self::RECORD_RAW];
219
220 $badge = new ilBadge(0);
221 $badge->setId($badge_item['id']);
222 $badge->setImageRid($badge_item['image_rid']);
223 $badge->setImage($badge_item['image']);
224
225 $images = [
226 'rendered' => null,
227 'large' => null,
228 ];
229 $image_src = $this->badge_image_service->getImageFromResourceId($badge);
230 if ($image_src !== '') {
231 $images['rendered'] = $this->renderer->render(
232 $this->factory->image()->responsive(
233 $image_src,
234 $badge_item['title']
235 )
236 );
237
238 $image_src_large = $this->badge_image_service->getImageFromResourceId(
239 $badge,
240 ilBadgeImage::IMAGE_SIZE_XL
241 );
242 if ($image_src_large !== '') {
243 $images['large'] = $this->factory->image()->responsive(
244 $image_src_large,
245 $badge_item['title']
246 );
247 }
248 }
249
250 $container_title_parts = [
251 'icon' => $this->renderer->render(
252 $this->factory->symbol()->icon()->custom(
253 ilObject::_getIcon($badge_item['parent_id'], 'big', $badge_item['parent_type'] ?? ''),
254 $this->lng->txt('obj_' . ($badge_item['parent_type'] ?? ''))
255 )
256 ),
257 'title' => $badge_item['parent_title'] ?? '',
258 ];
259
260 $sortable_container_title_parts = [
261 'title' => $badge_item['parent_title'] ?? ''
262 ];
263 if ($badge_item['deleted']) {
264 $container_title_parts['suffix'] = $container_deleted_title_part;
265 $sortable_container_title_parts['suffix'] = $container_deleted_title_part;
266 } else {
267 if (isset($this->has_access_by_parent_cache[$badge_item['parent_id']])) {
268 $has_access = $this->has_access_by_parent_cache[$badge_item['parent_id']] ?? false;
269 $ref_id = $this->first_ref_id_for_parent_cache[$badge_item['parent_id']] ?? null;
270 } else {
271 $ref_ids = ilObject::_getAllReferences($badge_item['parent_id']);
272 $ref_id = array_shift($ref_ids);
273 $this->first_ref_id_for_parent_cache[$badge_item['parent_id']] = $ref_id;
274 $has_access = $ref_id && $this->access->checkAccess('read', '', $ref_id);
275 $this->has_access_by_parent_cache[$badge_item['parent_id']] = $has_access;
276 }
277
278 if ($has_access) {
279 $container_title_parts['title'] = $this->renderer->render(
280 new Standard(
281 $container_title_parts['title'],
282 (string) new URI(
283 ilLink::_getLink(
284 $ref_id,
285 $badge_item['parent_type'] ?? ''
286 )
287 )
288 )
289 );
290 } else {
291 $container_title_parts['suffix'] = $container_deleted_title_part;
292 $sortable_container_title_parts['suffix'] = $container_deleted_title_part;
293 }
294 }
295
296 $modal = $modal_builder->constructModal(
297 $images['large'],
298 $badge_item['title'],
299 [
300 'active' => $badge_item['active'] ? $this->lng->txt('yes') : $this->lng->txt('no'),
301 'type' => $record['type'],
302 'container' => implode(' ', \array_slice($container_title_parts, 1, null, true)),
303 ],
304 true
305 );
306
307 return [
308 'id' => $badge_item['id'],
309 'active' => (bool) $badge_item['active'],
310 'type' => $record['type'],
311 'image' => $images['rendered'] ? ($modal_builder->renderShyButton(
312 $images['rendered'],
313 $modal
314 ) . ' ') : '',
315 'title' => implode('', [
316 $modal_builder->renderShyButton($badge_item['title'], $modal),
317 $modal_builder->renderModal($modal)
318 ]),
319 'title_sortable' => $badge_item['title'],
320 'container' => implode(' ', $container_title_parts),
321 'container_sortable' => implode(' ', $sortable_container_title_parts),
322 ];
323 }
324
350 private function getRecords(): array
351 {
352 if ($this->cached_records !== null) {
353 return $this->cached_records;
354 }
355
356 // A filter is not implemented, yet
357 $filter = [
358 'type' => '',
359 'title' => '',
360 'object' => ''
361 ];
362
363 $types = ilBadgeHandler::getInstance()->getAvailableTypes(false);
364 $raw_records = ilBadge::getObjectInstances($filter);
365
366 $sortable_rows = array_map(function (array $badge_item) use ($types) {
367 return [
368 'id' => $badge_item['id'],
369 'active' => (bool) $badge_item['active'],
370 'type' => ilBadge::getExtendedTypeCaption($types[$badge_item['type_id']]),
371 'title_sortable' => $badge_item['title'],
372 'container_sortable' => ($badge_item['parent_title'] ?? '') .
373 ($badge_item['deleted'] ? ' ' . $this->lng->txt('deleted') : ''),
374 self::RECORD_RAW => $badge_item
375 ];
376 }, $raw_records);
377
378 $this->cached_records = $sortable_rows;
379
380 return $this->cached_records;
381 }
382
386 public function getColumns(): array
387 {
388 return [
389 'image' => $this->factory->table()->column()->text($this->lng->txt('image'))->withIsSortable(false),
390 'title' => $this->factory->table()->column()->text($this->lng->txt('title')),
391 'type' => $this->factory->table()->column()->text($this->lng->txt('type')),
392 'container' => $this->factory->table()->column()->text($this->lng->txt('object')),
393 'active' => $this->factory->table()->column()->boolean(
394 $this->lng->txt('active'),
395 $this->lng->txt('yes'),
396 $this->lng->txt('no')
397 )->withOrderingLabels(
398 $this->lng->txt('badge_sort_active_badges_first'),
399 $this->lng->txt('badge_sort_active_badges_last')
400 )
401 ];
402 }
403
407 private function getActions(
408 URLBuilder $url_builder,
409 URLBuilderToken $action_parameter_token,
410 URLBuilderToken $row_id_token
411 ): array {
412 return $this->has_write ? [
413 'obj_badge_activate' => $this->factory->table()->action()->multi(
414 $this->lng->txt('activate'),
415 $url_builder->withParameter($action_parameter_token, 'obj_badge_activate'),
416 $row_id_token
417 ),
418 'obj_badge_deactivate' =>
419 $this->factory->table()->action()->multi(
420 $this->lng->txt('deactivate'),
421 $url_builder->withParameter($action_parameter_token, 'obj_badge_deactivate'),
422 $row_id_token
423 ),
424 'obj_badge_delete' =>
425 $this->factory->table()->action()->multi(
426 $this->lng->txt('delete'),
427 $url_builder->withParameter($action_parameter_token, 'obj_badge_delete'),
428 $row_id_token
429 ),
430 'obj_badge_show_users' =>
431 $this->factory->table()->action()->single(
432 $this->lng->txt('user'),
433 $url_builder->withParameter($action_parameter_token, 'obj_badge_show_users'),
434 $row_id_token
435 )
436 ] : [];
437 }
438
439 public function renderTable(string $url): void
440 {
441 $df = new \ILIAS\Data\Factory();
442
443 $table_uri = $df->uri($url);
444 $url_builder = new URLBuilder($table_uri);
445 $query_params_namespace = ['tid'];
446
447 [$url_builder, $action_parameter_token, $row_id_token] = $url_builder->acquireParameters(
448 $query_params_namespace,
449 'table_action',
450 'id',
451 );
452
453 $table = $this->factory
454 ->table()
455 ->data($this, $this->lng->txt('badge_object_badges'), $this->getColumns())
456 ->withId(str_replace('\\', '', self::class))
457 ->withOrder(new Order('title', Order::ASC))
458 ->withRange(new Range(0, 100))
459 ->withActions($this->getActions($url_builder, $action_parameter_token, $row_id_token))
460 ->withRequest($this->request);
461
462 $query = $this->http->wrapper()->query();
463 if ($query->has($action_parameter_token->getName())) {
464 $action = $query->retrieve($action_parameter_token->getName(), $this->refinery->kindlyTo()->string());
465 $ids = $query->retrieve($row_id_token->getName(), $this->refinery->custom()->transformation(fn($v) => $v));
466
467 if ($action === 'obj_badge_delete') {
468 $items = [];
469 if (\is_array($ids) && \count($ids) > 0) {
470 if ($ids === ['ALL_OBJECTS']) {
471 $filter = [
472 'type' => '',
473 'title' => '',
474 'object' => ''
475 ];
476 $ids = [];
477 foreach (ilBadge::getObjectInstances($filter) as $badge_item) {
478 $ids[] = $badge_item['id'];
479 }
480 }
481
482 foreach ($ids as $id) {
483 $badge = new ilBadge((int) $id);
484 $items[] = $this->factory->modal()->interruptiveItem()->keyValue(
485 (string) $id,
486 (string) $badge->getId(),
487 $badge->getTitle()
488 );
489 }
490
491 $this->http->saveResponse(
492 $this->http
493 ->response()
494 ->withBody(
495 Streams::ofString($this->renderer->renderAsync([
496 $this->factory->modal()->interruptive(
497 $this->lng->txt('badge_deletion'),
498 $this->lng->txt('badge_deletion_confirmation'),
499 '#'
500 )->withAffectedItems($items)
501 ]))
502 )
503 );
504 $this->http->sendResponse();
505 $this->http->close();
506 }
507 }
508 }
509
510 $content_wrapper = new TableContentWrapper($this->renderer, $this->factory);
511 $this->tpl->setContent($this->renderer->render(
512 $content_wrapper->wrap(
513 $table
514 )
515 ));
516 }
517}
$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:38
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
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
Interface ilAccessHandler This interface combines all available interfaces which can be called via gl...
$ref_id
Definition: ltiauth.php:66
static http()
Fetches the global http state from ILIAS.
global $DIC
Definition: shib_login.php:26
$url
Definition: shib_logout.php:70