ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
class.assOrderingHorizontal.php
Go to the documentation of this file.
1 <?php
2 
19 require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
20 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
21 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
22 require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
23 require_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']);
141  } catch (ilTestQuestionPoolException $e) {
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 
297  $points = $this->calculateReachedPointsForSolution($data['value1']);
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 
450  public function getRTETextWithMediaObjects()
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 
531  public function getRandomOrderingElements()
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
817  public function buildTestPresentationConfig()
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 }
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getId()
Gets the id of the assQuestion object.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
Class iQuestionCondition.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
$data
Definition: storeScorm.php:23
static strPos($a_haystack, $a_needle, $a_offset=null)
Definition: class.ilStr.php:30
$result
$mobs
Definition: imgupload.php:54
getPoints()
Returns the maximum available points for the question.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
Abstract basic class which is to be extended by the concrete assessment question type classes...
getSeparator()
Get order text separator.
copyObject($target_questionpool_id, $title="")
Copies an assOrderingHorizontal object.
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
setId($id=-1)
Sets the id of the assQuestion object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
splitAndTrimOrderElementText($in_string, $separator)
Splits the answer string either by space(s) or the separator (eg.
setOrderText($a_value)
Set order text.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setNrOfTries($a_nr_of_tries)
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
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...
getObjId()
Get the object id of the container object.
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
loadFromDb($question_id)
Loads a assOrderingHorizontal object from a database.
Base Exception for all Exceptions relating to Modules/Test.
$index
Definition: metadata.php:128
toJSON()
Returns a JSON representation of the question.
static _getLogLanguage()
retrieve the log language for assessment logging
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setAuthor($author="")
Sets the authors name of the assQuestion object.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assOrderingHorizontal constructor
Class ilUserQuestionResult.
isComplete()
Returns true, if a single choice question is complete for use.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
global $DIC
Definition: goto.php:24
Class for formula question question exports.
buildTestPresentationConfig()
Get the test question configuration.
getQuestion()
Gets the question string of the question object.
Class for formula question imports.
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping, array $solutionhints=[])
Creates a question from a QTI file.
setTextSize($a_value)
Set text size.
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...
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
getRandomOrderingElements()
Get ordering elements from order text in random sequence.
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
__set($key, $value)
Object setter.
setSeparator($a_value)
Set order text separator.
deleteAnswers($question_id)
Deletes datasets from answers tables.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
removeCurrentSolution($active_id, $pass, $authorized=true)
__construct(Container $dic, ilPlugin $plugin)
getQuestionType()
Returns the question type of the question.
global $ilDB
setOriginalId($original_id)
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass...
setLifecycle(ilAssQuestionLifecycle $lifecycle)
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getTitle()
Gets the title string of the assQuestion object.
getExpressionTypes()
Get all available expression types for a specific question.
$ilUser
Definition: imgupload.php:18
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
saveToDb($original_id="")
Saves a assOrderingHorizontal object to a database.
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assOrderingHorizontal.
setComment($comment="")
Sets the comment string of the assQuestion object.
$_POST["username"]
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
$i
Definition: metadata.php:24
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
getAnswerTableName()
Returns the name of the answer table in the database.
getOrderingElements()
Get ordering elements from order text.
getOperators($expression)
Get all available operations for a specific question.