ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilAssQuestionSkillAssignmentsGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
16{
17 const CMD_SHOW_SKILL_QUEST_ASSIGNS = 'showSkillQuestionAssignments';
18 const CMD_SHOW_SKILL_SELECT = 'showSkillSelection';
19 const CMD_UPDATE_SKILL_QUEST_ASSIGNS = 'updateSkillQuestionAssignments';
20 const CMD_SHOW_SKILL_QUEST_ASSIGN_PROPERTIES_FORM = 'showSkillQuestionAssignmentPropertiesForm';
21 const CMD_SAVE_SKILL_QUEST_ASSIGN_PROPERTIES_FORM = 'saveSkillQuestionAssignmentPropertiesForm';
22 const CMD_SAVE_SKILL_POINTS = 'saveSkillPoints';
23 const CMD_SHOW_SYNC_ORIGINAL_CONFIRMATION = 'showSyncOriginalConfirmation';
24 const CMD_SYNC_ORIGINAL = 'syncOriginal';
25
26 const PARAM_SKILL_SELECTION = 'skill_ids';
27
31 private $ctrl;
32
36 private $access;
37
41 private $tpl;
42
46 private $lng;
47
51 private $db;
52
57
62
67
72
77
86 {
87 $this->ctrl = $ctrl;
88 $this->access = $access;
89 $this->tpl = $tpl;
90 $this->lng = $lng;
91 $this->db = $db;
92 }
93
97 public function getQuestionOrderSequence()
98 {
100 }
101
106 {
108 }
109
114 {
115 $this->assignmentConfigurationHintMessage = $assignmentConfigurationHintMessage;
116 }
117
122 {
123 $this->questionOrderSequence = $questionOrderSequence;
124 }
125
129 public function getQuestionList()
130 {
131 return $this->questionList;
132 }
133
138 {
139 $this->questionList = $questionList;
140 }
141
145 public function getQuestionContainerId()
146 {
148 }
149
154 {
155 $this->questionContainerId = $questionContainerId;
156 }
157
162 {
164 }
165
170 {
171 $this->assignmentEditingEnabled = $assignmentEditingEnabled;
172 }
173
174 public function executeCommand()
175 {
176 $nextClass = $this->ctrl->getNextClass();
177
178 $command = $this->ctrl->getCmd(self::CMD_SHOW_SKILL_QUEST_ASSIGNS);
179
180 if ($this->isAvoidManipulationRedirectRequired($command)) {
181 $this->ctrl->redirect($this, self::CMD_SHOW_SKILL_QUEST_ASSIGNS);
182 }
183
184 switch ($nextClass) {
185 case strtolower(__CLASS__):
186 case '':
187
188 $command .= 'Cmd';
189 $this->$command();
190 break;
191
192 default:
193
194 throw new ilTestQuestionPoolException('unsupported next class in ctrl flow');
195 }
196 }
197
198 private function isAvoidManipulationRedirectRequired($command)
199 {
200 if ($this->isAssignmentEditingEnabled()) {
201 return false;
202 }
203
204 switch ($command) {
207
208 return true;
209 }
210
211 return false;
212 }
213
214 private function saveSkillPointsCmd()
215 {
216 $success = true;
217
218 if (is_array($_POST['skill_points'])) {
219 for ($i = 0; $i < 2; $i++) {
220 foreach ($_POST['skill_points'] as $assignmentKey => $skillPoints) {
221 $assignmentKey = explode(':', $assignmentKey);
222 $skillBaseId = (int) $assignmentKey[0];
223 $skillTrefId = (int) $assignmentKey[1];
224 $questionId = (int) $assignmentKey[2];
225
226 if ($this->isTestQuestion($questionId)) {
227 $assignment = new ilAssQuestionSkillAssignment($this->db);
228
229 if ($i == 0) {
230 if (!$assignment->isValidSkillPoint($skillPoints)) {
231 $success = false;
232 break 2;
233 }
234 continue;
235 }
236
237 $assignment->setParentObjId($this->getQuestionContainerId());
238 $assignment->setQuestionId($questionId);
239 $assignment->setSkillBaseId($skillBaseId);
240 $assignment->setSkillTrefId($skillTrefId);
241
242 if ($assignment->dbRecordExists()) {
243 $assignment->loadFromDb();
244
245 if (!$assignment->hasEvalModeBySolution()) {
246 $assignment->setSkillPoints((int) $skillPoints);
247 $assignment->saveToDb();
248 }
249 }
250 }
251 }
252 }
253 }
254
255 if ($success) {
256 ilUtil::sendSuccess($this->lng->txt('tst_msg_skl_qst_assign_points_saved'), true);
257 $this->ctrl->redirect($this, self::CMD_SHOW_SKILL_QUEST_ASSIGNS);
258 } else {
259 ilUtil::sendFailure($this->lng->txt('tst_msg_skl_qst_assign_points_not_saved'));
261 }
262 }
263
265 {
266 $questionId = (int) $_GET['question_id'];
267
268 if ($this->isTestQuestion($questionId)) {
269 $assignmentList = new ilAssQuestionSkillAssignmentList($this->db);
270 $assignmentList->setParentObjId($this->getQuestionContainerId());
271 $assignmentList->loadFromDb();
272
273 $handledSkills = array();
274
275 //$skillIds = (array)$_POST['skill_ids'];
276 $sgui = $this->buildSkillSelectorExplorerGUI(array());
277 $skillIds = $sgui->getSelectedSkills();
278
279 foreach ($skillIds as $skillId) {
280 $skill = explode(':', $skillId);
281 $skillBaseId = (int) $skill[0];
282 $skillTrefId = (int) $skill[1];
283
284 if ($skillBaseId) {
285 if (!$assignmentList->isAssignedToQuestionId($skillBaseId, $skillTrefId, $questionId)) {
286 $assignment = new ilAssQuestionSkillAssignment($this->db);
287
288 $assignment->setParentObjId($this->getQuestionContainerId());
289 $assignment->setQuestionId($questionId);
290 $assignment->setSkillBaseId($skillBaseId);
291 $assignment->setSkillTrefId($skillTrefId);
292
295 $assignment->saveToDb();
296 }
297
298 $handledSkills[$skillId] = $skill;
299 }
300 }
301
302 foreach ($assignmentList->getAssignmentsByQuestionId($questionId) as $assignment) {
303 if (isset($handledSkills["{$assignment->getSkillBaseId()}:{$assignment->getSkillTrefId()}"])) {
304 continue;
305 }
306
307 $assignment->deleteFromDb();
308 }
309
310 ilUtil::sendSuccess($this->lng->txt('qpl_qst_skl_assigns_updated'), true);
311
312 if ($this->isSyncOriginalPossibleAndAllowed($questionId)) {
314 $this->ctrl->redirect($this, self::CMD_SHOW_SYNC_ORIGINAL_CONFIRMATION);
315 }
316 }
317
318 $this->ctrl->redirect($this, self::CMD_SHOW_SKILL_QUEST_ASSIGNS);
319 }
320
321 private function showSkillSelectionCmd()
322 {
323 $this->ctrl->saveParameter($this, 'question_id');
324 $questionId = (int) $_GET['question_id'];
325
326 $assignmentList = new ilAssQuestionSkillAssignmentList($this->db);
327 $assignmentList->setParentObjId($this->getQuestionContainerId());
328 $assignmentList->loadFromDb();
329
330 $skillSelectorExplorerGUI = $this->buildSkillSelectorExplorerGUI(
331 $assignmentList->getAssignmentsByQuestionId($questionId)
332 );
333
334 if (!$skillSelectorExplorerGUI->handleCommand()) {
335 $tpl = new ilTemplate('tpl.qpl_qst_skl_assign_selection.html', false, false, 'Modules/TestQuestionPool');
336
337 $tpl->setVariable('SKILL_SELECTOR_HEADER', $this->getSkillSelectorHeader($questionId));
338
339 $skillSelectorToolbarGUI = $this->buildSkillSelectorToolbarGUI();
340
341 $skillSelectorToolbarGUI->setOpenFormTag(true);
342 $skillSelectorToolbarGUI->setCloseFormTag(false);
343 $skillSelectorToolbarGUI->setLeadingImage(ilUtil::getImagePath("arrow_upright.svg"), " ");
344 $tpl->setVariable('SKILL_SELECTOR_TOOLBAR_TOP', $this->ctrl->getHTML($skillSelectorToolbarGUI));
345
346 $tpl->setVariable('SKILL_SELECTOR_EXPLORER', $this->ctrl->getHTML($skillSelectorExplorerGUI));
347
348 $skillSelectorToolbarGUI->setOpenFormTag(false);
349 $skillSelectorToolbarGUI->setCloseFormTag(true);
350 $skillSelectorToolbarGUI->setLeadingImage(ilUtil::getImagePath("arrow_downright.svg"), " ");
351 $tpl->setVariable('SKILL_SELECTOR_TOOLBAR_BOTTOM', $this->ctrl->getHTML($skillSelectorToolbarGUI));
352
353 $this->tpl->setContent($tpl->get());
354 }
355 }
356
358 assQuestionGUI $questionGUI = null,
359 ilAssQuestionSkillAssignment $assignment = null,
360 ilPropertyFormGUI $form = null
361 ) {
363
365
366 if ($questionGUI === null) {
367 $questionGUI = assQuestionGUI::_getQuestionGUI('', (int) $_GET['question_id']);
368 }
369
370 if ($assignment === null) {
371 $assignment = $this->buildQuestionSkillAssignment(
372 (int) $_GET['question_id'],
373 (int) $_GET['skill_base_id'],
374 (int) $_GET['skill_tref_id']
375 );
376 }
377
378 if ($form === null) {
379 $form = $this->buildSkillQuestionAssignmentPropertiesForm($questionGUI->object, $assignment);
380 }
381
382 $questionPageHTML = $this->buildQuestionPage($questionGUI);
383
384 $this->tpl->setContent($this->ctrl->getHTML($form) . '<br />' . $questionPageHTML);
385 }
386
388 {
389 $questionId = (int) $_GET['question_id'];
390
391 if ($this->isTestQuestion($questionId)) {
392 $questionGUI = assQuestionGUI::_getQuestionGUI('', $questionId);
393
394 $assignment = $this->buildQuestionSkillAssignment(
395 (int) $_GET['question_id'],
396 (int) $_GET['skill_base_id'],
397 (int) $_GET['skill_tref_id']
398 );
399
401 $form = $this->buildSkillQuestionAssignmentPropertiesForm($questionGUI->object, $assignment);
402 if (!$form->checkInput()) {
403 $form->setValuesByPost();
404 $this->showSkillQuestionAssignmentPropertiesFormCmd($questionGUI, $assignment, $form);
405 return;
406 }
407 $form->setValuesByPost();
408
409 if ($form->getItemByPostVar('eval_mode')) {
410 $assignment->setEvalMode($form->getItemByPostVar('eval_mode')->getValue());
411 } else {
413 }
414
415 if ($assignment->hasEvalModeBySolution()) {
416 $solCmpExprInput = $form->getItemByPostVar('solution_compare_expressions');
417
418 if (!$this->checkSolutionCompareExpressionInput($solCmpExprInput, $questionGUI->object)) {
419 ilUtil::sendFailure($this->lng->txt("form_input_not_valid"));
420 $this->showSkillQuestionAssignmentPropertiesFormCmd($questionGUI, $assignment, $form);
421 return;
422 }
423
424 $assignment->initSolutionComparisonExpressionList();
425 $assignment->getSolutionComparisonExpressionList()->reset();
426
427 foreach ($solCmpExprInput->getValues() as $expression) {
428 $assignment->getSolutionComparisonExpressionList()->add($expression);
429 }
430 } else {
431 $assignment->setSkillPoints($form->getItemByPostVar('q_res_skill_points')->getValue());
432 }
433
434 $assignment->saveToDb();
435
436 ilUtil::sendSuccess($this->lng->txt('qpl_qst_skl_assign_properties_modified'), true);
437
438 if ($this->isSyncOriginalPossibleAndAllowed($questionId)) {
439 $this->ctrl->redirect($this, self::CMD_SHOW_SYNC_ORIGINAL_CONFIRMATION);
440 }
441 }
442
443 $this->ctrl->redirect($this, self::CMD_SHOW_SKILL_QUEST_ASSIGNS);
444 }
445
447 {
448 $form = new ilAssQuestionSkillAssignmentPropertyFormGUI($this->tpl, $this->ctrl, $this->lng, $this);
449
450 $form->setQuestion($question);
451 $form->setAssignment($assignment);
452 $form->setManipulationEnabled($this->isAssignmentEditingEnabled());
453
454 $form->build();
455
456 return $form;
457 }
458
459 private function showSkillQuestionAssignmentsCmd($loadSkillPointsFromRequest = false)
460 {
462
463 $table = $this->buildTableGUI();
464 $table->loadSkillPointsFromRequest($loadSkillPointsFromRequest);
465
466 $assignmentList = $this->buildSkillQuestionAssignmentList();
467 $assignmentList->loadFromDb();
468 $assignmentList->loadAdditionalSkillData();
469 $table->setSkillQuestionAssignmentList($assignmentList);
470 $table->setData($this->orderQuestionData($this->questionList->getQuestionDataArray()));
471
472 $this->tpl->setContent($this->ctrl->getHTML($table));
473 }
474
475 private function isSyncOriginalPossibleAndAllowed($questionId)
476 {
477 $questionData = $this->questionList->getDataArrayForQuestionId($questionId);
478
479 if (!$questionData['original_id']) {
480 return false;
481 }
482
483 $parentObjId = assQuestion::lookupParentObjId($questionData['original_id']);
484
485 if (!$this->doesObjectTypeMatch($parentObjId)) {
486 return false;
487 }
488
489 foreach (ilObject::_getAllReferences($parentObjId) as $parentRefId) {
490 if ($this->access->checkAccess('write', '', $parentRefId)) {
491 return true;
492 }
493 }
494
495 return false;
496 }
497
499 {
500 $questionId = (int) $_GET['question_id'];
501
502 $confirmation = new ilConfirmationGUI();
503
504 $confirmation->setHeaderText($this->lng->txt('qpl_sync_quest_skl_assigns_confirmation'));
505
506 $confirmation->setFormAction($this->ctrl->getFormAction($this));
507 $confirmation->addHiddenItem('question_id', $questionId);
508 $confirmation->setConfirm($this->lng->txt('yes'), self::CMD_SYNC_ORIGINAL);
509 $confirmation->setCancel($this->lng->txt('no'), self::CMD_SHOW_SKILL_QUEST_ASSIGNS);
510
511 $this->tpl->setContent($this->ctrl->getHTML($confirmation));
512 }
513
514 private function syncOriginalCmd()
515 {
516 $questionId = (int) $_POST['question_id'];
517
518 if ($this->isTestQuestion($questionId) && $this->isSyncOriginalPossibleAndAllowed($questionId)) {
519 $question = assQuestion::_instantiateQuestion($questionId);
520
521 $question->syncSkillAssignments(
522 $question->getObjId(),
523 $question->getId(),
524 $question->lookupParentObjId($question->getOriginalId()),
525 $question->getOriginalId()
526 );
527
528 ilUtil::sendSuccess($this->lng->txt('qpl_qst_skl_assign_synced_to_orig'), true);
529 }
530
531 $this->ctrl->redirect($this, self::CMD_SHOW_SKILL_QUEST_ASSIGNS);
532 }
533
534 private function buildTableGUI()
535 {
536 $table = new ilAssQuestionSkillAssignmentsTableGUI($this, self::CMD_SHOW_SKILL_QUEST_ASSIGNS, $this->ctrl, $this->lng);
537 $table->setManipulationsEnabled($this->isAssignmentEditingEnabled());
538 $table->init();
539
540 return $table;
541 }
542
544 {
545 $assignmentList = new ilAssQuestionSkillAssignmentList($this->db);
546 $assignmentList->setParentObjId($this->getQuestionContainerId());
547
548 return $assignmentList;
549 }
550
554 private function buildSkillSelectorExplorerGUI($assignments)
555 {
556 $skillSelectorExplorerGUI = new ilSkillSelectorGUI(
557 $this,
558 self::CMD_SHOW_SKILL_SELECT,
559 $this,
560 self::CMD_UPDATE_SKILL_QUEST_ASSIGNS,
561 self::PARAM_SKILL_SELECTION
562 );
563
564 $skillSelectorExplorerGUI->setSelectMode(self::PARAM_SKILL_SELECTION, true);
565 //$skillSelectorExplorerGUI->setNodeOnclickEnabled(false);
566
567 // parameter name for skill selection is actually taken from value passed to constructor,
568 // but passing a non empty name to setSelectMode is neccessary to keep input fields enabled
569
570 foreach ($assignments as $assignment) {
571 $id = "{$assignment->getSkillBaseId()}:{$assignment->getSkillTrefId()}";
572 //$skillSelectorExplorerGUI->setNodeSelected($id);
573 $skillSelectorExplorerGUI->setSkillSelected($id);
574 }
575
576 return $skillSelectorExplorerGUI;
577 }
578
583 {
584 $skillSelectorToolbarGUI = new ilToolbarGUI();
585
586 $skillSelectorToolbarGUI->setFormAction($this->ctrl->getFormAction($this));
587 $skillSelectorToolbarGUI->addFormButton($this->lng->txt('qpl_save_skill_assigns_update'), self::CMD_UPDATE_SKILL_QUEST_ASSIGNS);
588 $skillSelectorToolbarGUI->addFormButton($this->lng->txt('qpl_cancel_skill_assigns_update'), self::CMD_SHOW_SKILL_QUEST_ASSIGNS);
589
590 return $skillSelectorToolbarGUI;
591 }
592
593 private function buildQuestionPage(assQuestionGUI $questionGUI)
594 {
595 $this->tpl->addCss('Services/COPage/css/content.css');
596
597 $pageGUI = new ilAssQuestionPageGUI($questionGUI->object->getId());
598
599 $pageGUI->setOutputMode("presentation");
600 $pageGUI->setRenderPageContainer(true);
601
602 $pageGUI->setPresentationTitle($questionGUI->object->getTitle());
603
604 $questionGUI->object->setShuffle(false); // dirty, but works ^^
605 $questionHTML = $questionGUI->getSolutionOutput(0, 0, false, false, true, false, true, false, true);
606 $pageGUI->setQuestionHTML(array($questionGUI->object->getId() => $questionHTML));
607
608 $pageHTML = $pageGUI->presentation();
609 $pageHTML = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $pageHTML);
610
611 return $pageHTML;
612 }
613
617 private function buildQuestionSkillAssignment($questionId, $skillBaseId, $skillTrefId)
618 {
619 $assignment = new ilAssQuestionSkillAssignment($this->db);
620
621 $assignment->setParentObjId($this->getQuestionContainerId());
622 $assignment->setQuestionId($questionId);
623 $assignment->setSkillBaseId($skillBaseId);
624 $assignment->setSkillTrefId($skillTrefId);
625
626 $assignment->loadFromDb();
627 $assignment->loadAdditionalSkillData();
628
629 return $assignment;
630 }
631
632 private function isTestQuestion($questionId)
633 {
634 return $this->questionList->isInList($questionId);
635 }
636
638 {
639 $errors = array();
640
641 foreach ($input->getValues() as $expression) {
642 $result = $this->validateSolutionCompareExpression($expression, $question);
643
644 if ($result !== true) {
645 $errors[] = "{$this->lng->txt('ass_lac_expression')} {$expression->getOrderIndex()}: {$result}";
646 }
647 }
648
649 if (count($errors)) {
650 $alert = $this->lng->txt('ass_lac_validation_error');
651 $alert .= '<br />' . implode('<br />', $errors);
652 $input->setAlert($alert);
653 return false;
654 }
655
656 return true;
657 }
658
660 {
661 try {
662 $conditionParser = new ilAssLacConditionParser();
663 $conditionComposite = $conditionParser->parse($expression->getExpression());
664 $questionProvider = new ilAssLacQuestionProvider();
665 $questionProvider->setQuestion($question);
666 $conditionValidator = new ilAssLacCompositeValidator($questionProvider);
667
668 $conditionValidator->validate($conditionComposite);
669 } catch (ilAssLacException $e) {
670 if ($e instanceof ilAssLacFormAlertProvider) {
671 return $e->getFormAlert($this->lng);
672 }
673
674 throw $e;
675 }
676
677 return true;
678 }
679
680 private function keepAssignmentParameters()
681 {
682 $this->ctrl->saveParameter($this, 'question_id');
683 $this->ctrl->saveParameter($this, 'skill_base_id');
684 $this->ctrl->saveParameter($this, 'skill_tref_id');
685 }
686
687 private function orderQuestionData($questionData)
688 {
689 $orderedQuestionsData = array();
690
691 if ($this->getQuestionOrderSequence()) {
692 foreach ($this->getQuestionOrderSequence() as $questionId) {
693 $orderedQuestionsData[$questionId] = $questionData[$questionId];
694 }
695
696 return $orderedQuestionsData;
697 }
698
699 foreach ($questionData as $questionId => $data) {
700 $orderedQuestionsData[$questionId] = $data['title'];
701 }
702
703 $orderedQuestionsData = $this->sortAlphabetically($orderedQuestionsData);
704
705 foreach ($orderedQuestionsData as $questionId => $questionTitle) {
706 $orderedQuestionsData[$questionId] = $questionData[$questionId];
707 }
708
709 return $orderedQuestionsData;
710 }
711
713 {
716 }
717 }
718
719 private function getSkillSelectorHeader($questionId)
720 {
721 $questionData = $this->questionList->getDataArrayForQuestionId($questionId);
722
723 return sprintf($this->lng->txt('qpl_qst_skl_selection_for_question_header'), $questionData['title']);
724 }
725
726 private function sortAlphabetically($array)
727 {
728 $flags = SORT_REGULAR;
729
730 if (defined('SORT_NATURAL')) {
731 $flags = SORT_NATURAL;
732 } elseif (defined('SORT_STRING')) {
733 $flags = SORT_STRING;
734 }
735
736 if (defined('SORT_FLAG_CASE')) {
737 $flags = $flags | SORT_FLAG_CASE;
738 }
739
740 asort($array, $flags);
741
742 return $array;
743 }
744
745 protected function doesObjectTypeMatch($objectId)
746 {
747 return ilObject::_lookupType($objectId) == 'qpl';
748 }
749}
$result
$success
Definition: Utf8Test.php:86
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Basic GUI class for assessment questions.
static _getQuestionGUI($question_type, $question_id=-1)
Creates a question gui representation and returns the alias to the question gui note: please do not u...
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
Abstract basic class which is to be extended by the concrete assessment question type classes.
static _instantiateQuestion($question_id)
static lookupParentObjId($questionId)
@global ilDBInterface $ilDB
Class ilParserQuestionProvider.
Question page GUI class.
buildQuestionSkillAssignment($questionId, $skillBaseId, $skillTrefId)
checkSolutionCompareExpressionInput(ilLogicalAnswerComparisonExpressionInputGUI $input, assQuestion $question)
validateSolutionCompareExpression(ilAssQuestionSolutionComparisonExpression $expression, iQuestionCondition $question)
setAssignmentConfigurationHintMessage($assignmentConfigurationHintMessage)
showSkillQuestionAssignmentPropertiesFormCmd(assQuestionGUI $questionGUI=null, ilAssQuestionSkillAssignment $assignment=null, ilPropertyFormGUI $form=null)
__construct(ilCtrl $ctrl, ilAccessHandler $access, ilGlobalTemplateInterface $tpl, ilLanguage $lng, ilDBInterface $db)
showSkillQuestionAssignmentsCmd($loadSkillPointsFromRequest=false)
buildSkillQuestionAssignmentPropertiesForm(assQuestion $question, ilAssQuestionSkillAssignment $assignment)
Confirmation screen class.
This class provides processing control methods.
setAlert($a_alert)
Set Alert Text.
language handling
static _getAllReferences($a_id)
get all reference ids of object
static _lookupType($a_id, $a_reference=false)
lookup object type
This class represents a property form user interface.
Explorer class that works on tree objects (Services/Tree)
special template class to simplify handling of ITX/PEAR
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
Class iQuestionCondition.
Interface ilAccessHandler.
Interface ilDBInterface.
$i
Definition: metadata.php:24
$data
Definition: storeScorm.php:23
$errors