ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.SurveyQuestionGUI.php
Go to the documentation of this file.
1 <?php
2 
21 
28 abstract class SurveyQuestionGUI
29 {
30  protected \ILIAS\Survey\InternalGUIService $gui;
34  protected ilObjUser $user;
36  protected ilTree $tree;
38  protected ilTabsGUI $tabs;
40  protected ilLanguage $lng;
41  protected ilCtrl $ctrl;
42  protected array $cumulated = [];
43  protected string $parent_url = "";
44  protected ilLogger $log;
45  public ?SurveyQuestion $object = null;
46 
47  public function __construct($a_id = -1)
48  {
49  global $DIC;
50 
51  $this->rbacsystem = $DIC->rbac()->system();
52  $this->user = $DIC->user();
53  $this->access = $DIC->access();
54  $this->tree = $DIC->repositoryTree();
55  $this->toolbar = $DIC->toolbar();
56  $lng = $DIC->language();
57  $tpl = $DIC["tpl"];
58  $ilCtrl = $DIC->ctrl();
59 
60 
61  $this->request = $DIC->surveyQuestionPool()
62  ->internal()
63  ->gui()
64  ->editing()
65  ->request();
66 
67  $this->lng = $lng;
68  $this->tpl = $tpl;
69  $this->ctrl = $ilCtrl;
70  $this->ctrl->saveParameter($this, "q_id");
71  $this->ctrl->setParameterByClass(
72  $this->ctrl->getCmdClass(),
73  "sel_question_types",
74  $this->request->getSelectedQuestionTypes()
75  );
76  $this->cumulated = array();
77  $this->tabs = $DIC->tabs();
78 
79  $this->initObject();
80 
81  if ($a_id > 0) {
82  $this->object->loadFromDb($a_id);
83  }
84  $this->log = ilLoggerFactory::getLogger('svy');
85 
86  $this->edit_manager = $DIC->surveyQuestionPool()
87  ->internal()
88  ->domain()
89  ->editing();
90  $this->gui = $DIC->survey()->internal()->gui();
91  }
92 
93  abstract protected function initObject(): void;
94 
95  abstract public function setQuestionTabs(): void;
96 
97  public function executeCommand(): string
98  {
99  $cmd = $this->ctrl->getCmd();
100  $next_class = $this->ctrl->getNextClass($this);
101  switch ($next_class) {
102  default:
103  $ret = $this->$cmd();
104  break;
105  }
106  return (string) $ret;
107  }
108 
113  public static function _getQuestionGUI(
114  ?string $questiontype,
115  int $question_id = -1
116  ): SurveyQuestionGUI {
117  if ((!$questiontype) and ($question_id > 0)) {
118  $questiontype = SurveyQuestion::_getQuestionType($question_id);
119  }
120  SurveyQuestion::_includeClass($questiontype, 1);
121  $question_type_gui = $questiontype . "GUI";
122  $question = new $question_type_gui($question_id);
123  return $question;
124  }
125 
126  public static function _getGUIClassNameForId(int $a_q_id): string
127  {
128  $q_type = SurveyQuestion::_getQuestionType($a_q_id);
129  $class_name = SurveyQuestionGUI::_getClassNameForQType($q_type);
130  return $class_name;
131  }
132 
133  public static function _getClassNameForQType(string $q_type): string
134  {
135  return $q_type;
136  }
137 
141  public function getQuestionType(): string
142  {
143  return $this->object->getQuestionType();
144  }
145 
146  protected function outQuestionText(ilTemplate $template): void
147  {
148  $questiontext = $this->object->getQuestiontext();
149  if (preg_match("/^<.[\\>]?>(.*?)<\\/.[\\>]*?>$/", $questiontext, $matches)) {
150  $questiontext = $matches[1];
151  }
152  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
153  if ($this->object->getObligatory()) {
154  $template->setVariable("OBLIGATORY_TEXT", ' *');
155  }
156  }
157 
158  public function setBackUrl(string $a_url): void
159  {
160  $this->parent_url = $a_url;
161  }
162 
163  public function setQuestionTabsForClass(string $guiclass): void
164  {
165  $rbacsystem = $this->rbacsystem;
166  $ilTabs = $this->tabs;
167 
168  $this->ctrl->setParameterByClass($guiclass, "sel_question_types", $this->getQuestionType());
169  $this->ctrl->setParameterByClass(
170  $guiclass,
171  "q_id",
172  $this->request->getQuestionId()
173  );
174 
175  if ($this->parent_url) {
176  $addurl = "";
177  if ($this->request->getNewForSurvey() > 0) {
178  $addurl = "&new_id=" . $this->request->getQuestionId();
179  }
180  $ilTabs->setBackTarget($this->lng->txt("menubacktosurvey"), $this->parent_url . $addurl);
181  } else {
182  $ilTabs->setBackTarget($this->lng->txt("spl"), $this->ctrl->getLinkTargetByClass("ilObjSurveyQuestionPoolGUI", "questions"));
183  }
184  if ($this->request->getQuestionId()) {
185  $ilTabs->addNonTabbedLink(
186  "preview",
187  $this->lng->txt("preview"),
188  $this->ctrl->getLinkTargetByClass($guiclass, "preview")
189  );
190  }
191 
192  if ($rbacsystem->checkAccess('edit', $this->request->getRefId())) {
193  $ilTabs->addTab(
194  "edit_properties",
195  $this->lng->txt("properties"),
196  $this->ctrl->getLinkTargetByClass($guiclass, "editQuestion")
197  );
198 
199  if (stripos($guiclass, "matrix") !== false) {
200  $ilTabs->addTab(
201  "layout",
202  $this->lng->txt("layout"),
203  $this->ctrl->getLinkTargetByClass($guiclass, "layout")
204  );
205  }
206  }
207 
208  if ($this->object->getId() > 0) {
209  $title = $this->lng->txt("edit") . " &quot;" . $this->object->getTitle() . "&quot";
210  } else {
211  $title = $this->lng->txt("create_new") . " " . $this->lng->txt($this->getQuestionType());
212  }
213 
214  $this->tpl->setVariable("HEADER", $title);
215  }
216 
217 
218  //
219  // EDITOR
220  //
221 
222  protected function initEditForm(): ilPropertyFormGUI
223  {
224  $form = new ilPropertyFormGUI();
225  $form->setFormAction($this->ctrl->getFormAction($this, "save"));
226  $form->setTitle($this->lng->txt($this->getQuestionType()));
227  $form->setMultipart(false);
228  $form->setTableWidth("100%");
229  // $form->setId("essay");
230 
231  // title
232  $title = new ilTextInputGUI($this->lng->txt("title"), "title");
233  $title->setMaxLength(200);
234  $title->setRequired(true);
235  $form->addItem($title);
236 
237  // label
238  $label = new ilTextInputGUI($this->lng->txt("label"), "label");
239  $label->setInfo($this->lng->txt("label_info"));
240  $title->setMaxLength(255);
241  $label->setRequired(false);
242  $form->addItem($label);
243 
244  // author
245  $author = new ilTextInputGUI($this->lng->txt("author"), "author");
246  $author->setRequired(true);
247  $title->setMaxLength(100);
248  $form->addItem($author);
249 
250  // description
251  $description = new ilTextInputGUI($this->lng->txt("description"), "description");
252  $description->setRequired(false);
253  $title->setMaxLength(200);
254  $form->addItem($description);
255 
256  // questiontext
257  $question = new ilTextAreaInputGUI($this->lng->txt("question"), "question");
258  $question->setRequired(true);
259  $question->setRows(10);
260  $question->setCols(80);
261  if (ilObjAdvancedEditing::_getRichTextEditor() === "tinymce") {
262  $question->setUseRte(true);
263  $question->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("survey"));
264  $question->addPlugin("latex");
265  $question->addButton("latex");
266  $question->addButton("pastelatex");
267  $question->setRTESupport($this->object->getId(), "spl", "survey");
268  }
269  $form->addItem($question);
270 
271  // obligatory
272  $shuffle = new ilCheckboxInputGUI($this->lng->txt("obligatory"), "obligatory");
273  $shuffle->setValue(1);
274  $shuffle->setRequired(false);
275  $form->addItem($shuffle);
276 
277  $this->addFieldsToEditForm($form);
278 
279  $this->addCommandButtons($form);
280 
281  // values
282  $title->setValue($this->object->getTitle());
283  $label->setValue($this->object->label);
284  $author->setValue($this->object->getAuthor());
285  $description->setValue($this->object->getDescription());
286  $question->setValue($this->object->prepareTextareaOutput($this->object->getQuestiontext()));
287  $shuffle->setChecked($this->object->getObligatory());
288 
289  return $form;
290  }
291 
292  protected function addCommandButtons(ilPropertyFormGUI $a_form): void
293  {
294  $a_form->addCommandButton("saveReturn", $this->lng->txt("save_return"));
295  $a_form->addCommandButton("save", $this->lng->txt("save"));
296 
297  // pool question?
298  if (ilObject::_lookupType($this->object->getObjId()) === "spl" && $this->object->hasCopies()) {
299  $a_form->addCommandButton("saveSync", $this->lng->txt("svy_save_sync"));
300  }
301  }
302 
303  protected function editQuestion(ilPropertyFormGUI $a_form = null): void
304  {
305  $ilTabs = $this->tabs;
306 
307  $ilTabs->activateTab("edit_properties");
308 
309  if (!$a_form) {
310  $a_form = $this->initEditForm();
311  }
312  $this->tpl->setContent($a_form->getHTML());
313  }
314 
315  protected function saveSync(): void
316  {
317  $this->save($this->request->getReturn(), true);
318  }
319 
320  protected function saveReturn(): void
321  {
322  $this->save(true);
323  }
324 
325  protected function saveForm(): bool
326  {
327  $form = $this->initEditForm();
328  if ($form->checkInput() && $this->validateEditForm($form)) {
329  $this->object->setTitle($form->getInput("title"));
330  $this->object->label = ($form->getInput("label"));
331  $this->object->setAuthor($form->getInput("author"));
332  $this->object->setDescription($form->getInput("description"));
333  $this->object->setQuestiontext($form->getInput("question"));
334  $this->object->setObligatory($form->getInput("obligatory"));
335 
336  $this->importEditFormValues($form);
337 
338  // will save both core and extended data
339  $this->object->saveToDb();
340 
341  return true;
342  }
343 
344  $form->setValuesByPost();
345  $this->editQuestion($form);
346  return false;
347  }
348 
349  protected function save(
350  bool $a_return = false,
351  bool $a_sync = false
352  ): void {
353  $ilUser = $this->user;
354 
355  if ($this->saveForm()) {
356  // #13784
357  if ($a_return &&
358  !SurveyQuestion::_isComplete($this->object->getId())) {
359  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("survey_error_insert_incomplete_question"));
360  $this->editQuestion();
361  return;
362  }
363 
364  $ilUser->setPref("svy_lastquestiontype", $this->object->getQuestionType());
365  $ilUser->writePref("svy_lastquestiontype", $this->object->getQuestionType());
366 
367  $originalexists = SurveyQuestion::_questionExists((int) $this->object->original_id);
368  $this->ctrl->setParameter($this, "q_id", $this->object->getId());
369 
370  // pool question?
371  if ($a_sync) {
372  $this->tpl->setOnScreenMessage('success', $this->lng->txt("msg_obj_modified"), true);
373  $this->ctrl->redirect($this, 'copySyncForm');
374  } elseif ($originalexists &&
375  SurveyQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
376  // form: update original pool question, too?
377  if ($a_return) {
378  $this->ctrl->setParameter($this, 'rtrn', 1);
379  }
380  $this->ctrl->redirect($this, 'originalSyncForm');
381  }
382 
383  $this->tpl->setOnScreenMessage('success', $this->lng->txt("msg_obj_modified"), true);
384  $this->redirectAfterSaving($a_return);
385  }
386  }
387 
388  protected function copySyncForm(): void
389  {
390  $ilTabs = $this->tabs;
391 
392  $ilTabs->activateTab("edit_properties");
393 
394  $tbl = new ilSurveySyncTableGUI($this, "copySyncForm", $this->object);
395 
396  $this->tpl->setContent($tbl->getHTML());
397  }
398 
399  protected function syncCopies(): void
400  {
401  $lng = $this->lng;
402  $ilAccess = $this->access;
403 
404  $qids = $this->request->getQuestionIds();
405  if (count($qids) === 0) {
406  $this->tpl->setOnScreenMessage('failure', $lng->txt("select_one"));
407  $this->copySyncForm();
408  return;
409  }
410 
411  foreach ($this->object->getCopyIds(true) as $survey_id => $questions) {
412  // check permissions for "parent" survey
413  $can_write = false;
414  $ref_ids = ilObject::_getAllReferences($survey_id);
415  foreach ($ref_ids as $ref_id) {
416  if ($ilAccess->checkAccess("edit", "", $ref_id)) {
417  $can_write = true;
418  break;
419  }
420  }
421 
422  if ($can_write) {
423  foreach ($questions as $qid) {
424  if (in_array($qid, $qids)) {
425  $id = $this->object->getId();
426 
427  $this->object->setId($qid);
428  $this->object->setOriginalId($id);
429  $this->object->saveToDb();
430 
431  $this->object->setId($id);
432  $this->object->setOriginalId(null);
433 
434  // see: SurveyQuestion::syncWithOriginal()
435  // what about material?
436  }
437  }
438  }
439  }
440 
441  $this->tpl->setOnScreenMessage('success', $lng->txt("survey_sync_success"), true);
442  $this->redirectAfterSaving($this->request->getReturn());
443  }
444 
445  protected function originalSyncForm(): void
446  {
447  $ilTabs = $this->tabs;
448 
449  $ilTabs->activateTab("edit_properties");
450 
451  $this->ctrl->saveParameter($this, "rtrn");
452 
453  $cgui = new ilConfirmationGUI();
454  $cgui->setHeaderText($this->lng->txt("confirm_sync_questions"));
455 
456  $cgui->setFormAction($this->ctrl->getFormAction($this, "confirmRemoveQuestions"));
457  $cgui->setCancel($this->lng->txt("no"), "cancelSync");
458  $cgui->setConfirm($this->lng->txt("yes"), "sync");
459 
460  $this->tpl->setContent($cgui->getHTML());
461  }
462 
463  protected function sync(): void
464  {
465  $original_id = $this->object->original_id;
466  if ($original_id) {
467  $this->object->syncWithOriginal();
468  }
469 
470  $this->tpl->setOnScreenMessage('success', $this->lng->txt("msg_obj_modified"), true);
471  $this->redirectAfterSaving($this->request->getReturn());
472  }
473 
474  protected function cancelSync(): void
475  {
476  $this->tpl->setOnScreenMessage('info', $this->lng->txt("question_changed_in_survey_only"), true);
477  $this->redirectAfterSaving($this->request->getReturn());
478  }
479 
483  protected function redirectAfterSaving(
484  bool $a_return = false
485  ): void {
486  // return?
487  if ($a_return) {
488  // to calling survey
489  if ($this->parent_url) {
490  $addurl = "";
491  if ($this->request->getNewForSurvey() > 0) {
492  $addurl = "&new_id=" . $this->request->getQuestionId();
493  }
494  ilUtil::redirect(str_replace("&amp;", "&", $this->parent_url) . $addurl);
495  }
496  // to pool
497  else {
498  $this->ctrl->redirectByClass("ilObjSurveyQuestionPoolGUI", "questions");
499  }
500  }
501  // stay in form
502  else {
503  $this->ctrl->setParameterByClass(
504  $this->ctrl->getCmdClass(),
505  "q_id",
506  $this->object->getId()
507  );
508  $this->ctrl->setParameterByClass(
509  $this->ctrl->getCmdClass(),
510  "sel_question_types",
511  $this->request->getSelectedQuestionTypes()
512  );
513  $this->ctrl->setParameterByClass(
514  $this->ctrl->getCmdClass(),
515  "new_for_survey",
516  $this->request->getNewForSurvey()
517  );
518  $this->ctrl->redirectByClass($this->ctrl->getCmdClass(), "editQuestion");
519  }
520  }
521 
522  protected function cancel(): void
523  {
524  if ($this->parent_url) {
525  ilUtil::redirect($this->parent_url);
526  } else {
527  $this->ctrl->redirectByClass("ilobjsurveyquestionpoolgui", "questions");
528  }
529  }
530 
531  protected function validateEditForm(ilPropertyFormGUI $a_form): bool
532  {
533  return true;
534  }
535 
536  abstract protected function addFieldsToEditForm(ilPropertyFormGUI $a_form): void;
537 
538  abstract protected function importEditFormValues(ilPropertyFormGUI $a_form): void;
539 
540  abstract public function getPrintView(
541  int $question_title = 1,
542  bool $show_questiontext = true,
543  ?int $survey_id = null,
544  ?array $working_data = null
545  ): string;
546 
547  protected function getPrintViewQuestionTitle(
548  int $question_title = 1
549  ): string {
550  $title = "";
551  switch ($question_title) {
553  $title = ilLegacyFormElementsUtil::prepareFormOutput($this->object->getTitle());
554  break;
555 
556  #19448 get rid of showing only the label without title
557  //case 2:
558  // $title = ilUtil::prepareFormOutput($this->object->getLabel());
559  // break;
560 
562  $title = ilLegacyFormElementsUtil::prepareFormOutput($this->object->getTitle());
563  if (trim($this->object->getLabel())) {
564  $title .= ' <span class="questionLabel">(' . ilLegacyFormElementsUtil::prepareFormOutput(
565  $this->object->getLabel()
566  ) . ')</span>';
567  }
568  break;
569  }
570  return $title;
571  }
572 
573  protected function getQuestionTitle(
574  int $question_title_mode = 1
575  ): string {
576  $title = "";
577  switch ($question_title_mode) {
579  $title = $this->object->getTitle();
580  break;
581 
583  $title = $this->object->getTitle();
584  if (trim($this->object->getLabel())) {
585  $title .= ' <span class="questionLabel">(' .
586  $this->object->getLabel()
587  . ')</span>';
588  }
589  break;
590  }
591  return $title;
592  }
593 
594  public function preview(): void
595  {
596  $ilTabs = $this->tabs;
597 
598  $ilTabs->activateTab("preview");
599 
600  $tpl = new ilTemplate("tpl.il_svy_qpl_preview.html", true, true, "Modules/SurveyQuestionPool");
601 
602  if ($this->object->getObligatory()) {
603  $tpl->setCurrentBlock("required");
604  $tpl->setVariable("TEXT_REQUIRED", $this->lng->txt("required_field"));
605  $tpl->parseCurrentBlock();
606  }
607 
608  $tpl->setVariable("QUESTION_OUTPUT", $this->getWorkingForm());
609 
610  $f = $this->gui->ui()->factory();
611  $r = $this->gui->ui()->renderer();
612  $p = $f->panel()->standard(
613  "",
614  $f->legacy($tpl->get())
615  );
616 
617  $this->tpl->setContent($r->render($p));
618  }
619 
620 
621  //
622  // EXECUTION
623  //
624 
625  abstract public function getWorkingForm(
626  array $working_data = null,
627  int $question_title = 1,
628  bool $show_questiontext = true,
629  string $error_message = "",
630  int $survey_id = null,
631  bool $compress_view = false
632  ): string;
633 
634 
635  protected function renderStatisticsDetailsTable(
636  array $a_head,
637  array $a_rows,
638  array $a_foot = null
639  ): string {
640  $html = array();
641  $html[] = '<div class="ilTableOuter table-responsive">';
642  $html[] = '<table class="table table-striped">';
643 
644  $html[] = "<thead>";
645  $html[] = "<tr>";
646  foreach ($a_head as $col) {
647  $col = trim($col);
648  $html[] = "<th>";
649  $html[] = ($col != "") ? $col : "&nbsp;";
650  $html[] = "</th>";
651  }
652  $html[] = "</tr>";
653  $html[] = "</thead>";
654 
655  $html[] = "<tbody>";
656  foreach ($a_rows as $row) {
657  $html[] = "<tr>";
658  foreach ($row as $col) {
659  $col = trim($col);
660  $html[] = "<td>";
661  $html[] = ($col != "") ? $col : "&nbsp;";
662  $html[] = "</td>";
663  }
664  $html[] = "</tr>";
665  }
666  $html[] = "</tbody>";
667 
668  if ($a_foot) {
669  $html[] = "<tfoot>";
670  $html[] = "<tr>";
671  foreach ($a_foot as $col) {
672  $col = trim($col);
673  $html[] = "<td>";
674  $html[] = ($col != "") ? $col : "&nbsp;";
675  $html[] = "</td>";
676  }
677  $html[] = "</tr>";
678  $html[] = "</tfoot>";
679  }
680 
681  $html[] = "</table>";
682  $html[] = "</div>";
683  return implode("\n", $html);
684  }
685 }
getQuestionTitle(int $question_title_mode=1)
static getLogger(string $a_component_id)
Get component logger.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
static _getRichTextEditor()
Returns the identifier for the Rich Text Editor.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getPrintViewQuestionTitle(int $question_title=1)
static _getAllReferences(int $id)
get all reference ids for object ID
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
getQuestionType()
Returns the question type string.
static _getQuestionType(int $question_id)
Returns the question type of a question with a given id.
setVariable(string $variable, $value='')
Sets the given variable to the given value.
static prepareFormOutput($a_str, bool $a_strip=false)
renderStatisticsDetailsTable(array $a_head, array $a_rows, array $a_foot=null)
getPrintView(int $question_title=1, bool $show_questiontext=true, ?int $survey_id=null, ?array $working_data=null)
outQuestionText(ilTemplate $template)
static _isWriteable(int $question_id, int $user_id)
is question writeable by a certain user
global $DIC
Definition: feed.php:28
checkAccess(string $a_operations, int $a_ref_id, string $a_type="")
checkAccess represents the main method of the RBAC-system in ILIAS3 developers want to use With this ...
EditingGUIRequest $request
static _getQuestionGUI(?string $questiontype, int $question_id=-1)
Creates a question gui representation.
static _isComplete(int $question_id)
Checks whether the question is complete or not.
$ref_id
Definition: ltiauth.php:67
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:546
setQuestionTabsForClass(string $guiclass)
redirectAfterSaving(bool $a_return=false)
Redirect to calling survey or to edit form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addFieldsToEditForm(ilPropertyFormGUI $a_form)
validateEditForm(ilPropertyFormGUI $a_form)
ilGlobalTemplateInterface $tpl
static _includeClass(string $question_type, int $gui=0)
Include the php class file for a given question type.
static _getClassNameForQType(string $q_type)
setRequired(bool $a_required)
addCommandButton(string $a_cmd, string $a_text, string $a_id="")
static _getGUIClassNameForId(int $a_q_id)
ILIAS Survey InternalGUIService $gui
static redirect(string $a_script)
setCurrentBlock(string $part=self::DEFAULT_BLOCK)
Sets the template to the given block.
importEditFormValues(ilPropertyFormGUI $a_form)
activateTab(string $a_id)
save(bool $a_return=false, bool $a_sync=false)
addCommandButtons(ilPropertyFormGUI $a_form)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a text area property in a property form.
editQuestion(ilPropertyFormGUI $a_form=null)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
parseCurrentBlock(string $block_name=self::DEFAULT_BLOCK)
Parses the given block.
static _lookupType(int $id, bool $reference=false)
Basic class for all survey question types The SurveyQuestionGUI class defines and encapsulates basic ...
getWorkingForm(array $working_data=null, int $question_title=1, bool $show_questiontext=true, string $error_message="", int $survey_id=null, bool $compress_view=false)
static _getUsedHTMLTags(string $a_module="")
Returns an array of all allowed HTML tags for text editing.
static _questionExists(int $question_id)
$r