ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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 = split($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 $this->getProcessLocker()->requestUserSolutionUpdateLock();
356
357 $affectedRows = $this->removeCurrentSolution($active_id, $pass, $authorized);
358
359 $solutionSubmit = $this->getSolutionSubmit();
360
361 $entered_values = false;
362 if (strlen($solutionSubmit))
363 {
364 $affectedRows = $this->saveCurrentSolution($active_id, $pass, $_POST['orderresult'], null, $authorized);
365 $entered_values = true;
366 }
367
368 $this->getProcessLocker()->releaseUserSolutionUpdateLock();
369
370 if ($entered_values)
371 {
372 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
374 {
375 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
376 }
377 }
378 else
379 {
380 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
382 {
383 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
384 }
385 }
386
387 return true;
388 }
389
391 {
392 global $ilDB;
393
394 // save additional data
395 $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName()
396 . " WHERE question_fi = %s",
397 array( "integer" ),
398 array( $this->getId() )
399 );
400
401 $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName()
402 . " (question_fi, ordertext, textsize) VALUES (%s, %s, %s)",
403 array( "integer", "text", "float" ),
404 array(
405 $this->getId(),
406 $this->getOrderText(),
407 ($this->getTextSize() < 10) ? NULL : $this->getTextSize()
408 )
409 );
410 }
411
420 protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
421 {
422 // nothing to rework!
423 }
424
430 public function getQuestionType()
431 {
432 return "assOrderingHorizontal";
433 }
434
440 public function getAdditionalTableName()
441 {
442 return "qpl_qst_horder";
443 }
444
450 public function getAnswerTableName()
451 {
452 return "";
453 }
454
460 public function deleteAnswers($question_id)
461 {
462 }
463
469 {
470 $text = parent::getRTETextWithMediaObjects();
471 return $text;
472 }
473
485 public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
486 {
487 include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
488 $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
489 $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
490
491 $solutionvalue = "";
492 $solutions =& $this->getSolutionValues($active_id, $pass);
493 $solutionvalue = str_replace("{::}", " ", $solutions[0]["value1"]);
494 $i = 1;
495 $worksheet->writeString($startrow+$i, 0, ilExcelUtils::_convert_text($solutionvalue));
496 $i++;
497 return $startrow + $i + 1;
498 }
499
512 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
513 {
514 include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assOrderingHorizontalImport.php";
515 $import = new assOrderingHorizontalImport($this);
516 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
517 }
518
525 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
526 {
527 include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assOrderingHorizontalExport.php";
528 $export = new assOrderingHorizontalExport($this);
529 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
530 }
531
537 public function getBestSolution($active_id, $pass)
538 {
539 $user_solution = array();
540 return $user_solution;
541 }
542
548 public function getOrderingElements()
549 {
550 return $this->splitAndTrimOrderElementText($this->getOrderText(), $this->separator);
551 }
552
559 {
560 $elements = $this->getOrderingElements();
561 $elements = $this->getShuffler()->shuffle($elements);
562 return $elements;
563 }
564
570 public function getOrderText()
571 {
572 return $this->ordertext;
573 }
574
580 public function setOrderText($a_value)
581 {
582 $this->ordertext = $a_value;
583 }
584
590 public function getTextSize()
591 {
592 return $this->textsize;
593 }
594
600 public function setTextSize($a_value)
601 {
602 if ($a_value >= 10)
603 {
604 $this->textsize = $a_value;
605 }
606 }
607
613 public function getSeparator()
614 {
615 return $this->separator;
616 }
617
623 public function setSeparator($a_value)
624 {
625 $this->separator = $a_value;
626 }
627
631 public function __get($value)
632 {
633 switch ($value)
634 {
635 case "ordertext":
636 return $this->getOrderText();
637 break;
638 case "textsize":
639 return $this->getTextSize();
640 break;
641 case "separator":
642 return $this->getSeparator();
643 break;
644 default:
645 return parent::__get($value);
646 break;
647 }
648 }
649
653 public function __set($key, $value)
654 {
655 switch ($key)
656 {
657 case "ordertext":
658 $this->setOrderText($value);
659 break;
660 case "textsize":
661 $this->setTextSize($value);
662 break;
663 case "separator":
664 $this->setSeparator($value);
665 break;
666 default:
667 parent::__set($key, $value);
668 break;
669 }
670 }
671
672 public function supportsJavascriptOutput()
673 {
674 return true;
675 }
676
677 public function supportsNonJsOutput()
678 {
679 return false;
680 }
681
685 public function toJSON()
686 {
687 include_once("./Services/RTE/classes/class.ilRTE.php");
688 $result = array();
689 $result['id'] = (int) $this->getId();
690 $result['type'] = (string) $this->getQuestionType();
691 $result['title'] = (string) $this->getTitle();
692 $result['question'] = $this->formatSAQuestion($this->getQuestion());
693 $result['nr_of_tries'] = (int) $this->getNrOfTries();
694 $result['shuffle'] = (bool) true;
695 $result['points'] = (bool) $this->getPoints();
696 $result['textsize'] = ((int)$this->getTextSize()) // #10923
697 ? (int)$this->getTextSize()
698 : 100;
699 $result['feedback'] = array(
700 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
701 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
702 );
703
704 $arr = array();
705 foreach ($this->getOrderingElements() as $order => $answer)
706 {
707 array_push($arr, array(
708 "answertext" => (string) $answer,
709 "order" => (int) $order+1
710 ));
711 }
712 $result['answers'] = $arr;
713
714 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
715 $result['mobs'] = $mobs;
716
717 return json_encode($result);
718 }
719
728 public function getOperators($expression)
729 {
730 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
732 }
733
738 public function getExpressionTypes()
739 {
740 return array(
745 );
746 }
747
756 public function getUserQuestionResult($active_id, $pass)
757 {
759 global $ilDB;
760 $result = new ilUserQuestionResult($this, $active_id, $pass);
761
762 $maxStep = $this->lookupMaxStep($active_id, $pass);
763
764 if( $maxStep !== null )
765 {
766 $data = $ilDB->queryF(
767 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
768 array("integer", "integer", "integer","integer"),
769 array($active_id, $pass, $this->getId(), $maxStep)
770 );
771 }
772 else
773 {
774 $data = $ilDB->queryF(
775 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
776 array("integer", "integer", "integer"),
777 array($active_id, $pass, $this->getId())
778 );
779 }
780 $row = $ilDB->fetchAssoc($data);
781
782 $answer_elements = $this->splitAndTrimOrderElementText($row["value1"], $this->answer_separator);
783 $elements = $this->getOrderingElements();
784 $solutions = array();
785
786 foreach($answer_elements as $answer)
787 {
788 foreach($elements as $key => $element)
789 {
790 if($element == $answer)
791 {
792 $result->addKeyValue($key+1, $answer);
793 }
794 }
795 }
796
797 $glue = " ";
798 if($this->answer_separator = '{::}')
799 {
800 $glue = "";
801 }
802 $result->addKeyValue(null, join($glue, $answer_elements));
803
804 $points = $this->calculateReachedPoints($active_id, $pass);
805 $max_points = $this->getMaximumPoints();
806
807 $result->setReachedPercentage(($points/$max_points) * 100);
808
809 return $result;
810 }
811
820 public function getAvailableAnswerOptions($index = null)
821 {
822 $elements = $this->getOrderingElements();
823 if($index !== null)
824 {
825 if(array_key_exists($index, $elements))
826 {
827 return $elements[$index];
828 }
829 return null;
830 }
831 else
832 {
833 return $elements;
834 }
835 }
836
841 protected function calculateReachedPointsForSolution($value)
842 {
843 $value = $this->splitAndTrimOrderElementText($value, $this->answer_separator);
844 $value = join($value, $this->answer_separator);
845 if(strcmp($value, join($this->getOrderingElements(), $this->answer_separator)) == 0)
846 {
847 $points = $this->getPoints();
848 return $points;
849 }
850 return 0;
851 }
852}
$result
Class for formula question question exports.
Class for formula question imports.
Class for horizontal ordering questions.
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
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.
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.
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
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.
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
__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.
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.
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.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
removeCurrentSolution($active_id, $pass, $authorized=true, $ignoredSolutionIds=array())
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
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true)
setQuestion($question="")
Sets the question string of the question object.
_convert_text($a_text, $a_target="has been removed")
_getLogLanguage()
retrieve the log language for assessment logging
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
_getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
_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.
$_POST['username']
Definition: cron.php:12
$data
$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
global $ilUser
Definition: imgupload.php:15