ILIAS  release_4-4 Revision
All Data Structures Namespaces Files Functions Variables Modules Pages
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 
4 require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
5 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7 
20 {
21  protected $ordertext;
22  protected $textsize;
23  protected $separator = "::";
24  protected $answer_separator = '{::}';
25 
38  function __construct(
39  $title = "",
40  $comment = "",
41  $author = "",
42  $owner = -1,
43  $question = ""
44  )
45  {
46  parent::__construct($title, $comment, $author, $owner, $question);
47  $this->ordertext = "";
48  }
49 
55  public function isComplete()
56  {
57  if (strlen($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0))
58  {
59  return true;
60  }
61  else
62  {
63  return false;
64  }
65  }
66 
71  public function saveToDb($original_id = "")
72  {
75  parent::saveToDb();
76  }
77 
81  public function getAnswerSeparator()
82  {
84  }
85 
86 
93  public function loadFromDb($question_id)
94  {
95  global $ilDB;
96 
97  $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",
98  array("integer"),
99  array($question_id)
100  );
101  if ($result->numRows() == 1)
102  {
103  $data = $ilDB->fetchAssoc($result);
104  $this->setId($question_id);
105  $this->setObjId($data["obj_fi"]);
106  $this->setTitle($data["title"]);
107  $this->setComment($data["description"]);
108  $this->setOriginalId($data["original_id"]);
109  $this->setNrOfTries($data['nr_of_tries']);
110  $this->setAuthor($data["author"]);
111  $this->setPoints($data["points"]);
112  $this->setOwner($data["owner"]);
113  include_once("./Services/RTE/classes/class.ilRTE.php");
114  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
115  $this->setOrderText($data["ordertext"]);
116  $this->setTextSize($data["textsize"]);
117  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
118 
119  try
120  {
121  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
122  }
124  {
125  }
126  }
127 
128  parent::loadFromDb($question_id);
129  }
130 
134  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
135  {
136  if ($this->id <= 0)
137  {
138  // The question has not been saved. It cannot be duplicated
139  return;
140  }
141  // duplicate the question in database
142  $this_id = $this->getId();
143  $thisObjId = $this->getObjId();
144 
145  $clone = $this;
146  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
148  $clone->id = -1;
149 
150  if( (int)$testObjId > 0 )
151  {
152  $clone->setObjId($testObjId);
153  }
154 
155  if ($title)
156  {
157  $clone->setTitle($title);
158  }
159 
160  if ($author)
161  {
162  $clone->setAuthor($author);
163  }
164  if ($owner)
165  {
166  $clone->setOwner($owner);
167  }
168 
169  if ($for_test)
170  {
171  $clone->saveToDb($original_id);
172  }
173  else
174  {
175  $clone->saveToDb();
176  }
177 
178  // copy question page content
179  $clone->copyPageOfQuestion($this_id);
180  // copy XHTML media objects
181  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
182 
183  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
184 
185  return $clone->id;
186  }
187 
191  public function copyObject($target_questionpool_id, $title = "")
192  {
193  if ($this->id <= 0)
194  {
195  // The question has not been saved. It cannot be duplicated
196  return;
197  }
198  // duplicate the question in database
199  $clone = $this;
200  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
202  $clone->id = -1;
203  $source_questionpool_id = $this->getObjId();
204  $clone->setObjId($target_questionpool_id);
205  if ($title)
206  {
207  $clone->setTitle($title);
208  }
209  $clone->saveToDb();
210  // copy question page content
211  $clone->copyPageOfQuestion($original_id);
212  // copy XHTML media objects
213  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
214 
215  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
216 
217  return $clone->id;
218  }
219 
220  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
221  {
222  if ($this->id <= 0)
223  {
224  // The question has not been saved. It cannot be duplicated
225  return;
226  }
227 
228  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
229 
230  $sourceQuestionId = $this->id;
231  $sourceParentId = $this->getObjId();
232 
233  // duplicate the question in database
234  $clone = $this;
235  $clone->id = -1;
236 
237  $clone->setObjId($targetParentId);
238 
239  if ($targetQuestionTitle)
240  {
241  $clone->setTitle($targetQuestionTitle);
242  }
243 
244  $clone->saveToDb();
245  // copy question page content
246  $clone->copyPageOfQuestion($sourceQuestionId);
247  // copy XHTML media objects
248  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
249 
250  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
251 
252  return $clone->id;
253  }
254 
260  public function getMaximumPoints()
261  {
262  return $this->getPoints();
263  }
264 
275  public function calculateReachedPoints($active_id, $pass = NULL, $returndetails = FALSE)
276  {
277  if( $returndetails )
278  {
279  throw new ilTestException('return details not implemented for '.__METHOD__);
280  }
281 
282  global $ilDB;
283 
284  $found_values = array();
285  if (is_null($pass))
286  {
287  $pass = $this->getSolutionMaxPass($active_id);
288  }
289  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
290  array('integer','integer','integer'),
291  array($active_id, $this->getId(), $pass)
292  );
293  $points = 0;
294  $data = $ilDB->fetchAssoc($result);
295 
296  $data["value1"] = $this->splitAndTrimOrderElementText($data["value1"], $this->answer_separator);
297 
298  $data['value1'] = join($data['value1'], $this->answer_separator);
299 
300  if (strcmp($data["value1"], join($this->getOrderingElements(), $this->answer_separator)) == 0)
301  {
302  $points = $this->getPoints();
303  }
304  return $points;
305  }
306 
316  private function splitAndTrimOrderElementText($in_string, $separator)
317  {
318  $result = array();
319  include_once "./Services/Utilities/classes/class.ilStr.php";
320 
321  if (ilStr::strPos($in_string, $separator) === false)
322  {
323  $result = preg_split("/\\s+/", $in_string);
324  }
325  else
326  {
327  $result = split($separator, $in_string);
328  }
329 
330  foreach ($result as $key => $value)
331  {
332  $result[$key] = trim($value);
333  }
334 
335  return $result;
336  }
337 
346  public function saveWorkingData($active_id, $pass = NULL)
347  {
348  global $ilDB;
349  global $ilUser;
350 
351  if (is_null($pass))
352  {
353  include_once "./Modules/Test/classes/class.ilObjTest.php";
354  $pass = ilObjTest::_getPass($active_id);
355  }
356 
357  $this->getProcessLocker()->requestUserSolutionUpdateLock();
358 
359  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
360  array('integer','integer','integer'),
361  array($active_id, $this->getId(), $pass)
362  );
363 
364  $entered_values = false;
365  if (strlen($_POST["orderresult"]))
366  {
367  $next_id = $ilDB->nextId('tst_solutions');
368  $affectedRows = $ilDB->insert("tst_solutions", array(
369  "solution_id" => array("integer", $next_id),
370  "active_fi" => array("integer", $active_id),
371  "question_fi" => array("integer", $this->getId()),
372  "value1" => array("clob", $_POST['orderresult']),
373  "value2" => array("clob", null),
374  "pass" => array("integer", $pass),
375  "tstamp" => array("integer", time())
376  ));
377  $entered_values = true;
378  }
379 
380  $this->getProcessLocker()->releaseUserSolutionUpdateLock();
381 
382  if ($entered_values)
383  {
384  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
386  {
387  $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
388  }
389  }
390  else
391  {
392  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
394  {
395  $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
396  }
397  }
398 
399  return true;
400  }
401 
403  {
404  global $ilDB;
405 
406  // save additional data
407  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName()
408  . " WHERE question_fi = %s",
409  array( "integer" ),
410  array( $this->getId() )
411  );
412 
413  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName()
414  . " (question_fi, ordertext, textsize) VALUES (%s, %s, %s)",
415  array( "integer", "text", "float" ),
416  array(
417  $this->getId(),
418  $this->getOrderText(),
419  ($this->getTextSize() < 10) ? NULL : $this->getTextSize()
420  )
421  );
422  }
423 
432  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
433  {
434  // nothing to rework!
435  }
436 
437  /*
438  * Move an element to the right during a test when a user selects/deselects a word without using javascript
439  */
440  public function moveRight($position, $active_id, $pass = null)
441  {
442  global $ilDB;
443  global $ilUser;
444 
445  if (is_null($pass))
446  {
447  include_once "./Modules/Test/classes/class.ilObjTest.php";
448  $pass = ilObjTest::_getPass($active_id);
449  }
450 
451  $solutions =& $this->getSolutionValues($active_id, $pass);
452  $elements = array();
453  if (count($solutions) == 1)
454  {
455  $elements = split("{::}", $solutions[0]["value1"]);
456  }
457  else
458  {
459  $elements = $_SESSION['qst_ordering_horizontal_elements'];
460  }
461  if (count($elements))
462  {
463  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
464  array('integer','integer','integer'),
465  array($active_id, $this->getId(), $pass)
466  );
467 
468  if ($position < count($elements)-1)
469  {
470  $temp = $elements[$position];
471  $elements[$position] = $elements[$position+1];
472  $elements[$position+1] = $temp;
473  }
474  $entered_values = false;
475  $next_id = $ilDB->nextId('tst_solutions');
476  $affectedRows = $ilDB->insert("tst_solutions", array(
477  "solution_id" => array("integer", $next_id),
478  "active_fi" => array("integer", $active_id),
479  "question_fi" => array("integer", $this->getId()),
480  "value1" => array("clob", join($elements, '{::}')),
481  "value2" => array("clob", null),
482  "pass" => array("integer", $pass),
483  "tstamp" => array("integer", time())
484  ));
485  $entered_values = true;
486  if ($entered_values)
487  {
488  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
490  {
491  $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
492  }
493  }
494  else
495  {
496  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
498  {
499  $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
500  }
501  }
502 
503  $this->calculateReachedPoints($active_id, $pass);
504  }
505  }
506 
512  public function getQuestionType()
513  {
514  return "assOrderingHorizontal";
515  }
516 
522  public function getAdditionalTableName()
523  {
524  return "qpl_qst_horder";
525  }
526 
532  public function getAnswerTableName()
533  {
534  return "";
535  }
536 
542  public function deleteAnswers($question_id)
543  {
544  }
545 
550  public function getRTETextWithMediaObjects()
551  {
552  $text = parent::getRTETextWithMediaObjects();
553  return $text;
554  }
555 
567  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
568  {
569  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
570  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
571  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
572 
573  $solutionvalue = "";
574  $solutions =& $this->getSolutionValues($active_id, $pass);
575  $solutionvalue = str_replace("{::}", " ", $solutions[0]["value1"]);
576  $i = 1;
577  $worksheet->writeString($startrow+$i, 0, ilExcelUtils::_convert_text($solutionvalue));
578  $i++;
579  return $startrow + $i + 1;
580  }
581 
594  public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
595  {
596  include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assOrderingHorizontalImport.php";
597  $import = new assOrderingHorizontalImport($this);
598  $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
599  }
600 
607  public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
608  {
609  include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assOrderingHorizontalExport.php";
610  $export = new assOrderingHorizontalExport($this);
611  return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
612  }
613 
619  public function getBestSolution($active_id, $pass)
620  {
621  $user_solution = array();
622  return $user_solution;
623  }
624 
630  public function getOrderingElements()
631  {
632  return $this->splitAndTrimOrderElementText($this->getOrderText(), $this->separator);
633  }
634 
640  public function getRandomOrderingElements()
641  {
642  $elements = $this->getOrderingElements();
643  shuffle($elements);
644  return $elements;
645  }
646 
652  public function getOrderText()
653  {
654  return $this->ordertext;
655  }
656 
662  public function setOrderText($a_value)
663  {
664  $this->ordertext = $a_value;
665  }
666 
672  public function getTextSize()
673  {
674  return $this->textsize;
675  }
676 
682  public function setTextSize($a_value)
683  {
684  if ($a_value >= 10)
685  {
686  $this->textsize = $a_value;
687  }
688  }
689 
695  public function getSeparator()
696  {
697  return $this->separator;
698  }
699 
705  public function setSeparator($a_value)
706  {
707  $this->separator = $a_value;
708  }
709 
713  public function __get($value)
714  {
715  switch ($value)
716  {
717  case "ordertext":
718  return $this->getOrderText();
719  break;
720  case "textsize":
721  return $this->getTextSize();
722  break;
723  case "separator":
724  return $this->getSeparator();
725  break;
726  default:
727  return parent::__get($value);
728  break;
729  }
730  }
731 
735  public function __set($key, $value)
736  {
737  switch ($key)
738  {
739  case "ordertext":
740  $this->setOrderText($value);
741  break;
742  case "textsize":
743  $this->setTextSize($value);
744  break;
745  case "separator":
746  $this->setSeparator($value);
747  break;
748  default:
749  parent::__set($key, $value);
750  break;
751  }
752  }
753 
754  public function supportsJavascriptOutput()
755  {
756  return true;
757  }
758 
759  public function supportsNonJsOutput()
760  {
761  return false;
762  }
763 
767  public function toJSON()
768  {
769  include_once("./Services/RTE/classes/class.ilRTE.php");
770  $result = array();
771  $result['id'] = (int) $this->getId();
772  $result['type'] = (string) $this->getQuestionType();
773  $result['title'] = (string) $this->getTitle();
774  $result['question'] = $this->formatSAQuestion($this->getQuestion());
775  $result['nr_of_tries'] = (int) $this->getNrOfTries();
776  $result['shuffle'] = (bool) true;
777  $result['points'] = (bool) $this->getPoints();
778  $result['feedback'] = array(
779  "onenotcorrect" => $this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false),
780  "allcorrect" => $this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true)
781  );
782 
783  $arr = array();
784  foreach ($this->getOrderingElements() as $order => $answer)
785  {
786  array_push($arr, array(
787  "answertext" => (string) $answer,
788  "order" => (int) $order+1
789  ));
790  }
791  $result['answers'] = $arr;
792 
793  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
794  $result['mobs'] = $mobs;
795 
796  return json_encode($result);
797  }
798 }
799 
800 ?>
< a tabindex="-1" style="border-style: none;" href="#" title="Refresh Image" onclick="document.getElementById('siimage').src = './securimage_show.php?sid=' + Math.random(); this.blur(); return false">< img src="./images/refresh.png" alt="Reload Image" height="32" width="32" onclick="this.blur()" align="bottom" border="0"/></a >< br/>< strong > Enter Code *if($_SERVER['REQUEST_METHOD']=='POST' &&@ $_POST['do']=='contact') $_SESSION['ctform']['success']
getId()
Gets the id of the assQuestion object.
Class for horizontal ordering questions.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
$_POST['username']
Definition: cron.php:12
$result
getPoints()
Returns the maximum available points for the question.
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
& getSolutionValues($active_id, $pass=NULL)
Loads solutions of a given user from the database an returns it.
Abstract basic class which is to be extended by the concrete assessment question type classes...
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
_convert_text($a_text, $a_target="has been removed")
getSeparator()
Get order text separator.
copyObject($target_questionpool_id, $title="")
Copies an assOrderingHorizontal object.
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.
splitAndTrimOrderElementText($in_string, $separator)
Splits the answer string either by space(s) or the separator (eg.
setOrderText($a_value)
Set order text.
setNrOfTries($a_nr_of_tries)
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
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.
$mobs
toJSON()
Returns a JSON representation of the question.
fetchAssoc($a_set)
Fetch row as associative array from result set.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setAuthor($author="")
Sets the authors name of the assQuestion object.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assOrderingHorizontal constructor
saveWorkingData($active_id, $pass=NULL)
Saves the learners input of the question to the database.
isComplete()
Returns true, if a single choice question is complete for use.
Class for formula question question exports.
getQuestion()
Gets the question string of the question object.
Class for formula question imports.
setTextSize($a_value)
Set text size.
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Creates a question from a QTI file.
_getLogLanguage()
retrieve the log language for assessment logging
moveRight($position, $active_id, $pass=null)
_getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
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 ...
strPos($a_haystack, $a_needle, $a_offset=NULL)
Definition: class.ilStr.php:46
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.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0)
replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
while($lm_rec=$ilDB->fetchAssoc($lm_set)) $data
global $ilUser
Definition: imgupload.php:15
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
getQuestionType()
Returns the question type of the question.
setOriginalId($original_id)
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getTitle()
Gets the title string of the assQuestion object.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
saveToDb($original_id="")
Saves a assOrderingHorizontal object to a database.
calculateReachedPoints($active_id, $pass=NULL, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
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.
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
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.