ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilDclRecordListGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22{
23 public const GET_TABLE_ID = 'table_id';
24 public const GET_TABLEVIEW_ID = 'tableview_id';
25 public const GET_MODE = "mode";
26 public const MODE_VIEW = "view";
27 public const MODE_MANAGE = "manage";
28 public const CMD_LIST_RECORDS = 'listRecords';
29 public const CMD_SHOW = 'show';
30 public const CMD_CONFIRM_DELETE_RECORDS = 'confirmDeleteRecords';
31 public const CMD_CANCEL_DELETE = 'cancelDelete';
32 public const CMD_DELETE_RECORDS = 'deleteRecords';
33 public const CMD_SHOW_IMPORT_EXCEL = 'showImportExcel';
34
37 protected \ILIAS\UI\Factory $ui_factory;
38 protected \ILIAS\UI\Renderer $renderer;
39
43 protected string $mode = self::MODE_VIEW;
45 protected ?int $table_id;
46 protected int $obj_id;
48 protected ?int $tableview_id;
50
51 protected ilCtrl $ctrl;
53 protected ilLanguage $lng;
54 protected ilTabsGUI $tabs;
57 protected \ILIAS\ResourceStorage\Services $irss;
58 protected bool $filter_changed = false;
59
63 public function __construct(ilObjDataCollectionGUI $a_parent_obj, int $table_id, int $tableview_id)
64 {
65 global $DIC;
66
67 $this->ctrl = $DIC->ctrl();
68 $this->toolbar = $DIC->toolbar();
69 $this->lng = $DIC->language();
70 $this->tabs = $DIC->tabs();
71 $this->http = $DIC->http();
72 $this->refinery = $DIC->refinery();
73 $this->irss = $DIC->resourceStorage();
74 $this->access = $DIC->access();
75 $this->tpl = $DIC->ui()->mainTemplate();
76 $this->ui_factory = $DIC->ui()->factory();
77 $this->renderer = $DIC->ui()->renderer();
78
79 $this->table_id = $table_id;
80 $this->tableview_id = $tableview_id;
81
82 $this->obj_id = $a_parent_obj->getObject()->getId();
83 $this->parent_obj = $a_parent_obj;
84 $this->table_obj = ilDclCache::getTableCache($table_id);
85
86 $this->ctrl->setParameterByClass(ilDclRecordEditGUI::class, self::GET_TABLE_ID, $this->table_id);
87 $this->ctrl->setParameterByClass(ilDclRecordEditGUI::class, self::GET_TABLEVIEW_ID, $this->tableview_id);
88 $this->ctrl->setParameterByClass(ilDclDetailedViewGUI::class, self::GET_TABLEVIEW_ID, $this->tableview_id);
89
90 $this->mode = self::MODE_VIEW;
91
92 if ($this->http->wrapper()->query()->has(self::GET_MODE)) {
93 $mode = $this->http->wrapper()->query()->retrieve(self::GET_MODE, $this->refinery->kindlyTo()->string());
94 if (in_array($mode, self::$available_modes, true)) {
95 $this->mode = $mode;
96 }
97 }
98 }
99
100 public function getRefId(): int
101 {
102 return $this->parent_obj->getRefId();
103 }
104
105 public function getObjId(): int
106 {
107 return $this->parent_obj->getObject()->getId();
108 }
109
114 public function executeCommand(): void
115 {
116 if (!$this->checkAccess()) {
117 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true);
118 return;
119 }
120
121 $this->ctrl->saveParameter($this, self::GET_MODE);
122 $cmd = $this->ctrl->getCmd(self::CMD_SHOW);
123
124 // 'show' fills all filters with the predefined values from the tableview,
125 // whereas 'listRecords' handels the filters "normally", filling them from the POST-variable
126 switch ($cmd) {
127 case self::CMD_SHOW:
130 $this->setSubTabs($this->mode);
131 $this->listRecords();
132 break;
134 $this->confirmDeleteRecords();
135 break;
137 $this->deleteRecords();
138 break;
140 $this->tabs->setBackTarget($this->lng->txt('back'), $this->ctrl->getLinkTarget($this));
141 $this->$cmd();
142 break;
143
144 default:
145 $this->$cmd();
146 break;
147 }
148 }
149
150 public function listRecords(): void
151 {
152 $list = $this->getRecordListTableGUI();
153
154 $this->createSwitchers();
155
156 $permission_to_add_or_import = ilObjDataCollectionAccess::hasPermissionToAddRecord(
157 $this->parent_obj->getRefId(),
158 $this->table_id
159 ) && $this->table_obj->hasCustomFields();
160 if ($permission_to_add_or_import) {
161 $this->ctrl->setParameterByClass(ilDclRecordEditGUI::class, "record_id", null);
162
163 $add_new = $this->ui_factory->button()->primary(
164 $this->lng->txt("dcl_add_new_record"),
165 $this->ctrl->getFormActionByClass(ilDclRecordEditGUI::class, "create")
166 );
167 $this->toolbar->addStickyItem($add_new);
168 }
169
170 if ($permission_to_add_or_import && $this->table_obj->getImportEnabled()) {
171 $this->ctrl->setParameterByClass(ilDclRecordEditGUI::class, "record_id", null);
172
173 $import_button = $this->ui_factory->button()->standard(
174 $this->lng->txt("dcl_import_records .xls"),
175 $this->ctrl->getFormActionByClass(ilDclRecordListGUI::class, self::CMD_SHOW_IMPORT_EXCEL)
176 );
177 $this->toolbar->addComponent($import_button);
178 }
179
180 if (count($this->table_obj->getRecordFields()) == 0) {
181 $message = $this->lng->txt("dcl_no_fields_yet") . " "
183 $this->parent_obj->getRefId(),
184 $this->table_id
185 ) ? $this->lng->txt("dcl_create_fields") : "");
186 $this->tpl->setOnScreenMessage('info', $message, true);
187 }
188
189 $target = '';
190 if ($this->http->wrapper()->query()->has('table_id')) {
191 $target .= $this->http->wrapper()->query()->retrieve('table_id', $this->refinery->to()->string());
192 }
193 if ($this->http->wrapper()->query()->has('tableview_id')) {
194 $target .= '_' . $this->http->wrapper()->query()->retrieve('tableview_id', $this->refinery->to()->string());
195 }
196
197 $this->tpl->setPermanentLink("dcl", $this->parent_obj->getRefId(), $target);
198
199 if ($desc = $this->table_obj->getDescription()) {
200 $desc = $this->refinery->string()->markdown()->toHTML()->transform($desc);
201 $desc = '<div class="ilDclTableDescription">' . $desc . '</div>';
202 }
203 $this->tpl->setContent($desc . $list->getHTML());
204 }
205
206 public function showImportExcel(?ilPropertyFormGUI $form = null): void
207 {
208 if (!$form) {
209 $form = $this->initImportForm();
210 }
211 $this->tpl->setContent($form->getHTML());
212 }
213
218 {
219 $form = new ilPropertyFormGUI();
220
221 $item = new ilCustomInputGUI();
222 $item->setHtml($this->lng->txt('dcl_file_format_description'));
223 $item->setTitle("Info");
224 $form->addItem($item);
225
226 $file = new ilFileInputGUI($this->lng->txt("import_file"), "import_file");
227 $file->setSuffixes(['xlsx']);
228 $file->setRequired(true);
229 $form->addItem($file);
230
231 $cb = new ilCheckboxInputGUI($this->lng->txt("dcl_simulate_import"), "simulate");
232 $cb->setInfo($this->lng->txt("dcl_simulate_info"));
233 $form->addItem($cb);
234
235 $form->addCommandButton("importExcel", $this->lng->txt("import"));
236
237 return $form;
238 }
239
243 public function importExcel(): void
244 {
246 $this->parent_obj->getRefId(),
247 $this->table_id
248 )) || !$this->table_obj->getImportEnabled()) {
249 throw new ilDclException($this->lng->txt("access_denied"));
250 }
251 $form = $this->initImportForm();
252 if ($form->checkInput()) {
253 $file = $form->getInput("import_file");
254 $file_location = $file["tmp_name"];
255 $simulate = $form->getInput("simulate");
256 $this->importRecords($file_location, (bool) $simulate);
257 } else {
258 $this->showImportExcel($form);
259 }
260 }
261
265 private function importRecords(string $file, bool $simulate = false): void
266 {
267 $importer = new ilDclContentImporter($this->parent_obj->object->getRefId(), $this->table_id);
268 $result = $importer->import($file, $simulate);
269
270 $this->endImport($result['line'], $result['warnings']);
271 }
272
277 public function endImport(int $i, array $warnings): void
278 {
279 $output = new ilTemplate("tpl.dcl_import_terminated.html", true, true, "components/ILIAS/DataCollection");
280 $output->setVariable("IMPORT_TERMINATED", $this->lng->txt("dcl_import_terminated") . ": " . $i);
281 foreach ($warnings as $warning) {
282 $output->setCurrentBlock("warnings");
283 $output->setVariable("WARNING", $warning);
284 $output->parseCurrentBlock();
285 }
286
287 $output->setVariable("BACK_LINK", $this->ctrl->getLinkTargetByClass(ilDclRecordListGUI::class, "listRecords"));
288 $output->setVariable("BACK", $this->lng->txt("back"));
289 $this->tpl->setContent($output->get());
290 }
291
295 protected function applyFilter(): void
296 {
297 $table = new ilDclRecordListTableGUI($this, "listRecords", $this->table_obj, $this->tableview_id);
298 $table->initFilter();
299 $table->resetOffset();
300 $table->writeFilterToSession();
301 $this->filter_changed = true;
302 $this->listRecords();
303 }
304
308 protected function resetFilter(): void
309 {
310 $table = new ilDclRecordListTableGUI($this, "show", $this->table_obj, $this->tableview_id);
311 $table->initFilter();
312 $table->resetOffset();
313 $table->resetFilter();
314 $this->filter_changed = true;
315 $this->listRecords();
316 }
317
321 public function sendFile(): void
322 {
323 $hasIlFileHash = $this->http->wrapper()->query()->has('ilfilehash');
324 //need read access to receive file
325 if ($this->access->checkAccess('read', "", $this->parent_obj->getRefId())) {
326 // deliver temp-files
327 if ($hasIlFileHash) {
328 $filehash = $this->http->wrapper()->query()->retrieve(
329 'ilfilehash',
330 $this->refinery->kindlyTo()->string()
331 );
332 $field_id = $this->http->wrapper()->query()->retrieve('field_id', $this->refinery->kindlyTo()->int());
334
335 $filepath = $_FILES["field_" . $field_id]['tmp_name'];
336 $filetitle = $_FILES["field_" . $field_id]['name'];
337
338 ilFileDelivery::deliverFileLegacy($filepath, $filetitle);
339 } else {
340 $rec_id = $this->http->wrapper()
341 ->query()
342 ->retrieve('record_id', $this->refinery->kindlyTo()->int());
343
344 $record = ilDclCache::getRecordCache($rec_id);
345 if (!$this->recordBelongsToCollection($record)) {
346 return;
347 }
348
349 $field_id = $this->http->wrapper()
350 ->query()
351 ->retrieve('field_id', $this->refinery->kindlyTo()->string());
352
353
354
355 // Find the current revision
356 $rid_string = $record->getRecordFieldValue($field_id);
357 $identification = $this->irss->manage()->find($rid_string);
358 if ($identification === null) {
359 return;
360 }
361 $current_revision = $this->irss->manage()->getCurrentRevision($identification);
362
363 // Download the File
364 $this->irss->consume()
365 ->download($identification)
366 ->overrideFileName($current_revision->getTitle())
367 ->run();
368 }
369 }
370 }
371
375 public function confirmDeleteRecords(): void
376 {
377 $this->tabs->clearTargets();
378
379 $conf = new ilConfirmationGUI();
380 $conf->setFormAction($this->ctrl->getFormAction($this));
381 $conf->setHeaderText($this->lng->txt('dcl_confirm_delete_records'));
382
383 $has_record_ids = $this->http->wrapper()->post()->has('record_ids');
384 $record_ids = [];
385 if ($has_record_ids) {
386 $record_ids = $this->http->wrapper()->post()->retrieve(
387 'record_ids',
388 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
389 );
390 }
391 $all_fields = $this->table_obj->getRecordFields();
392 foreach ($record_ids as $record_id) {
394 $record = ilDclCache::getRecordCache($record_id);
395 $record_data = "";
396 foreach ($all_fields as $field) {
397 $field_record = ilDclCache::getRecordFieldCache($record, $field);
398
399 $record_representation = ilDclCache::getRecordRepresentation($field_record);
400 if ($record_representation->getConfirmationHTML() != false) {
401 $record_data .= $field->getTitle() . ": " . $record_representation->getConfirmationHTML() . "<br />";
402 }
403 }
404 $conf->addItem('record_ids[]', (string) $record->getId(), $record_data);
405 }
406 $conf->addHiddenItem('table_id', (string) $this->table_id);
407 $conf->setConfirm($this->lng->txt('dcl_delete_records'), self::CMD_DELETE_RECORDS);
408 $conf->setCancel($this->lng->txt('cancel'), self::CMD_CANCEL_DELETE);
409 $this->tpl->setContent($conf->getHTML());
410 }
411
415 public function deleteRecords(): void
416 {
417 $has_record_ids = $this->http->wrapper()->post()->has('record_ids');
418 $record_ids = [];
419 if ($has_record_ids) {
420 $record_ids = $this->http->wrapper()->post()->retrieve(
421 'record_ids',
422 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
423 );
424 }
425
426 // Invoke deletion
427 $n_skipped = 0;
428 foreach ($record_ids as $record_id) {
430 $record = ilDclCache::getRecordCache($record_id);
431 $ref_id = $this->parent_obj->getRefId();
432
433 if ($record->hasPermissionToDelete($ref_id)) {
434 $record->doDelete();
435 } else {
436 $n_skipped++;
437 }
438 }
439
440 $n_deleted = (count($record_ids) - $n_skipped);
441 if ($n_deleted) {
442 $message = sprintf(
443 $this->lng->txt('dcl_deleted_records'),
444 $n_deleted
445 );
446 $this->tpl->setOnScreenMessage('success', $message, true);
447 }
448 if ($n_skipped) {
449 $message = sprintf(
450 $this->lng->txt('dcl_skipped_delete_records'),
451 $n_skipped
452 );
453 $this->tpl->setOnScreenMessage('info', $message, true);
454 }
455 $this->ctrl->redirect($this, self::CMD_LIST_RECORDS);
456 }
457
458 private function recordBelongsToCollection(ilDclBaseRecordModel $record): bool
459 {
460 $table = $record->getTable();
461 $obj_id = $this->parent_obj->object->getId();
462 $obj_id_rec = $table->getCollectionObject()->getId();
463
464 return $obj_id == $obj_id_rec;
465 }
466
467 protected function setSubTabs(string $active_mode = self::GET_MODE): void
468 {
469 $this->ctrl->setParameter($this, self::GET_MODE, self::MODE_VIEW);
470 $this->tabs->addSubTab(
471 self::MODE_VIEW,
472 $this->lng->txt('view'),
473 $this->ctrl->getLinkTarget($this, self::CMD_LIST_RECORDS)
474 );
475
476 $ref_id = $this->http->wrapper()->query()->retrieve('ref_id', $this->refinery->kindlyTo()->int());
477 if ($this->table_obj->hasPermissionToDeleteRecords($ref_id)) {
478 $this->ctrl->setParameter($this, self::GET_MODE, self::MODE_MANAGE);
479 $this->tabs->addSubTab(
480 self::MODE_MANAGE,
481 $this->lng->txt('dcl_manage'),
482 $this->ctrl->getLinkTarget($this, self::CMD_LIST_RECORDS)
483 );
484 }
485 $this->tabs->activateSubTab($active_mode);
486 $this->ctrl->clearParameters($this);
487 }
488
490 {
492
493 $list = new ilDclRecordListTableGUI($this, "listRecords", $table_obj, $this->tableview_id, $this->mode);
494 $list->initFilter();
495
496 $list->setExternalSegmentation(true);
497 $list->setExternalSorting(true);
498 $list->determineOffsetAndOrder();
499
500 if ($this->filter_changed) {
501 $list->resetOffset();
502 }
503
504 $limit = $list->getLimit();
505 $offset = $list->getOffset();
506
508 (string) $this->getRefId(),
509 $list->getOrderField(),
510 $list->getOrderDirection(),
511 $limit,
512 $offset,
513 $list->getFilter()
514 );
515 $records = $data['records'];
516 $total = $data['total'];
517
518 $list->setMaxCount($total);
519 $list->setRecordData($records);
520
521 $list->determineOffsetAndOrder();
522 $list->determineLimit();
523
524 return $list;
525 }
526
527 protected function createSwitchers(): void
528 {
529 if (ilObjDataCollectionAccess::hasWriteAccess($this->parent_obj->getRefId())) {
530 $tables = $this->parent_obj->object->getTables();
531 } else {
532 $tables = $this->parent_obj->object->getVisibleTables();
533 }
534
535 $switcher = new ilDclSwitcher($this->toolbar, $this->ui_factory, $this->ctrl, $this->lng);
536 $switcher->addTableSwitcherToToolbar(
537 $tables,
538 self::class,
539 self::CMD_SHOW
540 );
541
542 $switcher->addViewSwitcherToToolbar(
543 $this->table_obj->getVisibleTableViews(),
544 $this->getTableId(),
545 self::class,
546 self::CMD_SHOW
547 );
548 }
549
550 protected function checkAccess(): bool
551 {
552 if (null === $this->table_id || null === $this->tableview_id) {
553 return false;
554 }
555
556 return ilObjDataCollectionAccess::hasAccessTo(
557 $this->parent_obj->getRefId(),
558 $this->table_id,
559 $this->tableview_id
560 );
561 }
562
563 public function getTableId(): int
564 {
565 return $this->table_id;
566 }
567
568 public function getTableviewId(): int
569 {
570 return $this->tableview_id;
571 }
572}
renderer()
Builds data types.
Definition: Factory.php:36
Class Services.
Definition: Services.php:38
This class represents a checkbox property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilCtrl provides processing control methods.
This class represents a custom property in a property form.
static getRecordCache(?int $record_id)
static getRecordFieldCache(object $record, object $field)
static getTableCache(?int $table_id=null)
static getRecordRepresentation(ilDclBaseRecordFieldModel $record_field)
Returns a record representation.
static rebuildTempFileByHash(string $hash)
ilObjDataCollectionGUI $parent_obj
endImport(int $i, array $warnings)
End import.
ILIAS HTTP Services $http
importExcel()
Import Data from Excel sheet.
showImportExcel(?ilPropertyFormGUI $form=null)
__construct(ilObjDataCollectionGUI $a_parent_obj, int $table_id, int $tableview_id)
ILIAS Refinery Factory $refinery
recordBelongsToCollection(ilDclBaseRecordModel $record)
string $mode
Stores current mode active.
ILIAS ResourceStorage Services $irss
setSubTabs(string $active_mode=self::GET_MODE)
ilGlobalTemplateInterface $tpl
importRecords(string $file, bool $simulate=false)
Import records from Excel file.
getPartialRecords(string $ref_id, string $sort, string $direction, ?int $limit, int $offset, array $filter=[])
Return only the needed subset of record objects for the table, according to sorting,...
static deliverFileLegacy(string $a_file, ?string $a_filename=null, ?string $a_mime=null, ?bool $isInline=false, ?bool $removeAfterDelivery=false, ?bool $a_exit_after=true)
This class represents a file property in a property form.
language handling
static hasAccessToFields(int $ref_id, int $table_id)
static hasWriteAccess(int $ref, ?int $user_id=0)
static hasPermissionToAddRecord(int $ref_id, int $table_id)
@ilCtrl_Calls ilObjDataCollectionGUI: ilInfoScreenGUI, ilNoteGUI, ilCommonActionDispatcherGUI @ilCtrl...
This class represents a property form user interface.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
special template class to simplify handling of ITX/PEAR
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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
$message
Definition: xapiexit.php:31