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