ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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  var $answers;
35 
38 
41 
43  var $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  {
71  parent::__construct($title, $comment, $author, $owner, $question);
72  $this->image_filename = $image_filename;
73  $this->answers = array();
74  $this->coords = array();
75  }
76 
83  {
84  $this->is_multiple_choice = $is_multiple_choice;
85  }
86 
92  public function getIsMultipleChoice()
93  {
95  }
96 
103  function isComplete()
104  {
105  if (strlen($this->title)
106  && ($this->author)
107  && ($this->question)
108  && ($this->image_filename)
109  && (count($this->answers))
110  && ($this->getMaximumPoints() > 0)
111  )
112  {
113  return true;
114  }
115  return false;
116  }
117 
127  public function saveToDb($original_id = "")
128  {
132  parent::saveToDb($original_id);
133  }
134 
135  public function saveAnswerSpecificDataToDb()
136  {
137  global $ilDB;
138  $ilDB->manipulateF( "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  {
146  $answer_obj = $this->answers[$key];
147  $next_id = $ilDB->nextId( 'qpl_a_imagemap' );
148  $ilDB->manipulateF( "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)",
149  array( "integer", "integer", "text", "float", "integer", "text", "text", "float" ),
150  array( $next_id, $this->id, $answer_obj->getAnswertext(
151  ), $answer_obj->getPoints(), $answer_obj->getOrder(
152  ), $answer_obj->getCoords(), $answer_obj->getArea(
153  ), $answer_obj->getPointsUnchecked() )
154  );
155  }
156  }
157 
159  {
160  global $ilDB;
161 
162  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
163  array( "integer" ),
164  array( $this->getId() )
165  );
166 
167  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName(
168  ) . " (question_fi, image_file, is_multiple_choice) VALUES (%s, %s, %s)",
169  array( "integer", "text", 'integer' ),
170  array(
171  $this->getId(),
172  $this->image_filename,
173  (int)$this->is_multiple_choice
174  )
175  );
176  }
177 
183  function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
184  {
185  if ($this->id <= 0)
186  {
187  // The question has not been saved. It cannot be duplicated
188  return;
189  }
190  // duplicate the question in database
191  $this_id = $this->getId();
192  $thisObjId = $this->getObjId();
193 
194  $clone = $this;
195  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
197  $clone->id = -1;
198 
199  if( (int)$testObjId > 0 )
200  {
201  $clone->setObjId($testObjId);
202  }
203 
204  if ($title)
205  {
206  $clone->setTitle($title);
207  }
208  if ($author)
209  {
210  $clone->setAuthor($author);
211  }
212  if ($owner)
213  {
214  $clone->setOwner($owner);
215  }
216  if ($for_test)
217  {
218  $clone->saveToDb($original_id);
219  }
220  else
221  {
222  $clone->saveToDb();
223  }
224 
225  // copy question page content
226  $clone->copyPageOfQuestion($this_id);
227  // copy XHTML media objects
228  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
229  // duplicate the image
230  $clone->duplicateImage($this_id, $thisObjId);
231 
232  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
233 
234  return $clone->id;
235  }
236 
244  function copyObject($target_questionpool_id, $title = "")
245  {
246  if ($this->id <= 0)
247  {
248  // The question has not been saved. It cannot be duplicated
249  return;
250  }
251  // duplicate the question in database
252  $clone = $this;
253  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
255  $clone->id = -1;
256  $source_questionpool_id = $this->getObjId();
257  $clone->setObjId($target_questionpool_id);
258  if ($title)
259  {
260  $clone->setTitle($title);
261  }
262  $clone->saveToDb();
263 
264  // copy question page content
265  $clone->copyPageOfQuestion($original_id);
266  // copy XHTML media objects
267  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
268  // duplicate the image
269  $clone->copyImage($original_id, $source_questionpool_id);
270 
271  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
272 
273  return $clone->id;
274  }
275 
276  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
277  {
278  if ($this->id <= 0)
279  {
280  // The question has not been saved. It cannot be duplicated
281  return;
282  }
283 
284  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
285 
286  $sourceQuestionId = $this->id;
287  $sourceParentId = $this->getObjId();
288 
289  // duplicate the question in database
290  $clone = $this;
291  $clone->id = -1;
292 
293  $clone->setObjId($targetParentId);
294 
295  if ($targetQuestionTitle)
296  {
297  $clone->setTitle($targetQuestionTitle);
298  }
299 
300  $clone->saveToDb();
301  // copy question page content
302  $clone->copyPageOfQuestion($sourceQuestionId);
303  // copy XHTML media objects
304  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
305  // duplicate the image
306  $clone->copyImage($sourceQuestionId, $sourceParentId);
307 
308  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
309 
310  return $clone->id;
311  }
312 
313  function duplicateImage($question_id, $objectId = null)
314  {
315  global $ilLog;
316 
317  $imagepath = $this->getImagePath();
318  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
319 
320  if( (int)$objectId > 0 )
321  {
322  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
323  }
324 
325  if(!file_exists($imagepath))
326  {
327  ilUtil::makeDirParents($imagepath);
328  }
329  $filename = $this->getImageFilename();
330 
331  // #18755
332  if(!file_exists($imagepath_original . $filename))
333  {
334  $ilLog->write("Could not find an image map file when trying to duplicate image: " . $imagepath_original . $filename);
335  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
336  $ilLog->write("Using fallback source directory:" . $imagepath_original);
337  }
338 
339  if(!file_exists($imagepath_original . $filename) || !copy($imagepath_original . $filename, $imagepath . $filename))
340  {
341  $ilLog->write("Could not duplicate image for image map question: " . $imagepath_original . $filename);
342  }
343  }
344 
345  function copyImage($question_id, $source_questionpool)
346  {
347  $imagepath = $this->getImagePath();
348  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
349  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
350  if (!file_exists($imagepath))
351  {
352  ilUtil::makeDirParents($imagepath);
353  }
354  $filename = $this->getImageFilename();
355  if (!copy($imagepath_original . $filename, $imagepath . $filename))
356  {
357  print "image could not be copied!!!! ";
358  }
359  }
360 
370  function loadFromDb($question_id)
371  {
372  global $ilDB;
373 
374  $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",
375  array("integer"),
376  array($question_id)
377  );
378  if ($result->numRows() == 1)
379  {
380  $data = $ilDB->fetchAssoc($result);
381  $this->setId($question_id);
382  $this->setObjId($data["obj_fi"]);
383  $this->setTitle($data["title"]);
384  $this->setComment($data["description"]);
385  $this->setOriginalId($data["original_id"]);
386  $this->setNrOfTries($data['nr_of_tries']);
387  $this->setAuthor($data["author"]);
388  $this->setPoints($data["points"]);
389  $this->setOwner($data["owner"]);
390  $this->setIsMultipleChoice($data["is_multiple_choice"] == self::MODE_MULTIPLE_CHOICE);
391  include_once("./Services/RTE/classes/class.ilRTE.php");
392  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
393  $this->setImageFilename($data["image_file"]);
394  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
395 
396  try
397  {
398  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
399  }
401  {
402  }
403 
404  $result = $ilDB->queryF("SELECT * FROM qpl_a_imagemap WHERE question_fi = %s ORDER BY aorder ASC",
405  array("integer"),
406  array($question_id)
407  );
408  include_once "./Modules/TestQuestionPool/classes/class.assAnswerImagemap.php";
409  if ($result->numRows() > 0)
410  {
411  while ($data = $ilDB->fetchAssoc($result))
412  {
413  array_push($this->answers, new ASS_AnswerImagemap($data["answertext"], $data["points"], $data["aorder"], $data["coords"], $data["area"], $data['question_fi'], $data['points_unchecked']));
414  }
415  }
416  }
417  parent::loadFromDb($question_id);
418  }
419 
426  public function uploadImagemap(array $shapes)
427  {
428  $added = 0;
429 
430  if(count($shapes) > 0)
431  {
432  foreach($shapes as $shape)
433  {
434  $this->addAnswer($shape->getAnswertext(), 0.0, count($this->answers), $shape->getCoords(), $shape->getArea());
435  $added++;
436  }
437  }
438 
439  return $added;
440  }
441 
442  function getImageFilename()
443  {
444  return $this->image_filename;
445  }
446 
454  function setImageFilename($image_filename, $image_tempfilename = "")
455  {
456  if (!empty($image_filename))
457  {
458  $image_filename = str_replace(" ", "_", $image_filename);
459  $this->image_filename = $image_filename;
460  }
461  if (!empty($image_tempfilename))
462  {
463  $imagepath = $this->getImagePath();
464  if (!file_exists($imagepath))
465  {
466  ilUtil::makeDirParents($imagepath);
467  }
468  if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
469  {
470  $this->ilias->raiseError("The image could not be uploaded!", $this->ilias->error_obj->MESSAGE);
471  }
472  global $ilLog; $ilLog->write("gespeichert: " . $imagepath.$image_filename);
473  }
474  }
475 
485  function get_imagemap_contents($href = "#") {
486  $imagemap_contents = "<map name=\"".$this->title."\"> ";
487  for ($i = 0; $i < count($this->answers); $i++) {
488  $imagemap_contents .= "<area alt=\"".$this->answers[$i]->getAnswertext()."\" ";
489  $imagemap_contents .= "shape=\"".$this->answers[$i]->getArea()."\" ";
490  $imagemap_contents .= "coords=\"".$this->answers[$i]->getCoords()."\" ";
491  $imagemap_contents .= "href=\"$href&selimage=" . $this->answers[$i]->getOrder() . "\" /> ";
492  }
493  $imagemap_contents .= "</map>";
494  return $imagemap_contents;
495  }
496 
511  function addAnswer(
512  $answertext = "",
513  $points = 0.0,
514  $order = 0,
515  $coords="",
516  $area="",
517  $points_unchecked = 0.0
518  )
519  {
520  include_once "./Modules/TestQuestionPool/classes/class.assAnswerImagemap.php";
521  if (array_key_exists($order, $this->answers))
522  {
523  // Insert answer
524  $answer = new ASS_AnswerImagemap($answertext, $points, $order, $coords, $area, -1, $points_unchecked);
525  for ($i = count($this->answers) - 1; $i >= $order; $i--)
526  {
527  $this->answers[$i+1] = $this->answers[$i];
528  $this->answers[$i+1]->setOrder($i+1);
529  }
530  $this->answers[$order] = $answer;
531  }
532  else
533  {
534  // Append answer
535  $answer = new ASS_AnswerImagemap($answertext, $points, count($this->answers), $coords, $area, -1, $points_unchecked);
536  array_push($this->answers, $answer);
537  }
538  }
539 
549  function getAnswerCount() {
550  return count($this->answers);
551  }
552 
564  function getAnswer($index = 0) {
565  if ($index < 0) return NULL;
566  if (count($this->answers) < 1) return NULL;
567  if ($index >= count($this->answers)) return NULL;
568  return $this->answers[$index];
569  }
570 
580  function &getAnswers()
581  {
582  return $this->answers;
583  }
584 
595  function deleteArea($index = 0)
596  {
597  if ($index < 0) return;
598  if (count($this->answers) < 1) return;
599  if ($index >= count($this->answers)) return;
600  unset($this->answers[$index]);
601  $this->answers = array_values($this->answers);
602  for ($i = 0; $i < count($this->answers); $i++) {
603  if ($this->answers[$i]->getOrder() > $index) {
604  $this->answers[$i]->setOrder($i);
605  }
606  }
607  }
608 
617  function flushAnswers() {
618  $this->answers = array();
619  }
620 
629  function getMaximumPoints() {
630  $points = 0;
631  foreach ($this->answers as $key => $value) {
632  if($this->is_multiple_choice)
633  {
634  if($value->getPoints() > $value->getPointsUnchecked())
635  {
636  $points += $value->getPoints();
637  }
638  else
639  {
640  $points += $value->getPointsUnchecked();
641  }
642  }
643  else
644  {
645  if($value->getPoints() > $points)
646  {
647  $points = $value->getPoints();
648  }
649  }
650  }
651  return $points;
652  }
653 
664  public function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = FALSE)
665  {
666  if( $returndetails )
667  {
668  throw new ilTestException('return details not implemented for '.__METHOD__);
669  }
670 
671  global $ilDB;
672 
673  $found_values = array();
674  if (is_null($pass))
675  {
676  $pass = $this->getSolutionMaxPass($active_id);
677  }
678  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
679  while ($data = $ilDB->fetchAssoc($result))
680  {
681  if (strcmp($data["value1"], "") != 0)
682  {
683  array_push($found_values, $data["value1"]);
684  }
685  }
686 
687  $points = $this->calculateReachedPointsForSolution($found_values);
688 
689  return $points;
690  }
691 
693  {
694  $solutionData = $previewSession->getParticipantsSolution();
695 
696  $reachedPoints = $this->calculateReachedPointsForSolution(is_array($solutionData) ? array_values($solutionData) : array());
697  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $reachedPoints);
698 
699  return $this->ensureNonNegativePoints($reachedPoints);
700  }
701 
702  public function isAutosaveable()
703  {
704  return false; // #15217
705  }
706 
715  public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
716  {
717  global $ilDB;
718 
719  if (is_null($pass))
720  {
721  include_once "./Modules/Test/classes/class.ilObjTest.php";
722  $pass = ilObjTest::_getPass($active_id);
723  }
724 
725  $solutionSelectionChanged = false;
726 
727  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function() use (&$solutionSelectionChanged, $ilDB, $active_id, $pass, $authorized) {
728 
729  if( $authorized )
730  {
731  // remove the dummy record of the intermediate solution
732  $this->deleteDummySolutionRecord($active_id, $pass);
733 
734  // delete the authorized solution and make the intermediate solution authorized (keeping timestamps)
735  $this->removeCurrentSolution($active_id, $pass, true);
736  $this->updateCurrentSolutionsAuthorization($active_id, $pass, true, true);
737 
738  $solutionSelectionChanged = true;
739  }
740  else
741  {
743  $active_id, $pass, $this->is_multiple_choice
744  );
745 
746  if( $this->isReuseSolutionSelectionRequest() )
747  {
748  $selection = $this->getReuseSolutionSelectionParameter();
749 
750  foreach($selection as $selectedIndex)
751  {
752  $this->saveCurrentSolution($active_id, $pass, (int)$selectedIndex, null, $authorized);
753  $solutionSelectionChanged = true;
754  }
755  }
756  elseif( $this->isRemoveSolutionSelectionRequest() )
757  {
758  $selection = $this->getRemoveSolutionSelectionParameter();
759 
760  $this->deleteSolutionRecordByValues($active_id, $pass, $authorized, array(
761  'value1' => (int)$selection
762  ));
763 
764  $solutionSelectionChanged = true;
765  }
766  elseif( $this->isAddSolutionSelectionRequest() )
767  {
768  $selection = $this->getAddSolutionSelectionParameter();
769 
770  if( $this->is_multiple_choice )
771  {
772  $this->deleteSolutionRecordByValues($active_id, $pass, $authorized, array(
773  'value1' => (int)$_GET['selImage']
774  ));
775  }
776  else
777  {
778  $this->removeCurrentSolution($active_id, $pass, $authorized);
779  }
780 
781  $this->saveCurrentSolution($active_id, $pass, $_GET['selImage'], null, $authorized);
782 
783  $solutionSelectionChanged = true;
784  }
785  }
786  });
787 
788  require_once 'Modules/Test/classes/class.ilObjAssessmentFolder.php';
790  {
791  if( $solutionSelectionChanged )
792  {
793  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
794  }
795  else
796  {
797  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
798  }
799  }
800 
801  return true;
802  }
803 
804  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
805  {
806  $solution = $previewSession->getParticipantsSolution();
807 
808  if( $this->is_multiple_choice && strlen($_GET['remImage']) )
809  {
810  unset($solution[(int)$_GET['remImage']]);
811  }
812 
813  if( strlen($_GET['selImage']) )
814  {
815  if( !$this->is_multiple_choice )
816  {
817  $solution = array();
818  }
819 
820  $solution[(int)$_GET['selImage']] = (int)$_GET['selImage'];
821  }
822 
823  $previewSession->setParticipantsSolution($solution);
824  }
825 
829  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
830  {
831  // nothing to rework!
832  }
833 
834  function syncWithOriginal()
835  {
836  if ($this->getOriginalId())
837  {
838  parent::syncWithOriginal();
839  }
840  }
841 
850  function getQuestionType()
851  {
852  return "assImagemapQuestion";
853  }
854 
864  {
865  return "qpl_qst_imagemap";
866  }
867 
877  {
878  return "qpl_a_imagemap";
879  }
880 
886  {
887  $text = parent::getRTETextWithMediaObjects();
888  foreach ($this->answers as $index => $answer)
889  {
890  $text .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->getId(), $index);
891  }
892  return $text;
893  }
894 
898  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
899  {
900  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
901 
902  $solution = $this->getSolutionValues($active_id, $pass);
903 
904  $i = 1;
905  foreach ($this->getAnswers() as $id => $answer)
906  {
907  $worksheet->setCell($startrow + $i, 0, $answer->getArea() . ": " . $answer->getCoords());
908  $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
909 
910  $cellValue = 0;
911  foreach($solution as $solIndex => $sol)
912  {
913  if( $sol['value1'] == $id )
914  {
915  $cellValue = 1;
916  break;
917  }
918  }
919 
920  $worksheet->setCell($startrow + $i, 1, $cellValue);
921 
922  $i++;
923  }
924 
925  return $startrow + $i + 1;
926  }
927 
931  public function deleteImage()
932  {
933  $file = $this->getImagePath() . $this->getImageFilename();
934  @unlink($file);
935  $this->flushAnswers();
936  $this->image_filename = "";
937  }
938 
942  public function toJSON()
943  {
944  include_once("./Services/RTE/classes/class.ilRTE.php");
945  $result = array();
946  $result['id'] = (int) $this->getId();
947  $result['type'] = (string) $this->getQuestionType();
948  $result['title'] = (string) $this->getTitle();
949  $result['question'] = $this->formatSAQuestion($this->getQuestion());
950  $result['nr_of_tries'] = (int) $this->getNrOfTries();
951  $result['shuffle'] = (bool) $this->getShuffle();
952  $result['is_multiple'] = (bool) $this->getIsMultipleChoice();
953  $result['feedback'] = array(
954  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
955  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
956  );
957  $result['image'] = (string) $this->getImagePathWeb() . $this->getImageFilename();
958 
959  $answers = array();
960  $order = 0;
961  foreach ($this->getAnswers() as $key => $answer_obj)
962  {
963  array_push($answers, array(
964  "answertext" => (string)$answer_obj->getAnswertext(),
965  "points" => (float)$answer_obj->getPoints(),
966  "points_unchecked" => (float)$answer_obj->getPointsUnchecked(),
967  "order" => (int)$order,
968  "coords" => $answer_obj->getCoords(),
969  "state" => $answer_obj->getState(),
970  "area" => $answer_obj->getArea(),
971  "feedback" => $this->formatSAQuestion(
972  $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), $key)
973  )
974  ));
975  $order++;
976  }
977  $result['answers'] = $answers;
978 
979  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
980  $result['mobs'] = $mobs;
981 
982  return json_encode($result);
983  }
984 
989  protected function calculateReachedPointsForSolution($found_values)
990  {
991  $points = 0;
992  if(count($found_values) > 0)
993  {
994  foreach($this->answers as $key => $answer)
995  {
996  if(in_array($key, $found_values))
997  {
998  $points += $answer->getPoints();
999  } elseif($this->getIsMultipleChoice())
1000  {
1001  $points += $answer->getPointsUnchecked();
1002  }
1003  }
1004  return $points;
1005  }
1006  return $points;
1007  }
1008 
1017  public function getOperators($expression)
1018  {
1019  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1021  }
1022 
1027  public function getExpressionTypes()
1028  {
1029  return array(
1034  );
1035  }
1036 
1045  public function getUserQuestionResult($active_id, $pass)
1046  {
1048  global $ilDB;
1049  $result = new ilUserQuestionResult($this, $active_id, $pass);
1050 
1051  $maxStep = $this->lookupMaxStep($active_id, $pass);
1052 
1053  if( $maxStep !== null )
1054  {
1055  $data = $ilDB->queryF("SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1056  array("integer", "integer", "integer", "integer"),
1057  array($active_id, $pass, $this->getId(), $maxStep)
1058  );
1059  }
1060  else
1061  {
1062  $data = $ilDB->queryF("SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step IS NULL",
1063  array("integer", "integer", "integer"),
1064  array($active_id, $pass, $this->getId())
1065  );
1066  }
1067 
1068  while($row = $ilDB->fetchAssoc($data))
1069  {
1070  $result->addKeyValue($row["value1"], $row["value1"]);
1071  }
1072 
1073  $points = $this->calculateReachedPoints($active_id, $pass);
1074  $max_points = $this->getMaximumPoints();
1075 
1076  $result->setReachedPercentage(($points/$max_points) * 100);
1077 
1078  return $result;
1079  }
1080 
1089  public function getAvailableAnswerOptions($index = null)
1090  {
1091  if($index !== null)
1092  {
1093  return $this->getAnswer($index);
1094  }
1095  else
1096  {
1097  return $this->getAnswers();
1098  }
1099  }
1100 
1101  // hey: prevPassSolutions - wtf is imagemap ^^
1102  public function getTestOutputSolutions($activeId, $pass)
1103  {
1104  $solution = parent::getTestOutputSolutions($activeId, $pass);
1105 
1106  $this->currentSolution = array();
1107  foreach($solution as $record)
1108  {
1109  $this->currentSolution[] = $record['value1'];
1110  }
1111 
1112  return $solution;
1113  }
1115  {
1116  if( !$this->isAddSolutionSelectionRequest() )
1117  {
1118  return null;
1119  }
1120 
1121  return $_GET["selImage"];
1122  }
1123  protected function isAddSolutionSelectionRequest()
1124  {
1125  if( !isset($_GET["selImage"]) )
1126  {
1127  return false;
1128  }
1129 
1130  if( !strlen($_GET["selImage"]) )
1131  {
1132  return false;
1133  }
1134 
1135  return true;
1136  }
1138  {
1139  if( !$this->isRemoveSolutionSelectionRequest() )
1140  {
1141  return null;
1142  }
1143 
1144  return $_GET["remImage"];
1145  }
1147  {
1148  if( !$this->is_multiple_choice )
1149  {
1150  return false;
1151  }
1152 
1153  if( !isset($_GET["remImage"]) )
1154  {
1155  return false;
1156  }
1157 
1158  if( !strlen($_GET["remImage"]) )
1159  {
1160  return false;
1161  }
1162 
1163  return true;
1164  }
1166  {
1167  if( !$this->isReuseSolutionSelectionRequest() )
1168  {
1169  return null;
1170  }
1171 
1172  return assQuestion::explodeKeyValues($_GET["reuseSelection"]);
1173  }
1174  protected function isReuseSolutionSelectionRequest()
1175  {
1176  if( !$this->getTestPresentationConfig()->isPreviousPassSolutionReuseAllowed() )
1177  {
1178  return false;
1179  }
1180 
1181  if( !isset($_GET["reuseSelection"]) )
1182  {
1183  return false;
1184  }
1185 
1186  if( !strlen($_GET["reuseSelection"]) )
1187  {
1188  return false;
1189  }
1190 
1191  if( !preg_match('/\d(,\d)*/', $_GET["reuseSelection"]) )
1192  {
1193  return false;
1194  }
1195 
1196  return true;
1197  }
1198  // hey.
1199 }
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)
$worksheet
Class iQuestionCondition.
forceExistingIntermediateSolution($activeId, $passIndex, $considerDummyRecordCreation)
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
$result
savePreviewData(ilAssQuestionPreviewSession $previewSession)
$_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
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. ...
Add rich text string
The name of the decorator.
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
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 moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static explodeKeyValues($keyValues)
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)
Create styles array
The data for the language used.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{}
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
duplicateImage($question_id, $objectId=null)
setIsMultipleChoice($is_multiple_choice)
Set true if the Imagemapquestion is a multiplechoice Question.
getExpressionTypes()
Get all available expression types for a specific question.
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
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...
$text
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
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.
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
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.
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.