ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilBadgeTableGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\Badge;
22 
27 use ilLanguage;
34 use Generator;
37 use ilBadge;
38 use ilBadgeAuto;
41 
43 {
44  private readonly Factory $factory;
45  private readonly Renderer $renderer;
46  private readonly \ILIAS\Refinery\Factory $refinery;
48  private readonly Services $http;
49  private readonly int $parent_id;
50  private readonly string $parent_type;
51  private readonly ilLanguage $lng;
52  private readonly ilGlobalTemplateInterface $tpl;
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) {
104  return $this->cached_records;
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,
200  Range $range,
201  Order $order,
202  ?array $filter_data,
203  ?array $additional_parameters
204  ): Generator {
205  $records = $this->getRecords();
206 
207  if ($order) {
208  [$order_field, $order_direction] = $order->join(
209  [],
210  fn($ret, $key, $value) => [$key, $value]
211  );
212 
213  usort($records, static function (array $left, array $right) use ($order_field): int {
214  if (\in_array($order_field, ['title', 'type'], true)) {
215  if ($order_field === 'title') {
216  $order_field .= '_sortable';
217  }
218 
219  return \ilStr::strCmp(
220  $left[$order_field],
221  $right[$order_field]
222  );
223  }
224 
225  if ($order_field === 'active') {
226  return $right[$order_field] <=> $left[$order_field];
227  }
228 
229  return $left[$order_field] <=> $right[$order_field];
230  });
231 
232  if ($order_direction === Order::DESC) {
233  $records = array_reverse($records);
234  }
235  }
236 
237  if ($range) {
238  $records = \array_slice($records, $range->getStart(), $range->getLength());
239  }
240 
241  $identifications = [];
242  foreach ($records as $record) {
243  if ($record['badge']->getImageRid() !== null && $record['badge']->getImageRid() !== '') {
244  $identifications[] = $record['badge']->getImageRid();
245  }
246  }
247 
248  $this->irss->preload($identifications);
249 
250  $modal_container = new ModalBuilder();
251  foreach ($records as $record) {
252  $record = $this->enrichRecord($modal_container, $record);
253 
254  yield $row_builder
255  ->buildDataRow((string) $record['id'], $record)
256  ->withDisabledAction(
257  'award_revoke_badge',
258  !$record['manual'] || !$record['active']
259  );
260  }
261  }
262 
263  public function getTotalRowCount(
264  ?array $filter_data,
265  ?array $additional_parameters
266  ): ?int {
267  return \count($this->getRecords());
268  }
269 
273  private function getColumns(): array
274  {
275  return [
276  'image' => $this->factory->table()->column()->text($this->lng->txt('image'))->withIsSortable(false),
277  'title' => $this->factory->table()->column()->text($this->lng->txt('title')),
278  'type' => $this->factory->table()->column()->text($this->lng->txt('type')),
279  'active' => $this->factory->table()->column()->boolean(
280  $this->lng->txt('active'),
281  $this->lng->txt('yes'),
282  $this->lng->txt('no')
283  )->withOrderingLabels(
284  $this->lng->txt('badge_sort_active_badges_first'),
285  $this->lng->txt('badge_sort_active_badges_last')
286  )
287  ];
288  }
289 
293  private function getActions(
294  URLBuilder $url_builder,
295  URLBuilderToken $action_parameter_token,
296  URLBuilderToken $row_id_token,
297  ): array {
298  return $this->has_write ? [
299  'badge_table_activate' =>
300  $this->factory->table()->action()->multi(
301  $this->lng->txt('activate'),
302  $url_builder->withParameter($action_parameter_token, 'badge_table_activate'),
303  $row_id_token
304  ),
305  'badge_table_deactivate' =>
306  $this->factory->table()->action()->multi(
307  $this->lng->txt('deactivate'),
308  $url_builder->withParameter($action_parameter_token, 'badge_table_deactivate'),
309  $row_id_token
310  ),
311  'badge_table_edit' => $this->factory->table()->action()->single(
312  $this->lng->txt('edit'),
313  $url_builder->withParameter($action_parameter_token, 'badge_table_edit'),
314  $row_id_token
315  ),
316  'badge_table_delete' =>
317  $this->factory->table()->action()->standard(
318  $this->lng->txt('delete'),
319  $url_builder->withParameter($action_parameter_token, 'badge_table_delete'),
320  $row_id_token
321  ),
322  'award_revoke_badge' =>
323  $this->factory->table()->action()->single(
324  $this->lng->txt('badge_award_revoke'),
325  $url_builder->withParameter($action_parameter_token, 'award_revoke_badge'),
326  $row_id_token
327  )
328  ] : [];
329  }
330 
331  public function renderTable(string $url): void
332  {
333  $df = new \ILIAS\Data\Factory();
334 
335  $table_uri = $df->uri($url);
336  $url_builder = new URLBuilder($table_uri);
337  $query_params_namespace = ['tid'];
338 
339  [$url_builder, $action_parameter_token, $row_id_token] = $url_builder->acquireParameters(
340  $query_params_namespace,
341  'table_action',
342  'id',
343  );
344 
345  $table = $this->factory
346  ->table()
347  ->data($this, $this->lng->txt('obj_bdga'), $this->getColumns())
348  ->withId(self::class . '_' . $this->parent_id)
349  ->withOrder(new Order('title', Order::ASC))
350  ->withActions($this->getActions($url_builder, $action_parameter_token, $row_id_token))
351  ->withRequest($this->request);
352  $out = [$table];
353 
354  $query = $this->http->wrapper()->query();
355 
356  if ($query->has($action_parameter_token->getName())) {
357  $action = $query->retrieve($action_parameter_token->getName(), $this->refinery->to()->string());
358  $ids = $query->retrieve($row_id_token->getName(), $this->refinery->custom()->transformation(fn($v) => $v));
359 
360  if ($action === 'delete') {
361  $items = [];
362  foreach ($ids as $id) {
363  $items[] = $this->factory->modal()->interruptiveItem()->keyValue(
364  $id,
365  $row_id_token->getName(),
366  $id
367  );
368  }
369 
370  $this->http->saveResponse(
371  $this->http
372  ->response()
373  ->withBody(
374  Streams::ofString($this->renderer->renderAsync([
375  $this->factory->modal()->interruptive(
376  $this->lng->txt('badge_deletion'),
377  $this->lng->txt('badge_deletion_confirmation'),
378  '#'
379  )->withAffectedItems($items)
380  ]))
381  )
382  );
383  $this->http->sendResponse();
384  $this->http->close();
385  }
386  }
387 
388  $this->tpl->setContent($this->renderer->render($out));
389  }
390 }
constructModal(?Image $badge_image, string $badge_title, array $badge_properties=[])
readonly ilGlobalTemplateInterface $tpl
join($init, callable $fn)
Definition: Order.php:75
getActions(URLBuilder $url_builder, URLBuilderToken $action_parameter_token, URLBuilderToken $row_id_token,)
static getInstancesByParentId(int $a_parent_id, ?array $a_filter=null)
factory()
renderModal(Modal $modal)
renderer()
__construct(int $parent_obj_id, string $parent_obj_type, protected bool $has_write=false)
$url
Definition: shib_logout.php:68
readonly ILIAS Refinery Factory $refinery
readonly ilBadgeImage $badge_image_service
Both the subject and the direction need to be specified when expressing an order. ...
Definition: Order.php:28
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static http()
Fetches the global http state from ILIAS.
static getExtendedTypeCaption(ilBadgeType $a_type)
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...
getRows(DataRowBuilder $row_builder, array $visible_column_ids, Range $range, Order $order, ?array $filter_data, ?array $additional_parameters)
$out
Definition: buildRTE.php:24
global $DIC
Definition: shib_login.php:26
Builds data types.
Definition: Factory.php:35
static ofString(string $string)
Creates a new stream with an initial value.
Definition: Streams.php:41
readonly ServerRequestInterface RequestInterface $request
withParameter(URLBuilderToken $token, string|array $value)
Change an acquired parameter&#39;s value if the supplied token is valid.
Definition: URLBuilder.php:166
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
enrichRecord(ModalBuilder $modal_builder, array $record)
renderShyButton(string $label, Modal $modal)
URLBuilder.
Definition: URLBuilder.php:40
const DESC
Definition: Order.php:31
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:28
readonly ILIAS ResourceStorage Services $irss