ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 $ilDB;
88  $ilDB->manipulateF(
89  "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
90  array( "integer" ),
91  array( $this->getId() )
92  );
93  $ilDB->manipulateF(
94  "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  public function loadFromDb($question_id)
140  {
141  global $ilDB;
142  $result = $ilDB->queryF(
143  "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",
144  array("integer"),
145  array($question_id)
146  );
147  if ($result->numRows() == 1) {
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  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
166  } catch (ilTestQuestionPoolException $e) {
167  }
168 
169  // load additional data
170  $result = $ilDB->queryF(
171  "SELECT * FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
172  array("integer"),
173  array($question_id)
174  );
175  if ($result->numRows() == 1) {
176  $data = $ilDB->fetchAssoc($result);
177  $this->setWidth($data["width"]);
178  $this->setHeight($data["height"]);
179  $this->setApplet($data["applet"]);
180  $this->parameters = unserialize($data["params"]);
181  if (!is_array($this->parameters)) {
182  $this->clearParameters();
183  }
184  unset($_SESSION["flash_upload_filename"]);
185  }
186  }
187  parent::loadFromDb($question_id);
188  }
189 
197  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
198  {
199  if ($this->id <= 0) {
200  // The question has not been saved. It cannot be duplicated
201  return;
202  }
203  // duplicate the question in database
204  $this_id = $this->getId();
205  $thisObjId = $this->getObjId();
206 
207  $clone = $this;
208  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
210  $clone->id = -1;
211 
212  if ((int) $testObjId > 0) {
213  $clone->setObjId($testObjId);
214  }
215 
216  if ($title) {
217  $clone->setTitle($title);
218  }
219 
220  if ($author) {
221  $clone->setAuthor($author);
222  }
223  if ($owner) {
224  $clone->setOwner($owner);
225  }
226 
227  if ($for_test) {
228  $clone->saveToDb($original_id);
229  } else {
230  $clone->saveToDb();
231  }
232 
233  // copy question page content
234  $clone->copyPageOfQuestion($this_id);
235  // copy XHTML media objects
236  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
237  // duplicate the applet
238  $clone->duplicateApplet($this_id, $thisObjId);
239 
240  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
241 
242  return $clone->id;
243  }
244 
252  public function copyObject($target_questionpool_id, $title = "")
253  {
254  if ($this->id <= 0) {
255  // The question has not been saved. It cannot be duplicated
256  return;
257  }
258  // duplicate the question in database
259  $clone = $this;
260  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
262  $clone->id = -1;
263  $source_questionpool_id = $this->getObjId();
264  $clone->setObjId($target_questionpool_id);
265  if ($title) {
266  $clone->setTitle($title);
267  }
268  $clone->saveToDb();
269 
270  // copy question page content
271  $clone->copyPageOfQuestion($original_id);
272  // copy XHTML media objects
273  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
274  // duplicate the applet
275  $clone->copyApplet($original_id, $source_questionpool_id);
276 
277  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
278 
279  return $clone->id;
280  }
281 
282  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
283  {
284  if ($this->id <= 0) {
285  // The question has not been saved. It cannot be duplicated
286  return;
287  }
288 
289  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
290 
291  $sourceQuestionId = $this->id;
292  $sourceParentId = $this->getObjId();
293 
294  // duplicate the question in database
295  $clone = $this;
296  $clone->id = -1;
297 
298  $clone->setObjId($targetParentId);
299 
300  if ($targetQuestionTitle) {
301  $clone->setTitle($targetQuestionTitle);
302  }
303 
304  $clone->saveToDb();
305  // copy question page content
306  $clone->copyPageOfQuestion($sourceQuestionId);
307  // copy XHTML media objects
308  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
309  // duplicate the applet
310  $clone->copyApplet($sourceQuestionId, $sourceParentId);
311 
312  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
313 
314  return $clone->id;
315  }
316 
323  protected function duplicateApplet($question_id, $objectId = null)
324  {
325  $flashpath = $this->getFlashPath();
326  $flashpath_original = preg_replace("/([^\d])$this->id([^\d])/", "\${1}$question_id\${2}", $flashpath);
327 
328  if ((int) $objectId > 0) {
329  $flashpath_original = str_replace("/$this->obj_id/", "/$objectId/", $flashpath_original);
330  }
331 
332  if (!file_exists($flashpath)) {
333  ilUtil::makeDirParents($flashpath);
334  }
335  $filename = $this->getApplet();
336  if (!copy($flashpath_original . $filename, $flashpath . $filename)) {
337  print "flash applet could not be duplicated!!!! ";
338  }
339  }
340 
347  protected function copyApplet($question_id, $source_questionpool)
348  {
349  $flashpath = $this->getFlashPath();
350  $flashpath_original = preg_replace("/([^\d])$this->id([^\d])/", "\${1}$question_id\${2}", $flashpath);
351  $flashpath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $flashpath_original);
352  if (!file_exists($flashpath)) {
353  ilUtil::makeDirParents($flashpath);
354  }
355  $filename = $this->getApplet();
356  if (!copy($flashpath_original . $filename, $flashpath . $filename)) {
357  print "flash applet could not be copied!!!! ";
358  }
359  }
360 
367  public function getMaximumPoints()
368  {
369  return $this->points;
370  }
371 
382  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
383  {
384  if ($returndetails) {
385  throw new ilTestException('return details not implemented for ' . __METHOD__);
386  }
387 
388  global $ilDB;
389 
390  $found_values = array();
391  if (is_null($pass)) {
392  $pass = $this->getSolutionMaxPass($active_id);
393  }
394 
395  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
396 
397  $points = 0;
398  while ($data = $ilDB->fetchAssoc($result)) {
399  $points += $data["points"];
400  }
401 
402  return $points;
403  }
404 
406  {
407  $points = 0;
408  foreach ($previewSession->getParticipantsSolution() as $solution) {
409  if (isset($solution['points'])) {
410  $points += $solution['points'];
411  }
412  }
413 
414  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $points);
415 
416  return $this->ensureNonNegativePoints($reachedPoints);
417  }
418 
419  public function sendToHost($url, $data, $optional_headers = null)
420  {
421  $params = array('http' => array(
422  'method' => 'POST',
423  'content' => $data
424  ));
425  if ($optional_headers !== null) {
426  $params['http']['header'] = $optional_headers;
427  }
428  $ctx = stream_context_create($params);
429  $fp = @fopen($url, 'rb', false, $ctx);
430  if (!$fp) {
431  throw new Exception("Problem with $url, $php_errormsg");
432  }
433  $response = @stream_get_contents($fp);
434  if ($response === false) {
435  throw new Exception("Problem reading data from $url, $php_errormsg");
436  }
437  return $response;
438  }
439 
448  public function moveUploadedFile($tmpfile, $flashfile)
449  {
450  $result = "";
451  if (!empty($tmpfile)) {
452  $flashfile = str_replace(" ", "_", $flashfile);
453  $flashpath = $this->getFlashPath();
454  if (!file_exists($flashpath)) {
455  ilUtil::makeDirParents($flashpath);
456  }
457  if (ilUtil::moveUploadedFile($tmpfile, $flashfile, $flashpath . $flashfile)) {
458  $result = $flashfile;
459  }
460  }
461  return $result;
462  }
463 
464  public function deleteApplet()
465  {
466  @unlink($this->getFlashPath() . $this->getApplet());
467  $this->applet = "";
468  }
469 
478  public function saveWorkingData($active_id, $pass = null, $authorized = true)
479  {
480  // nothing to save!
481 
482  //$this->getProcessLocker()->requestUserSolutionUpdateLock();
483  // store in tst_solutions
484  //$this->getProcessLocker()->releaseUserSolutionUpdateLock();
485 
486  return true;
487  }
488 
489  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
490  {
491  // nothing to save!
492 
493  return true;
494  }
495 
499  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
500  {
501  // nothing to rework!
502  }
503 
512  public function getQuestionType()
513  {
514  return "assFlashQuestion";
515  }
516 
525  public function getAdditionalTableName()
526  {
527  return "qpl_qst_flash";
528  }
529 
538  public function getAnswerTableName()
539  {
540  return "";
541  }
542 
549  public function deleteAnswers($question_id)
550  {
551  }
552 
557  public function getRTETextWithMediaObjects()
558  {
559  $text = parent::getRTETextWithMediaObjects();
560  return $text;
561  }
562 
566  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
567  {
568  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
569 
570  return $startrow + 1;
571  }
572 
586  public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
587  {
588  include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assFlashQuestionImport.php";
589  $import = new assFlashQuestionImport($this);
590  $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
591  }
592 
600  public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
601  {
602  include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assFlashQuestionExport.php";
603  $export = new assFlashQuestionExport($this);
604  return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
605  }
606 
613  public function getBestSolution($active_id, $pass)
614  {
615  $user_solution = array();
616  return $user_solution;
617  }
618 
619  public function setHeight($a_height)
620  {
621  if (!$a_height) {
622  $a_height = 400;
623  }
624  $this->height = $a_height;
625  }
626 
627  public function getHeight()
628  {
629  return $this->height;
630  }
631 
632  public function setWidth($a_width)
633  {
634  if (!$a_width) {
635  $a_width = 550;
636  }
637  $this->width = $a_width;
638  }
639 
640  public function getWidth()
641  {
642  return $this->width;
643  }
644 
645  public function setApplet($a_applet)
646  {
647  $this->applet = $a_applet;
648  }
649 
650  public function getApplet()
651  {
652  return $this->applet;
653  }
654 
655  public function addParameter($name, $value)
656  {
657  $this->parameters[$name] = $value;
658  }
659 
660  public function setParameters($params)
661  {
662  if (is_array($params)) {
663  $this->parameters = $params;
664  } else {
665  $this->parameters = array();
666  }
667  }
668 
669  public function removeParameter($name)
670  {
671  unset($this->parameters[$name]);
672  }
673 
674  public function clearParameters()
675  {
676  $this->parameters = array();
677  }
678 
679  public function getParameters()
680  {
681  return $this->parameters;
682  }
683 
684  public function isAutosaveable()
685  {
686  return false;
687  }
688 
697  public function getOperators($expression)
698  {
699  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
701  }
702 
707  public function getExpressionTypes()
708  {
709  return array(
713  );
714  }
715 
724  public function getUserQuestionResult($active_id, $pass)
725  {
726  // TODO: Implement getUserQuestionResult() method.
727  }
728 
737  public function getAvailableAnswerOptions($index = null)
738  {
739  // TODO: Implement getAvailableAnswerOptions() method.
740  }
741 
742  // fau: testNav - new function getTestQuestionConfig()
747  // hey: refactored identifiers
748  public function buildTestPresentationConfig()
749  // hey.
750  {
751  // hey: refactored identifiers
752  return parent::buildTestPresentationConfig()
753  // hey.
754  ->setFormChangeDetectionEnabled(false)
755  ->setBackgroundChangeDetectionEnabled(true);
756  }
757  // fau.
758 }
$params
Definition: disable.php:11
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
$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. ...
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...
if($format !==null) $name
Definition: metadata.php:146
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="")
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...
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.
moveUploadedFile($tmpfile, $flashfile)
Uploads a flash file.