ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 $ilDB;
94
95 $result = $ilDB->queryF(
96 "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",
97 array("integer"),
98 array($question_id)
99 );
100 if ($result->numRows() == 1) {
101 $data = $ilDB->fetchAssoc($result);
102 $this->setId($question_id);
103 $this->setObjId($data["obj_fi"]);
104 $this->setTitle($data["title"]);
105 $this->setComment($data["description"]);
106 $this->setOriginalId($data["original_id"]);
107 $this->setNrOfTries($data['nr_of_tries']);
108 $this->setAuthor($data["author"]);
109 $this->setPoints($data["points"]);
110 $this->setOwner($data["owner"]);
111 include_once("./Services/RTE/classes/class.ilRTE.php");
112 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
113 $this->setOrderText($data["ordertext"]);
114 $this->setTextSize($data["textsize"]);
115 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
116
117 try {
118 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
119 } catch (ilTestQuestionPoolException $e) {
120 }
121 }
122
123 parent::loadFromDb($question_id);
124 }
125
129 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
130 {
131 if ($this->id <= 0) {
132 // The question has not been saved. It cannot be duplicated
133 return;
134 }
135 // duplicate the question in database
136 $this_id = $this->getId();
137 $thisObjId = $this->getObjId();
138
139 $clone = $this;
140 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
142 $clone->id = -1;
143
144 if ((int) $testObjId > 0) {
145 $clone->setObjId($testObjId);
146 }
147
148 if ($title) {
149 $clone->setTitle($title);
150 }
151
152 if ($author) {
153 $clone->setAuthor($author);
154 }
155 if ($owner) {
156 $clone->setOwner($owner);
157 }
158
159 if ($for_test) {
160 $clone->saveToDb($original_id);
161 } else {
162 $clone->saveToDb();
163 }
164
165 // copy question page content
166 $clone->copyPageOfQuestion($this_id);
167 // copy XHTML media objects
168 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
169
170 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
171
172 return $clone->id;
173 }
174
178 public function copyObject($target_questionpool_id, $title = "")
179 {
180 if ($this->id <= 0) {
181 // The question has not been saved. It cannot be duplicated
182 return;
183 }
184 // duplicate the question in database
185 $clone = $this;
186 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
188 $clone->id = -1;
189 $source_questionpool_id = $this->getObjId();
190 $clone->setObjId($target_questionpool_id);
191 if ($title) {
192 $clone->setTitle($title);
193 }
194 $clone->saveToDb();
195 // copy question page content
196 $clone->copyPageOfQuestion($original_id);
197 // copy XHTML media objects
198 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
199
200 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
201
202 return $clone->id;
203 }
204
205 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
206 {
207 if ($this->id <= 0) {
208 // The question has not been saved. It cannot be duplicated
209 return;
210 }
211
212 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
213
214 $sourceQuestionId = $this->id;
215 $sourceParentId = $this->getObjId();
216
217 // duplicate the question in database
218 $clone = $this;
219 $clone->id = -1;
220
221 $clone->setObjId($targetParentId);
222
223 if ($targetQuestionTitle) {
224 $clone->setTitle($targetQuestionTitle);
225 }
226
227 $clone->saveToDb();
228 // copy question page content
229 $clone->copyPageOfQuestion($sourceQuestionId);
230 // copy XHTML media objects
231 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
232
233 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
234
235 return $clone->id;
236 }
237
243 public function getMaximumPoints()
244 {
245 return $this->getPoints();
246 }
247
258 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
259 {
260 if ($returndetails) {
261 throw new ilTestException('return details not implemented for ' . __METHOD__);
262 }
263
264 global $ilDB;
265
266 $found_values = array();
267 if (is_null($pass)) {
268 $pass = $this->getSolutionMaxPass($active_id);
269 }
270 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
271 $points = 0;
272 $data = $ilDB->fetchAssoc($result);
273
275
276 return $points;
277 }
278
288 public function splitAndTrimOrderElementText($in_string, $separator)
289 {
290 $result = array();
291 include_once "./Services/Utilities/classes/class.ilStr.php";
292
293 if (ilStr::strPos($in_string, $separator) === false) {
294 $result = preg_split("/\\s+/", $in_string);
295 } else {
296 $result = explode($separator, $in_string);
297 }
298
299 foreach ($result as $key => $value) {
300 $result[$key] = trim($value);
301 }
302
303 return $result;
304 }
305
306 public function getSolutionSubmit()
307 {
308 return $_POST["orderresult"];
309 }
310
319 public function saveWorkingData($active_id, $pass = null, $authorized = true)
320 {
321 global $ilDB;
322 global $ilUser;
323
324 if (is_null($pass)) {
325 include_once "./Modules/Test/classes/class.ilObjTest.php";
326 $pass = ilObjTest::_getPass($active_id);
327 }
328
329 $entered_values = false;
330
331 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $active_id, $pass, $authorized) {
332 $this->removeCurrentSolution($active_id, $pass, $authorized);
333
334 $solutionSubmit = $this->getSolutionSubmit();
335
336 $entered_values = false;
337 if (strlen($solutionSubmit)) {
338 $this->saveCurrentSolution($active_id, $pass, $_POST['orderresult'], null, $authorized);
339 $entered_values = true;
340 }
341 });
342
343 if ($entered_values) {
344 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
346 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
347 }
348 } else {
349 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
351 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
352 }
353 }
354
355 return true;
356 }
357
359 {
360 global $ilDB;
361
362 // save additional data
363 $ilDB->manipulateF(
364 "DELETE FROM " . $this->getAdditionalTableName()
365 . " WHERE question_fi = %s",
366 array( "integer" ),
367 array( $this->getId() )
368 );
369
370 $ilDB->manipulateF(
371 "INSERT INTO " . $this->getAdditionalTableName()
372 . " (question_fi, ordertext, textsize) VALUES (%s, %s, %s)",
373 array( "integer", "text", "float" ),
374 array(
375 $this->getId(),
376 $this->getOrderText(),
377 ($this->getTextSize() < 10) ? null : $this->getTextSize()
378 )
379 );
380 }
381
385 protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
386 {
387 // nothing to rework!
388 }
389
395 public function getQuestionType()
396 {
397 return "assOrderingHorizontal";
398 }
399
405 public function getAdditionalTableName()
406 {
407 return "qpl_qst_horder";
408 }
409
415 public function getAnswerTableName()
416 {
417 return "";
418 }
419
425 public function deleteAnswers($question_id)
426 {
427 }
428
434 {
435 $text = parent::getRTETextWithMediaObjects();
436 return $text;
437 }
438
442 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
443 {
444 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
445
446 $solutionvalue = "";
447 $solutions =&$this->getSolutionValues($active_id, $pass);
448 $solutionvalue = str_replace("{::}", " ", $solutions[0]["value1"]);
449 $i = 1;
450 $worksheet->setCell($startrow+$i, 0, $solutionvalue);
451 $i++;
452
453 return $startrow + $i + 1;
454 }
455
468 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
469 {
470 include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assOrderingHorizontalImport.php";
471 $import = new assOrderingHorizontalImport($this);
472 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
473 }
474
481 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
482 {
483 include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assOrderingHorizontalExport.php";
484 $export = new assOrderingHorizontalExport($this);
485 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
486 }
487
493 public function getBestSolution($active_id, $pass)
494 {
495 $user_solution = array();
496 return $user_solution;
497 }
498
504 public function getOrderingElements()
505 {
506 return $this->splitAndTrimOrderElementText($this->getOrderText(), $this->separator);
507 }
508
515 {
516 $elements = $this->getOrderingElements();
517 $elements = $this->getShuffler()->shuffle($elements);
518 return $elements;
519 }
520
526 public function getOrderText()
527 {
528 return $this->ordertext;
529 }
530
536 public function setOrderText($a_value)
537 {
538 $this->ordertext = $a_value;
539 }
540
546 public function getTextSize()
547 {
548 return $this->textsize;
549 }
550
556 public function setTextSize($a_value)
557 {
558 if ($a_value >= 10) {
559 $this->textsize = $a_value;
560 }
561 }
562
568 public function getSeparator()
569 {
570 return $this->separator;
571 }
572
578 public function setSeparator($a_value)
579 {
580 $this->separator = $a_value;
581 }
582
586 public function __get($value)
587 {
588 switch ($value) {
589 case "ordertext":
590 return $this->getOrderText();
591 break;
592 case "textsize":
593 return $this->getTextSize();
594 break;
595 case "separator":
596 return $this->getSeparator();
597 break;
598 default:
599 return parent::__get($value);
600 break;
601 }
602 }
603
607 public function __set($key, $value)
608 {
609 switch ($key) {
610 case "ordertext":
611 $this->setOrderText($value);
612 break;
613 case "textsize":
614 $this->setTextSize($value);
615 break;
616 case "separator":
617 $this->setSeparator($value);
618 break;
619 default:
620 parent::__set($key, $value);
621 break;
622 }
623 }
624
625 public function supportsJavascriptOutput()
626 {
627 return true;
628 }
629
630 public function supportsNonJsOutput()
631 {
632 return false;
633 }
634
638 public function toJSON()
639 {
640 include_once("./Services/RTE/classes/class.ilRTE.php");
641 $result = array();
642 $result['id'] = (int) $this->getId();
643 $result['type'] = (string) $this->getQuestionType();
644 $result['title'] = (string) $this->getTitle();
645 $result['question'] = $this->formatSAQuestion($this->getQuestion());
646 $result['nr_of_tries'] = (int) $this->getNrOfTries();
647 $result['shuffle'] = (bool) true;
648 $result['points'] = (bool) $this->getPoints();
649 $result['textsize'] = ((int) $this->getTextSize()) // #10923
650 ? (int) $this->getTextSize()
651 : 100;
652 $result['feedback'] = array(
653 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
654 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
655 );
656
657 $arr = array();
658 foreach ($this->getOrderingElements() as $order => $answer) {
659 array_push($arr, array(
660 "answertext" => (string) $answer,
661 "order" => (int) $order+1
662 ));
663 }
664 $result['answers'] = $arr;
665
666 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
667 $result['mobs'] = $mobs;
668
669 return json_encode($result);
670 }
671
680 public function getOperators($expression)
681 {
682 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
684 }
685
690 public function getExpressionTypes()
691 {
692 return array(
697 );
698 }
699
708 public function getUserQuestionResult($active_id, $pass)
709 {
711 global $ilDB;
712 $result = new ilUserQuestionResult($this, $active_id, $pass);
713
714 $maxStep = $this->lookupMaxStep($active_id, $pass);
715
716 if ($maxStep !== null) {
717 $data = $ilDB->queryF(
718 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
719 array("integer", "integer", "integer","integer"),
720 array($active_id, $pass, $this->getId(), $maxStep)
721 );
722 } else {
723 $data = $ilDB->queryF(
724 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
725 array("integer", "integer", "integer"),
726 array($active_id, $pass, $this->getId())
727 );
728 }
729 $row = $ilDB->fetchAssoc($data);
730
731 $answer_elements = $this->splitAndTrimOrderElementText($row["value1"], $this->answer_separator);
732 $elements = $this->getOrderingElements();
733 $solutions = array();
734
735 foreach ($answer_elements as $answer) {
736 foreach ($elements as $key => $element) {
737 if ($element == $answer) {
738 $result->addKeyValue($key+1, $answer);
739 }
740 }
741 }
742
743 $glue = " ";
744 if ($this->answer_separator = '{::}') {
745 $glue = "";
746 }
747 $result->addKeyValue(null, join($glue, $answer_elements));
748
749 $points = $this->calculateReachedPoints($active_id, $pass);
750 $max_points = $this->getMaximumPoints();
751
752 $result->setReachedPercentage(($points/$max_points) * 100);
753
754 return $result;
755 }
756
765 public function getAvailableAnswerOptions($index = null)
766 {
767 $elements = $this->getOrderingElements();
768 if ($index !== null) {
769 if (array_key_exists($index, $elements)) {
770 return $elements[$index];
771 }
772 return null;
773 } else {
774 return $elements;
775 }
776 }
777
782 protected function calculateReachedPointsForSolution($value)
783 {
784 $value = $this->splitAndTrimOrderElementText($value, $this->answer_separator);
785 $value = join($value, $this->answer_separator);
786 if (strcmp($value, join($this->getOrderingElements(), $this->answer_separator)) == 0) {
787 $points = $this->getPoints();
788 return $points;
789 }
790 return 0;
791 }
792
793 // fau: testNav - new function getTestQuestionConfig()
798 // hey: refactored identifiers
800 // hey.
801 {
802 // hey: refactored identifiers
803 return parent::buildTestPresentationConfig()
804 // hey.
805 ->setIsUnchangedAnswerPossible(true)
806 ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
807 }
808 // fau.
809}
$worksheet
$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.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{Reworks the allready saved working data if neccessary.}
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
global $ilDB
$mobs
$ilUser
Definition: imgupload.php:18
$text
Definition: errorreport.php:18