19declare(strict_types=1);
72 MimeType::APPLICATION__X_ZIP_COMPRESSED,
73 MimeType::APPLICATION__ZIP,
105 $this->db =
$DIC[
'ilDB'];
106 $this->log =
$DIC[
'ilLog'];
107 $this->
help = $DIC[
'ilHelp'];
108 $this->global_screen =
$DIC[
'global_screen'];
109 $this->component_factory =
$DIC[
'component.factory'];
110 $this->component_repository =
$DIC[
'component.repository'];
111 $this->navigation_history =
$DIC[
'ilNavigationHistory'];
112 $this->ui_service =
$DIC->uiService();
113 $this->taxonomy =
$DIC->taxonomy();
114 $this->archives =
$DIC->archives();
115 $this->content_style =
$DIC->contentStyle();
116 $this->skill_usage_service =
$DIC->skills()->usage();
118 $this->data_factory =
new DataFactory();
120 $local_dic = QuestionPoolDIC::dic();
121 $this->request_data_collector = $local_dic[
'request_data_collector'];
122 $this->questionrepository = $local_dic[
'question.general_properties.repository'];
123 $this->global_test_settings = $local_dic[
'global_test_settings'];
127 $this->
ctrl->saveParameter($this, [
135 $this->
ctrl->saveParameterByClass(
'ilAssQuestionPageGUI',
'consumer_context');
136 $this->
ctrl->saveParameterByClass(
'ilobjquestionpoolgui',
'consumer_context');
138 $this->
lng->loadLanguageModule(
'assessment');
140 $here_uri = $this->data_factory->uri($this->request->getUri()->__toString());
142 $query_params_namespace = [
'qpool',
'table'];
144 $query_params_namespace,
152 $this->notes_service->gui()->initJavascript();
157 $write_access = $this->
access->checkAccess(
'write',
'', $this->request_data_collector->getRefId());
159 if ((!$this->
access->checkAccess(
'read',
'', $this->request_data_collector->getRefId()))
160 && (!$this->access->checkAccess(
'visible',
'', $this->request_data_collector->getRefId()))) {
161 $this->
ilias->raiseError($this->
lng->txt(
'permission_denied'), $this->ilias->error_obj->MESSAGE);
165 $this->
access->checkAccess(
'read',
'', $this->request_data_collector->getRefId())) {
166 if (
'qpl' === $this->
object->getType()) {
167 $this->navigation_history->addItem(
168 $this->request_data_collector->getRefId(),
169 ilLink::_getLink($this->request_data_collector->getRefId(),
"qpl"),
175 $cmd = $this->
ctrl->getCmd(self::DEFAULT_CMD);
176 $next_class = $this->
ctrl->getNextClass($this);
177 $q_id = $this->request_data_collector->getQuestionId() ??
null;
179 if (in_array($next_class, [
'',
'ilobjquestionpoolgui']) && $cmd == self::DEFAULT_CMD) {
187 $q_type = $this->request_data_collector->string(
'question_type');
188 switch ($next_class) {
189 case 'ilcommonactiondispatchergui':
191 $this->
ctrl->forwardCommand($gui);
194 case 'ilobjectmetadatagui':
195 if (!$this->
access->checkAccess(
'write',
'', $this->object->getRefId())) {
196 $this->
error->raiseError($this->
lng->txt(
'permission_denied'), $this->error->WARNING);
199 $this->
ctrl->forwardCommand($md_gui);
202 case 'ilassquestionpreviewgui':
203 if (!$this->
access->checkAccess(
'read',
'', $this->object->getRefId())) {
207 $this->
ctrl->saveParameterByClass(ilAssQuestionPreviewGUI::class,
'q_id');
208 $this->
ctrl->saveParameter($this,
'q_id');
219 $this->global_screen,
225 $question_gui = assQuestion::instantiateQuestionGUI($this->request_data_collector->int(
'q_id'));
227 $this->
lng->txt(
'edit_question'),
228 $this->ctrl->getLinkTargetByClass(
229 get_class($question_gui),
233 $gui->addAdditionalCmd(
234 $this->
lng->txt(
'edit_page'),
235 $this->ctrl->getLinkTargetByClass(
236 ilAssQuestionPageGUI::class,
245 $gui->initPreviewSettings($this->
object->getRefId());
246 $gui->initPreviewSession($this->
user->getId(), $this->fetchAuthoringQuestionIdParamater());
247 $this->
ctrl->clearParameterByClass(self::class,
'q_id');
248 $this->tabs_gui->setBackTarget(
249 $this->
lng->txt(
'backtocallingpool'),
250 $this->ctrl->getLinkTargetByClass(self::class, self::DEFAULT_CMD)
253 $this->
help->setScreenIdComponent(
'qpl');
255 $this->
ctrl->forwardCommand($gui);
258 case 'ilassquestionpagegui':
259 if ($cmd ==
'finishEditing') {
260 $this->
ctrl->redirectByClass(
'ilassquestionpreviewgui',
'show');
263 if ($cmd ===
'edit' && !$this->
access->checkAccess(
'write',
'', $this->object->getRefId())) {
266 $this->tpl->setCurrentBlock(
'ContentStyle');
268 $this->tpl->parseCurrentBlock();
270 $this->tpl->setCurrentBlock(
'SyntaxStyle');
272 $this->tpl->parseCurrentBlock();
275 $question_gui->setQuestionTabs();
276 $question_gui->getObject()->setObjId($this->
object->getId());
277 $question_gui->setQuestionActionCmd(
'');
279 if ($this->
object->getType() ===
'qpl') {
280 $question_gui->addHeaderAction();
283 $question = $question_gui->getObject();
285 if ($this->questionrepository->isInActiveTest($question->getObjId())) {
286 $this->tpl->setOnScreenMessage(
288 $this->
lng->txt(
'question_is_part_of_running_test'),
294 $this->
ctrl->saveParameter($this,
'q_id');
295 $this->
lng->loadLanguageModule(
'content');
296 $this->
ctrl->setReturnByClass(
'ilAssQuestionPageGUI',
'view');
297 $this->
ctrl->setReturn($this, self::DEFAULT_CMD);
299 $page_gui->setFileDownloadLink(
300 $this->
ctrl->getLinkTargetByClass(ilObjQuestionPoolGUI::class,
'downloadFile')
302 $page_gui->obj->addUpdateListener(
306 $page_gui->setEditPreview(
true);
307 $page_gui->setEnabledTabs(
false);
308 $page_gui->setQuestionHTML([$question_gui->getObject()->getId() => $question_gui->getPreview(
true)]);
309 $page_gui->setTemplateTargetVar(
'ADM_CONTENT');
310 $page_gui->setOutputMode(
'edit');
311 $page_gui->setHeader($question->getTitleForHTMLOutput());
312 $page_gui->setPresentationTitle($question->getTitleForHTMLOutput());
313 $ret = $this->
ctrl->forwardCommand($page_gui);
315 $this->tpl->setContent($ret);
319 case 'ilpermissiongui':
321 $this->
ctrl->forwardCommand($perm_gui);
324 case 'ilobjectcopygui':
327 $this->
ctrl->forwardCommand($cp);
332 $ret = $this->
ctrl->forwardCommand($exp_gui);
335 case strtolower(ilInfoScreenGUI::class):
339 case 'illocalunitconfigurationgui':
340 if (!$this->
access->checkAccess(
'write',
'', $this->object->getRefId())) {
341 $this->
error->raiseError($this->
lng->txt(
'permission_denied'), $this->error->WARNING);
347 $question = $question_gui->getObject();
348 $question->setObjId($this->
object->getId());
349 $question_gui->setObject($question);
350 $question_gui->setQuestionTabs();
352 $this->
ctrl->setReturn($this, self::DEFAULT_CMD);
356 $this->
ctrl->forwardCommand($gui);
359 case 'ilassquestionfeedbackeditinggui':
360 if (!$this->
access->checkAccess(
'write',
'', $this->object->getRefId())) {
364 $this->
ctrl->setReturn($this, self::DEFAULT_CMD);
369 $question = $question_gui->getObject();
370 $question->setObjId($this->
object->getId());
371 $question_gui->setObject($question);
372 $question_gui->setQuestionTabs();
374 if ($this->questionrepository->isInActiveTest($question_gui->getObject()->getObjId())) {
375 $this->tpl->setOnScreenMessage(
377 $this->
lng->txt(
'question_is_part_of_running_test'),
383 $this->
help->setScreenIdComponent(
'qpl');
385 if ($this->
object->getType() ==
'qpl' && $write_access) {
386 $question_gui->addHeaderAction();
396 $this->request_data_collector,
397 $this->content_style,
400 $this->
ctrl->forwardCommand($gui);
404 case 'ilobjquestionpoolsettingsgeneralgui':
417 $this->
ctrl->forwardCommand($gui);
420 case strtolower(ilTaxonomySettingsGUI::class):
431 $this->component_repository,
438 $forwarder->forward();
442 case strtolower(ilQuestionPoolSkillAdministrationGUI::class):
446 $this->
ctrl->forwardCommand(
458 $this->component_repository,
462 $this->skill_usage_service,
463 $this->request_data_collector,
469 case 'ilbulkeditquestionsgui':
470 if (!$this->
access->checkAccess(
'read',
'', $this->object->getRefId())) {
473 $this->tabs_gui->setBackTarget(
474 $this->
lng->txt(
'backtocallingpool'),
475 $this->ctrl->getLinkTargetByClass(self::class, self::DEFAULT_CMD)
477 $this->tabs_gui->addTarget(
481 $this->
ctrl->getCmdClass(),
484 $this->tabs_gui->setTabActive(
'edit_questions');
486 $gui = new \ilBulkEditQuestionsGUI(
494 $this->request_wrapper,
497 $this->
ctrl->forwardCommand($gui);
500 case 'ilobjquestionpoolgui':
503 if ($action = $this->request_data_collector->string($this->action_parameter_token->getName())) {
504 $ids = $this->request_data_collector->raw($this->row_id_token->getName()) ??
null;
507 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'msg_no_questions_selected'),
true);
508 $this->
ctrl->redirect($this, self::DEFAULT_CMD);
510 if ($ids[0] ===
'ALL_OBJECTS') {
511 $ids = $this->
object->getAllQuestionIds();
513 if (!is_array($ids)) {
514 $ids = explode(
',', $ids);
516 $ids = array_map(
'intval', $ids);
518 $this->
ctrl->setParameterByClass(ilAssQuestionPreviewGUI::class,
'q_id', current($ids));
522 $this->
ctrl->redirectToURL(
527 $this->
ctrl->redirectToURL(
531 case 'edit_question':
532 $class = strtolower($this->questionrepository->getForQuestionId(current($ids))->getGuiClassName());
533 $this->
ctrl->setParameterByClass($class,
'q_id', current($ids));
534 $this->
ctrl->redirectToURL(
535 $this->
ctrl->getLinkTargetByClass($class,
'editQuestion')
539 $this->
ctrl->setParameterByClass(ilAssQuestionPageGUI::class,
'q_id', current($ids));
540 $this->
ctrl->redirectToURL(
541 $this->
ctrl->getLinkTargetByClass(ilAssQuestionPageGUI::class,
'edit')
545 $this->
ctrl->setParameterByClass(ilAssQuestionFeedbackEditingGUI::class,
'q_id', current($ids));
546 $this->
ctrl->redirectToURL(
552 $this->
ctrl->redirectByClass(self::class, self::DEFAULT_CMD);
556 $this->
ctrl->redirectByClass(self::class, self::DEFAULT_CMD);
563 $this->
ctrl->redirectByClass(self::class, self::DEFAULT_CMD);
568 $this->
object->getRefId(),
570 $this->object->getId(),
576 .
' event = new Event("click");'
585 $this->
ctrl->clearParameters($this);
586 $this->
ctrl->setParameterByClass(
587 ilBulkEditQuestionsGUI::class,
591 $this->
ctrl->redirectToURL(
592 $this->
ctrl->getLinkTargetByClass(
593 ilBulkEditQuestionsGUI::class,
600 throw new \Exception(
"'{$action}' not implemented");
606 if ($cmd == self::DEFAULT_CMD) {
607 $this->
ctrl->setParameterByClass(self::class,
'q_id',
'');
610 $ret = $this->$cmd();
616 [
'editQuestion',
'save',
'suggestedsolution',
'uploadImage',
'removeImage']
617 ) && !$this->
access->checkAccess(
620 $this->object->getRefId()
625 $this->
ctrl->setReturnByClass(self::class, self::DEFAULT_CMD);
633 $question = $question_gui->getObject();
634 $question->setObjId($this->
object->getId());
635 $question_gui->setObject($question);
637 if ($this->
object->getType() ===
'qpl') {
638 $question_gui->setTaxonomyIds($this->
object->getTaxonomyIds());
641 $question_gui->addHeaderAction();
645 $this->
help->setScreenIdComponent(
'qpl');
647 if ($qid === 0 && $question_gui->cmdNeedsExistingQuestion($cmd)) {
648 $question_gui->getObject()->createNewQuestion();
651 $question_gui->setQuestionTabs();
653 if (!in_array($cmd, [
'save',
'saveReturn'])) {
654 $question_gui->$cmd();
658 if (!$question_gui->saveQuestion()) {
661 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'msg_obj_modified'),
true);
662 if ($cmd ===
'saveReturn') {
663 $this->
ctrl->setParameterByClass(
664 ilAssQuestionPreviewGUI::class,
666 (
string) $question_gui->getObject()->getId()
668 $this->
ctrl->redirectToURL(
673 if ($cmd ===
'save') {
674 $this->tabs_gui->activateTab(
'edit_question');
675 $question_gui->editQuestion(
false,
false);
680 if (!(strtolower($this->request_data_collector->raw(
'baseClass')) ==
'iladministrationgui'
681 || strtolower($this->request_data_collector->raw(
'baseClass')) ==
'ilrepositorygui')
682 && $this->getCreationMode() !=
true) {
683 $this->tpl->printToStdout();
689 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'no_permission'),
true);
690 $target_class = get_class($this->
object) .
'GUI';
691 $this->
ctrl->setParameterByClass($target_class,
'ref_id', $this->ref_id);
692 $this->
ctrl->redirectByClass($target_class);
701 $this->
ctrl->redirectByClass(
'ilQuestionPoolExportGUI');
706 $file = explode(
'_', $this->request_data_collector->raw(
'file_id'));
707 $fileObj =
new ilObjFile((
int) $file[count($file) - 1],
false);
708 $fileObj->sendFile();
718 $page_gui->setFileDownloadLink(
719 $this->
ctrl->getLinkTargetByClass(ilObjQuestionPoolGUI::class,
'downloadFile')
721 $page_gui->showMediaFullscreen();
730 $pg_obj->sendParagraph($this->request_data_collector->raw(
'par_id'), $this->request_data_collector->raw(
'downloadtitle'));
736 if ($this->creation_mode
737 && !$this->
checkPermissionBool(
'create',
'', $this->request_data_collector->string(
'new_type'))
738 || !$this->creation_mode
739 && !$this->checkPermissionBool(
'read',
'', $this->object->getType())) {
748 $new_obj->setType($this->request_data_collector->raw(
'new_type'));
749 $new_obj->setTitle(
'dummy');
750 $new_obj->setDescription(
'questionpool import');
751 $new_obj->create(
true);
752 $new_obj->createReference();
753 $new_obj->putInTree($this->request_data_collector->getRefId());
754 $new_obj->setPermissions($this->request_data_collector->getRefId());
757 'importVerifiedFile',
763 if (is_file($importdir . DIRECTORY_SEPARATOR .
'manifest.xml')) {
778 $new_obj->fromXML($xmlfile);
781 $new_obj->saveToDb();
785 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'object_imported'),
true);
786 $this->
ctrl->setParameterByClass(self::class,
'ref_id', $new_obj->getRefId());
787 $this->
ctrl->redirectByClass(self::class);
794 if (mb_substr($file_to_import, -3) ===
'xml') {
795 $importdir = dirname($file_to_import);
797 'importVerifiedQuestionsFile',
811 'importVerifiedQuestionsFile',
816 if (is_file($importdir . DIRECTORY_SEPARATOR .
'manifest.xml')) {
835 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'object_imported'),
true);
842 $data = $import_questions_modal->getData();
843 if (
$data ===
null) {
845 $import_questions_modal->withOnLoad(
846 $import_questions_modal->getShowSignal()
851 $path_to_imported_file_in_temp_dir =
$data[
'import_file'][0];
857 $constraint = $this->
refinery->custom()->constraint(
858 function ($vs):
bool {
864 $this->
lng->txt(
'msg_no_files_selected')
867 $file_upload_input = $this->ui_factory->input()->field()
869 ->withAcceptedMimeTypes(self::SUPPORTED_IMPORT_MIME_TYPES)
871 ->withAdditionalTransformation($constraint);
872 return $this->ui_factory->modal()->roundtrip(
873 $this->
lng->txt(
'import'),
875 [
'import_file' => $file_upload_input],
876 $this->ctrl->getFormActionByClass(self::class,
'uploadQuestionsImport')
877 )->withSubmitLabel($this->
lng->txt(
'import'));
882 array $selected_questions,
883 string $file_to_import
885 ilSession::set(
'qpl_import_selected_questions', $selected_questions);
886 $imp =
new ilImport($this->request_data_collector->getRefId());
887 $map = $imp->getMapping();
888 $map->addMapping(
'components/ILIAS/TestQuestionPool',
'qpl',
'new_id', (
string) $obj->
getId());
889 $imp->importObject($obj, $file_to_import, basename($file_to_import),
'qpl',
'components/ILIAS/TestQuestionPool',
true);
894 array $selected_questions,
908 if ($xmlfile ===
'') {
917 $cont_parser->setQuestionMapping($qti_parser->getImportMapping());
918 $cont_parser->startParsing();
924 $this->deleteUploadedImportFile(
ilSession::get(
'path_to_uploaded_file_in_temp_dir'));
929 public function createQuestionObject(): void
931 $form = $this->buildQuestionCreationForm()->withRequest($this->request);
932 $data_with_section = $form->getData();
933 if ($data_with_section ===
null) {
934 $this->createQuestionFormObject($form);
937 $data = $data_with_section[0];
939 $this->
ctrl->setReturnByClass(self::class, self::DEFAULT_CMD);
945 $question = $question_gui->getObject();
946 $question->setObjId($this->
object->getId());
947 $question->setAdditionalContentEditingMode(
$data[
'editing_type']);
948 $question_gui->setObject($question);
949 $question_gui->setQuestionTabs();
950 $question_gui->editQuestion();
956 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'object_added'),
true);
959 'ilias.php?ref_id=' . $new_object->
getRefId() .
960 '&baseClass=ilObjQuestionPoolGUI'
966 $rbacsystem = $this->rbac_system;
968 $questionIdsToDelete = array_filter(array_map(
'intval', $ids));
969 if (0 === count($questionIdsToDelete)) {
970 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'qpl_delete_select_none'),
true);
971 $this->
ctrl->redirect($this, self::DEFAULT_CMD);
974 $this->tpl->setOnScreenMessage(
'question', $this->
lng->txt(
'qpl_confirm_delete_questions'));
975 $deleteable_questions = $this->
object->getDeleteableQuestionDetails($questionIdsToDelete);
976 $table_gui =
new ilQuestionBrowserTableGUI($this, self::DEFAULT_CMD, (($rbacsystem->checkAccess(
'write', $this->request_data_collector->getRefId()) ?
true :
false)),
true);
977 $table_gui->setShowRowsSelector(
false);
978 $table_gui->setLimit(PHP_INT_MAX);
979 $table_gui->setEditable($rbacsystem->checkAccess(
'write', $this->request_data_collector->getRefId()));
980 $table_gui->setData($deleteable_questions);
981 $this->tpl->setVariable(
'ADM_CONTENT', $table_gui->getHTML());
989 $rbacsystem = $this->rbac_system;
991 $questionIdsToDelete = $this->request_data_collector->isset(
'q_id') ? (array) $this->request_data_collector->raw(
'q_id') : [];
992 if ($questionIdsToDelete === [] && $this->request_data_collector->isset(
'q_id')) {
993 $questionIdsToDelete = [$this->request_data_collector->getQuestionId()];
996 $questionIdsToDelete = array_filter(array_map(
'intval', $questionIdsToDelete));
997 if ($questionIdsToDelete === []) {
998 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'qpl_delete_select_none'),
true);
999 $this->
ctrl->redirect($this, self::DEFAULT_CMD);
1002 $this->tpl->setOnScreenMessage(
'question', $this->
lng->txt(
'qpl_confirm_delete_questions'));
1003 $deleteable_questions = &$this->
object->getDeleteableQuestionDetails($questionIdsToDelete);
1007 (($rbacsystem->checkAccess(
'write', $this->request_data_collector->getRefId()) ?
true :
false)),
1010 $table_gui->setShowRowsSelector(
false);
1011 $table_gui->setLimit(PHP_INT_MAX);
1012 $table_gui->setEditable($rbacsystem->checkAccess(
'write', $this->request_data_collector->getRefId()));
1013 $table_gui->setData($deleteable_questions);
1014 $this->tpl->setVariable(
'ADM_CONTENT', $table_gui->getHTML());
1022 $qst_ids = $this->request_data_collector->intArray(
'q_id');
1023 foreach ($qst_ids as $value) {
1024 $this->
object->deleteQuestion((
int) $value);
1025 $this->
object->cleanupClipboard((
int) $value);
1027 if ($qst_ids !== []) {
1028 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'qpl_questions_deleted'),
true);
1031 $this->
ctrl->setParameter($this,
'q_id',
'');
1032 $this->
ctrl->redirect($this, self::DEFAULT_CMD);
1037 $this->
ctrl->redirect($this, self::DEFAULT_CMD);
1046 $export_file = $qpl_exp->buildExportFile();
1049 if ($export_file ===
'') {
1050 $export_file =
'StandIn';
1055 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'qpl_export_select_none'),
true);
1062 $qsaImportFails->deleteRegisteredImportFails();
1064 $this->
ctrl->redirectByClass(
1066 ilRepositoryGUI::class,
1068 ilInfoScreenGUI::class
1078 if (!$this->
access->checkAccess(
"read",
"", $this->request_data_collector->getRefId())) {
1079 $this->infoScreenForward();
1083 $this->
object->purgeQuestions();
1085 if ($qsa_import_fails->failedImportsRegistered()) {
1086 $button = $this->ui_factory->button()->standard(
1087 $this->
lng->txt(
'ass_skl_import_fails_remove_btn'),
1088 $this->ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class],
'renoveImportFails')
1090 $this->tpl->setOnScreenMessage(
1092 $qsa_import_fails->getFailedImportsMessage($this->lng) .
'<br />' . $this->ui_renderer->render(
1099 if ($this->rbac_system->checkAccess(
'write', $this->request_data_collector->getRefId())) {
1100 $btn = $this->ui_factory->button()->primary(
1101 $this->
lng->txt(
'ass_create_question'),
1102 $this->ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class],
'createQuestionForm')
1104 $this->
toolbar->addComponent($btn);
1106 if ($import_questions_modal ===
null) {
1107 $import_questions_modal = $this->buildImportQuestionsModal();
1110 $btn_import = $this->ui_factory->button()->standard(
1111 $this->
lng->txt(
'import'),
1112 $import_questions_modal->getShowSignal()
1114 $this->
toolbar->addComponent($btn_import);
1115 $out[] = $this->ui_renderer->render($import_questions_modal);
1118 $btn_paste = $this->ui_factory->button()->standard(
1119 $this->
lng->txt(
'paste'),
1120 $this->ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class],
'paste')
1122 $this->
toolbar->addComponent($btn_paste);
1126 $this->tpl->setPermanentLink($this->
object->getType(), $this->object->getRefId());
1127 $out[] = $this->getTable();
1128 $this->tpl->setContent(implode(
'',
$out));
1133 $q_id = $this->request_data_collector->getQuestionId();
1135 if ($q_id === 0 || $this->
object->checkQuestionParent($q_id)) {
1144 $this->
help->setScreenId(
'assQuestions');
1145 if ($this->global_test_settings->isPageEditorEnabled()) {
1146 $this->
help->setSubScreenId(
'createQuestion_editMode');
1148 $this->
help->setSubScreenId(
'createQuestion');
1151 $this->tpl->setContent(
1152 $this->ui_renderer->render(
1153 $form ?? $this->buildQuestionCreationForm()
1160 $inputs[
'question_type'] = $this->buildInputQuestionType();
1161 $inputs[
'editing_type'] = $this->buildInputEditingType();
1164 $this->ui_factory->input()->field()->section(
$inputs, $this->
lng->txt(
'ass_create_question'))
1167 $form = $this->ui_factory->input()->container()->form()->standard(
1168 $this->
ctrl->getFormAction($this,
'createQuestion'),
1170 )->withSubmitLabel($this->
lng->txt(
'create'));
1177 $question_types = (
new ilObjQuestionPool())->getQuestionTypes(
false,
true,
false);
1179 foreach ($question_types as $label =>
$data) {
1183 return $this->ui_factory->input()->field()->select(
1184 $this->
lng->txt(
'question_type'),
1186 )->withRequired(
true);
1191 if (!$this->global_test_settings->isPageEditorEnabled()) {
1192 return $this->ui_factory->input()->field()->hidden()->
withValue(
1197 return $this->ui_factory->input()->field()->radio($this->
lng->txt(
'tst_add_quest_cont_edit_mode'))
1200 $this->
lng->txt(
'tst_add_quest_cont_edit_mode_IPE'),
1201 $this->lng->txt(
'tst_add_quest_cont_edit_mode_IPE_info')
1204 $this->
lng->txt(
'tst_add_quest_cont_edit_mode_RTE'),
1205 $this->lng->txt(
'tst_add_quest_cont_edit_mode_RTE_info')
1212 $this->tabs_gui->activateTab(
'print_view');
1213 $this->
ctrl->setParameter($this,
'output',
'overview');
1214 $output_link = $this->
ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class],
'print');
1215 $this->
ctrl->setParameter($this,
'output',
'detailed_output_solutions');
1216 $output_link_detailed = $this->
ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class],
'print');
1217 $this->
ctrl->setParameter($this,
'output',
'detailed_output_printview');
1218 $output_link_printview = $this->
ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class],
'print');
1220 $mode = $this->ui_factory->dropdown()->standard([
1221 $this->ui_factory->button()->shy($this->lng->txt(
'overview'), $output_link),
1222 $this->ui_factory->button()->shy($this->lng->txt(
'detailed_output_solutions'), $output_link_detailed),
1223 $this->ui_factory->button()->shy($this->lng->txt(
'detailed_output_printview'), $output_link_printview)
1224 ])->withLabel($this->
lng->txt(
'output_mode'));
1226 $output = $this->request_data_collector->raw(
'output') ??
'';
1229 $data = $this->
object->getPrintviewQuestions();
1232 $totalPoints +=
$d[
'points'];
1234 $table_gui->setTotalPoints($totalPoints);
1235 $table_gui->initColumns();
1236 $table_gui->setData(
$data);
1237 $this->tpl->setContent($this->ui_renderer->render($mode) . $table_gui->getHTML());
1242 $this->
object->update();
1243 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'msg_obj_modified'),
true);
1249 if ($this->
object->pasteFromClipboard()) {
1250 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'qpl_paste_success'),
true);
1252 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'qpl_paste_error'),
true);
1255 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'qpl_paste_no_objects'),
true);
1257 $this->
ctrl->redirect($this, self::DEFAULT_CMD);
1263 foreach ($ids as
$id) {
1264 $this->
object->copyToClipboard($id);
1266 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'qpl_copy_insert_clipboard'),
true);
1268 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'qpl_copy_select_none'),
true);
1274 if ($this->checkPermission(
'write')) {
1275 $this->tpl->setOnScreenMessage(
'failure',
'permission_denied');
1280 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'qpl_move_select_none'),
true);
1284 foreach ($ids as
$id) {
1285 $this->
object->moveToClipboard($id);
1287 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'qpl_move_insert_clipboard'),
true);
1292 $rbacsystem = $this->rbac_system;
1293 if ($rbacsystem->checkAccess(
'write', $this->request_data_collector->getRefId())) {
1294 $question_ids = &$this->
object->getAllQuestionIds();
1296 $qpl_exp->buildExportFile();
1297 $this->
ctrl->redirectByClass(
'ilquestionpoolexportgui',
'');
1303 $this->
ctrl->redirectByClass(ilAssQuestionPreviewGUI::class,
'show');
1308 if (!$this->temp_file_system->hasDir($path_to_uploaded_file_in_temp_dir)
1309 || ($files = $this->temp_file_system->listContents($path_to_uploaded_file_in_temp_dir)) === []
1310 || mb_stripos($files[0]->getPath(),
'tst') !==
false) {
1311 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'obj_import_file_error'),
true);
1312 $this->
ctrl->redirectByClass(self::class, self::DEFAULT_CMD);
1315 $file_to_import = $this->import_temp_directory . DIRECTORY_SEPARATOR . $files[0]->getPath();
1316 $qtifile = $file_to_import;
1317 $importdir = dirname($file_to_import);
1320 if ($this->temp_file_system->getMimeType($files[0]->getPath()) === MimeType::APPLICATION__ZIP) {
1323 $unzip = $this->archives->unzip($this->temp_file_system->readStream($files[0]->getPath()),
$options);
1327 if (!file_exists($qtifile)) {
1329 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'cannot_find_xml'),
true);
1330 $this->questionsObject();
1335 ilSession::set(
'path_to_uploaded_file_in_temp_dir', $path_to_uploaded_file_in_temp_dir);
1338 'importVerifiedQuestionsFile',
1341 $path_to_uploaded_file_in_temp_dir
1344 if ($form ===
null) {
1348 $panel = $this->ui_factory->panel()->standard(
1349 $this->
lng->txt(
'import_question'),
1351 $this->ui_factory->legacy()->content($this->lng->txt(
'qpl_import_verify_found_questions')),
1355 $this->tpl->setContent($this->ui_renderer->render($panel));
1356 $this->tpl->printToStdout();
1360 protected function importFile(
string $file_to_import,
string $path_to_uploaded_file_in_temp_dir): void
1367 $unzip = $this->archives->unzip(Streams::ofResource(fopen($file_to_import,
'r')),
$options);
1370 if (!file_exists($qtifile)) {
1372 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'cannot_find_xml'),
true);
1377 ilSession::set(
'path_to_uploaded_file_in_temp_dir', $path_to_uploaded_file_in_temp_dir);
1379 $this->
ctrl->setParameterByClass(self::class,
'new_type', $this->type);
1381 'importVerifiedFile',
1384 $path_to_uploaded_file_in_temp_dir
1387 if ($form ===
null) {
1391 $panel = $this->ui_factory->panel()->standard(
1392 $this->
lng->txt(
'import_qpl'),
1394 $this->ui_factory->legacy()->content($this->lng->txt(
'qpl_import_verify_found_questions')),
1398 $this->tpl->setContent($this->ui_renderer->render($panel));
1399 $this->tpl->printToStdout();
1405 $ilLocator = $this->locator;
1407 switch ($this->
ctrl->getCmd()) {
1413 $this->
ctrl->clearParameterByClass(self::class,
'q_id');
1414 $ilLocator->addItem(
1415 $this->
object->getTitle(),
1416 $this->ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class],
''),
1418 $this->request_data_collector->getRefId()
1420 $this->
ctrl->setParameter($this,
'q_id', $this->request_data_collector->getQuestionId());
1424 if (!is_array($this->request_data_collector->raw(
'q_id')) && $this->request_data_collector->raw(
'q_id') > 0 && $this->request_data_collector->raw(
1426 ) !== self::DEFAULT_CMD) {
1428 if ($question_gui !==
null && $question_gui->getObject() instanceof
assQuestion) {
1429 $question = $question_gui->getObject();
1430 $question->setObjId($this->
object->getId());
1431 $question_gui->setObject($question);
1432 $title = $question_gui->getObject()->getTitleForHTMLOutput();
1434 $title = $this->
lng->txt(
'new') .
': ' . $this->questionrepository->getForQuestionId(
1435 $question_gui->getObject()->getId()
1436 )->getTypeName($this->
lng);
1438 $ilLocator->addItem($title, $this->
ctrl->getLinkTargetByClass(get_class($question_gui),
'editQuestion'));
1441 $this->
ctrl->setParameter($this,
'q_id',
'');
1442 $this->
ctrl->redirect($this);
1452 parent::setTitleAndDescription();
1454 if (!is_array($this->request_data_collector->raw(
'q_id')) && $this->request_data_collector->raw(
'q_id') > 0 && $this->request_data_collector->raw(
1456 ) !== self::DEFAULT_CMD) {
1458 if ($question_gui->getObject() instanceof
assQuestion) {
1459 $question = $question_gui->getObject();
1460 $question->setObjId($this->
object->getId());
1461 $question_gui->setObject($question);
1462 $title = $this->
object->getTitle() .
': ' . $question_gui->getObject()->getTitleForHTMLOutput();
1464 $title = $this->
lng->txt(
'new') .
': ' . $this->questionrepository->getForQuestionId(
1465 $question_gui->getObject()->getId()
1466 )->getTypeName($this->
lng);
1468 $this->tpl->setTitle(
1469 $this->
refinery->encode()->htmlSpecialCharsAsEntities()->transform(
1473 $this->tpl->setDescription(
1474 $question_gui->getObject()->getDescriptionForHTMLOutput()
1479 $this->
ctrl->setParameter($this,
'q_id',
'');
1480 $this->
ctrl->redirect($this);
1483 $this->tpl->setTitle(
1484 $this->
refinery->encode()->htmlSpecialCharsAsEntities()->transform(
1485 $this->object->getTitle()
1488 $this->tpl->setDescription(
1489 $this->
refinery->encode()->htmlSpecialCharsAsEntities()->transform(
1490 $this->object->getLongDescription()
1504 $with_write_access = $this->
access->checkAccess(
'write',
'', $this->
object->getRefId());
1505 $with_read_access = $this->
access->checkAccess(
'read',
'', $this->
object->getRefId());
1507 $this->
help->setScreenIdComponent(
'qpl');
1509 switch ($this->
ctrl->getNextClass()) {
1511 case strtolower(ilInfoScreenGUI::class):
1512 case strtolower(ilPermissionGUI::class):
1513 case strtolower(ilObjectMetaDataGUI::class):
1514 case strtolower(ilExportGUI::class):
1515 case strtolower(ilQuestionPoolSkillAdministrationGUI::class):
1518 case strtolower(ilTaxonomySettingsGUI::class):
1519 case strtolower(ilObjQuestionPoolSettingsGeneralGUI::class):
1520 if ($with_write_access) {
1521 $this->addSettingsSubTabs($this->tabs_gui);
1530 $force_active =
false;
1531 $commands = $this->request_data_collector->raw(
'cmd');
1532 if (is_array($commands)) {
1533 foreach ($commands as $key => $value) {
1534 if (preg_match(
'/^delete_.*/', $key, $matches) ||
1535 preg_match(
'/^addSelectGap_.*/', $key, $matches) ||
1536 preg_match(
'/^addTextGap_.*/', $key, $matches) ||
1537 preg_match(
'/^deleteImage_.*/', $key, $matches) ||
1538 preg_match(
'/^upload_.*/', $key, $matches) ||
1539 preg_match(
'/^addSuggestedSolution_.*/', $key, $matches)
1541 $force_active =
true;
1546 $force_active = $force_active || $this->request_data_collector->isset(
'imagemap_x');
1547 if (!$force_active) {
1548 $force_active = strtolower($this->
ctrl->getCmdClass()) === strtolower(self::class)
1549 || $this->
ctrl->getCmdClass() ===
'' && $this->
ctrl->getCmd() ===
''
1553 if ($with_read_access) {
1554 $this->tabs_gui->addTarget(
1556 $this->
ctrl->getLinkTargetByClass(
1557 [ilRepositoryGUI::class, self::class],
1567 'filterQuestionBrowser',
1576 'addSuggestedSolution',
1579 'removeSuggestedSolution',
1586 'uploadingImagemap',
1592 'uploadingJavaapplet',
1599 'toggleGraphicalAnswers',
1609 if ($with_read_access) {
1610 $this->tabs_gui->addTab(
1612 $this->
lng->txt(
'info_short'),
1613 $this->ctrl->getLinkTargetByClass(
1615 ilRepositoryGUI::class,
1617 ilInfoScreenGUI::class
1623 if ($with_write_access) {
1625 $this->tabs_gui->addTarget(
1627 $this->
ctrl->getLinkTargetByClass(ilObjQuestionPoolSettingsGeneralGUI::class),
1629 [ilObjQuestionPoolSettingsGeneralGUI::class, ilObjTaxonomyGUI::class]
1633 if ($this->isSkillsTabRequired()) {
1634 $link = $this->
ctrl->getLinkTargetByClass(
1635 [ilQuestionPoolSkillAdministrationGUI::class, ilAssQuestionSkillAssignmentsGUI::class],
1639 $this->tabs_gui->addTarget(
'qpl_tab_competences', $link, [], []);
1643 if ($with_read_access) {
1645 $this->tabs_gui->addTarget(
1647 $this->
ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class],
'print'),
1654 if ($with_write_access) {
1656 $mdtab = $mdgui->getTab();
1658 $this->tabs_gui->addTarget(
1667 if ($with_write_access) {
1668 $this->tabs_gui->addTarget(
1670 $this->
ctrl->getLinkTargetByClass(ilExportGUI::class,
''),
1676 if ($this->
access->checkAccess(
'edit_permission',
'', $this->object->getRefId())) {
1677 $this->tabs_gui->addTarget(
1679 $this->
ctrl->getLinkTargetByClass([ilRepositoryGUI::class, self::class, ilPermissionGUI::class],
'perm'),
1680 [
'perm',
'info',
'owner'],
1692 if (!$this->
object->isSkillServiceEnabled()) {
1707 $this->
lng->txt(
'qpl_settings_subtab_general'),
1708 $this->ctrl->getLinkTargetByClass(ilObjQuestionPoolSettingsGeneralGUI::class),
1713 $this->
lng->txt(
'qpl_settings_subtab_taxonomies'),
1714 $this->ctrl->getLinkTargetByClass(ilTaxonomySettingsGUI::class,
''),
1720 $this->
ctrl->redirectByClass(
1722 ilRepositoryGUI::class,
1724 ilInfoScreenGUI::class
1731 if (!$this->
access->checkAccess(
'visible',
'', $this->ref_id)) {
1732 $this->
error->raiseError($this->
lng->txt(
'msg_no_perm_read'));
1735 $this->tabs_gui->activateTab(
'info_short');
1737 $info->enablePrivateNotes();
1738 $info->addMetaDataSections($this->
object->getId(), 0, $this->object->getType());
1743 public static function _goto($a_target): void
1747 $main_tpl =
$DIC->ui()->mainTemplate();
1748 $ilAccess =
$DIC[
'ilAccess'];
1751 $ctrl =
$DIC[
'ilCtrl'];
1753 $target_ref_id = (
int) $a_target;
1755 if ($ilAccess->checkAccess(
'write',
'', $target_ref_id)
1756 || $ilAccess->checkAccess(
'read',
'', $target_ref_id)
1758 $ctrl->setParameterByClass(ilObjQuestionPoolGUI::class,
'ref_id', $a_target);
1759 $ctrl->redirectByClass([ilRepositoryGUI::class, ilObjQuestionPoolGUI::class], self::DEFAULT_CMD);
1762 if ($ilAccess->checkAccess(
'visible',
'', $target_ref_id)) {
1763 $DIC->ctrl()->setParameterByClass(ilInfoScreenGUI::class,
'ref_id', $a_target);
1764 $DIC->ctrl()->redirectByClass(
1766 ilRepositoryGUI::class,
1768 ilInfoScreenGUI::class
1773 $main_tpl->setOnScreenMessage(
1776 $lng->txt(
'msg_no_perm_read_item'),
1789 $f = $this->ui_factory;
1790 $r = $this->ui_renderer;
1795 $this->data_factory,
1798 $this->action_parameter_token,
1799 $this->row_id_token,
1802 $this->component_repository,
1805 $this->taxonomy->domain(),
1806 $this->notes_service,
1807 $this->object->getId(),
1808 $this->request_data_collector->getRefId()
1815 $filter_action = $this->
ctrl->getLinkTarget($this, self::DEFAULT_CMD);
1816 $filter = $table->getFilter($this->ui_service, $filter_action);
1818 $filter_params = $this->ui_service->filter()->getData($filter);
1820 if ($filter_params) {
1821 foreach (array_filter($filter_params) as $item => $value) {
1824 foreach ($value as $tax_value) {
1825 if ($tax_value ===
'null') {
1826 $table->addTaxonomyFilterNoTaxonomySet(
true);
1828 $tax_nodes = explode(
'-', $tax_value);
1829 $tax_id = array_shift($tax_nodes);
1830 $table->addTaxonomyFilter(
1834 $this->object->getType()
1840 $table->setCommentFilter((
int) $value);
1843 $table->addFieldFilter($item, $value);
1851 ->withRequest($this->request)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Stream factory which enables the user to create streams without the knowledge of the concrete class.
acquireParameters(array $namespace, string ... $names)
static _getQuestionGUI(string $question_type='', int $question_id=-1)
Creates a question gui representation and returns the alias to the question gui.
const EDIT_CONTEXT_AUTHORING
const RENDER_PURPOSE_PREVIEW
const ADDITIONAL_CONTENT_EDITING_MODE_RTE
const ADDITIONAL_CONTENT_EDITING_MODE_IPE
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const CMD_SHOW_SKILL_QUEST_ASSIGNS
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
static buildAjaxHash(int $node_type, ?int $node_id, string $obj_type, int $obj_id, ?string $sub_type=null, ?int $sub_id=null, int $news_id=0)
Build ajax hash.
Component logger with individual log levels by component id.
Export User Interface Class.
static deliverFileLegacy(string $a_file, ?string $a_filename=null, ?string $a_mime=null, ?bool $isInline=false, ?bool $removeAfterDelivery=false, ?bool $a_exit_after=true)
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
Class ilLocalUnitConfigurationGUI.
Last visited history for repository items.
static getListCommentsJSCall(string $a_hash, ?string $a_update_code=null)
Get list comments js call.
Class ilObjQuestionPoolGUI.
moveQuestions(array $ids)
addSettingsSubTabs(ilTabsGUI $tabs)
renoveImportFailsObject()
uploadQuestionsImportObject()
confirmDeleteQuestionsObject()
delete questions after confirmation
GlobalTestSettings $global_test_settings
updateObject()
updates object entry in object_data
DataFactory $data_factory
fetchAuthoringQuestionIdParamater()
download_paragraphObject()
download source code paragraph
afterSave(ilObject $new_object)
Post (successful) object creation hook.
deleteQuestionsObject()
delete questions confirmation screen
GlobalScreen $global_screen
getTabs()
adds tabs to tab gui object
confirmDeleteQuestions(array $ids)
importQuestionsFromQtiFile(ilObjQuestionPool $obj, array $selected_questions, string $qtifile, string $importdir, string $xmlfile='')
addLocatorItems()
should be overwritten to add object specific items (repository items are preloaded)
importVerifiedFileObject()
SkillUsageService $skill_usage_service
URLBuilderToken $action_parameter_token
cleanupAfterImport(string $importdir)
cancelDeleteQuestionsObject()
importFile(string $file_to_import, string $path_to_uploaded_file_in_temp_dir)
ilComponentFactory $component_factory
ilNavigationHistory $navigation_history
importVerifiedQuestionsFileObject()
redirectAfterMissingWrite()
questionsObject(?RoundTripModal $import_questions_modal=null)
list questions of question pool
setTitleAndDescription()
called by prepare output
buildImportQuestionsModal()
editQuestionForTestObject()
URLBuilderToken $row_id_token
RequestDataCollector $request_data_collector
const SUPPORTED_IMPORT_MIME_TYPES
buildQuestionCreationForm()
importQuestionsFile(string $path_to_uploaded_file_in_temp_dir)
ContentStyle $content_style
createQuestionFormObject(?Form $form=null)
exportObject()
Gateway for exports initiated from workspace, as there is a generic forward to {objTypeMainGUI}::expo...
importQuestionPoolWithValidManifest(ilObjQuestionPool $obj, array $selected_questions, string $file_to_import)
ilComponentRepository $component_repository
GeneralQuestionPropertiesRepository $questionrepository
copyQuestions(array $ids)
fullscreenObject()
show fullscreen view
exportQuestions(array $ids)
const TAB_COMMON_SETTINGS
static isSkillManagementGloballyActivated()
static getQuestionTypeByTypeId($type_id)
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
static getSyntaxStylePath()
GUI class for the workflow of copying objects.
Class ilObjectGUI Basic methods of all Output classes.
static _gotoRepositoryRoot(bool $raise_error=false)
Goto repository root.
checkPermissionBool(string $perm, string $cmd="", string $type="", ?int $ref_id=null)
prepareOutput(bool $show_sub_objects=true)
Class ilObject Basic functions for all objects.
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
startParsing()
stores xml data in array
Legacy Content Object Parser.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static get(string $a_var)
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addSubTab(string $a_id, string $a_text, string $a_link, string $a_frame="")
Class ilUnitConfigurationRepository.
static getStyleSheetLocation(string $mode="output", string $a_css_name="")
get full style sheet file name (path inclusive) of current user
static redirect(string $a_script)
Readable part of repository interface to ilComponentDataDB.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
trait TestQuestionsImportTrait
buildImportQuestionsSelectionForm(string $form_cmd, string $importdir, string $qtifile, ?string $path_to_uploaded_file_in_temp_dir=null)
buildImportDirectoriesFromImportFile(string $file_to_import)
retrieveSelectedQuestionsFromImportQuestionsSelectionForm(string $form_cmd, string $importdir, string $qtifile, ServerRequestInterface $request)
Class ilObjForumAdministration.
if(!file_exists('../ilias.ini.php'))