ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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  return $points;
436  }
437 
438  function sendToHost($url, $data, $optional_headers = null)
439  {
440  $params = array('http' => array(
441  'method' => 'POST',
442  'content' => $data
443  ));
444  if ($optional_headers !== null)
445  {
446  $params['http']['header'] = $optional_headers;
447  }
448  $ctx = stream_context_create($params);
449  $fp = @fopen($url, 'rb', false, $ctx);
450  if (!$fp)
451  {
452  throw new Exception("Problem with $url, $php_errormsg");
453  }
454  $response = @stream_get_contents($fp);
455  if ($response === false)
456  {
457  throw new Exception("Problem reading data from $url, $php_errormsg");
458  }
459  return $response;
460  }
461 
470  function moveUploadedFile($tmpfile, $flashfile)
471  {
472  $result = "";
473  if (!empty($tmpfile))
474  {
475  $flashfile = str_replace(" ", "_", $flashfile);
476  $flashpath = $this->getFlashPath();
477  if (!file_exists($flashpath))
478  {
479  ilUtil::makeDirParents($flashpath);
480  }
481  if (ilUtil::moveUploadedFile($tmpfile, $flashfile, $flashpath.$flashfile))
482  {
483  $result = $flashfile;
484  }
485  }
486  return $result;
487  }
488 
489  function deleteApplet()
490  {
491  @unlink($this->getFlashPath() . $this->getApplet());
492  $this->applet = "";
493  }
494 
503  public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
504  {
505  // nothing to save!
506 
507  //$this->getProcessLocker()->requestUserSolutionUpdateLock();
508  // store in tst_solutions
509  //$this->getProcessLocker()->releaseUserSolutionUpdateLock();
510 
511  return true;
512  }
513 
514  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
515  {
516  // nothing to save!
517 
518  return true;
519  }
520 
529  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
530  {
531  // nothing to rework!
532  }
533 
542  function getQuestionType()
543  {
544  return "assFlashQuestion";
545  }
546 
556  {
557  return "qpl_qst_flash";
558  }
559 
569  {
570  return "";
571  }
572 
579  function deleteAnswers($question_id)
580  {
581  }
582 
588  {
589  $text = parent::getRTETextWithMediaObjects();
590  return $text;
591  }
592 
605  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
606  {
607  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
608  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
609  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
610  return $startrow + 1;
611  }
612 
626  function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
627  {
628  include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assFlashQuestionImport.php";
629  $import = new assFlashQuestionImport($this);
630  $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
631  }
632 
640  function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
641  {
642  include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assFlashQuestionExport.php";
643  $export = new assFlashQuestionExport($this);
644  return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
645  }
646 
653  public function getBestSolution($active_id, $pass)
654  {
655  $user_solution = array();
656  return $user_solution;
657  }
658 
659  public function setHeight($a_height)
660  {
661  if (!$a_height) $a_height = 400;
662  $this->height = $a_height;
663  }
664 
665  public function getHeight()
666  {
667  return $this->height;
668  }
669 
670  public function setWidth($a_width)
671  {
672  if (!$a_width) $a_width = 550;
673  $this->width = $a_width;
674  }
675 
676  public function getWidth()
677  {
678  return $this->width;
679  }
680 
681  public function setApplet($a_applet)
682  {
683  $this->applet = $a_applet;
684  }
685 
686  public function getApplet()
687  {
688  return $this->applet;
689  }
690 
691  public function addParameter($name, $value)
692  {
693  $this->parameters[$name] = $value;
694  }
695 
696  public function setParameters($params)
697  {
698  if (is_array($params))
699  {
700  $this->parameters = $params;
701  }
702  else
703  {
704  $this->parameters = array();
705  }
706  }
707 
708  public function removeParameter($name)
709  {
710  unset($this->parameters[$name]);
711  }
712 
713  public function clearParameters()
714  {
715  $this->parameters = array();
716  }
717 
718  public function getParameters()
719  {
720  return $this->parameters;
721  }
722 
723  public function isAutosaveable()
724  {
725  return FALSE;
726  }
727 
736  public function getOperators($expression)
737  {
738  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
740  }
741 
746  public function getExpressionTypes()
747  {
748  return array(
752  );
753  }
754 
763  public function getUserQuestionResult($active_id, $pass)
764  {
765  // TODO: Implement getUserQuestionResult() method.
766  }
767 
776  public function getAvailableAnswerOptions($index = null)
777  {
778  // TODO: Implement getAvailableAnswerOptions() method.
779  }
780 }
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.
static _getOriginalId($question_id)
Returns the original id of a question.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFlashQuestion constructor
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.
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.
_convert_text($a_text, $a_target="has been removed")
getOperators($expression)
Get all available operations for a specific question.
setId($id=-1)
Sets the id of the assQuestion object.
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.
$data
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.
$filename
Definition: buildRTE.php:89
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, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
$path
Definition: index.php:22
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.
getTitle()
Gets the title string of the assQuestion object.
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.
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
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.