ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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  public function __construct(
41  $title = "",
42  $comment = "",
43  $author = "",
44  $owner = -1,
45  $question = ""
46  ) {
47  parent::__construct($title, $comment, $author, $owner, $question);
48  $this->parameters = array();
49  $this->width = 540;
50  $this->height = 400;
51  $this->applet = "";
52  }
53 
60  public function isComplete()
61  {
62  if (strlen($this->title)
63  && ($this->author)
64  && ($this->question)
65  && ($this->getMaximumPoints() > 0)
66  && (strlen($this->getApplet()))
67  ) {
68  return true;
69  }
70  return false;
71  }
72 
78  public function saveToDb($original_id = "")
79  {
82  parent::saveToDb();
83  }
84 
86  {
87  global $DIC;
88  $ilDB = $DIC['ilDB'];
89  $ilDB->manipulateF(
90  "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
91  array( "integer" ),
92  array( $this->getId() )
93  );
94  $ilDB->manipulateF(
95  "INSERT INTO " . $this->getAdditionalTableName(
96  ) . " (question_fi, width, height, applet, params) VALUES (%s, %s, %s, %s, %s)",
97  array( "integer", "integer", "integer", "text", "text" ),
98  array(
99  $this->getId(),
100  (strlen($this->getWidth())) ? $this->getWidth() : 550,
101  (strlen($this->getHeight())) ? $this->getHeight() : 400,
102  $this->getApplet(),
103  serialize($this->getParameters())
104  )
105  );
106 
107  try {
108  $this->moveAppletIfExists();
109  } catch (\ilFileUtilsException $e) {
110  \ilLoggerFactory::getRootLogger()->error($e->getMessage());
111  }
112  }
113 
118  protected function moveAppletIfExists()
119  {
120  if (
121  isset($_SESSION['flash_upload_filename']) && is_string($_SESSION['flash_upload_filename']) &&
122  file_exists($_SESSION['flash_upload_filename']) && is_file($_SESSION['flash_upload_filename'])
123  ) {
124  $path = $this->getFlashPath();
126 
127  require_once 'Services/Utilities/classes/class.ilFileUtils.php';
128  \ilFileUtils::rename($_SESSION['flash_upload_filename'], $path . $this->getApplet());
129  unset($_SESSION['flash_upload_filename']);
130  }
131  }
132 
140  public function loadFromDb($question_id)
141  {
142  global $DIC;
143  $ilDB = $DIC['ilDB'];
144  $result = $ilDB->queryF(
145  "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",
146  array("integer"),
147  array($question_id)
148  );
149  if ($result->numRows() == 1) {
150  $data = $ilDB->fetchAssoc($result);
151  $this->setId($question_id);
152  $this->setNrOfTries($data['nr_of_tries']);
153  $this->setTitle($data["title"]);
154  $this->setComment($data["description"]);
155  $this->setSuggestedSolution($data["solution_hint"]);
156  $this->setOriginalId($data["original_id"]);
157  $this->setObjId($data["obj_fi"]);
158  $this->setAuthor($data["author"]);
159  $this->setOwner($data["owner"]);
160  $this->setPoints($data["points"]);
161 
162  include_once("./Services/RTE/classes/class.ilRTE.php");
163  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
164  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
165 
166  try {
167  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
168  } catch (ilTestQuestionPoolException $e) {
169  }
170 
171  // load additional data
172  $result = $ilDB->queryF(
173  "SELECT * FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
174  array("integer"),
175  array($question_id)
176  );
177  if ($result->numRows() == 1) {
178  $data = $ilDB->fetchAssoc($result);
179  $this->setWidth($data["width"]);
180  $this->setHeight($data["height"]);
181  $this->setApplet($data["applet"]);
182  $this->parameters = unserialize($data["params"]);
183  if (!is_array($this->parameters)) {
184  $this->clearParameters();
185  }
186  unset($_SESSION["flash_upload_filename"]);
187  }
188  }
189  parent::loadFromDb($question_id);
190  }
191 
199  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
200  {
201  if ($this->id <= 0) {
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  $clone->setObjId($testObjId);
216  }
217 
218  if ($title) {
219  $clone->setTitle($title);
220  }
221 
222  if ($author) {
223  $clone->setAuthor($author);
224  }
225  if ($owner) {
226  $clone->setOwner($owner);
227  }
228 
229  if ($for_test) {
230  $clone->saveToDb($original_id);
231  } else {
232  $clone->saveToDb();
233  }
234 
235  // copy question page content
236  $clone->copyPageOfQuestion($this_id);
237  // copy XHTML media objects
238  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
239  // duplicate the applet
240  $clone->duplicateApplet($this_id, $thisObjId);
241 
242  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
243 
244  return $clone->id;
245  }
246 
254  public function copyObject($target_questionpool_id, $title = "")
255  {
256  if ($this->id <= 0) {
257  // The question has not been saved. It cannot be duplicated
258  return;
259  }
260  // duplicate the question in database
261  $clone = $this;
262  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
264  $clone->id = -1;
265  $source_questionpool_id = $this->getObjId();
266  $clone->setObjId($target_questionpool_id);
267  if ($title) {
268  $clone->setTitle($title);
269  }
270  $clone->saveToDb();
271 
272  // copy question page content
273  $clone->copyPageOfQuestion($original_id);
274  // copy XHTML media objects
275  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
276  // duplicate the applet
277  $clone->copyApplet($original_id, $source_questionpool_id);
278 
279  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
280 
281  return $clone->id;
282  }
283 
284  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
285  {
286  if ($this->id <= 0) {
287  // The question has not been saved. It cannot be duplicated
288  return;
289  }
290 
291  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
292 
293  $sourceQuestionId = $this->id;
294  $sourceParentId = $this->getObjId();
295 
296  // duplicate the question in database
297  $clone = $this;
298  $clone->id = -1;
299 
300  $clone->setObjId($targetParentId);
301 
302  if ($targetQuestionTitle) {
303  $clone->setTitle($targetQuestionTitle);
304  }
305 
306  $clone->saveToDb();
307  // copy question page content
308  $clone->copyPageOfQuestion($sourceQuestionId);
309  // copy XHTML media objects
310  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
311  // duplicate the applet
312  $clone->copyApplet($sourceQuestionId, $sourceParentId);
313 
314  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
315 
316  return $clone->id;
317  }
318 
325  protected function duplicateApplet($question_id, $objectId = null)
326  {
327  $flashpath = $this->getFlashPath();
328  $flashpath_original = preg_replace("/([^\d])$this->id([^\d])/", "\${1}$question_id\${2}", $flashpath);
329 
330  if ((int) $objectId > 0) {
331  $flashpath_original = str_replace("/$this->obj_id/", "/$objectId/", $flashpath_original);
332  }
333 
334  if (!file_exists($flashpath)) {
335  ilUtil::makeDirParents($flashpath);
336  }
337  $filename = $this->getApplet();
338  if (!copy($flashpath_original . $filename, $flashpath . $filename)) {
339  print "flash applet could not be duplicated!!!! ";
340  }
341  }
342 
349  protected function copyApplet($question_id, $source_questionpool)
350  {
351  $flashpath = $this->getFlashPath();
352  $flashpath_original = preg_replace("/([^\d])$this->id([^\d])/", "\${1}$question_id\${2}", $flashpath);
353  $flashpath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $flashpath_original);
354  if (!file_exists($flashpath)) {
355  ilUtil::makeDirParents($flashpath);
356  }
357  $filename = $this->getApplet();
358  if (!copy($flashpath_original . $filename, $flashpath . $filename)) {
359  print "flash applet could not be copied!!!! ";
360  }
361  }
362 
369  public function getMaximumPoints()
370  {
371  return $this->points;
372  }
373 
384  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
385  {
386  if ($returndetails) {
387  throw new ilTestException('return details not implemented for ' . __METHOD__);
388  }
389 
390  global $DIC;
391  $ilDB = $DIC['ilDB'];
392 
393  $found_values = array();
394  if (is_null($pass)) {
395  $pass = $this->getSolutionMaxPass($active_id);
396  }
397 
398  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
399 
400  $points = 0;
401  while ($data = $ilDB->fetchAssoc($result)) {
402  $points += $data["points"];
403  }
404 
405  return $points;
406  }
407 
409  {
410  $points = 0;
411  foreach ($previewSession->getParticipantsSolution() as $solution) {
412  if (isset($solution['points'])) {
413  $points += $solution['points'];
414  }
415  }
416 
417  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $points);
418 
419  return $this->ensureNonNegativePoints($reachedPoints);
420  }
421 
422  public function sendToHost($url, $data, $optional_headers = null)
423  {
424  $params = array('http' => array(
425  'method' => 'POST',
426  'content' => $data
427  ));
428  if ($optional_headers !== null) {
429  $params['http']['header'] = $optional_headers;
430  }
431  $ctx = stream_context_create($params);
432  $fp = @fopen($url, 'rb', false, $ctx);
433  if (!$fp) {
434  throw new Exception("Problem with $url, $php_errormsg");
435  }
436  $response = @stream_get_contents($fp);
437  if ($response === false) {
438  throw new Exception("Problem reading data from $url, $php_errormsg");
439  }
440  return $response;
441  }
442 
451  public function moveUploadedFile($tmpfile, $flashfile)
452  {
453  $result = "";
454  if (!empty($tmpfile)) {
455  $flashfile = str_replace(" ", "_", $flashfile);
456  $flashpath = $this->getFlashPath();
457  if (!file_exists($flashpath)) {
458  ilUtil::makeDirParents($flashpath);
459  }
460  if (ilUtil::moveUploadedFile($tmpfile, $flashfile, $flashpath . $flashfile)) {
461  $result = $flashfile;
462  }
463  }
464  return $result;
465  }
466 
467  public function deleteApplet()
468  {
469  @unlink($this->getFlashPath() . $this->getApplet());
470  $this->applet = "";
471  }
472 
481  public function saveWorkingData($active_id, $pass = null, $authorized = true)
482  {
483  // nothing to save!
484 
485  //$this->getProcessLocker()->requestUserSolutionUpdateLock();
486  // store in tst_solutions
487  //$this->getProcessLocker()->releaseUserSolutionUpdateLock();
488 
489  return true;
490  }
491 
492  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
493  {
494  // nothing to save!
495 
496  return true;
497  }
498 
507  public function getQuestionType()
508  {
509  return "assFlashQuestion";
510  }
511 
520  public function getAdditionalTableName()
521  {
522  return "qpl_qst_flash";
523  }
524 
533  public function getAnswerTableName()
534  {
535  return "";
536  }
537 
544  public function deleteAnswers($question_id)
545  {
546  }
547 
552  public function getRTETextWithMediaObjects()
553  {
554  $text = parent::getRTETextWithMediaObjects();
555  return $text;
556  }
557 
561  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
562  {
563  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
564 
565  return $startrow + 1;
566  }
567 
581  public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
582  {
583  include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assFlashQuestionImport.php";
584  $import = new assFlashQuestionImport($this);
585  $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
586  }
587 
595  public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
596  {
597  include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assFlashQuestionExport.php";
598  $export = new assFlashQuestionExport($this);
599  return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
600  }
601 
608  public function getBestSolution($active_id, $pass)
609  {
610  $user_solution = array();
611  return $user_solution;
612  }
613 
614  public function setHeight($a_height)
615  {
616  if (!$a_height) {
617  $a_height = 400;
618  }
619  $this->height = $a_height;
620  }
621 
622  public function getHeight()
623  {
624  return $this->height;
625  }
626 
627  public function setWidth($a_width)
628  {
629  if (!$a_width) {
630  $a_width = 550;
631  }
632  $this->width = $a_width;
633  }
634 
635  public function getWidth()
636  {
637  return $this->width;
638  }
639 
640  public function setApplet($a_applet)
641  {
642  $this->applet = $a_applet;
643  }
644 
645  public function getApplet()
646  {
647  return $this->applet;
648  }
649 
650  public function addParameter($name, $value)
651  {
652  $this->parameters[$name] = $value;
653  }
654 
655  public function setParameters($params)
656  {
657  if (is_array($params)) {
658  $this->parameters = $params;
659  } else {
660  $this->parameters = array();
661  }
662  }
663 
664  public function removeParameter($name)
665  {
666  unset($this->parameters[$name]);
667  }
668 
669  public function clearParameters()
670  {
671  $this->parameters = array();
672  }
673 
674  public function getParameters()
675  {
676  return $this->parameters;
677  }
678 
679  public function isAutosaveable()
680  {
681  return false;
682  }
683 
692  public function getOperators($expression)
693  {
694  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
696  }
697 
702  public function getExpressionTypes()
703  {
704  return array(
708  );
709  }
710 
719  public function getUserQuestionResult($active_id, $pass)
720  {
721  // TODO: Implement getUserQuestionResult() method.
722  }
723 
732  public function getAvailableAnswerOptions($index = null)
733  {
734  // TODO: Implement getAvailableAnswerOptions() method.
735  }
736 
737  // fau: testNav - new function getTestQuestionConfig()
742  // hey: refactored identifiers
743  public function buildTestPresentationConfig()
744  // hey.
745  {
746  // hey: refactored identifiers
747  return parent::buildTestPresentationConfig()
748  // hey.
749  ->setFormChangeDetectionEnabled(false)
750  ->setBackgroundChangeDetectionEnabled(true);
751  }
752  // fau.
753 }
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
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
global $DIC
Definition: saml.php:7
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. ...
Class for Flash based questions.
$index
Definition: metadata.php:60
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.
Class for flash question exports.
deleteAnswers($question_id)
Deletes datasets from answers tables.
duplicateApplet($question_id, $objectId=null)
Duplicate the flash applet.
$text
Definition: errorreport.php:18
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
$filename
Definition: buildRTE.php:89
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...
Class for flash question imports.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
moveAppletIfExists()
Moves an applet file (maybe stored in the PHP session) to its final filesystem destination.
$url
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.
$response
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.
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.
$data
Definition: bench.php:6
moveUploadedFile($tmpfile, $flashfile)
Uploads a flash file.