ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 function __construct(
41 $title = "",
42 $comment = "",
43 $author = "",
44 $owner = -1,
45 $question = ""
46 )
47 {
48 parent::__construct($title, $comment, $author, $owner, $question);
49 $this->ordertext = "";
50 }
51
57 public function isComplete()
58 {
59 if (strlen($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0))
60 {
61 return true;
62 }
63 else
64 {
65 return false;
66 }
67 }
68
73 public function saveToDb($original_id = "")
74 {
77 parent::saveToDb();
78 }
79
83 public function getAnswerSeparator()
84 {
86 }
87
88
95 public function loadFromDb($question_id)
96 {
97 global $ilDB;
98
99 $result = $ilDB->queryF("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",
100 array("integer"),
101 array($question_id)
102 );
103 if ($result->numRows() == 1)
104 {
105 $data = $ilDB->fetchAssoc($result);
106 $this->setId($question_id);
107 $this->setObjId($data["obj_fi"]);
108 $this->setTitle($data["title"]);
109 $this->setComment($data["description"]);
110 $this->setOriginalId($data["original_id"]);
111 $this->setNrOfTries($data['nr_of_tries']);
112 $this->setAuthor($data["author"]);
113 $this->setPoints($data["points"]);
114 $this->setOwner($data["owner"]);
115 include_once("./Services/RTE/classes/class.ilRTE.php");
116 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
117 $this->setOrderText($data["ordertext"]);
118 $this->setTextSize($data["textsize"]);
119 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
120
121 try
122 {
123 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
124 }
126 {
127 }
128 }
129
130 parent::loadFromDb($question_id);
131 }
132
136 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
137 {
138 if ($this->id <= 0)
139 {
140 // The question has not been saved. It cannot be duplicated
141 return;
142 }
143 // duplicate the question in database
144 $this_id = $this->getId();
145 $thisObjId = $this->getObjId();
146
147 $clone = $this;
148 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
150 $clone->id = -1;
151
152 if( (int)$testObjId > 0 )
153 {
154 $clone->setObjId($testObjId);
155 }
156
157 if ($title)
158 {
159 $clone->setTitle($title);
160 }
161
162 if ($author)
163 {
164 $clone->setAuthor($author);
165 }
166 if ($owner)
167 {
168 $clone->setOwner($owner);
169 }
170
171 if ($for_test)
172 {
173 $clone->saveToDb($original_id);
174 }
175 else
176 {
177 $clone->saveToDb();
178 }
179
180 // copy question page content
181 $clone->copyPageOfQuestion($this_id);
182 // copy XHTML media objects
183 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
184
185 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
186
187 return $clone->id;
188 }
189
193 public function copyObject($target_questionpool_id, $title = "")
194 {
195 if ($this->id <= 0)
196 {
197 // The question has not been saved. It cannot be duplicated
198 return;
199 }
200 // duplicate the question in database
201 $clone = $this;
202 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
204 $clone->id = -1;
205 $source_questionpool_id = $this->getObjId();
206 $clone->setObjId($target_questionpool_id);
207 if ($title)
208 {
209 $clone->setTitle($title);
210 }
211 $clone->saveToDb();
212 // copy question page content
213 $clone->copyPageOfQuestion($original_id);
214 // copy XHTML media objects
215 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
216
217 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
218
219 return $clone->id;
220 }
221
222 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
223 {
224 if ($this->id <= 0)
225 {
226 // The question has not been saved. It cannot be duplicated
227 return;
228 }
229
230 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
231
232 $sourceQuestionId = $this->id;
233 $sourceParentId = $this->getObjId();
234
235 // duplicate the question in database
236 $clone = $this;
237 $clone->id = -1;
238
239 $clone->setObjId($targetParentId);
240
241 if ($targetQuestionTitle)
242 {
243 $clone->setTitle($targetQuestionTitle);
244 }
245
246 $clone->saveToDb();
247 // copy question page content
248 $clone->copyPageOfQuestion($sourceQuestionId);
249 // copy XHTML media objects
250 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
251
252 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
253
254 return $clone->id;
255 }
256
262 public function getMaximumPoints()
263 {
264 return $this->getPoints();
265 }
266
277 public function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = FALSE)
278 {
279 if( $returndetails )
280 {
281 throw new ilTestException('return details not implemented for '.__METHOD__);
282 }
283
284 global $ilDB;
285
286 $found_values = array();
287 if (is_null($pass))
288 {
289 $pass = $this->getSolutionMaxPass($active_id);
290 }
291 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
292 $points = 0;
293 $data = $ilDB->fetchAssoc($result);
294
296
297 return $points;
298 }
299
309 public function splitAndTrimOrderElementText($in_string, $separator)
310 {
311 $result = array();
312 include_once "./Services/Utilities/classes/class.ilStr.php";
313
314 if (ilStr::strPos($in_string, $separator) === false)
315 {
316 $result = preg_split("/\\s+/", $in_string);
317 }
318 else
319 {
320 $result = explode($separator, $in_string);
321 }
322
323 foreach ($result as $key => $value)
324 {
325 $result[$key] = trim($value);
326 }
327
328 return $result;
329 }
330
331 public function getSolutionSubmit()
332 {
333 return $_POST["orderresult"];
334 }
335
344 public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
345 {
346 global $ilDB;
347 global $ilUser;
348
349 if (is_null($pass))
350 {
351 include_once "./Modules/Test/classes/class.ilObjTest.php";
352 $pass = ilObjTest::_getPass($active_id);
353 }
354
355 $entered_values = false;
356
357 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function() use (&$entered_values, $active_id, $pass, $authorized) {
358
359 $this->removeCurrentSolution($active_id, $pass, $authorized);
360
361 $solutionSubmit = $this->getSolutionSubmit();
362
363 $entered_values = false;
364 if (strlen($solutionSubmit))
365 {
366 $this->saveCurrentSolution($active_id, $pass, $_POST['orderresult'], null, $authorized);
367 $entered_values = true;
368 }
369
370 });
371
372 if ($entered_values)
373 {
374 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
376 {
377 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
378 }
379 }
380 else
381 {
382 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
384 {
385 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
386 }
387 }
388
389 return true;
390 }
391
393 {
394 global $ilDB;
395
396 // save additional data
397 $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName()
398 . " WHERE question_fi = %s",
399 array( "integer" ),
400 array( $this->getId() )
401 );
402
403 $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName()
404 . " (question_fi, ordertext, textsize) VALUES (%s, %s, %s)",
405 array( "integer", "text", "float" ),
406 array(
407 $this->getId(),
408 $this->getOrderText(),
409 ($this->getTextSize() < 10) ? NULL : $this->getTextSize()
410 )
411 );
412 }
413
417 protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
418 {
419 // nothing to rework!
420 }
421
427 public function getQuestionType()
428 {
429 return "assOrderingHorizontal";
430 }
431
437 public function getAdditionalTableName()
438 {
439 return "qpl_qst_horder";
440 }
441
447 public function getAnswerTableName()
448 {
449 return "";
450 }
451
457 public function deleteAnswers($question_id)
458 {
459 }
460
466 {
467 $text = parent::getRTETextWithMediaObjects();
468 return $text;
469 }
470
474 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
475 {
476 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
477
478 $solutionvalue = "";
479 $solutions =& $this->getSolutionValues($active_id, $pass);
480 $solutionvalue = str_replace("{::}", " ", $solutions[0]["value1"]);
481 $i = 1;
482 $worksheet->setCell($startrow+$i, 0, $solutionvalue);
483 $i++;
484
485 return $startrow + $i + 1;
486 }
487
500 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
501 {
502 include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assOrderingHorizontalImport.php";
503 $import = new assOrderingHorizontalImport($this);
504 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
505 }
506
513 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
514 {
515 include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assOrderingHorizontalExport.php";
516 $export = new assOrderingHorizontalExport($this);
517 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
518 }
519
525 public function getBestSolution($active_id, $pass)
526 {
527 $user_solution = array();
528 return $user_solution;
529 }
530
536 public function getOrderingElements()
537 {
538 return $this->splitAndTrimOrderElementText($this->getOrderText(), $this->separator);
539 }
540
547 {
548 $elements = $this->getOrderingElements();
549 $elements = $this->getShuffler()->shuffle($elements);
550 return $elements;
551 }
552
558 public function getOrderText()
559 {
560 return $this->ordertext;
561 }
562
568 public function setOrderText($a_value)
569 {
570 $this->ordertext = $a_value;
571 }
572
578 public function getTextSize()
579 {
580 return $this->textsize;
581 }
582
588 public function setTextSize($a_value)
589 {
590 if ($a_value >= 10)
591 {
592 $this->textsize = $a_value;
593 }
594 }
595
601 public function getSeparator()
602 {
603 return $this->separator;
604 }
605
611 public function setSeparator($a_value)
612 {
613 $this->separator = $a_value;
614 }
615
619 public function __get($value)
620 {
621 switch ($value)
622 {
623 case "ordertext":
624 return $this->getOrderText();
625 break;
626 case "textsize":
627 return $this->getTextSize();
628 break;
629 case "separator":
630 return $this->getSeparator();
631 break;
632 default:
633 return parent::__get($value);
634 break;
635 }
636 }
637
641 public function __set($key, $value)
642 {
643 switch ($key)
644 {
645 case "ordertext":
646 $this->setOrderText($value);
647 break;
648 case "textsize":
649 $this->setTextSize($value);
650 break;
651 case "separator":
652 $this->setSeparator($value);
653 break;
654 default:
655 parent::__set($key, $value);
656 break;
657 }
658 }
659
660 public function supportsJavascriptOutput()
661 {
662 return true;
663 }
664
665 public function supportsNonJsOutput()
666 {
667 return false;
668 }
669
673 public function toJSON()
674 {
675 include_once("./Services/RTE/classes/class.ilRTE.php");
676 $result = array();
677 $result['id'] = (int) $this->getId();
678 $result['type'] = (string) $this->getQuestionType();
679 $result['title'] = (string) $this->getTitle();
680 $result['question'] = $this->formatSAQuestion($this->getQuestion());
681 $result['nr_of_tries'] = (int) $this->getNrOfTries();
682 $result['shuffle'] = (bool) true;
683 $result['points'] = (bool) $this->getPoints();
684 $result['textsize'] = ((int)$this->getTextSize()) // #10923
685 ? (int)$this->getTextSize()
686 : 100;
687 $result['feedback'] = array(
688 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
689 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
690 );
691
692 $arr = array();
693 foreach ($this->getOrderingElements() as $order => $answer)
694 {
695 array_push($arr, array(
696 "answertext" => (string) $answer,
697 "order" => (int) $order+1
698 ));
699 }
700 $result['answers'] = $arr;
701
702 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
703 $result['mobs'] = $mobs;
704
705 return json_encode($result);
706 }
707
716 public function getOperators($expression)
717 {
718 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
720 }
721
726 public function getExpressionTypes()
727 {
728 return array(
733 );
734 }
735
744 public function getUserQuestionResult($active_id, $pass)
745 {
747 global $ilDB;
748 $result = new ilUserQuestionResult($this, $active_id, $pass);
749
750 $maxStep = $this->lookupMaxStep($active_id, $pass);
751
752 if( $maxStep !== null )
753 {
754 $data = $ilDB->queryF(
755 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
756 array("integer", "integer", "integer","integer"),
757 array($active_id, $pass, $this->getId(), $maxStep)
758 );
759 }
760 else
761 {
762 $data = $ilDB->queryF(
763 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
764 array("integer", "integer", "integer"),
765 array($active_id, $pass, $this->getId())
766 );
767 }
768 $row = $ilDB->fetchAssoc($data);
769
770 $answer_elements = $this->splitAndTrimOrderElementText($row["value1"], $this->answer_separator);
771 $elements = $this->getOrderingElements();
772 $solutions = array();
773
774 foreach($answer_elements as $answer)
775 {
776 foreach($elements as $key => $element)
777 {
778 if($element == $answer)
779 {
780 $result->addKeyValue($key+1, $answer);
781 }
782 }
783 }
784
785 $glue = " ";
786 if($this->answer_separator = '{::}')
787 {
788 $glue = "";
789 }
790 $result->addKeyValue(null, join($glue, $answer_elements));
791
792 $points = $this->calculateReachedPoints($active_id, $pass);
793 $max_points = $this->getMaximumPoints();
794
795 $result->setReachedPercentage(($points/$max_points) * 100);
796
797 return $result;
798 }
799
808 public function getAvailableAnswerOptions($index = null)
809 {
810 $elements = $this->getOrderingElements();
811 if($index !== null)
812 {
813 if(array_key_exists($index, $elements))
814 {
815 return $elements[$index];
816 }
817 return null;
818 }
819 else
820 {
821 return $elements;
822 }
823 }
824
829 protected function calculateReachedPointsForSolution($value)
830 {
831 $value = $this->splitAndTrimOrderElementText($value, $this->answer_separator);
832 $value = join($value, $this->answer_separator);
833 if(strcmp($value, join($this->getOrderingElements(), $this->answer_separator)) == 0)
834 {
835 $points = $this->getPoints();
836 return $points;
837 }
838 return 0;
839 }
840
841// fau: testNav - new function getTestQuestionConfig()
846 // hey: refactored identifiers
848 // hey.
849 {
850 // hey: refactored identifiers
851 return parent::buildTestPresentationConfig()
852 // hey.
853 ->setIsUnchangedAnswerPossible(true)
854 ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
855 }
856// fau.
857}
$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
__set($key, $value)
Object setter.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
splitAndTrimOrderElementText($in_string, $separator)
Splits the answer string either by space(s) or the separator (eg.
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
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.
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.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
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:34
Base Exception for all Exceptions relating to Modules/Test.
Class ilUserQuestionResult.
$text
Class iQuestionCondition.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
Interface ilObjQuestionScoringAdjustable.
global $ilDB
$mobs
$ilUser
Definition: imgupload.php:18