ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilResourceCollectionGUI.php
Go to the documentation of this file.
1<?php
2
34use ILIAS\components\ResourceStorage\BinToHexSerializer;
40use ILIAS\Services\ResourceStorage\Collections\View\EditForm;
42
47{
48 use BinToHexSerializer;
49
50 public const P_RESOURCE_ID = 'resource_id';
51 public const P_RESOURCE_IDS = 'resource_ids';
52
53 public const CMD_INDEX = 'index';
54 public const CMD_INFO = 'info';
55 public const CMD_UPLOAD = 'upload';
56 public const CMD_POST_UPLOAD = 'postUpload';
57 public const CMD_REMOVE = 'remove';
58 public const CMD_DOWNLOAD = 'download';
59
60 public const CMD_UNZIP = 'unzip';
61 public const CMD_EDIT = 'rename';
62 public const CMD_RENDER_CONFIRM_REMOVE = 'renderConfirmRemove';
63 public const CMD_STORE = 'store';
70 private Services $http;
72 private \ILIAS\ResourceStorage\Services $irss;
75 private \ILIAS\UI\Factory $ui_factory;
79
80 final public function __construct(
81 private Configuration $view_configuration
82 ) {
83 global $DIC;
84 $this->ctrl = $DIC->ctrl();
85 $this->main_tpl = $DIC->ui()->mainTemplate();
86 $this->ui_renderer = $DIC->ui()->renderer();
87 $this->ui_factory = $DIC->ui()->factory();
88 $this->http = $DIC->http();
89 $this->refinery = $DIC->refinery();
90 $this->language = $DIC->language();
91 $this->language->loadLanguageModule('irss');
92 $this->irss = $DIC->resourceStorage();
93 $this->upload = $DIC->upload();
94 $this->archive = $DIC->archives();
95 $this->preview_definition = new PreviewDefinition();
96
97 $this->view_request = new Request(
98 $DIC->ctrl(),
99 $DIC->http()->wrapper()->query(),
100 $this->view_configuration
101 );
102
103 $data_provider = new TableDataProvider($this->view_request);
104
105 $this->action_builder = new ActionBuilder(
106 $this->view_request,
107 $this->ctrl,
108 $DIC->ui()->factory(),
109 $DIC->language(),
110 $this->irss
111 );
112
114 $this->view_request,
115 $data_provider,
116 $this->ctrl,
117 $DIC->ui()->factory(),
118 $DIC->language()
119 );
120
121 $upload_builder = new UploadBuilder(
122 $this->view_request,
123 $this->ctrl,
124 $DIC->ui()->factory(),
125 $DIC->language(),
126 $this
127 );
128
129 $this->view_factory = new ViewFactory(
130 $data_provider,
131 $this->action_builder,
133 $upload_builder
134 );
135 }
136
137 // CMD CLASS
138
144 {
145 $rid = $this->getResourceIdsFromRequest()[0] ?? null;
146 if ($rid === null || !$this->view_request->getCollection()->isIn($rid)) {
148 }
149 return $rid;
150 }
151
152 protected function abortWithPermissionDenied(): void
153 {
154 $this->main_tpl->setOnScreenMessage('failure', $this->language->txt('msg_no_perm_read'), true);
155 $this->ctrl->redirect($this, self::CMD_INDEX);
156 }
157
158 final public function executeCommand(): void
159 {
160 if ($this->view_request->handleViewTitle()) {
161 $title = $this->view_request->getTitle();
162 if ($title !== null) {
163 $this->main_tpl->setTitle($title);
164 }
165 $description = $this->view_request->getDescription();
166 if ($description !== null) {
167 $this->main_tpl->setDescription($description);
168 }
169 }
170
171 $this->view_request->init($this);
172
173 switch ($this->ctrl->getCmd(self::CMD_INDEX)) {
174 case self::CMD_INDEX:
175 $this->index();
176 break;
177 case self::CMD_UPLOAD:
178 $this->upload();
179 break;
181 $this->postUpload();
182 break;
183 case self::CMD_REMOVE:
184 $this->remove();
185 break;
187 $this->download();
188 break;
189 case self::CMD_UNZIP:
190 $this->unzip();
191 break;
193 $this->renderConfirmRemove();
194 break;
195 case self::CMD_EDIT:
196 $this->edit();
197 break;
198 case self::CMD_STORE:
199 $this->store();
200 break;
201 }
202 }
203
204 // RESOURCE COLLECTION GUI
205
206 private function index(): void
207 {
208 $provider = $this->view_factory->getComponentProvider($this->view_request);
209 $components = [];
210 foreach ($provider->getComponents() as $component) {
211 $components[] = $component;
212 }
213
214 $this->main_tpl->setContent($this->ui_renderer->render($components));
215 }
216
217 public function upload(): void
218 {
219 if (!$this->view_request->canUserUplaod()) {
221 return;
222 }
223 $this->upload->process();
224 if (!$this->upload->hasUploads()) {
225 return;
226 }
227 $collection = $this->view_request->getCollection();
228 foreach ($this->upload->getResults() as $result) {
229 if (!$result->isOK()) {
230 continue;
231 }
232 $rid = $this->irss->manage()->upload(
233 $result,
234 $this->view_configuration->getStakeholder()
235 );
236 $collection->add($rid);
237
238 // ensure flavour
239 $this->irss->flavours()->ensure(
240 $rid,
241 $this->preview_definition
242 );
243 }
244 $this->irss->collection()->store($collection);
245 $upload_result = new BasicHandlerResult(
246 self::P_RESOURCE_ID,
247 BasicHandlerResult::STATUS_OK,
248 $rid->serialize(),
249 ''
250 );
251 $response = $this->http->response()->withBody(Streams::ofString(json_encode($upload_result)));
252 $this->http->saveResponse($response);
253 $this->http->sendResponse();
254 $this->http->close();
255 }
256
257 private function postUpload(): void
258 {
259 if (!$this->view_request->canUserUplaod()) {
261 return;
262 }
263 $this->main_tpl->setOnScreenMessage('success', $this->language->txt('rids_appended'), true);
264 $this->ctrl->redirect($this, self::CMD_INDEX);
265 }
266
267 private function download(): void
268 {
269 $rid = $this->checkResourceOrRedirect();
270 $this->irss->consume()->download($rid)->run();
271 }
272
273 private function unzip(): void
274 {
275 if (!$this->view_request->canUserAdministrate()) {
277 return;
278 }
279 $rid = $this->checkResourceOrRedirect();
280 $zip_stream = $this->irss->consume()->stream($rid)->getStream();
281
282 $collection = $this->view_request->getCollection();
283
284 $unzip_options = $this->archive->unzipOptions()
285 ->withDirectoryHandling(ZipDirectoryHandling::FLAT_STRUCTURE);
286
287 foreach ($this->archive->unzip($zip_stream, $unzip_options)->getFileStreams() as $stream) {
288 $rid = $this->irss->manage()->stream(
289 Streams::ofString($stream->getContents()),
290 $this->view_configuration->getStakeholder(),
291 basename((string) $stream->getMetadata()['uri'])
292 );
293 $collection->add($rid);
294
295 // ensure flavour
296 try {
297 $this->irss->flavours()->ensure(
298 $rid,
299 $this->preview_definition
300 );
301 } catch (\Throwable) {
302 }
303 }
304 $this->irss->collection()->store($collection);
305 $this->postUpload();
306 }
307
308 private function edit(): void
309 {
310 if (!$this->view_request->canUserAdministrate()) {
312 return;
313 }
314 $rid = $this->checkResourceOrRedirect();
315 $this->ctrl->setParameter(
316 $this,
317 self::P_RESOURCE_ID,
318 $this->hash($rid->serialize())
319 );
320
321 // build simple form
322 $form = new EditForm(
323 $this->view_request,
324 $rid
325 );
326
327 $modal = $this->ui_factory->modal()->roundtrip(
328 $this->language->txt('edit'),
329 null,
330 $form->getFields(),
331 $this->ctrl->getLinkTarget($this, self::CMD_STORE)
332 );
333
334 $signal = $modal->getForm()->getSubmitSignal();
335
336 $stream = Streams::ofString(
337 $this->ui_renderer->renderAsync(
338 $modal
339 )
340 );
341
342 $this->http->saveResponse($this->http->response()->withBody($stream));
343 $this->http->sendResponse();
344 $this->http->close();
345 }
346
347 private function store(): void
348 {
349 if (!$this->view_request->canUserAdministrate()) {
351 return;
352 }
353 $rid = $this->checkResourceOrRedirect();
354 $form = (new EditForm(
355 $this->view_request,
356 $rid
357 ))->getAsForm($this->ctrl->getLinkTarget($this, self::CMD_STORE))
358 ->withRequest(
359 $this->http->request()
360 );
361 // Store the data
362 $form->getData();
363 $this->main_tpl->setOnScreenMessage('success', $this->language->txt('rids_updated'), true);
364 $this->ctrl->redirect($this, self::CMD_INDEX);
365 }
366
367 private function renderConfirmRemove(): void
368 {
369 if (!$this->view_request->canUserAdministrate()) {
371 return;
372 }
373 $rids = $this->getResourceIdsFromRequest();
374 $stream = Streams::ofString(
375 $this->ui_renderer->render(
376 $this->ui_factory->modal()->interruptive(
377 $this->language->txt('action_remove_resource'),
378 $this->language->txt('action_remove_resource_msg'),
379 $this->ctrl->getLinkTarget($this, self::CMD_REMOVE)
380 )->withAffectedItems(
381 array_map(function (ResourceIdentification $rid): Standard {
382 $revision = $this->irss->manage()->getCurrentRevision($rid);
383
384 return $this->ui_factory->modal()->interruptiveItem()->standard(
385 $this->hash($rid->serialize()),
386 $revision->getTitle()
387 );
388 }, $rids)
389 )
390 )
391 );
392 $this->http->saveResponse($this->http->response()->withBody($stream));
393 $this->http->sendResponse();
394 $this->http->close();
395 }
396
397 private function remove(): void
398 {
399 if (!$this->view_request->canUserAdministrate()) {
401 return;
402 }
403 $rids = $this->getResourceIdsFromRequest();
404 if (empty($rids)) {
405 $this->main_tpl->setOnScreenMessage('failure', $this->language->txt('msg_no_perm_read'), true);
406 $this->ctrl->redirect($this, self::CMD_INDEX);
407 return;
408 }
409 foreach ($rids as $rid) {
410 if (!$this->view_request->getCollection()->isIn($rid)) {
411 $this->main_tpl->setOnScreenMessage('failure', $this->language->txt('msg_no_perm_read'), true);
412 $this->ctrl->redirect($this, self::CMD_INDEX);
413 return;
414 }
415 }
416
417 foreach ($rids as $rid) {
418 $this->irss->manage()->remove($rid, $this->view_configuration->getStakeholder());
419 }
420
421 $this->main_tpl->setOnScreenMessage('success', $this->language->txt('rids_deleted'), true);
422 $this->ctrl->redirect($this, self::CMD_INDEX);
423 }
424
425 // REQUEST HELPERS
426
430 private function getResourceIdsFromRequest(): array
431 {
432 $token = $this->action_builder->getUrlToken();
433 $wrapper = $this->http->wrapper();
434 $to_string = $this->refinery->kindlyTo()->string();
435 $to_array_of_string = $this->refinery->to()->listOf($to_string);
436 $rid_string = null;
437
438 if ($wrapper->query()->has($token->getName())) {
439 try {
440 $rid_string = $wrapper->query()->retrieve(
441 $token->getName(),
442 $to_string
443 );
444 $rid_strings = explode(',', (string) $rid_string);
446 $rid_strings = $wrapper->query()->retrieve(
447 $token->getName(),
448 $to_array_of_string
449 );
450 }
451 }
452
453 if ($wrapper->post()->has('interruptive_items')) {
454 $rid_strings = $wrapper->post()->retrieve(
455 'interruptive_items',
456 $to_array_of_string
457 );
458 }
459
460 if (empty($rid_strings)) {
461 // try single resource
462 $rid_strings = $this->http->wrapper()->query()->has(self::P_RESOURCE_ID)
463 ? [$this->http->wrapper()->query()->retrieve(self::P_RESOURCE_ID, $this->refinery->kindlyTo()->string())]
464 : [];
465 }
466
467 if (isset($rid_strings[0]) && $rid_strings[0] === 'ALL_OBJECTS') {
468 return $this->view_request->getCollection()->getResourceIdentifications();
469 }
470
471 if ($rid_strings === []) {
472 return [];
473 }
474 $resource_identifications = [];
475 foreach ($rid_strings as $rid_string) {
476 $resource_identification = $this->irss->manage()->find($this->unhash($rid_string));
477 if ($resource_identification === null) {
478 continue;
479 }
480 $resource_identifications[] = $resource_identification;
481 }
482 return $resource_identifications;
483 }
484
485 // UPLOAD HANDLER
486 public function getFileIdentifierParameterName(): string
487 {
488 return self::P_RESOURCE_ID;
489 }
490
491 public function getUploadURL(): string
492 {
493 return $this->ctrl->getLinkTarget($this, self::CMD_UPLOAD);
494 }
495
496 public function getFileRemovalURL(): string
497 {
498 return '';
499 }
500
501 public function getExistingFileInfoURL(): string
502 {
503 return $this->ctrl->getLinkTarget($this, self::CMD_INFO);
504 }
505
506 public function getInfoForExistingFiles(array $file_ids): array
507 {
508 return [];
509 }
510
511 public function getInfoResult(string $identifier): ?FileInfoResult
512 {
513 return null;
514 }
515
516 public function supportsChunkedUploads(): bool
517 {
518 return false;
519 }
520}
$components
Builds data types.
Definition: Factory.php:36
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
language handling
ilGlobalTemplateInterface $main_tpl
__construct(private Configuration $view_configuration)
ILIAS ResourceStorage Services $irss
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...
$provider
Definition: ltitoken.php:80
static http()
Fetches the global http state from ILIAS.
@ FLAT_STRUCTURE
@description Will keep the top directory of the ZIP file if there is one (simple unzip).
global $DIC
Definition: shib_login.php:26
$token
Definition: xapitoken.php:70
$response
Definition: xapitoken.php:93