ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
class.ilBadgeTableGUI.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;
38use ilBadgeAuto;
41
43{
44 private readonly Factory $factory;
45 private readonly Renderer $renderer;
46 private readonly \ILIAS\Refinery\Factory $refinery;
47 private readonly ServerRequestInterface|RequestInterface $request;
48 private readonly Services $http;
49 private readonly int $parent_id;
50 private readonly string $parent_type;
51 private readonly ilLanguage $lng;
53 private readonly \ILIAS\ResourceStorage\Services $irss;
67 private ?array $cached_records = null;
68
69 public function __construct(int $parent_obj_id, string $parent_obj_type, protected bool $has_write = false)
70 {
71 global $DIC;
72
73 $this->lng = $DIC->language();
74 $this->tpl = $DIC->ui()->mainTemplate();
75 $this->factory = $DIC->ui()->factory();
76 $this->renderer = $DIC->ui()->renderer();
77 $this->refinery = $DIC->refinery();
78 $this->request = $DIC->http()->request();
79 $this->http = $DIC->http();
80 $this->irss = $DIC->resourceStorage();
81
82 $this->parent_id = $parent_obj_id;
83 $this->parent_type = $parent_obj_type;
84 $this->badge_image_service = new ilBadgeImage(
85 $this->irss,
86 $DIC->upload(),
87 $DIC->ui()->mainTemplate()
88 );
89 }
90
101 private function getRecords(): array
102 {
103 if ($this->cached_records !== null) {
105 }
106
107 $rows = [];
108 foreach (ilBadge::getInstancesByParentId($this->parent_id) as $badge) {
109 $rows[] = [
110 'id' => $badge->getId(),
111 'badge' => $badge,
112 'active' => $badge->isActive(),
113 'type' => $this->parent_type !== 'bdga'
114 ? ilBadge::getExtendedTypeCaption($badge->getTypeInstance())
115 : $badge->getTypeInstance()->getCaption(),
116 'manual' => !$badge->getTypeInstance() instanceof ilBadgeAuto,
117 'title_sortable' => $badge->getTitle()
118 ];
119 }
120
121 $this->cached_records = $rows;
122
123 return $rows;
124 }
125
146 private function enrichRecord(ModalBuilder $modal_builder, array $record): array
147 {
148 $badge = $record['badge'];
149
150 $images = [
151 'rendered' => null,
152 'large' => null,
153 ];
154
155 $image_src = $this->badge_image_service->getImageFromBadge($badge);
156 if ($image_src !== '') {
157 $images['rendered'] = $this->renderer->render(
158 $this->factory->image()->responsive(
159 $image_src,
160 $badge->getTitle()
161 )
162 );
163
164 $image_src_large = $this->badge_image_service->getImageFromBadge(
165 $badge,
167 );
168 if ($image_src_large !== '') {
169 $images['large'] = $this->factory->image()->responsive(
170 $image_src_large,
171 $badge->getTitle()
172 );
173 }
174 }
175
176 $modal = $modal_builder->constructModal(
177 $images['large'],
178 $badge->getTitle(),
179 [
180 'description' => $badge->getDescription(),
181 'badge_criteria' => $badge->getCriteria(),
182 ]
183 );
184
185 $record['image'] = $images['rendered']
186 ? $modal_builder->renderShyButton($images['rendered'], $modal) . ' '
187 : '';
188 $record['title'] = implode('', [
189 $modal_builder->renderShyButton($badge->getTitle(), $modal),
190 $modal_builder->renderModal($modal)
191 ]);
192
193 return $record;
194 }
195
196
197 public function getRows(
198 DataRowBuilder $row_builder,
199 array $visible_column_ids,
201 Order $order,
202 mixed $additional_viewcontrol_data,
203 mixed $filter_data,
204 mixed $additional_parameters
205 ): Generator {
206 $records = $this->getRecords();
207
208 if ($order) {
209 [$order_field, $order_direction] = $order->join(
210 [],
211 fn($ret, $key, $value) => [$key, $value]
212 );
213
214 usort($records, static function (array $left, array $right) use ($order_field): int {
215 if (\in_array($order_field, ['title', 'type'], true)) {
216 if ($order_field === 'title') {
217 $order_field .= '_sortable';
218 }
219
220 return \ilStr::strCmp(
221 $left[$order_field],
222 $right[$order_field]
223 );
224 }
225
226 if ($order_field === 'active') {
227 return $right[$order_field] <=> $left[$order_field];
228 }
229
230 return $left[$order_field] <=> $right[$order_field];
231 });
232
233 if ($order_direction === Order::DESC) {
234 $records = array_reverse($records);
235 }
236 }
237
238 if ($range) {
239 $records = \array_slice($records, $range->getStart(), $range->getLength());
240 }
241
242 $identifications = [];
243 foreach ($records as $record) {
244 if ($record['badge']->getImageRid() !== null && $record['badge']->getImageRid() !== '') {
245 $identifications[] = $record['badge']->getImageRid();
246 }
247 }
248
249 $this->irss->preload($identifications);
250
251 $modal_container = new ModalBuilder();
252 foreach ($records as $record) {
253 $record = $this->enrichRecord($modal_container, $record);
254
255 yield $row_builder
256 ->buildDataRow((string) $record['id'], $record)
257 ->withDisabledAction(
258 'award_revoke_badge',
259 !$record['manual'] || !$record['active']
260 );
261 }
262 }
263
264 public function getTotalRowCount(
265 mixed $additional_viewcontrol_data,
266 mixed $filter_data,
267 mixed $additional_parameters
268 ): ?int {
269 return \count($this->getRecords());
270 }
271
275 private function getColumns(): array
276 {
277 return [
278 'image' => $this->factory->table()->column()->text($this->lng->txt('image'))->withIsSortable(false),
279 'title' => $this->factory->table()->column()->text($this->lng->txt('title')),
280 'type' => $this->factory->table()->column()->text($this->lng->txt('type')),
281 'active' => $this->factory->table()->column()->boolean(
282 $this->lng->txt('active'),
283 $this->lng->txt('yes'),
284 $this->lng->txt('no')
285 )->withOrderingLabels(
286 $this->lng->txt('badge_sort_active_badges_first'),
287 $this->lng->txt('badge_sort_active_badges_last')
288 )
289 ];
290 }
291
295 private function getActions(
296 URLBuilder $url_builder,
297 URLBuilderToken $action_parameter_token,
298 URLBuilderToken $row_id_token,
299 ): array {
300 return $this->has_write ? [
301 'badge_table_activate' =>
302 $this->factory->table()->action()->multi(
303 $this->lng->txt('activate'),
304 $url_builder->withParameter($action_parameter_token, 'badge_table_activate'),
305 $row_id_token
306 ),
307 'badge_table_deactivate' =>
308 $this->factory->table()->action()->multi(
309 $this->lng->txt('deactivate'),
310 $url_builder->withParameter($action_parameter_token, 'badge_table_deactivate'),
311 $row_id_token
312 ),
313 'badge_table_edit' => $this->factory->table()->action()->single(
314 $this->lng->txt('edit'),
315 $url_builder->withParameter($action_parameter_token, 'badge_table_edit'),
316 $row_id_token
317 ),
318 'badge_table_delete' =>
319 $this->factory->table()->action()->standard(
320 $this->lng->txt('delete'),
321 $url_builder->withParameter($action_parameter_token, 'badge_table_delete'),
322 $row_id_token
323 ),
324 'award_revoke_badge' =>
325 $this->factory->table()->action()->single(
326 $this->lng->txt('badge_award_revoke'),
327 $url_builder->withParameter($action_parameter_token, 'award_revoke_badge'),
328 $row_id_token
329 )
330 ] : [];
331 }
332
333 public function renderTable(string $url): void
334 {
335 $df = new \ILIAS\Data\Factory();
336
337 $table_uri = $df->uri($url);
338 $url_builder = new URLBuilder($table_uri);
339 $query_params_namespace = ['tid'];
340
341 [$url_builder, $action_parameter_token, $row_id_token] = $url_builder->acquireParameters(
342 $query_params_namespace,
343 'table_action',
344 'id',
345 );
346
347 $table = $this->factory
348 ->table()
349 ->data($this, $this->lng->txt('obj_bdga'), $this->getColumns())
350 ->withId(self::class . '_' . $this->parent_id)
351 ->withOrder(new Order('title', Order::ASC))
352 ->withActions($this->getActions($url_builder, $action_parameter_token, $row_id_token))
353 ->withRequest($this->request);
354 $out = [$table];
355
356 $query = $this->http->wrapper()->query();
357
358 if ($query->has($action_parameter_token->getName())) {
359 $action = $query->retrieve($action_parameter_token->getName(), $this->refinery->to()->string());
360 $ids = $query->retrieve($row_id_token->getName(), $this->refinery->custom()->transformation(fn($v) => $v));
361
362 if ($action === 'delete') {
363 $items = [];
364 foreach ($ids as $id) {
365 $items[] = $this->factory->modal()->interruptiveItem()->keyValue(
366 $id,
367 $row_id_token->getName(),
368 $id
369 );
370 }
371
372 $this->http->saveResponse(
373 $this->http
374 ->response()
375 ->withBody(
376 Streams::ofString($this->renderer->renderAsync([
377 $this->factory->modal()->interruptive(
378 $this->lng->txt('badge_deletion'),
379 $this->lng->txt('badge_deletion_confirmation'),
380 '#'
381 )->withAffectedItems($items)
382 ]))
383 )
384 );
385 $this->http->sendResponse();
386 $this->http->close();
387 }
388 }
389
390 $this->tpl->setContent($this->renderer->render($out));
391 }
392}
$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 ILIAS Refinery Factory $refinery
readonly ILIAS ResourceStorage Services $irss
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....
__construct(int $parent_obj_id, string $parent_obj_type, protected bool $has_write=false)
readonly ServerRequestInterface RequestInterface $request
readonly ilGlobalTemplateInterface $tpl
getActions(URLBuilder $url_builder, URLBuilderToken $action_parameter_token, URLBuilderToken $row_id_token,)
readonly ilBadgeImage $badge_image_service
enrichRecord(ModalBuilder $modal_builder, array $record)
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
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
static getExtendedTypeCaption(ilBadgeType $a_type)
static getInstancesByParentId(int $a_parent_id, ?array $a_filter=null)
language handling
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
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static http()
Fetches the global http state from ILIAS.
global $DIC
Definition: shib_login.php:26
$url
Definition: shib_logout.php:68