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