1<?php 2/* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4use ILIAS\Filesystem\Filesystems; 5use ILIAS\FileUpload\FileUpload; 6use ILIAS\HTTP\GlobalHttpState; 7use ILIAS\UI\Factory; 8use ILIAS\UI\Renderer; 9 10/** 11 * Class ilAccessibilityDocumentGUI 12 */ 13class ilAccessibilityDocumentGUI implements ilAccessibilityControllerEnabled 14{ 15 /** @var ilAccessibilityTableDataProviderFactory */ 16 protected $tableDataProviderFactory; 17 18 /** @var ilObjAccessibilitySettings */ 19 protected $accs; 20 21 /** @var ilGlobalPageTemplate */ 22 protected $tpl; 23 24 /** @var ilCtrl */ 25 protected $ctrl; 26 27 /** @var ilLanguage */ 28 protected $lng; 29 30 /** @var ilRbacSystem */ 31 protected $rbacsystem; 32 33 /** @var ilErrorHandling */ 34 protected $error; 35 36 /** @var ilObjUser */ 37 protected $user; 38 39 /** @var ilLogger */ 40 protected $log; 41 42 /** @var Factory */ 43 protected $uiFactory; 44 45 /** @var Renderer */ 46 protected $uiRenderer; 47 48 /** @var ILIAS\HTTP\GlobalHttpState */ 49 protected $httpState; 50 51 /** @var ilToolbarGUI */ 52 protected $toolbar; 53 54 /** @var FileUpload */ 55 protected $fileUpload; 56 57 /** @var Filesystems */ 58 protected $fileSystems; 59 60 /** @var ilAccessibilityCriterionTypeFactoryInterface */ 61 protected $criterionTypeFactory; 62 63 /** @var ilHtmlPurifierInterface */ 64 protected $documentPurifier; 65 66 /** 67 * ilAccessibilityDocumentGUI constructor. 68 * @param ilObjAccessibilitySettings $accs 69 * @param ilAccessibilityCriterionTypeFactoryInterface $criterionTypeFactory 70 * @param ilGlobalPageTemplate $tpl 71 * @param ilObjUser $user 72 * @param ilCtrl $ctrl 73 * @param ilLanguage $lng 74 * @param ilRbacSystem $rbacsystem 75 * @param ilErrorHandling $error 76 * @param ilLogger $log 77 * @param ilToolbarGUI $toolbar 78 * @param GlobalHttpState $httpState 79 * @param Factory $uiFactory 80 * @param Renderer $uiRenderer 81 * @param Filesystems $fileSystems , 82 * @param FileUpload $fileUpload 83 * @param ilAccessibilityTableDataProviderFactory $tableDataProviderFactory 84 * @param ilHtmlPurifierInterface $documentPurifier 85 */ 86 public function __construct( 87 ilObjAccessibilitySettings $accs, 88 ilAccessibilityCriterionTypeFactoryInterface $criterionTypeFactory, 89 ilGlobalPageTemplate $tpl, 90 ilObjUser $user, 91 ilCtrl $ctrl, 92 ilLanguage $lng, 93 ilRbacSystem $rbacsystem, 94 ilErrorHandling $error, 95 ilLogger $log, 96 ilToolbarGUI $toolbar, 97 GlobalHttpState $httpState, 98 Factory $uiFactory, 99 Renderer $uiRenderer, 100 Filesystems $fileSystems, 101 FileUpload $fileUpload, 102 ilAccessibilityTableDataProviderFactory $tableDataProviderFactory, 103 ilHtmlPurifierInterface $documentPurifier 104 ) { 105 $this->accs = $accs; 106 $this->criterionTypeFactory = $criterionTypeFactory; 107 $this->tpl = $tpl; 108 $this->ctrl = $ctrl; 109 $this->lng = $lng; 110 $this->rbacsystem = $rbacsystem; 111 $this->error = $error; 112 $this->user = $user; 113 $this->log = $log; 114 $this->toolbar = $toolbar; 115 $this->httpState = $httpState; 116 $this->uiFactory = $uiFactory; 117 $this->uiRenderer = $uiRenderer; 118 $this->fileSystems = $fileSystems; 119 $this->fileUpload = $fileUpload; 120 $this->tableDataProviderFactory = $tableDataProviderFactory; 121 $this->documentPurifier = $documentPurifier; 122 } 123 124 /** 125 * 126 */ 127 public function executeCommand() : void 128 { 129 $cmd = $this->ctrl->getCmd(); 130 131 if (!$this->rbacsystem->checkAccess('read', $this->accs->getRefId())) { 132 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 133 } 134 135 if ($cmd == '' || !method_exists($this, $cmd)) { 136 $cmd = 'showDocuments'; 137 } 138 $this->$cmd(); 139 } 140 141 142 /** 143 * @throws ilDateTimeException 144 * @throws ilAccessibilityMissingDatabaseAdapterException 145 */ 146 protected function showDocuments() : void 147 { 148 if ($this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 149 $addDocumentBtn = $this->uiFactory->button()->primary( 150 $this->lng->txt('acc_add_document_btn_label'), 151 $this->ctrl->getLinkTarget($this, 'showAddDocumentForm') 152 ); 153 $this->toolbar->addStickyItem($addDocumentBtn); 154 } 155 156 $documentTableGui = new ilAccessibilityDocumentTableGUI( 157 $this, 158 'showDocuments', 159 $this->criterionTypeFactory, 160 $this->uiFactory, 161 $this->uiRenderer, 162 $this->rbacsystem->checkAccess('write', $this->accs->getRefId()) 163 ); 164 $documentTableGui->setProvider($this->tableDataProviderFactory->getByContext(ilAccessibilityTableDataProviderFactory::CONTEXT_DOCUMENTS)); 165 $documentTableGui->populate(); 166 167 $this->tpl->setContent($documentTableGui->getHTML()); 168 } 169 170 /** 171 * @param ilAccessibilityDocument $document 172 * @return ilAccessibilityDocumentFormGUI 173 */ 174 protected function getDocumentForm(ilAccessibilityDocument $document) : ilAccessibilityDocumentFormGUI 175 { 176 if ($document->getId() > 0) { 177 $this->ctrl->setParameter($this, 'acc_id', $document->getId()); 178 } 179 180 $formAction = $this->ctrl->getFormAction($this, 'saveAddDocumentForm'); 181 $saveCommand = 'saveAddDocumentForm'; 182 183 if ($document->getId() > 0) { 184 $formAction = $this->ctrl->getFormAction($this, 'saveEditDocumentForm'); 185 $saveCommand = 'saveEditDocumentForm'; 186 } 187 188 $form = new ilAccessibilityDocumentFormGUI( 189 $document, 190 $this->documentPurifier, 191 $this->user, 192 $this->fileSystems->temp(), 193 $this->fileUpload, 194 $formAction, 195 $saveCommand, 196 'showDocuments', 197 $this->rbacsystem->checkAccess('write', $this->accs->getRefId()) 198 ); 199 200 return $form; 201 } 202 203 /** 204 * 205 */ 206 protected function saveAddDocumentForm() : void 207 { 208 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 209 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 210 } 211 212 $form = $this->getDocumentForm(new ilAccessibilityDocument()); 213 if ($form->saveObject()) { 214 ilUtil::sendSuccess($this->lng->txt('saved_successfully'), true); 215 if ($form->hasTranslatedInfo()) { 216 ilUtil::sendInfo($form->getTranslatedInfo(), true); 217 } 218 $this->ctrl->redirect($this, 'showDocuments'); 219 } elseif ($form->hasTranslatedError()) { 220 ilUtil::sendFailure($form->getTranslatedError()); 221 } 222 223 $this->tpl->setContent($form->getHTML()); 224 } 225 226 /** 227 * 228 */ 229 protected function showAddDocumentForm() : void 230 { 231 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 232 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 233 } 234 235 $form = $this->getDocumentForm(new ilAccessibilityDocument()); 236 $this->tpl->setContent($form->getHTML()); 237 } 238 239 /** 240 * 241 */ 242 protected function showEditDocumentForm() : void 243 { 244 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 245 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 246 } 247 248 $document = $this->getFirstDocumentFromList($this->getDocumentsByServerRequest()); 249 250 $form = $this->getDocumentForm($document); 251 $this->tpl->setContent($form->getHTML()); 252 } 253 254 /** 255 * 256 */ 257 protected function saveEditDocumentForm() : void 258 { 259 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 260 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 261 } 262 263 $document = $this->getFirstDocumentFromList($this->getDocumentsByServerRequest()); 264 265 $form = $this->getDocumentForm($document); 266 if ($form->saveObject()) { 267 ilUtil::sendSuccess($this->lng->txt('saved_successfully'), true); 268 if ($form->hasTranslatedInfo()) { 269 ilUtil::sendInfo($form->getTranslatedInfo(), true); 270 } 271 $this->ctrl->redirect($this, 'showDocuments'); 272 } elseif ($form->hasTranslatedError()) { 273 ilUtil::sendFailure($form->getTranslatedError()); 274 } 275 276 $this->tpl->setContent($form->getHTML()); 277 } 278 279 /** 280 * @return ilAccessibilityDocument[] 281 */ 282 protected function getDocumentsByServerRequest() : array 283 { 284 $documents = []; 285 286 $documentIds = $this->httpState->request()->getParsedBody()['acc_id'] ?? []; 287 if (!is_array($documentIds) || 0 === count($documentIds)) { 288 $documentIds = $this->httpState->request()->getQueryParams()['acc_id'] ? [$this->httpState->request()->getQueryParams()['acc_id']] : []; 289 } 290 291 if (0 === count($documentIds)) { 292 return $documents; 293 } 294 295 $documents = ilAccessibilityDocument::where( 296 ['id' => array_filter(array_map('intval', $documentIds))], 297 ['id' => 'IN'] 298 )->getArray(); 299 300 return $documents; 301 } 302 303 /** 304 * @param array $documents 305 * @return ilAccessibilityDocument 306 * @throws UnexpectedValueException 307 */ 308 protected function getFirstDocumentFromList(array $documents) : ilAccessibilityDocument 309 { 310 if (1 !== count($documents)) { 311 throw new UnexpectedValueException('Expected exactly one document in list'); 312 } 313 314 $document = new ilAccessibilityDocument(0); 315 $document = $document->buildFromArray(current($documents)); 316 317 return $document; 318 } 319 320 /** 321 * 322 */ 323 protected function deleteDocuments() : void 324 { 325 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 326 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 327 } 328 329 $documents = $this->getDocumentsByServerRequest(); 330 if (0 === count($documents)) { 331 $this->showDocuments(); 332 return; 333 } else { 334 $documents = array_map(function (array $data) { 335 $document = new ilAccessibilityDocument(0); 336 $document = $document->buildFromArray($data); 337 338 return $document; 339 }, $documents); 340 } 341 342 $isDeletionRequest = (bool) ($this->httpState->request()->getQueryParams()['delete'] ?? false); 343 if ($isDeletionRequest) { 344 $this->processDocumentDeletion($documents); 345 346 $this->ctrl->redirect($this); 347 } else { 348 $this->ctrl->setParameter($this, 'delete', 1); 349 $confirmation = new ilConfirmationGUI(); 350 $confirmation->setFormAction($this->ctrl->getFormAction($this, 'deleteDocuments')); 351 $confirmation->setConfirm($this->lng->txt('confirm'), 'deleteDocuments'); 352 $confirmation->setCancel($this->lng->txt('cancel'), 'showDocuments'); 353 354 $confirmation->setHeaderText($this->lng->txt('acc_sure_delete_documents_p')); 355 if (1 === count($documents)) { 356 $confirmation->setHeaderText($this->lng->txt('acc_sure_delete_documents_s')); 357 } 358 359 foreach ($documents as $document) { 360 /** @var $document ilAccessibilityDocument */ 361 $confirmation->addItem('acc_id[]', $document->getId(), implode(' | ', [ 362 $document->getTitle() 363 ])); 364 } 365 366 $this->tpl->setContent($confirmation->getHTML()); 367 } 368 } 369 370 /** 371 * @param array $documents 372 */ 373 protected function processDocumentDeletion(array $documents) : void 374 { 375 foreach ($documents as $document) { 376 /** @var $document ilAccessibilityDocument */ 377 $document->delete(); 378 } 379 380 ilUtil::sendSuccess($this->lng->txt('acc_deleted_documents_p'), true); 381 if (1 === count($documents)) { 382 ilUtil::sendSuccess($this->lng->txt('acc_deleted_documents_s'), true); 383 } 384 } 385 386 /** 387 * 388 */ 389 protected function deleteDocument() : void 390 { 391 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 392 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 393 } 394 395 $document = $this->getFirstDocumentFromList($this->getDocumentsByServerRequest()); 396 397 $this->processDocumentDeletion([$document]); 398 399 $this->ctrl->redirect($this); 400 } 401 402 /** 403 * 404 */ 405 protected function saveDocumentSorting() : void 406 { 407 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 408 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 409 } 410 411 $sorting = $this->httpState->request()->getParsedBody()['sorting'] ?? []; 412 if (!is_array($sorting) || 0 === count($sorting)) { 413 $this->showDocuments(); 414 return; 415 } 416 417 asort($sorting, SORT_NUMERIC); 418 419 $position = 0; 420 foreach ($sorting as $documentId => $ignoredSortValue) { 421 if (!is_numeric($documentId)) { 422 continue; 423 } 424 425 try { 426 $document = new ilAccessibilityDocument((int) $documentId); 427 $document->setSorting(++$position); 428 $document->store(); 429 } catch (ilException $e) { 430 // Empty catch block 431 } 432 } 433 434 ilUtil::sendSuccess($this->lng->txt('acc_saved_sorting'), true); 435 $this->ctrl->redirect($this); 436 } 437 438 /** 439 * @param ilAccessibilityDocument $document 440 * @param ilAccessibilityDocumentCriterionAssignment $criterionAssignment 441 * @return ilAccessibilityCriterionFormGUI 442 */ 443 protected function getCriterionForm( 444 ilAccessibilityDocument $document, 445 ilAccessibilityDocumentCriterionAssignment $criterionAssignment 446 ) : ilAccessibilityCriterionFormGUI { 447 $this->ctrl->setParameter($this, 'acc_id', $document->getId()); 448 449 if ($criterionAssignment->getId() > 0) { 450 $this->ctrl->setParameter($this, 'crit_id', $criterionAssignment->getId()); 451 } 452 453 $formAction = $this->ctrl->getFormAction($this, 'saveAttachCriterionForm'); 454 $saveCommand = 'saveAttachCriterionForm'; 455 456 if ($criterionAssignment->getId() > 0) { 457 $formAction = $this->ctrl->getFormAction($this, 'saveChangeCriterionForm'); 458 $saveCommand = 'saveChangeCriterionForm'; 459 } 460 461 $form = new ilAccessibilityCriterionFormGUI( 462 $document, 463 $criterionAssignment, 464 $this->criterionTypeFactory, 465 $this->user, 466 $formAction, 467 $saveCommand, 468 'showDocuments' 469 ); 470 471 return $form; 472 } 473 474 /** 475 * 476 */ 477 protected function saveAttachCriterionForm() : void 478 { 479 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 480 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 481 } 482 483 $document = $this->getFirstDocumentFromList($this->getDocumentsByServerRequest()); 484 485 $form = $this->getCriterionForm($document, new ilAccessibilityDocumentCriterionAssignment()); 486 if ($form->saveObject()) { 487 ilUtil::sendSuccess($this->lng->txt('acc_doc_crit_attached'), true); 488 $this->ctrl->redirect($this, 'showDocuments'); 489 } elseif ($form->hasTranslatedError()) { 490 ilUtil::sendFailure($form->getTranslatedError()); 491 } 492 493 $this->tpl->setContent($form->getHTML()); 494 } 495 496 /** 497 * 498 */ 499 protected function showAttachCriterionForm() : void 500 { 501 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 502 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 503 } 504 505 $document = $this->getFirstDocumentFromList($this->getDocumentsByServerRequest()); 506 507 $form = $this->getCriterionForm($document, new ilAccessibilityDocumentCriterionAssignment()); 508 $this->tpl->setContent($form->getHTML()); 509 } 510 511 /** 512 * 513 */ 514 protected function showChangeCriterionForm() : void 515 { 516 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 517 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 518 } 519 520 $document = $this->getFirstDocumentFromList($this->getDocumentsByServerRequest()); 521 522 $criterionId = $this->httpState->request()->getQueryParams()['crit_id'] ?? 0; 523 if (!is_numeric($criterionId) || $criterionId < 1) { 524 $this->showDocuments(); 525 return; 526 } 527 528 $criterionAssignment = array_values(array_filter( 529 $document->criteria(), 530 function (ilAccessibilityDocumentCriterionAssignment $criterionAssignment) use ($criterionId) { 531 return $criterionAssignment->getId() == $criterionId; 532 } 533 ))[0]; 534 535 $form = $this->getCriterionForm($document, $criterionAssignment); 536 $this->tpl->setContent($form->getHTML()); 537 } 538 539 /** 540 * 541 */ 542 protected function saveChangeCriterionForm() : void 543 { 544 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 545 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 546 } 547 548 $document = $this->getFirstDocumentFromList($this->getDocumentsByServerRequest()); 549 550 $criterionId = $this->httpState->request()->getQueryParams()['crit_id'] ?? 0; 551 if (!is_numeric($criterionId) || $criterionId < 1) { 552 $this->showDocuments(); 553 return; 554 } 555 556 $criterionAssignment = array_values(array_filter( 557 $document->criteria(), 558 function (ilAccessibilityDocumentCriterionAssignment $criterionAssignment) use ($criterionId) { 559 return $criterionAssignment->getId() == $criterionId; 560 } 561 ))[0]; 562 563 $form = $this->getCriterionForm($document, $criterionAssignment); 564 if ($form->saveObject()) { 565 ilUtil::sendSuccess($this->lng->txt('acc_doc_crit_changed'), true); 566 $this->ctrl->redirect($this, 'showDocuments'); 567 } elseif ($form->hasTranslatedError()) { 568 ilUtil::sendFailure($form->getTranslatedError()); 569 } 570 571 $this->tpl->setContent($form->getHTML()); 572 } 573 574 /** 575 * 576 */ 577 public function detachCriterionAssignment() : void 578 { 579 if (!$this->rbacsystem->checkAccess('write', $this->accs->getRefId())) { 580 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); 581 } 582 583 $document = $this->getFirstDocumentFromList($this->getDocumentsByServerRequest()); 584 585 $criterionId = $this->httpState->request()->getQueryParams()['crit_id'] ?? 0; 586 if (!is_numeric($criterionId) || $criterionId < 1) { 587 $this->showDocuments(); 588 return; 589 } 590 591 $criterionAssignment = array_values(array_filter( 592 $document->criteria(), 593 function (ilAccessibilityDocumentCriterionAssignment $criterionAssignment) use ($criterionId) { 594 return $criterionAssignment->getId() == $criterionId; 595 } 596 ))[0]; 597 598 $document->detachCriterion($criterionAssignment); 599 $document->update(); 600 601 ilUtil::sendSuccess($this->lng->txt('acc_doc_crit_detached'), true); 602 $this->ctrl->redirect($this, 'showDocuments'); 603 } 604} 605