ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.assImagemapQuestion.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 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
8 require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9 require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
10 
25 {
26  // hey: prevPassSolutions - wtf is imagemap ^^
27  public $currentSolution = array();
28  // hey.
29 
30  const MODE_SINGLE_CHOICE = 0;
32 
34  public $answers;
35 
38 
41 
43  public $coords;
44 
46  protected $is_multiple_choice = false;
47 
62  public function __construct(
63  $title = "",
64  $comment = "",
65  $author = "",
66  $owner = -1,
67  $question = "",
68  $image_filename = ""
69  ) {
70  parent::__construct($title, $comment, $author, $owner, $question);
71  $this->image_filename = $image_filename;
72  $this->answers = array();
73  $this->coords = array();
74  }
75 
82  {
83  $this->is_multiple_choice = $is_multiple_choice;
84  }
85 
91  public function getIsMultipleChoice()
92  {
94  }
95 
102  public function isComplete()
103  {
104  if (strlen($this->title)
105  && ($this->author)
106  && ($this->question)
107  && ($this->image_filename)
108  && (count($this->answers))
109  && ($this->getMaximumPoints() > 0)
110  ) {
111  return true;
112  }
113  return false;
114  }
115 
125  public function saveToDb($original_id = "")
126  {
130  parent::saveToDb($original_id);
131  }
132 
133  public function saveAnswerSpecificDataToDb()
134  {
135  global $DIC;
136  $ilDB = $DIC['ilDB'];
137  $ilDB->manipulateF(
138  "DELETE FROM qpl_a_imagemap WHERE question_fi = %s",
139  array( "integer" ),
140  array( $this->getId() )
141  );
142 
143  // Anworten wegschreiben
144  foreach ($this->answers as $key => $value) {
145  $answer_obj = $this->answers[$key];
146  $answer_obj->setOrder($key);
147  $next_id = $ilDB->nextId('qpl_a_imagemap');
148  $ilDB->manipulateF(
149  "INSERT INTO qpl_a_imagemap (answer_id, question_fi, answertext, points, aorder, coords, area, points_unchecked) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
150  array( "integer", "integer", "text", "float", "integer", "text", "text", "float" ),
151  array( $next_id, $this->id, $answer_obj->getAnswertext(
152  ), $answer_obj->getPoints(), $answer_obj->getOrder(
153  ), $answer_obj->getCoords(), $answer_obj->getArea(
154  ), $answer_obj->getPointsUnchecked() )
155  );
156  }
157  }
158 
160  {
161  global $DIC;
162  $ilDB = $DIC['ilDB'];
163 
164  $ilDB->manipulateF(
165  "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
166  array( "integer" ),
167  array( $this->getId() )
168  );
169 
170  $ilDB->manipulateF(
171  "INSERT INTO " . $this->getAdditionalTableName(
172  ) . " (question_fi, image_file, is_multiple_choice) VALUES (%s, %s, %s)",
173  array( "integer", "text", 'integer' ),
174  array(
175  $this->getId(),
176  $this->image_filename,
177  (int) $this->is_multiple_choice
178  )
179  );
180  }
181 
187  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
188  {
189  if ($this->id <= 0) {
190  // The question has not been saved. It cannot be duplicated
191  return;
192  }
193  // duplicate the question in database
194  $this_id = $this->getId();
195  $thisObjId = $this->getObjId();
196 
197  $clone = $this;
198  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
200  $clone->id = -1;
201 
202  if ((int) $testObjId > 0) {
203  $clone->setObjId($testObjId);
204  }
205 
206  if ($title) {
207  $clone->setTitle($title);
208  }
209  if ($author) {
210  $clone->setAuthor($author);
211  }
212  if ($owner) {
213  $clone->setOwner($owner);
214  }
215  if ($for_test) {
216  $clone->saveToDb($original_id);
217  } else {
218  $clone->saveToDb();
219  }
220 
221  // copy question page content
222  $clone->copyPageOfQuestion($this_id);
223  // copy XHTML media objects
224  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
225  // duplicate the image
226  $clone->duplicateImage($this_id, $thisObjId);
227 
228  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
229 
230  return $clone->id;
231  }
232 
240  public function copyObject($target_questionpool_id, $title = "")
241  {
242  if ($this->id <= 0) {
243  // The question has not been saved. It cannot be duplicated
244  return;
245  }
246  // duplicate the question in database
247  $clone = $this;
248  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
250  $clone->id = -1;
251  $source_questionpool_id = $this->getObjId();
252  $clone->setObjId($target_questionpool_id);
253  if ($title) {
254  $clone->setTitle($title);
255  }
256  $clone->saveToDb();
257 
258  // copy question page content
259  $clone->copyPageOfQuestion($original_id);
260  // copy XHTML media objects
261  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
262  // duplicate the image
263  $clone->copyImage($original_id, $source_questionpool_id);
264 
265  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
266 
267  return $clone->id;
268  }
269 
270  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
271  {
272  if ($this->id <= 0) {
273  // The question has not been saved. It cannot be duplicated
274  return;
275  }
276 
277  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
278 
279  $sourceQuestionId = $this->id;
280  $sourceParentId = $this->getObjId();
281 
282  // duplicate the question in database
283  $clone = $this;
284  $clone->id = -1;
285 
286  $clone->setObjId($targetParentId);
287 
288  if ($targetQuestionTitle) {
289  $clone->setTitle($targetQuestionTitle);
290  }
291 
292  $clone->saveToDb();
293  // copy question page content
294  $clone->copyPageOfQuestion($sourceQuestionId);
295  // copy XHTML media objects
296  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
297  // duplicate the image
298  $clone->copyImage($sourceQuestionId, $sourceParentId);
299 
300  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
301 
302  return $clone->id;
303  }
304 
305  public function duplicateImage($question_id, $objectId = null)
306  {
307  global $DIC;
308  $ilLog = $DIC['ilLog'];
309 
310  $imagepath = $this->getImagePath();
311  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
312 
313  if ((int) $objectId > 0) {
314  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
315  }
316 
317  if (!file_exists($imagepath)) {
318  ilUtil::makeDirParents($imagepath);
319  }
320  $filename = $this->getImageFilename();
321 
322  // #18755
323  if (!file_exists($imagepath_original . $filename)) {
324  $ilLog->write("Could not find an image map file when trying to duplicate image: " . $imagepath_original . $filename);
325  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
326  $ilLog->write("Using fallback source directory:" . $imagepath_original);
327  }
328 
329  if (!file_exists($imagepath_original . $filename) || !copy($imagepath_original . $filename, $imagepath . $filename)) {
330  $ilLog->write("Could not duplicate image for image map question: " . $imagepath_original . $filename);
331  }
332  }
333 
334  public function copyImage($question_id, $source_questionpool)
335  {
336  $imagepath = $this->getImagePath();
337  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
338  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
339  if (!file_exists($imagepath)) {
340  ilUtil::makeDirParents($imagepath);
341  }
342  $filename = $this->getImageFilename();
343  if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
344  print "image could not be copied!!!! ";
345  }
346  }
347 
357  public function loadFromDb($question_id)
358  {
359  global $DIC;
360  $ilDB = $DIC['ilDB'];
361 
362  $result = $ilDB->queryF(
363  "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",
364  array("integer"),
365  array($question_id)
366  );
367  if ($result->numRows() == 1) {
368  $data = $ilDB->fetchAssoc($result);
369  $this->setId($question_id);
370  $this->setObjId($data["obj_fi"]);
371  $this->setTitle($data["title"]);
372  $this->setComment($data["description"]);
373  $this->setOriginalId($data["original_id"]);
374  $this->setNrOfTries($data['nr_of_tries']);
375  $this->setAuthor($data["author"]);
376  $this->setPoints($data["points"]);
377  $this->setOwner($data["owner"]);
378  $this->setIsMultipleChoice($data["is_multiple_choice"] == self::MODE_MULTIPLE_CHOICE);
379  include_once("./Services/RTE/classes/class.ilRTE.php");
380  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
381  $this->setImageFilename($data["image_file"]);
382  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
383 
384  try {
385  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
386  } catch (ilTestQuestionPoolException $e) {
387  }
388 
389  $result = $ilDB->queryF(
390  "SELECT * FROM qpl_a_imagemap WHERE question_fi = %s ORDER BY aorder ASC",
391  array("integer"),
392  array($question_id)
393  );
394  include_once "./Modules/TestQuestionPool/classes/class.assAnswerImagemap.php";
395  if ($result->numRows() > 0) {
396  while ($data = $ilDB->fetchAssoc($result)) {
397  array_push($this->answers, new ASS_AnswerImagemap($data["answertext"], $data["points"], $data["aorder"], $data["coords"], $data["area"], $data['question_fi'], $data['points_unchecked']));
398  }
399  }
400  }
401  parent::loadFromDb($question_id);
402  }
403 
410  public function uploadImagemap(array $shapes)
411  {
412  $added = 0;
413 
414  if (count($shapes) > 0) {
415  foreach ($shapes as $shape) {
416  $this->addAnswer($shape->getAnswertext(), 0.0, count($this->answers), $shape->getCoords(), $shape->getArea());
417  $added++;
418  }
419  }
420 
421  return $added;
422  }
423 
424  public function getImageFilename()
425  {
426  return $this->image_filename;
427  }
428 
436  public function setImageFilename($image_filename, $image_tempfilename = "")
437  {
438  if (!empty($image_filename)) {
439  $image_filename = str_replace(" ", "_", $image_filename);
440  $this->image_filename = $image_filename;
441  }
442  if (!empty($image_tempfilename)) {
443  $imagepath = $this->getImagePath();
444  if (!file_exists($imagepath)) {
445  ilUtil::makeDirParents($imagepath);
446  }
447  if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath . $image_filename)) {
448  $this->ilias->raiseError("The image could not be uploaded!", $this->ilias->error_obj->MESSAGE);
449  }
450  global $DIC;
451  $ilLog = $DIC['ilLog'];
452  $ilLog->write("gespeichert: " . $imagepath . $image_filename);
453  }
454  }
455 
465  public function get_imagemap_contents($href = "#")
466  {
467  $imagemap_contents = "<map name=\"" . $this->title . "\"> ";
468  for ($i = 0; $i < count($this->answers); $i++) {
469  $imagemap_contents .= "<area alt=\"" . $this->answers[$i]->getAnswertext() . "\" ";
470  $imagemap_contents .= "shape=\"" . $this->answers[$i]->getArea() . "\" ";
471  $imagemap_contents .= "coords=\"" . $this->answers[$i]->getCoords() . "\" ";
472  $imagemap_contents .= "href=\"$href&selimage=" . $this->answers[$i]->getOrder() . "\" /> ";
473  }
474  $imagemap_contents .= "</map>";
475  return $imagemap_contents;
476  }
477 
492  public function addAnswer(
493  $answertext = "",
494  $points = 0.0,
495  $order = 0,
496  $coords = "",
497  $area = "",
498  $points_unchecked = 0.0
499  ) {
500  include_once "./Modules/TestQuestionPool/classes/class.assAnswerImagemap.php";
501  if (array_key_exists($order, $this->answers)) {
502  // Insert answer
503  $answer = new ASS_AnswerImagemap($answertext, $points, $order, $coords, $area, -1, $points_unchecked);
504  for ($i = count($this->answers) - 1; $i >= $order; $i--) {
505  $this->answers[$i + 1] = $this->answers[$i];
506  $this->answers[$i + 1]->setOrder($i + 1);
507  }
508  $this->answers[$order] = $answer;
509  } else {
510  // Append answer
511  $answer = new ASS_AnswerImagemap($answertext, $points, count($this->answers), $coords, $area, -1, $points_unchecked);
512  array_push($this->answers, $answer);
513  }
514  }
515 
525  public function getAnswerCount()
526  {
527  return count($this->answers);
528  }
529 
541  public function getAnswer($index = 0)
542  {
543  if ($index < 0) {
544  return null;
545  }
546  if (count($this->answers) < 1) {
547  return null;
548  }
549  if ($index >= count($this->answers)) {
550  return null;
551  }
552  return $this->answers[$index];
553  }
554 
564  public function &getAnswers()
565  {
566  return $this->answers;
567  }
568 
579  public function deleteArea($index = 0)
580  {
581  if ($index < 0) {
582  return;
583  }
584  if (count($this->answers) < 1) {
585  return;
586  }
587  if ($index >= count($this->answers)) {
588  return;
589  }
590  unset($this->answers[$index]);
591  $this->answers = array_values($this->answers);
592  for ($i = 0; $i < count($this->answers); $i++) {
593  if ($this->answers[$i]->getOrder() > $index) {
594  $this->answers[$i]->setOrder($i);
595  }
596  }
597  }
598 
607  public function flushAnswers()
608  {
609  $this->answers = array();
610  }
611 
620  public function getMaximumPoints()
621  {
622  $points = 0;
623  foreach ($this->answers as $key => $value) {
624  if ($this->is_multiple_choice) {
625  if ($value->getPoints() > $value->getPointsUnchecked()) {
626  $points += $value->getPoints();
627  } else {
628  $points += $value->getPointsUnchecked();
629  }
630  } else {
631  if ($value->getPoints() > $points) {
632  $points = $value->getPoints();
633  }
634  }
635  }
636  return $points;
637  }
638 
649  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
650  {
651  if ($returndetails) {
652  throw new ilTestException('return details not implemented for ' . __METHOD__);
653  }
654 
655  global $DIC;
656  $ilDB = $DIC['ilDB'];
657 
658  $found_values = array();
659  if (is_null($pass)) {
660  $pass = $this->getSolutionMaxPass($active_id);
661  }
662  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
663  while ($data = $ilDB->fetchAssoc($result)) {
664  if (strcmp($data["value1"], "") != 0) {
665  array_push($found_values, $data["value1"]);
666  }
667  }
668 
669  $points = $this->calculateReachedPointsForSolution($found_values);
670 
671  return $points;
672  }
673 
675  {
676  $solutionData = $previewSession->getParticipantsSolution();
677 
678  $reachedPoints = $this->calculateReachedPointsForSolution(is_array($solutionData) ? array_values($solutionData) : array());
679  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $reachedPoints);
680 
681  return $this->ensureNonNegativePoints($reachedPoints);
682  }
683 
684  public function isAutosaveable()
685  {
686  return false; // #15217
687  }
688 
697  public function saveWorkingData($active_id, $pass = null, $authorized = true)
698  {
699  global $DIC;
700  $ilDB = $DIC['ilDB'];
701 
702  if (is_null($pass)) {
703  include_once "./Modules/Test/classes/class.ilObjTest.php";
704  $pass = ilObjTest::_getPass($active_id);
705  }
706 
707  $solutionSelectionChanged = false;
708 
709  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$solutionSelectionChanged, $ilDB, $active_id, $pass, $authorized) {
710  if ($authorized) {
711  // remove the dummy record of the intermediate solution
712  $this->deleteDummySolutionRecord($active_id, $pass);
713 
714  // delete the authorized solution and make the intermediate solution authorized (keeping timestamps)
715  $this->removeCurrentSolution($active_id, $pass, true);
716  $this->updateCurrentSolutionsAuthorization($active_id, $pass, true, true);
717 
718  $solutionSelectionChanged = true;
719  } else {
721  $active_id,
722  $pass,
723  $this->is_multiple_choice
724  );
725 
726  if ($this->isReuseSolutionSelectionRequest()) {
727  $selection = $this->getReuseSolutionSelectionParameter();
728 
729  foreach ($selection as $selectedIndex) {
730  $this->saveCurrentSolution($active_id, $pass, (int) $selectedIndex, null, $authorized);
731  $solutionSelectionChanged = true;
732  }
733  } elseif ($this->isRemoveSolutionSelectionRequest()) {
734  $selection = $this->getRemoveSolutionSelectionParameter();
735 
736  $this->deleteSolutionRecordByValues($active_id, $pass, $authorized, array(
737  'value1' => (int) $selection
738  ));
739 
740  $solutionSelectionChanged = true;
741  } elseif ($this->isAddSolutionSelectionRequest()) {
742  $selection = $this->getAddSolutionSelectionParameter();
743 
744  if ($this->is_multiple_choice) {
745  $this->deleteSolutionRecordByValues($active_id, $pass, $authorized, array(
746  'value1' => (int) $_GET['selImage']
747  ));
748  } else {
749  $this->removeCurrentSolution($active_id, $pass, $authorized);
750  }
751 
752  $this->saveCurrentSolution($active_id, $pass, $_GET['selImage'], null, $authorized);
753 
754  $solutionSelectionChanged = true;
755  }
756  }
757  });
758 
759  require_once 'Modules/Test/classes/class.ilObjAssessmentFolder.php';
761  if ($solutionSelectionChanged) {
762  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
763  } else {
764  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
765  }
766  }
767 
768  return true;
769  }
770 
771  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
772  {
773  $solution = $previewSession->getParticipantsSolution();
774 
775  if ($this->is_multiple_choice && strlen($_GET['remImage'])) {
776  unset($solution[(int) $_GET['remImage']]);
777  }
778 
779  if (strlen($_GET['selImage'])) {
780  if (!$this->is_multiple_choice) {
781  $solution = array();
782  }
783 
784  $solution[(int) $_GET['selImage']] = (int) $_GET['selImage'];
785  }
786 
787  $previewSession->setParticipantsSolution($solution);
788  }
789 
790  public function syncWithOriginal()
791  {
792  if ($this->getOriginalId()) {
793  parent::syncWithOriginal();
794  }
795  }
796 
805  public function getQuestionType()
806  {
807  return "assImagemapQuestion";
808  }
809 
818  public function getAdditionalTableName()
819  {
820  return "qpl_qst_imagemap";
821  }
822 
831  public function getAnswerTableName()
832  {
833  return "qpl_a_imagemap";
834  }
835 
840  public function getRTETextWithMediaObjects()
841  {
842  $text = parent::getRTETextWithMediaObjects();
843  foreach ($this->answers as $index => $answer) {
844  $text .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->getId(), 0, $index);
845  }
846  return $text;
847  }
848 
852  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
853  {
854  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
855 
856  $solution = $this->getSolutionValues($active_id, $pass);
857 
858  $i = 1;
859  foreach ($this->getAnswers() as $id => $answer) {
860  $worksheet->setCell($startrow + $i, 0, $answer->getArea() . ": " . $answer->getCoords());
861  $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
862 
863  $cellValue = 0;
864  foreach ($solution as $solIndex => $sol) {
865  if ($sol['value1'] == $id) {
866  $cellValue = 1;
867  break;
868  }
869  }
870 
871  $worksheet->setCell($startrow + $i, 1, $cellValue);
872 
873  $i++;
874  }
875 
876  return $startrow + $i + 1;
877  }
878 
882  public function deleteImage()
883  {
884  $file = $this->getImagePath() . $this->getImageFilename();
885  @unlink($file);
886  $this->flushAnswers();
887  $this->image_filename = "";
888  }
889 
893  public function toJSON()
894  {
895  include_once("./Services/RTE/classes/class.ilRTE.php");
896  $result = array();
897  $result['id'] = (int) $this->getId();
898  $result['type'] = (string) $this->getQuestionType();
899  $result['title'] = (string) $this->getTitle();
900  $result['question'] = $this->formatSAQuestion($this->getQuestion());
901  $result['nr_of_tries'] = (int) $this->getNrOfTries();
902  $result['shuffle'] = (bool) $this->getShuffle();
903  $result['is_multiple'] = (bool) $this->getIsMultipleChoice();
904  $result['feedback'] = array(
905  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
906  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
907  );
908  $result['image'] = (string) $this->getImagePathWeb() . $this->getImageFilename();
909 
910  $answers = array();
911  $order = 0;
912  foreach ($this->getAnswers() as $key => $answer_obj) {
913  array_push($answers, array(
914  "answertext" => (string) $answer_obj->getAnswertext(),
915  "points" => (float) $answer_obj->getPoints(),
916  "points_unchecked" => (float) $answer_obj->getPointsUnchecked(),
917  "order" => (int) $order,
918  "coords" => $answer_obj->getCoords(),
919  "state" => $answer_obj->getState(),
920  "area" => $answer_obj->getArea(),
921  "feedback" => $this->formatSAQuestion(
922  $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), 0, $key)
923  )
924  ));
925  $order++;
926  }
927  $result['answers'] = $answers;
928 
929  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
930  $result['mobs'] = $mobs;
931 
932  return json_encode($result);
933  }
934 
939  protected function calculateReachedPointsForSolution($found_values)
940  {
941  $points = 0;
942  if (count($found_values) > 0) {
943  foreach ($this->answers as $key => $answer) {
944  if (in_array($key, $found_values)) {
945  $points += $answer->getPoints();
946  } elseif ($this->getIsMultipleChoice()) {
947  $points += $answer->getPointsUnchecked();
948  }
949  }
950  return $points;
951  }
952  return $points;
953  }
954 
963  public function getOperators($expression)
964  {
965  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
967  }
968 
973  public function getExpressionTypes()
974  {
975  return array(
980  );
981  }
982 
991  public function getUserQuestionResult($active_id, $pass)
992  {
994  global $DIC;
995  $ilDB = $DIC['ilDB'];
996  $result = new ilUserQuestionResult($this, $active_id, $pass);
997 
998  $maxStep = $this->lookupMaxStep($active_id, $pass);
999 
1000  if ($maxStep !== null) {
1001  $data = $ilDB->queryF(
1002  "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1003  array("integer", "integer", "integer", "integer"),
1004  array($active_id, $pass, $this->getId(), $maxStep)
1005  );
1006  } else {
1007  $data = $ilDB->queryF(
1008  "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step IS NULL",
1009  array("integer", "integer", "integer"),
1010  array($active_id, $pass, $this->getId())
1011  );
1012  }
1013 
1014  while ($row = $ilDB->fetchAssoc($data)) {
1015  $result->addKeyValue($row["value1"], $row["value1"]);
1016  }
1017 
1018  $points = $this->calculateReachedPoints($active_id, $pass);
1019  $max_points = $this->getMaximumPoints();
1020 
1021  $result->setReachedPercentage(($points / $max_points) * 100);
1022 
1023  return $result;
1024  }
1025 
1034  public function getAvailableAnswerOptions($index = null)
1035  {
1036  if ($index !== null) {
1037  return $this->getAnswer($index);
1038  } else {
1039  return $this->getAnswers();
1040  }
1041  }
1042 
1043  // hey: prevPassSolutions - wtf is imagemap ^^
1044  public function getTestOutputSolutions($activeId, $pass)
1045  {
1046  $solution = parent::getTestOutputSolutions($activeId, $pass);
1047 
1048  $this->currentSolution = array();
1049  foreach ($solution as $record) {
1050  $this->currentSolution[] = $record['value1'];
1051  }
1052 
1053  return $solution;
1054  }
1056  {
1057  if (!$this->isAddSolutionSelectionRequest()) {
1058  return null;
1059  }
1060 
1061  return $_GET["selImage"];
1062  }
1063  protected function isAddSolutionSelectionRequest()
1064  {
1065  if (!isset($_GET["selImage"])) {
1066  return false;
1067  }
1068 
1069  if (!strlen($_GET["selImage"])) {
1070  return false;
1071  }
1072 
1073  return true;
1074  }
1076  {
1077  if (!$this->isRemoveSolutionSelectionRequest()) {
1078  return null;
1079  }
1080 
1081  return $_GET["remImage"];
1082  }
1084  {
1085  if (!$this->is_multiple_choice) {
1086  return false;
1087  }
1088 
1089  if (!isset($_GET["remImage"])) {
1090  return false;
1091  }
1092 
1093  if (!strlen($_GET["remImage"])) {
1094  return false;
1095  }
1096 
1097  return true;
1098  }
1100  {
1101  if (!$this->isReuseSolutionSelectionRequest()) {
1102  return null;
1103  }
1104 
1105  return assQuestion::explodeKeyValues($_GET["reuseSelection"]);
1106  }
1107  protected function isReuseSolutionSelectionRequest()
1108  {
1109  if (!$this->getTestPresentationConfig()->isPreviousPassSolutionReuseAllowed()) {
1110  return false;
1111  }
1112 
1113  if (!isset($_GET["reuseSelection"])) {
1114  return false;
1115  }
1116 
1117  if (!strlen($_GET["reuseSelection"])) {
1118  return false;
1119  }
1120 
1121  if (!preg_match('/\d(,\d)*/', $_GET["reuseSelection"])) {
1122  return false;
1123  }
1124 
1125  return true;
1126  }
1127  // hey.
1128 }
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getId()
Gets the id of the assQuestion object.
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.
calculateReachedPointsForSolution($found_values)
Class iQuestionCondition.
forceExistingIntermediateSolution($activeId, $passIndex, $considerDummyRecordCreation)
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
$result
savePreviewData(ilAssQuestionPreviewSession $previewSession)
global $DIC
Definition: saml.php:7
$_GET["client_id"]
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assImagemapQuestion.
Class for true/false or yes/no answers.
Abstract basic class which is to be extended by the concrete assessment question type classes...
getOperators($expression)
Get all available operations for a specific question.
ensureNonNegativePoints($points)
deleteDummySolutionRecord($activeId, $passIndex)
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $image_filename="")
assImagemapQuestion constructor
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.
getImagePathWeb()
Returns the web image path for web accessable images of a question.
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. ...
$index
Definition: metadata.php:60
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
deleteArea($index=0)
Deletes an answer.
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.
getShuffle()
Gets the shuffle flag.
Base Exception for all Exceptions relating to Modules/Test.
getIsMultipleChoice()
Returns true, if the imagemap question is a multiplechoice question.
static _getLogLanguage()
retrieve the log language for assessment logging
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
getTestOutputSolutions($activeId, $pass)
setAuthor($author="")
Sets the authors name of the assQuestion object.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
getAnswer($index=0)
Returns an answer.
saveToDb($original_id="")
Saves an assImagemapQuestion object to a database.
uploadImagemap(array $shapes)
Uploads an image map and takes over the areas.
$mobs
toJSON()
Returns a JSON representation of the question.
Class ilUserQuestionResult.
updateCurrentSolutionsAuthorization($activeId, $pass, $authorized, $keepTime=false)
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
static explodeKeyValues($keyValues)
$text
Definition: errorreport.php:18
Interface ilObjAnswerScoringAdjustable.
getQuestion()
Gets the question string of the question object.
deleteImage()
Deletes the image file.
redirection script todo: (a better solution should control the processing via a xml file) ...
Class for image map questions.
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 ...
isComplete()
Returns true, if a imagemap question is complete for use.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
copyImage($question_id, $source_questionpool)
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
duplicateImage($question_id, $objectId=null)
$filename
Definition: buildRTE.php:89
setIsMultipleChoice($is_multiple_choice)
Set true if the Imagemapquestion is a multiplechoice Question.
getExpressionTypes()
Get all available expression types for a specific question.
$row
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
addAnswer( $answertext="", $points=0.0, $order=0, $coords="", $area="", $points_unchecked=0.0)
Adds a possible answer for a imagemap question.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
& getAnswers()
Returns the answer array.
copyObject($target_questionpool_id, $title="")
Copies an assImagemapQuestion object.
getAnswerCount()
Returns the number of answers.
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
removeCurrentSolution($active_id, $pass, $authorized=true)
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
deleteSolutionRecordByValues($activeId, $passIndex, $authorized, $matchValues)
getTestPresentationConfig()
Get the test question configuration (initialised once)
setImageFilename($image_filename, $image_tempfilename="")
Sets the image file name.
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...
$i
Definition: disco.tpl.php:19
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
getAnswerTableName()
Returns the name of the answer table in the database.
getTitle()
Gets the title string of the assQuestion object.
getQuestionType()
Returns the question type of the question.
flushAnswers()
Deletes all answers.
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
loadFromDb($question_id)
Loads a assImagemapQuestion object from a database.
$key
Definition: croninfo.php:18
setComment($comment="")
Sets the comment string of the assQuestion object.
get_imagemap_contents($href="#")
Gets the imagemap file contents.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
$data
Definition: bench.php:6