ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilMDVocabulariesGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21use ILIAS\HTTP\Services as HTTP;
22use ILIAS\UI\Factory as UIFactory;
23use ILIAS\UI\Renderer as UIRenderer;
24use ILIAS\UI\Component\Table\Data as DataTable;
27use ILIAS\UI\Component\Modal\RoundTrip as RoundtripModal;
36use ILIAS\Refinery\Factory as Refinery;
38use JetBrains\PhpStorm\NoReturn;
40
45{
46 protected const int MAX_CONFIRMATION_VALUES = 5;
47
48 protected ilCtrl $ctrl;
49 protected HTTP $http;
52 protected ilLanguage $lng;
54 protected UIFactory $ui_factory;
55 protected UIRenderer $ui_renderer;
58 protected Refinery $refinery;
59
60 protected VocabManager $vocab_manager;
63
65 {
66 global $DIC;
67
68 $services = new InternalServices($DIC);
69
70 $this->vocab_manager = $services->vocabularies()->manager();
71 $this->presentation = new Presentation(
72 $services->presentation()->elements(),
73 $services->presentation()->utilities(),
74 $services->vocabularies()->presentation(),
75 $services->vocabularies()->slotHandler(),
76 $services->structure()->structure(),
77 $services->paths()->navigatorFactory(),
78 $services->paths()->pathFactory()
79 );
80 $this->importer = new Importer(
81 $services->paths()->pathFactory(),
82 $this->vocab_manager->controlledVocabularyCreator(),
83 $services->vocabularies()->slotHandler()
84 );
85
86 $this->ctrl = $DIC->ctrl();
87 $this->http = $DIC->http();
88 $this->temp_files = $DIC->filesystem()->temp();
89 $this->lng = $DIC->language();
90 $this->tpl = $DIC->ui()->mainTemplate();
91 $this->toolbar = $DIC->toolbar();
92 $this->ui_factory = $DIC->ui()->factory();
93 $this->ui_renderer = $DIC->ui()->renderer();
94 $this->refinery = $DIC->refinery();
95
96 $this->parent_obj_gui = $parent_obj_gui;
97 $this->access_service = new ilMDSettingsAccessService(
98 $this->parent_obj_gui->getRefId(),
99 $DIC->access()
100 );
101
102 $this->lng->loadLanguageModule("meta");
103 }
104
105 public function executeCommand(): void
106 {
107 $next_class = $this->ctrl->getNextClass($this);
108 $cmd = $this->ctrl->getCmd();
109
110 if (
111 !$this->access_service->hasCurrentUserVisibleAccess() ||
112 !$this->access_service->hasCurrentUserReadAccess()
113 ) {
114 throw new ilPermissionException($this->lng->txt('no_permission'));
115 }
116
117 switch ($next_class) {
118 case strtolower(ilMDVocabularyUploadHandlerGUI::class):
120 $this->ctrl->forwardCommand($handler);
121
122 // no break
123 default:
124 if (!$cmd || $cmd === 'view') {
125 $cmd = 'showVocabularies';
126 }
127
128 $this->$cmd();
129 break;
130 }
131 }
132
133 public function showVocabularies(): void
134 {
135 $content = [];
136
137 if ($this->access_service->hasCurrentUserWriteAccess()) {
138 $import_modal = $this->getImportModal();
139 $this->toolbar->addComponent($this->getImportButton($import_modal->getShowSignal()));
140 $content[] = $import_modal;
141 }
142
143 $content[] = $this->getTable();
144
145 $this->tpl->setContent($this->ui_renderer->render($content));
146 }
147
148 public function tableAction(): void
149 {
150 $action = $this->fetchTableAction();
151 $vocab_id = $this->fetchVocabID();
152
153 if (
154 $vocab_id === '' ||
155 ($action !== 'show_all' && !$this->access_service->hasCurrentUserWriteAccess())
156 ) {
157 $this->ctrl->redirect($this, 'showVocabularies');
158 }
159
160 switch ($action) {
161 case 'delete':
162 $this->confirmDeleteVocabulary($vocab_id);
163 return;
164
165 case 'activate':
166 $this->activateVocabulary($vocab_id);
167 return;
168
169 case 'deactivate':
170 $this->deactivateVocabulary($vocab_id);
171 return;
172
173 case 'allow_custom_input':
174 $this->allowCustomInputForVocabulary($vocab_id);
175 return;
176
177 case 'disallow_custom_input':
178 $this->disallowCustomInputForVocabulary($vocab_id);
179 return;
180
181 case 'show_all':
182 $this->showAllValuesModalForVocabulary($vocab_id);
183 return;
184
185 default:
186 $this->ctrl->redirect($this, 'showVocabularies');
187 }
188 }
189
190 public function importVocabulary(): void
191 {
192 if (!$this->access_service->hasCurrentUserWriteAccess()) {
193 $this->ctrl->redirect($this, 'showVocabularies');
194 }
195
196 $message_type = 'failure';
197 $message_text = $this->lng->txt('md_vocab_import_upload_failed');
198
199 $modal = $this->getImportModal()->withRequest($this->http->request());
200
201 $upload_folder = null;
202 if ($modal->getData()) {
203 $upload_folder = (string) ($modal->getData()['file'][0] ?? null);
204 if (!$this->temp_files->hasDir($upload_folder)) {
205 $upload_folder = null;
206 }
207 }
208
209 $file_content = null;
210 if (!is_null($upload_folder)) {
211 $files = $files = $this->temp_files->listContents($upload_folder);
212 if (count($files) === 1 && ($files[0] ?? null)?->isFile()) {
213 $file_content = $this->temp_files->read($files[0]->getPath());
214 }
215 $this->temp_files->deleteDir($upload_folder);
216 }
217
218 if (!is_null($file_content)) {
219 $result = $this->importer->import($file_content);
220
221 if ($result->wasSuccessful()) {
222 $message_type = 'success';
223 $message_text = $this->lng->txt('md_vocab_import_successful');
224 } else {
225 $message_type = 'failure';
226 $message_text = sprintf(
227 $this->lng->txt('md_vocab_import_invalid'),
228 implode("<br/>", $result->getErrors())
229 );
230 }
231 }
232
233 $this->tpl->setOnScreenMessage($message_type, $message_text, true);
234 $this->ctrl->redirect($this, 'showVocabularies');
235 }
236
237 #[NoReturn] protected function confirmDeleteVocabulary(string $vocab_id): void
238 {
239 list($url_builder, $action_parameter_token, $vocabs_id_token) = $this->getTableURLBuilderAndParameters();
240 $key = $vocabs_id_token->getName();
241
242 $vocab = $this->vocab_manager->getVocabulary($vocab_id);
244 foreach ($this->presentation->makeValuesPresentable(
245 $vocab,
246 self::MAX_CONFIRMATION_VALUES
247 ) as $value) {
248 $value_items[] = $this->ui_factory->modal()->interruptiveItem()->standard(
249 '',
250 $value,
251 );
252 }
253
254 $this->ctrl->setParameter($this, $key, $vocab_id);
255 $link = $this->ctrl->getLinkTarget($this, 'deleteVocabulary');
256 $this->ctrl->clearParameters($this);
257
258 $modal = $this->ui_factory->modal()->interruptive(
259 $this->presentation->txt('md_vocab_delete_confirmation_title'),
260 $this->presentation->txtFill(
261 'md_vocab_delete_confirmation_text',
262 $this->presentation->makeSlotPresentable($vocab->slot()),
263 $vocab->source()
264 ),
265 $link
266 )->withAffectedItems($value_items);
267 echo $this->ui_renderer->renderAsync($modal);
269 }
270
271 protected function deleteVocabulary(): void
272 {
273 $vocab_id = $this->fetchVocabID();
274 if ($vocab_id !== '') {
275 $this->vocab_manager->actions()->delete(
276 $this->vocab_manager->getVocabulary($vocab_id)
277 );
278 }
279 $this->tpl->setOnScreenMessage(
280 GlobalTemplate::MESSAGE_TYPE_SUCCESS,
281 $this->lng->txt('md_vocab_deletion_successful'),
282 true
283 );
284 $this->ctrl->redirect($this, 'showVocabularies');
285 }
286
287 protected function activateVocabulary(string $vocab_id): void
288 {
289 $this->vocab_manager->actions()->activate(
290 $this->vocab_manager->getVocabulary($vocab_id)
291 );
292 $this->tpl->setOnScreenMessage(
293 GlobalTemplate::MESSAGE_TYPE_SUCCESS,
294 $this->lng->txt('md_vocab_update_successful'),
295 true
296 );
297 $this->ctrl->redirect($this, 'showVocabularies');
298 }
299
300 protected function deactivateVocabulary(string $vocab_id): void
301 {
302 $this->vocab_manager->actions()->deactivate(
303 $this->vocab_manager->getVocabulary($vocab_id)
304 );
305 $this->tpl->setOnScreenMessage(
306 GlobalTemplate::MESSAGE_TYPE_SUCCESS,
307 $this->lng->txt('md_vocab_update_successful'),
308 true
309 );
310 $this->ctrl->redirect($this, 'showVocabularies');
311 }
312
313 protected function allowCustomInputForVocabulary(string $vocab_id): void
314 {
315 $this->vocab_manager->actions()->allowCustomInput(
316 $this->vocab_manager->getVocabulary($vocab_id)
317 );
318 $this->tpl->setOnScreenMessage(
319 GlobalTemplate::MESSAGE_TYPE_SUCCESS,
320 $this->lng->txt('md_vocab_update_successful'),
321 true
322 );
323 $this->ctrl->redirect($this, 'showVocabularies');
324 }
325
326 protected function disallowCustomInputForVocabulary(string $vocab_id): void
327 {
328 $this->vocab_manager->actions()->disallowCustomInput(
329 $this->vocab_manager->getVocabulary($vocab_id)
330 );
331 $this->tpl->setOnScreenMessage(
332 GlobalTemplate::MESSAGE_TYPE_SUCCESS,
333 $this->lng->txt('md_vocab_update_successful'),
334 true
335 );
336 $this->ctrl->redirect($this, 'showVocabularies');
337 }
338
339 #[NoReturn] protected function showAllValuesModalForVocabulary(string $vocab_id): void
340 {
341 $vocab = $this->vocab_manager->getVocabulary($vocab_id);
342 $values = $this->ui_factory->listing()->unordered(
343 $this->presentation->makeValuesPresentable($vocab)
344 );
345 $modal = $this->ui_factory->modal()->roundtrip(
346 $this->presentation->txtFill(
347 'md_vocab_all_values_title',
348 $this->presentation->makeSlotPresentable($vocab->slot()),
349 $vocab->source()
350 ),
351 [$values]
352 );
353 echo $this->ui_renderer->renderAsync($modal);
354 exit;
355 }
356
357 protected function getTable(): DataTable
358 {
359 $column_factory = $this->ui_factory->table()->column();
360 $columns = [
361 'element' => $column_factory->text($this->lng->txt('md_vocab_element_column'))->withIsSortable(false),
362 'type' => $column_factory->status($this->lng->txt('md_vocab_type_column'))->withIsSortable(false),
363 'source' => $column_factory->text($this->lng->txt('md_vocab_source_column'))->withIsSortable(false),
364 'preview' => $column_factory->text($this->lng->txt('md_vocab_preview_column'))->withIsSortable(false),
365 'active' => $column_factory->statusIcon($this->lng->txt('md_vocab_active_column'))->withIsSortable(false),
366 'custom_input' => $column_factory->statusIcon($this->lng->txt('md_vocab_custom_input_column'))->withIsSortable(false)
367 ];
368
369 list($url_builder, $action_parameter_token, $row_id_token) = $this->getTableURLBuilderAndParameters();
370 $actions_factory = $this->ui_factory->table()->action();
371 $actions = [];
372
373 if ($this->access_service->hasCurrentUserWriteAccess()) {
374 $actions ['delete'] = $actions_factory->single(
375 $this->lng->txt('md_vocab_delete_action'),
376 $url_builder->withParameter($action_parameter_token, 'delete'),
377 $row_id_token
378 )->withAsync(true);
379 $actions['activate'] = $actions_factory->single(
380 $this->lng->txt('md_vocab_activate_action'),
381 $url_builder->withParameter($action_parameter_token, 'activate'),
382 $row_id_token
383 );
384 $actions['deactivate'] = $actions_factory->single(
385 $this->lng->txt('md_vocab_deactivate_action'),
386 $url_builder->withParameter($action_parameter_token, 'deactivate'),
387 $row_id_token
388 );
389 $actions['allow_custom_input'] = $actions_factory->single(
390 $this->lng->txt('md_vocab_allow_custom_input_action'),
391 $url_builder->withParameter($action_parameter_token, 'allow_custom_input'),
392 $row_id_token
393 );
394 $actions['disallow_custom_input'] = $actions_factory->single(
395 $this->lng->txt('md_vocab_disallow_custom_input_action'),
396 $url_builder->withParameter($action_parameter_token, 'disallow_custom_input'),
397 $row_id_token
398 );
399 }
400
401 $actions['show_all'] = $actions_factory->single(
402 $this->lng->txt('md_vocab_show_all_action'),
403 $url_builder->withParameter($action_parameter_token, 'show_all'),
404 $row_id_token
405 )->withAsync(true);
406
407 return $this->ui_factory->table()->data(
408 new DataRetrieval(
409 $this->vocab_manager,
410 $this->presentation,
411 $this->ui_factory
412 ),
413 $this->lng->txt('md_vocab_table_title'),
414 $columns,
415 )->withActions($actions)->withRequest($this->http->request());
416 }
417
418 protected function getImportModal(): RoundtripModal
419 {
420 $file_input = $this->ui_factory->input()->field()->file(
422 $this->lng->txt('md_import_file_vocab')
423 )->withAcceptedMimeTypes([MimeType::TEXT__XML])->withMaxFiles(1);
424
425 return $this->ui_factory->modal()->roundtrip(
426 $this->lng->txt('md_import_vocab_modal'),
427 null,
428 ['file' => $file_input],
429 $this->ctrl->getLinkTarget($this, 'importVocabulary')
430 );
431 }
432
433 protected function getImportButton(Signal $signal): Button
434 {
435 return $this->ui_factory->button()->standard(
436 $this->lng->txt('md_import_vocab'),
437 $signal
438 );
439 }
440
441 protected function fetchTableAction(): string
442 {
443 list($url_builder, $action_parameter_token, $vocabs_id_token) = $this->getTableURLBuilderAndParameters();
444 $key = $action_parameter_token->getName();
445 if ($this->http->wrapper()->query()->has($key)) {
446 return $this->http->wrapper()->query()->retrieve(
447 $key,
448 $this->refinery->identity()
449 );
450 }
451 return '';
452 }
453
454 protected function fetchVocabID(): string
455 {
456 list($url_builder, $action_parameter_token, $vocabs_id_token) = $this->getTableURLBuilderAndParameters();
457 $key = $vocabs_id_token->getName();
458 if ($this->http->wrapper()->query()->has($key)) {
459 return $this->http->wrapper()->query()->retrieve(
460 $key,
461 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
462 )[0] ?? '';
463 }
464 return '';
465 }
466
467 protected function getTableURLBuilderAndParameters(): array
468 {
469 $url_builder = new URLBuilder(new URI(
470 rtrim(ILIAS_HTTP_PATH, '/') . '/' . $this->ctrl->getLinkTarget($this, 'tableAction')
471 ));
472 return $url_builder->acquireParameters(
473 ['metadata', 'vocab'],
474 'table_action',
475 'ids'
476 );
477 }
478}
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
The scope of this class is split ilias-conform URI's into components.
Definition: URI.php:35
Mime type determination.
Definition: MimeType.php:30
Class Services.
Definition: Services.php:38
Class ilCtrl provides processing control methods.
language handling
@ilCtrl_Calls ilMDVocabulariesGUI: ilMDVocabularyUploadHandlerGUI
disallowCustomInputForVocabulary(string $vocab_id)
ilMDSettingsAccessService $access_service
allowCustomInputForVocabulary(string $vocab_id)
__construct(ilObjMDSettingsGUI $parent_obj_gui)
deactivateVocabulary(string $vocab_id)
ilGlobalTemplateInterface $tpl
activateVocabulary(string $vocab_id)
ilObjMDSettingsGUI $parent_obj_gui
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
The filesystem interface provides the public interface for the Filesystem service API consumer.
Definition: Filesystem.php:37
This describes a standard button.
Definition: Standard.php:27
This describes a Data Table.
Definition: Data.php:31
An entity that renders components to a string output.
Definition: Renderer.php:31
static http()
Fetches the global http state from ILIAS.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: Bulky.php:21
$handler
Definition: oai.php:29
global $DIC
Definition: shib_login.php:26