ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.assOrderingHorizontal.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
5require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
8require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
9
22{
23 protected $ordertext;
24 protected $textsize;
25 protected $separator = "::";
26 protected $answer_separator = '{::}';
27
40 public function __construct(
41 $title = "",
42 $comment = "",
43 $author = "",
44 $owner = -1,
45 $question = ""
46 ) {
47 parent::__construct($title, $comment, $author, $owner, $question);
48 $this->ordertext = "";
49 }
50
56 public function isComplete()
57 {
58 if (strlen($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0)) {
59 return true;
60 } else {
61 return false;
62 }
63 }
64
69 public function saveToDb($original_id = "")
70 {
73 parent::saveToDb();
74 }
75
79 public function getAnswerSeparator()
80 {
82 }
83
84
91 public function loadFromDb($question_id)
92 {
93 global $DIC;
94 $ilDB = $DIC['ilDB'];
95
96 $result = $ilDB->queryF(
97 "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",
98 array("integer"),
99 array($question_id)
100 );
101 if ($result->numRows() == 1) {
102 $data = $ilDB->fetchAssoc($result);
103 $this->setId($question_id);
104 $this->setObjId($data["obj_fi"]);
105 $this->setTitle($data["title"]);
106 $this->setComment($data["description"]);
107 $this->setOriginalId($data["original_id"]);
108 $this->setNrOfTries($data['nr_of_tries']);
109 $this->setAuthor($data["author"]);
110 $this->setPoints($data["points"]);
111 $this->setOwner($data["owner"]);
112 include_once("./Services/RTE/classes/class.ilRTE.php");
113 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
114 $this->setOrderText($data["ordertext"]);
115 $this->setTextSize($data["textsize"]);
116 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
117
118 try {
119 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
120 } catch (ilTestQuestionPoolException $e) {
121 }
122 }
123
124 parent::loadFromDb($question_id);
125 }
126
130 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
131 {
132 if ($this->id <= 0) {
133 // The question has not been saved. It cannot be duplicated
134 return;
135 }
136 // duplicate the question in database
137 $this_id = $this->getId();
138 $thisObjId = $this->getObjId();
139
140 $clone = $this;
141 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
143 $clone->id = -1;
144
145 if ((int) $testObjId > 0) {
146 $clone->setObjId($testObjId);
147 }
148
149 if ($title) {
150 $clone->setTitle($title);
151 }
152
153 if ($author) {
154 $clone->setAuthor($author);
155 }
156 if ($owner) {
157 $clone->setOwner($owner);
158 }
159
160 if ($for_test) {
161 $clone->saveToDb($original_id);
162 } else {
163 $clone->saveToDb();
164 }
165
166 // copy question page content
167 $clone->copyPageOfQuestion($this_id);
168 // copy XHTML media objects
169 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
170
171 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
172
173 return $clone->id;
174 }
175
179 public function copyObject($target_questionpool_id, $title = "")
180 {
181 if ($this->id <= 0) {
182 // The question has not been saved. It cannot be duplicated
183 return;
184 }
185 // duplicate the question in database
186 $clone = $this;
187 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
189 $clone->id = -1;
190 $source_questionpool_id = $this->getObjId();
191 $clone->setObjId($target_questionpool_id);
192 if ($title) {
193 $clone->setTitle($title);
194 }
195 $clone->saveToDb();
196 // copy question page content
197 $clone->copyPageOfQuestion($original_id);
198 // copy XHTML media objects
199 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
200
201 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
202
203 return $clone->id;
204 }
205
206 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
207 {
208 if ($this->id <= 0) {
209 // The question has not been saved. It cannot be duplicated
210 return;
211 }
212
213 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
214
215 $sourceQuestionId = $this->id;
216 $sourceParentId = $this->getObjId();
217
218 // duplicate the question in database
219 $clone = $this;
220 $clone->id = -1;
221
222 $clone->setObjId($targetParentId);
223
224 if ($targetQuestionTitle) {
225 $clone->setTitle($targetQuestionTitle);
226 }
227
228 $clone->saveToDb();
229 // copy question page content
230 $clone->copyPageOfQuestion($sourceQuestionId);
231 // copy XHTML media objects
232 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
233
234 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
235
236 return $clone->id;
237 }
238
244 public function getMaximumPoints()
245 {
246 return $this->getPoints();
247 }
248
259 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
260 {
261 if ($returndetails) {
262 throw new ilTestException('return details not implemented for ' . __METHOD__);
263 }
264
265 global $DIC;
266 $ilDB = $DIC['ilDB'];
267
268 $found_values = array();
269 if (is_null($pass)) {
270 $pass = $this->getSolutionMaxPass($active_id);
271 }
272 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
273 $points = 0;
274 $data = $ilDB->fetchAssoc($result);
275
277
278 return $points;
279 }
280
290 public function splitAndTrimOrderElementText($in_string, $separator)
291 {
292 $result = array();
293 include_once "./Services/Utilities/classes/class.ilStr.php";
294
295 if (ilStr::strPos($in_string, $separator) === false) {
296 $result = preg_split("/\\s+/", $in_string);
297 } else {
298 $result = explode($separator, $in_string);
299 }
300
301 foreach ($result as $key => $value) {
302 $result[$key] = trim($value);
303 }
304
305 return $result;
306 }
307
308 public function getSolutionSubmit()
309 {
310 return $_POST["orderresult"];
311 }
312
321 public function saveWorkingData($active_id, $pass = null, $authorized = true)
322 {
323 global $DIC;
324 $ilDB = $DIC['ilDB'];
325 $ilUser = $DIC['ilUser'];
326
327 if (is_null($pass)) {
328 include_once "./Modules/Test/classes/class.ilObjTest.php";
329 $pass = ilObjTest::_getPass($active_id);
330 }
331
332 $entered_values = false;
333
334 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $active_id, $pass, $authorized) {
335 $this->removeCurrentSolution($active_id, $pass, $authorized);
336
337 $solutionSubmit = $this->getSolutionSubmit();
338
339 $entered_values = false;
340 if (strlen($solutionSubmit)) {
341 $this->saveCurrentSolution($active_id, $pass, $_POST['orderresult'], null, $authorized);
342 $entered_values = true;
343 }
344 });
345
346 if ($entered_values) {
347 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
349 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
350 }
351 } else {
352 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
354 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
355 }
356 }
357
358 return true;
359 }
360
362 {
363 global $DIC;
364 $ilDB = $DIC['ilDB'];
365
366 // save additional data
367 $ilDB->manipulateF(
368 "DELETE FROM " . $this->getAdditionalTableName()
369 . " WHERE question_fi = %s",
370 array( "integer" ),
371 array( $this->getId() )
372 );
373
374 $ilDB->manipulateF(
375 "INSERT INTO " . $this->getAdditionalTableName()
376 . " (question_fi, ordertext, textsize) VALUES (%s, %s, %s)",
377 array( "integer", "text", "float" ),
378 array(
379 $this->getId(),
380 $this->getOrderText(),
381 ($this->getTextSize() < 10) ? null : $this->getTextSize()
382 )
383 );
384 }
385
391 public function getQuestionType()
392 {
393 return "assOrderingHorizontal";
394 }
395
401 public function getAdditionalTableName()
402 {
403 return "qpl_qst_horder";
404 }
405
411 public function getAnswerTableName()
412 {
413 return "";
414 }
415
421 public function deleteAnswers($question_id)
422 {
423 }
424
430 {
431 $text = parent::getRTETextWithMediaObjects();
432 return $text;
433 }
434
438 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
439 {
440 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
441
442 $solutionvalue = "";
443 $solutions = &$this->getSolutionValues($active_id, $pass);
444 $solutionvalue = str_replace("{::}", " ", $solutions[0]["value1"]);
445 $i = 1;
446 $worksheet->setCell($startrow + $i, 0, $solutionvalue);
447 $i++;
448
449 return $startrow + $i + 1;
450 }
451
464 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
465 {
466 include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assOrderingHorizontalImport.php";
467 $import = new assOrderingHorizontalImport($this);
468 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
469 }
470
477 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
478 {
479 include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assOrderingHorizontalExport.php";
480 $export = new assOrderingHorizontalExport($this);
481 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
482 }
483
489 public function getBestSolution($active_id, $pass)
490 {
491 $user_solution = array();
492 return $user_solution;
493 }
494
500 public function getOrderingElements()
501 {
502 return $this->splitAndTrimOrderElementText($this->getOrderText(), $this->separator);
503 }
504
511 {
512 $elements = $this->getOrderingElements();
513 $elements = $this->getShuffler()->shuffle($elements);
514 return $elements;
515 }
516
522 public function getOrderText()
523 {
524 return $this->ordertext;
525 }
526
532 public function setOrderText($a_value)
533 {
534 $this->ordertext = $a_value;
535 }
536
542 public function getTextSize()
543 {
544 return $this->textsize;
545 }
546
552 public function setTextSize($a_value)
553 {
554 if ($a_value >= 10) {
555 $this->textsize = $a_value;
556 }
557 }
558
564 public function getSeparator()
565 {
566 return $this->separator;
567 }
568
574 public function setSeparator($a_value)
575 {
576 $this->separator = $a_value;
577 }
578
582 public function __get($value)
583 {
584 switch ($value) {
585 case "ordertext":
586 return $this->getOrderText();
587 break;
588 case "textsize":
589 return $this->getTextSize();
590 break;
591 case "separator":
592 return $this->getSeparator();
593 break;
594 default:
595 return parent::__get($value);
596 break;
597 }
598 }
599
603 public function __set($key, $value)
604 {
605 switch ($key) {
606 case "ordertext":
607 $this->setOrderText($value);
608 break;
609 case "textsize":
610 $this->setTextSize($value);
611 break;
612 case "separator":
613 $this->setSeparator($value);
614 break;
615 default:
616 parent::__set($key, $value);
617 break;
618 }
619 }
620
621 public function supportsJavascriptOutput()
622 {
623 return true;
624 }
625
626 public function supportsNonJsOutput()
627 {
628 return false;
629 }
630
634 public function toJSON()
635 {
636 include_once("./Services/RTE/classes/class.ilRTE.php");
637 $result = array();
638 $result['id'] = (int) $this->getId();
639 $result['type'] = (string) $this->getQuestionType();
640 $result['title'] = (string) $this->getTitle();
641 $result['question'] = $this->formatSAQuestion($this->getQuestion());
642 $result['nr_of_tries'] = (int) $this->getNrOfTries();
643 $result['shuffle'] = (bool) true;
644 $result['points'] = (bool) $this->getPoints();
645 $result['textsize'] = ((int) $this->getTextSize()) // #10923
646 ? (int) $this->getTextSize()
647 : 100;
648 $result['feedback'] = array(
649 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
650 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
651 );
652
653 $arr = array();
654 foreach ($this->getOrderingElements() as $order => $answer) {
655 array_push($arr, array(
656 "answertext" => (string) $answer,
657 "order" => (int) $order + 1
658 ));
659 }
660 $result['answers'] = $arr;
661
662 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
663 $result['mobs'] = $mobs;
664
665 return json_encode($result);
666 }
667
676 public function getOperators($expression)
677 {
678 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
680 }
681
686 public function getExpressionTypes()
687 {
688 return array(
693 );
694 }
695
704 public function getUserQuestionResult($active_id, $pass)
705 {
707 global $DIC;
708 $ilDB = $DIC['ilDB'];
709 $result = new ilUserQuestionResult($this, $active_id, $pass);
710
711 $maxStep = $this->lookupMaxStep($active_id, $pass);
712
713 if ($maxStep !== null) {
714 $data = $ilDB->queryF(
715 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
716 array("integer", "integer", "integer","integer"),
717 array($active_id, $pass, $this->getId(), $maxStep)
718 );
719 } else {
720 $data = $ilDB->queryF(
721 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
722 array("integer", "integer", "integer"),
723 array($active_id, $pass, $this->getId())
724 );
725 }
726 $row = $ilDB->fetchAssoc($data);
727
728 $answer_elements = $this->splitAndTrimOrderElementText($row["value1"], $this->answer_separator);
729 $elements = $this->getOrderingElements();
730 $solutions = array();
731
732 foreach ($answer_elements as $answer) {
733 foreach ($elements as $key => $element) {
734 if ($element == $answer) {
735 $result->addKeyValue($key + 1, $answer);
736 }
737 }
738 }
739
740 $glue = " ";
741 if ($this->answer_separator = '{::}') {
742 $glue = "";
743 }
744 $result->addKeyValue(null, join($glue, $answer_elements));
745
746 $points = $this->calculateReachedPoints($active_id, $pass);
747 $max_points = $this->getMaximumPoints();
748
749 $result->setReachedPercentage(($points / $max_points) * 100);
750
751 return $result;
752 }
753
762 public function getAvailableAnswerOptions($index = null)
763 {
764 $elements = $this->getOrderingElements();
765 if ($index !== null) {
766 if (array_key_exists($index, $elements)) {
767 return $elements[$index];
768 }
769 return null;
770 } else {
771 return $elements;
772 }
773 }
774
779 protected function calculateReachedPointsForSolution($value)
780 {
781 $value = $this->splitAndTrimOrderElementText($value, $this->answer_separator);
782 $value = join($this->answer_separator, $value);
783 if (strcmp($value, join($this->answer_separator, $this->getOrderingElements())) == 0) {
784 $points = $this->getPoints();
785 return $points;
786 }
787 return 0;
788 }
789
790 // fau: testNav - new function getTestQuestionConfig()
795 // hey: refactored identifiers
797 // hey.
798 {
799 // hey: refactored identifiers
800 return parent::buildTestPresentationConfig()
801 // hey.
802 ->setIsUnchangedAnswerPossible(true)
803 ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
804 }
805 // fau.
806}
$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.
Class for horizontal ordering questions.
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.
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="")
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Creates a question from a QTI file.
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.
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.
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
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:60
$row
global $DIC
Definition: saml.php:7
global $ilDB
$mobs
$ilUser
Definition: imgupload.php:18
$data
Definition: bench.php:6
$text
Definition: errorreport.php:18