ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.assFlashQuestion.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.iQuestionCondition.php';
8 
21 {
22  private $width;
23  private $height;
24  private $parameters;
25  private $applet;
26 
40  function __construct(
41  $title = "",
42  $comment = "",
43  $author = "",
44  $owner = -1,
45  $question = ""
46  )
47  {
48  parent::__construct($title, $comment, $author, $owner, $question);
49  $this->parameters = array();
50  $this->width = 540;
51  $this->height = 400;
52  $this->applet = "";
53  }
54 
61  function isComplete()
62  {
63  if (strlen($this->title)
64  && ($this->author)
65  && ($this->question)
66  && ($this->getMaximumPoints() > 0)
67  && (strlen($this->getApplet()))
68  )
69  {
70  return true;
71  }
72  return false;
73  }
74 
80  function saveToDb($original_id = "")
81  {
84  parent::saveToDb();
85  }
86 
88  {
89  global $ilDB;
90  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
91  array( "integer" ),
92  array( $this->getId() )
93  );
94  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName(
95  ) . " (question_fi, width, height, applet, params) VALUES (%s, %s, %s, %s, %s)",
96  array( "integer", "integer", "integer", "text", "text" ),
97  array(
98  $this->getId(),
99  (strlen( $this->getWidth() )) ? $this->getWidth() : 550,
100  (strlen( $this->getHeight() )) ? $this->getHeight() : 400,
101  $this->getApplet(),
102  serialize( $this->getParameters() )
103  )
104  );
105 
106  try {
107  $this->moveAppletIfExists();
108  } catch (\ilFileUtilsException $e) {
109  \ilLoggerFactory::getRootLogger()->error($e->getMessage());
110  }
111  }
112 
117  protected function moveAppletIfExists()
118  {
119  if (
120  isset($_SESSION['flash_upload_filename']) && is_string($_SESSION['flash_upload_filename']) &&
121  file_exists($_SESSION['flash_upload_filename']) && is_file($_SESSION['flash_upload_filename'])
122  ) {
123  $path = $this->getFlashPath();
125 
126  require_once 'Services/Utilities/classes/class.ilFileUtils.php';
127  \ilFileUtils::rename($_SESSION['flash_upload_filename'], $path . $this->getApplet());
128  unset($_SESSION['flash_upload_filename']);
129  }
130  }
131 
139  function loadFromDb($question_id)
140  {
141  global $ilDB;
142  $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",
143  array("integer"),
144  array($question_id)
145  );
146  if ($result->numRows() == 1)
147  {
148  $data = $ilDB->fetchAssoc($result);
149  $this->setId($question_id);
150  $this->setNrOfTries($data['nr_of_tries']);
151  $this->setTitle($data["title"]);
152  $this->setComment($data["description"]);
153  $this->setSuggestedSolution($data["solution_hint"]);
154  $this->setOriginalId($data["original_id"]);
155  $this->setObjId($data["obj_fi"]);
156  $this->setAuthor($data["author"]);
157  $this->setOwner($data["owner"]);
158  $this->setPoints($data["points"]);
159 
160  include_once("./Services/RTE/classes/class.ilRTE.php");
161  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
162  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
163 
164  try
165  {
166  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
167  }
169  {
170  }
171 
172  // load additional data
173  $result = $ilDB->queryF("SELECT * FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
174  array("integer"),
175  array($question_id)
176  );
177  if ($result->numRows() == 1)
178  {
179  $data = $ilDB->fetchAssoc($result);
180  $this->setWidth($data["width"]);
181  $this->setHeight($data["height"]);
182  $this->setApplet($data["applet"]);
183  $this->parameters = unserialize($data["params"]);
184  if (!is_array($this->parameters)) $this->clearParameters();
185  unset($_SESSION["flash_upload_filename"]);
186  }
187  }
188  parent::loadFromDb($question_id);
189  }
190 
198  function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
199  {
200  if ($this->id <= 0)
201  {
202  // The question has not been saved. It cannot be duplicated
203  return;
204  }
205  // duplicate the question in database
206  $this_id = $this->getId();
207  $thisObjId = $this->getObjId();
208 
209  $clone = $this;
210  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
212  $clone->id = -1;
213 
214  if( (int)$testObjId > 0 )
215  {
216  $clone->setObjId($testObjId);
217  }
218 
219  if ($title)
220  {
221  $clone->setTitle($title);
222  }
223 
224  if ($author)
225  {
226  $clone->setAuthor($author);
227  }
228  if ($owner)
229  {
230  $clone->setOwner($owner);
231  }
232 
233  if ($for_test)
234  {
235  $clone->saveToDb($original_id);
236  }
237  else
238  {
239  $clone->saveToDb();
240  }
241 
242  // copy question page content
243  $clone->copyPageOfQuestion($this_id);
244  // copy XHTML media objects
245  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
246  // duplicate the applet
247  $clone->duplicateApplet($this_id, $thisObjId);
248 
249  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
250 
251  return $clone->id;
252  }
253 
261  function copyObject($target_questionpool_id, $title = "")
262  {
263  if ($this->id <= 0)
264  {
265  // The question has not been saved. It cannot be duplicated
266  return;
267  }
268  // duplicate the question in database
269  $clone = $this;
270  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
272  $clone->id = -1;
273  $source_questionpool_id = $this->getObjId();
274  $clone->setObjId($target_questionpool_id);
275  if ($title)
276  {
277  $clone->setTitle($title);
278  }
279  $clone->saveToDb();
280 
281  // copy question page content
282  $clone->copyPageOfQuestion($original_id);
283  // copy XHTML media objects
284  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
285  // duplicate the applet
286  $clone->copyApplet($original_id, $source_questionpool_id);
287 
288  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
289 
290  return $clone->id;
291  }
292 
293  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
294  {
295  if ($this->id <= 0)
296  {
297  // The question has not been saved. It cannot be duplicated
298  return;
299  }
300 
301  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
302 
303  $sourceQuestionId = $this->id;
304  $sourceParentId = $this->getObjId();
305 
306  // duplicate the question in database
307  $clone = $this;
308  $clone->id = -1;
309 
310  $clone->setObjId($targetParentId);
311 
312  if ($targetQuestionTitle)
313  {
314  $clone->setTitle($targetQuestionTitle);
315  }
316 
317  $clone->saveToDb();
318  // copy question page content
319  $clone->copyPageOfQuestion($sourceQuestionId);
320  // copy XHTML media objects
321  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
322  // duplicate the applet
323  $clone->copyApplet($sourceQuestionId, $sourceParentId);
324 
325  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
326 
327  return $clone->id;
328  }
329 
336  protected function duplicateApplet($question_id, $objectId = null)
337  {
338  $flashpath = $this->getFlashPath();
339  $flashpath_original = preg_replace("/([^\d])$this->id([^\d])/", "\${1}$question_id\${2}", $flashpath);
340 
341  if( (int)$objectId > 0 )
342  {
343  $flashpath_original = str_replace("/$this->obj_id/", "/$objectId/", $flashpath_original);
344  }
345 
346  if (!file_exists($flashpath))
347  {
348  ilUtil::makeDirParents($flashpath);
349  }
350  $filename = $this->getApplet();
351  if (!copy($flashpath_original . $filename, $flashpath . $filename)) {
352  print "flash applet could not be duplicated!!!! ";
353  }
354  }
355 
362  protected function copyApplet($question_id, $source_questionpool)
363  {
364  $flashpath = $this->getFlashPath();
365  $flashpath_original = preg_replace("/([^\d])$this->id([^\d])/", "\${1}$question_id\${2}", $flashpath);
366  $flashpath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $flashpath_original);
367  if (!file_exists($flashpath))
368  {
369  ilUtil::makeDirParents($flashpath);
370  }
371  $filename = $this->getApplet();
372  if (!copy($flashpath_original . $filename, $flashpath . $filename))
373  {
374  print "flash applet could not be copied!!!! ";
375  }
376  }
377 
384  function getMaximumPoints()
385  {
386  return $this->points;
387  }
388 
399  public function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = FALSE)
400  {
401  if( $returndetails )
402  {
403  throw new ilTestException('return details not implemented for '.__METHOD__);
404  }
405 
406  global $ilDB;
407 
408  $found_values = array();
409  if (is_null($pass))
410  {
411  $pass = $this->getSolutionMaxPass($active_id);
412  }
413 
414  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
415 
416  $points = 0;
417  while ($data = $ilDB->fetchAssoc($result))
418  {
419  $points += $data["points"];
420  }
421 
422  return $points;
423  }
424 
426  {
427  $points = 0;
428  foreach($previewSession->getParticipantsSolution() as $solution)
429  {
430  if( isset($solution['points']) )
431  {
432  $points += $solution['points'];
433  }
434  }
435 
436  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $points);
437 
438  return $this->ensureNonNegativePoints($reachedPoints);
439  }
440 
441  function sendToHost($url, $data, $optional_headers = null)
442  {
443  $params = array('http' => array(
444  'method' => 'POST',
445  'content' => $data
446  ));
447  if ($optional_headers !== null)
448  {
449  $params['http']['header'] = $optional_headers;
450  }
451  $ctx = stream_context_create($params);
452  $fp = @fopen($url, 'rb', false, $ctx);
453  if (!$fp)
454  {
455  throw new Exception("Problem with $url, $php_errormsg");
456  }
457  $response = @stream_get_contents($fp);
458  if ($response === false)
459  {
460  throw new Exception("Problem reading data from $url, $php_errormsg");
461  }
462  return $response;
463  }
464 
473  function moveUploadedFile($tmpfile, $flashfile)
474  {
475  $result = "";
476  if (!empty($tmpfile))
477  {
478  $flashfile = str_replace(" ", "_", $flashfile);
479  $flashpath = $this->getFlashPath();
480  if (!file_exists($flashpath))
481  {
482  ilUtil::makeDirParents($flashpath);
483  }
484  if (ilUtil::moveUploadedFile($tmpfile, $flashfile, $flashpath.$flashfile))
485  {
486  $result = $flashfile;
487  }
488  }
489  return $result;
490  }
491 
492  function deleteApplet()
493  {
494  @unlink($this->getFlashPath() . $this->getApplet());
495  $this->applet = "";
496  }
497 
506  public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
507  {
508  // nothing to save!
509 
510  //$this->getProcessLocker()->requestUserSolutionUpdateLock();
511  // store in tst_solutions
512  //$this->getProcessLocker()->releaseUserSolutionUpdateLock();
513 
514  return true;
515  }
516 
517  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
518  {
519  // nothing to save!
520 
521  return true;
522  }
523 
527  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
528  {
529  // nothing to rework!
530  }
531 
540  function getQuestionType()
541  {
542  return "assFlashQuestion";
543  }
544 
554  {
555  return "qpl_qst_flash";
556  }
557 
567  {
568  return "";
569  }
570 
577  function deleteAnswers($question_id)
578  {
579  }
580 
586  {
587  $text = parent::getRTETextWithMediaObjects();
588  return $text;
589  }
590 
594  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
595  {
596  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
597 
598  return $startrow + 1;
599  }
600 
614  function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
615  {
616  include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assFlashQuestionImport.php";
617  $import = new assFlashQuestionImport($this);
618  $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
619  }
620 
628  function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
629  {
630  include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assFlashQuestionExport.php";
631  $export = new assFlashQuestionExport($this);
632  return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
633  }
634 
641  public function getBestSolution($active_id, $pass)
642  {
643  $user_solution = array();
644  return $user_solution;
645  }
646 
647  public function setHeight($a_height)
648  {
649  if (!$a_height) $a_height = 400;
650  $this->height = $a_height;
651  }
652 
653  public function getHeight()
654  {
655  return $this->height;
656  }
657 
658  public function setWidth($a_width)
659  {
660  if (!$a_width) $a_width = 550;
661  $this->width = $a_width;
662  }
663 
664  public function getWidth()
665  {
666  return $this->width;
667  }
668 
669  public function setApplet($a_applet)
670  {
671  $this->applet = $a_applet;
672  }
673 
674  public function getApplet()
675  {
676  return $this->applet;
677  }
678 
679  public function addParameter($name, $value)
680  {
681  $this->parameters[$name] = $value;
682  }
683 
684  public function setParameters($params)
685  {
686  if (is_array($params))
687  {
688  $this->parameters = $params;
689  }
690  else
691  {
692  $this->parameters = array();
693  }
694  }
695 
696  public function removeParameter($name)
697  {
698  unset($this->parameters[$name]);
699  }
700 
701  public function clearParameters()
702  {
703  $this->parameters = array();
704  }
705 
706  public function getParameters()
707  {
708  return $this->parameters;
709  }
710 
711  public function isAutosaveable()
712  {
713  return FALSE;
714  }
715 
724  public function getOperators($expression)
725  {
726  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
728  }
729 
734  public function getExpressionTypes()
735  {
736  return array(
740  );
741  }
742 
751  public function getUserQuestionResult($active_id, $pass)
752  {
753  // TODO: Implement getUserQuestionResult() method.
754  }
755 
764  public function getAvailableAnswerOptions($index = null)
765  {
766  // TODO: Implement getAvailableAnswerOptions() method.
767  }
768 
769 // fau: testNav - new function getTestQuestionConfig()
774  // hey: refactored identifiers
775  public function buildTestPresentationConfig()
776  // hey.
777  {
778  // hey: refactored identifiers
779  return parent::buildTestPresentationConfig()
780  // hey.
781  ->setFormChangeDetectionEnabled(false)
782  ->setBackgroundChangeDetectionEnabled(true);
783  }
784 // fau.
785 }
static makeDirParents($a_dir)
Create a new directory and all parent directories.
getId()
Gets the id of the assQuestion object.
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
$path
Definition: aliased.php:25
static _getOriginalId($question_id)
Returns the original id of a question.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFlashQuestion constructor
$worksheet
isComplete()
Returns true, if a single choice question is complete for use.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
Class iQuestionCondition.
copyApplet($question_id, $source_questionpool)
Copy the flash applet.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{}
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
$_SESSION["AccountId"]
$result
sendToHost($url, $data, $optional_headers=null)
Abstract basic class which is to be extended by the concrete assessment question type classes...
getAdditionalTableName()
Returns the name of the additional question data table in the database.
getOperators($expression)
Get all available operations for a specific question.
ensureNonNegativePoints($points)
setId($id=-1)
Sets the id of the assQuestion object.
buildTestPresentationConfig()
Get the test question configuration.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
$url
Definition: shib_logout.php:72
Class for Flash based questions.
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.
Base Exception for all Exceptions relating to Modules/Test.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
saveToDb($original_id="")
Saves a assFlashQuestion object to a database.
static rename($a_source, $a_target)
Rename a file.
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...
getFlashPath()
Returns the image path for web accessable flash files of a question.
setAuthor($author="")
Sets the authors name of the assQuestion object.
getAnswerTableName()
Returns the name of the answer table in the database.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
Class for flash question exports.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
deleteAnswers($question_id)
Deletes datasets from answers tables.
duplicateApplet($question_id, $objectId=null)
Duplicate the flash applet.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
Create styles array
The data for the language used.
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
loadFromDb($question_id)
Loads a assFlashQuestion object from a database.
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
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
Class for flash question imports.
moveAppletIfExists()
Moves an applet file (maybe stored in the PHP session) to its final filesystem destination.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assFlashQuestion.
getExpressionTypes()
Get all available expression types for a specific question.
getQuestionType()
Returns the question type of the question.
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
copyObject($target_questionpool_id, $title="")
Copies an assFlashQuestion object.
setComment($comment="")
Sets the comment string of the assQuestion object.
$params
Definition: example_049.php:96
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Creates a question from a QTI file.
static getRootLogger()
The unique root logger has a fixed error level.
Class to report exception.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
moveUploadedFile($tmpfile, $flashfile)
Uploads a flash file.