ILIAS  release_7 Revision v7.30-3-g800a261c036
class.assOrderingHorizontal.php
Go to the documentation of this file.
1<?php
2
19require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
20require_once './Modules/Test/classes/inc.AssessmentConstants.php';
21require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
22require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
23require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
24
37{
38 protected $ordertext;
39 protected $textsize;
40 protected $separator = "::";
41 protected $answer_separator = '{::}';
42
55 public function __construct(
56 $title = "",
57 $comment = "",
58 $author = "",
59 $owner = -1,
60 $question = ""
61 ) {
63 $this->ordertext = "";
64 }
65
71 public function isComplete()
72 {
73 if (strlen($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0)) {
74 return true;
75 } else {
76 return false;
77 }
78 }
79
84 public function saveToDb($original_id = "")
85 {
88 parent::saveToDb();
89 }
90
94 public function getAnswerSeparator()
95 {
97 }
98
99
106 public function loadFromDb($question_id)
107 {
108 global $DIC;
109 $ilDB = $DIC['ilDB'];
110
111 $result = $ilDB->queryF(
112 "SELECT qpl_questions.*, " . $this->getAdditionalTableName() . ".* FROM qpl_questions LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = qpl_questions.question_id WHERE qpl_questions.question_id = %s",
113 array("integer"),
114 array($question_id)
115 );
116 if ($result->numRows() == 1) {
117 $data = $ilDB->fetchAssoc($result);
118 $this->setId($question_id);
119 $this->setObjId($data["obj_fi"]);
120 $this->setTitle($data["title"]);
121 $this->setComment($data["description"]);
122 $this->setOriginalId($data["original_id"]);
123 $this->setNrOfTries($data['nr_of_tries']);
124 $this->setAuthor($data["author"]);
125 $this->setPoints($data["points"]);
126 $this->setOwner($data["owner"]);
127 include_once("./Services/RTE/classes/class.ilRTE.php");
128 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
129 $this->setOrderText($data["ordertext"]);
130 $this->setTextSize($data["textsize"]);
131 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
132
133 try {
137 }
138
139 try {
140 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
142 }
143 }
144
145 parent::loadFromDb($question_id);
146 }
147
151 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
152 {
153 if ($this->id <= 0) {
154 // The question has not been saved. It cannot be duplicated
155 return;
156 }
157 // duplicate the question in database
158 $this_id = $this->getId();
159 $thisObjId = $this->getObjId();
160
161 $clone = $this;
162 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
164 $clone->id = -1;
165
166 if ((int) $testObjId > 0) {
167 $clone->setObjId($testObjId);
168 }
169
170 if ($title) {
171 $clone->setTitle($title);
172 }
173
174 if ($author) {
175 $clone->setAuthor($author);
176 }
177 if ($owner) {
178 $clone->setOwner($owner);
179 }
180
181 if ($for_test) {
182 $clone->saveToDb($original_id);
183 } else {
184 $clone->saveToDb();
185 }
186
187 // copy question page content
188 $clone->copyPageOfQuestion($this_id);
189 // copy XHTML media objects
190 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
191
192 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
193
194 return $clone->id;
195 }
196
200 public function copyObject($target_questionpool_id, $title = "")
201 {
202 if ($this->id <= 0) {
203 // The question has not been saved. It cannot be duplicated
204 return;
205 }
206 // duplicate the question in database
207 $clone = $this;
208 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
210 $clone->id = -1;
211 $source_questionpool_id = $this->getObjId();
212 $clone->setObjId($target_questionpool_id);
213 if ($title) {
214 $clone->setTitle($title);
215 }
216 $clone->saveToDb();
217 // copy question page content
218 $clone->copyPageOfQuestion($original_id);
219 // copy XHTML media objects
220 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
221
222 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
223
224 return $clone->id;
225 }
226
227 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
228 {
229 if ($this->id <= 0) {
230 // The question has not been saved. It cannot be duplicated
231 return;
232 }
233
234 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
235
236 $sourceQuestionId = $this->id;
237 $sourceParentId = $this->getObjId();
238
239 // duplicate the question in database
240 $clone = $this;
241 $clone->id = -1;
242
243 $clone->setObjId($targetParentId);
244
245 if ($targetQuestionTitle) {
246 $clone->setTitle($targetQuestionTitle);
247 }
248
249 $clone->saveToDb();
250 // copy question page content
251 $clone->copyPageOfQuestion($sourceQuestionId);
252 // copy XHTML media objects
253 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
254
255 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
256
257 return $clone->id;
258 }
259
265 public function getMaximumPoints()
266 {
267 return $this->getPoints();
268 }
269
280 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
281 {
282 if ($returndetails) {
283 throw new ilTestException('return details not implemented for ' . __METHOD__);
284 }
285
286 global $DIC;
287 $ilDB = $DIC['ilDB'];
288
289 $found_values = array();
290 if (is_null($pass)) {
291 $pass = $this->getSolutionMaxPass($active_id);
292 }
293 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
294 $points = 0;
295 $data = $ilDB->fetchAssoc($result);
296
298
299 return $points;
300 }
301
311 public function splitAndTrimOrderElementText($in_string, $separator)
312 {
313 $result = array();
314 include_once "./Services/Utilities/classes/class.ilStr.php";
315
316 if (ilStr::strPos($in_string, $separator) === false) {
317 $result = preg_split("/\\s+/", $in_string);
318 } else {
319 $result = explode($separator, $in_string);
320 }
321
322 foreach ($result as $key => $value) {
323 $result[$key] = trim($value);
324 }
325
326 return $result;
327 }
328
329 public function getSolutionSubmit()
330 {
331 return $_POST["orderresult"];
332 }
333
342 public function saveWorkingData($active_id, $pass = null, $authorized = true)
343 {
344 global $DIC;
345 $ilDB = $DIC['ilDB'];
346 $ilUser = $DIC['ilUser'];
347
348 if (is_null($pass)) {
349 include_once "./Modules/Test/classes/class.ilObjTest.php";
350 $pass = ilObjTest::_getPass($active_id);
351 }
352
353 $entered_values = false;
354
355 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $active_id, $pass, $authorized) {
356 $this->removeCurrentSolution($active_id, $pass, $authorized);
357
358 $solutionSubmit = $this->getSolutionSubmit();
359
360 $entered_values = false;
361 if (strlen($solutionSubmit)) {
362 $this->saveCurrentSolution($active_id, $pass, $_POST['orderresult'], null, $authorized);
363 $entered_values = true;
364 }
365 });
366
367 if ($entered_values) {
368 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
370 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
371 }
372 } else {
373 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
375 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
376 }
377 }
378
379 return true;
380 }
381
383 {
384 global $DIC;
385 $ilDB = $DIC['ilDB'];
386
387 // save additional data
388 $ilDB->manipulateF(
389 "DELETE FROM " . $this->getAdditionalTableName()
390 . " WHERE question_fi = %s",
391 array( "integer" ),
392 array( $this->getId() )
393 );
394
395 $ilDB->manipulateF(
396 "INSERT INTO " . $this->getAdditionalTableName()
397 . " (question_fi, ordertext, textsize) VALUES (%s, %s, %s)",
398 array( "integer", "text", "float" ),
399 array(
400 $this->getId(),
401 $this->getOrderText(),
402 ($this->getTextSize() < 10) ? null : $this->getTextSize()
403 )
404 );
405 }
406
412 public function getQuestionType()
413 {
414 return "assOrderingHorizontal";
415 }
416
422 public function getAdditionalTableName()
423 {
424 return "qpl_qst_horder";
425 }
426
432 public function getAnswerTableName()
433 {
434 return "";
435 }
436
442 public function deleteAnswers($question_id)
443 {
444 }
445
451 {
452 $text = parent::getRTETextWithMediaObjects();
453 return $text;
454 }
455
459 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
460 {
461 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
462
463 $solutionvalue = "";
464 $solutions = &$this->getSolutionValues($active_id, $pass);
465 $solutionvalue = str_replace("{::}", " ", $solutions[0]["value1"]);
466 $i = 1;
467 $worksheet->setCell($startrow + $i, 2, $solutionvalue);
468 $i++;
469
470 return $startrow + $i + 1;
471 }
472
485 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping, array $solutionhints = [])
486 {
487 include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assOrderingHorizontalImport.php";
488 $import = new assOrderingHorizontalImport($this);
489 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
490 }
491
498 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
499 {
500 include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assOrderingHorizontalExport.php";
501 $export = new assOrderingHorizontalExport($this);
502 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
503 }
504
510 public function getBestSolution($active_id, $pass)
511 {
512 $user_solution = array();
513 return $user_solution;
514 }
515
521 public function getOrderingElements()
522 {
523 return $this->splitAndTrimOrderElementText($this->getOrderText(), $this->separator);
524 }
525
532 {
533 $elements = $this->getOrderingElements();
534 $elements = $this->getShuffler()->shuffle($elements);
535 return $elements;
536 }
537
543 public function getOrderText()
544 {
545 return $this->ordertext;
546 }
547
553 public function setOrderText($a_value)
554 {
555 $this->ordertext = $a_value;
556 }
557
563 public function getTextSize()
564 {
565 return $this->textsize;
566 }
567
573 public function setTextSize($a_value)
574 {
575 if ($a_value >= 10) {
576 $this->textsize = $a_value;
577 }
578 }
579
585 public function getSeparator()
586 {
587 return $this->separator;
588 }
589
595 public function setSeparator($a_value)
596 {
597 $this->separator = $a_value;
598 }
599
603 public function __get($value)
604 {
605 switch ($value) {
606 case "ordertext":
607 return $this->getOrderText();
608 break;
609 case "textsize":
610 return $this->getTextSize();
611 break;
612 case "separator":
613 return $this->getSeparator();
614 break;
615 default:
616 return parent::__get($value);
617 break;
618 }
619 }
620
624 public function __set($key, $value)
625 {
626 switch ($key) {
627 case "ordertext":
628 $this->setOrderText($value);
629 break;
630 case "textsize":
631 $this->setTextSize($value);
632 break;
633 case "separator":
634 $this->setSeparator($value);
635 break;
636 default:
637 parent::__set($key, $value);
638 break;
639 }
640 }
641
642 public function supportsJavascriptOutput()
643 {
644 return true;
645 }
646
647 public function supportsNonJsOutput()
648 {
649 return false;
650 }
651
655 public function toJSON()
656 {
657 include_once("./Services/RTE/classes/class.ilRTE.php");
658 $result = array();
659 $result['id'] = (int) $this->getId();
660 $result['type'] = (string) $this->getQuestionType();
661 $result['title'] = (string) $this->getTitle();
662 $result['question'] = $this->formatSAQuestion($this->getQuestion());
663 $result['nr_of_tries'] = (int) $this->getNrOfTries();
664 $result['shuffle'] = (bool) true;
665 $result['points'] = (bool) $this->getPoints();
666 $result['textsize'] = ((int) $this->getTextSize()) // #10923
667 ? (int) $this->getTextSize()
668 : 100;
669 $result['feedback'] = array(
670 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
671 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
672 );
673
674 $arr = array();
675 foreach ($this->getOrderingElements() as $order => $answer) {
676 array_push($arr, array(
677 "answertext" => (string) $answer,
678 "order" => (int) $order + 1
679 ));
680 }
681 $result['answers'] = $arr;
682
683 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
684 $result['mobs'] = $mobs;
685
686 return json_encode($result);
687 }
688
697 public function getOperators($expression)
698 {
699 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
701 }
702
707 public function getExpressionTypes()
708 {
709 return array(
714 );
715 }
716
725 public function getUserQuestionResult($active_id, $pass)
726 {
728 global $DIC;
729 $ilDB = $DIC['ilDB'];
730 $result = new ilUserQuestionResult($this, $active_id, $pass);
731
732 $maxStep = $this->lookupMaxStep($active_id, $pass);
733
734 if ($maxStep !== null) {
735 $data = $ilDB->queryF(
736 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
737 array("integer", "integer", "integer","integer"),
738 array($active_id, $pass, $this->getId(), $maxStep)
739 );
740 } else {
741 $data = $ilDB->queryF(
742 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
743 array("integer", "integer", "integer"),
744 array($active_id, $pass, $this->getId())
745 );
746 }
747 $row = $ilDB->fetchAssoc($data);
748
749 $answer_elements = $this->splitAndTrimOrderElementText($row["value1"], $this->answer_separator);
750 $elements = $this->getOrderingElements();
751 $solutions = array();
752
753 foreach ($answer_elements as $answer) {
754 foreach ($elements as $key => $element) {
755 if ($element == $answer) {
756 $result->addKeyValue($key + 1, $answer);
757 }
758 }
759 }
760
761 $glue = " ";
762 if ($this->answer_separator = '{::}') {
763 $glue = "";
764 }
765 $result->addKeyValue(null, join($glue, $answer_elements));
766
767 $points = $this->calculateReachedPoints($active_id, $pass);
768 $max_points = $this->getMaximumPoints();
769
770 $result->setReachedPercentage(($points / $max_points) * 100);
771
772 return $result;
773 }
774
783 public function getAvailableAnswerOptions($index = null)
784 {
785 $elements = $this->getOrderingElements();
786 if ($index !== null) {
787 if (array_key_exists($index, $elements)) {
788 return $elements[$index];
789 }
790 return null;
791 } else {
792 return $elements;
793 }
794 }
795
800 protected function calculateReachedPointsForSolution($value)
801 {
802 $value = $this->splitAndTrimOrderElementText($value, $this->answer_separator);
803 $value = join($this->answer_separator, $value);
804 if (strcmp($value, join($this->answer_separator, $this->getOrderingElements())) == 0) {
805 $points = $this->getPoints();
806 return $points;
807 }
808 return 0;
809 }
810
811 // fau: testNav - new function getTestQuestionConfig()
816 // hey: refactored identifiers
818 // hey.
819 {
820 // hey: refactored identifiers
821 return parent::buildTestPresentationConfig()
822 // hey.
823 ->setIsUnchangedAnswerPossible(true)
824 ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
825 }
826 // fau.
827}
$result
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Class for formula question question exports.
Class for formula question imports.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setSeparator($a_value)
Set order text separator.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
copyObject($target_questionpool_id, $title="")
Copies an assOrderingHorizontal object.
isComplete()
Returns true, if a single choice question is complete for use.
saveToDb($original_id="")
Saves a assOrderingHorizontal object to a database.
setOrderText($a_value)
Set order text.
setTextSize($a_value)
Set text size.
getOperators($expression)
Get all available operations for a specific question.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
toJSON()
Returns a JSON representation of the question.
getAnswerTableName()
Returns the name of the answer table in the database.
loadFromDb($question_id)
Loads a assOrderingHorizontal object from a database.
getRandomOrderingElements()
Get ordering elements from order text in random sequence.
getOrderingElements()
Get ordering elements from order text.
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping, array $solutionhints=[])
Creates a question from a QTI file.
getQuestionType()
Returns the question type of the question.
toXML($a_include_header=true, $a_include_binary=true, $a_shuffle=false, $test_output=false, $force_image_references=false)
Returns a QTI xml representation of the question and sets the internal domxml variable with the DOM X...
getSeparator()
Get order text separator.
buildTestPresentationConfig()
Get the test question configuration.
getExpressionTypes()
Get all available expression types for a specific question.
deleteAnswers($question_id)
Deletes datasets from answers tables.
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assOrderingHorizontal constructor
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
__set($key, $value)
Object setter.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
splitAndTrimOrderElementText($in_string, $separator)
Splits the answer string either by space(s) or the separator (eg.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assOrderingHorizontal.
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass.
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
setId($id=-1)
Sets the id of the assQuestion object.
setOriginalId($original_id)
setObjId($obj_id=0)
Set the object id of the container object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
saveQuestionDataToDb($original_id="")
getId()
Gets the id of the assQuestion object.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
getObjId()
Get the object id of the container object.
setTitle($title="")
Sets the title string of the assQuestion object.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
removeCurrentSolution($active_id, $pass, $authorized=true)
setAuthor($author="")
Sets the authors name of the assQuestion object.
getPoints()
Returns the maximum available points for the question.
setLifecycle(ilAssQuestionLifecycle $lifecycle)
getTitle()
Gets the title string of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
setNrOfTries($a_nr_of_tries)
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
setQuestion($question="")
Sets the question string of the question object.
static _getLogLanguage()
retrieve the log language for assessment logging
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static strPos($a_haystack, $a_needle, $a_offset=null)
Definition: class.ilStr.php:30
Base Exception for all Exceptions relating to Modules/Test.
Class ilUserQuestionResult.
global $DIC
Definition: goto.php:24
$mobs
Definition: imgupload.php:54
$ilUser
Definition: imgupload.php:18
Class iQuestionCondition.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
Interface ilObjQuestionScoringAdjustable.
$index
Definition: metadata.php:128
$i
Definition: metadata.php:24
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $ilDB
$data
Definition: storeScorm.php:23