ILIAS  release_8 Revision v8.24
class.assFlashQuestion.php
Go to the documentation of this file.
1<?php
2
19require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
20require_once './Modules/Test/classes/inc.AssessmentConstants.php';
21require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
22require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
23
36{
37 private $width;
38 private $height;
39 private $parameters;
40 private $applet;
41
55 public function __construct(
56 $title = "",
57 $comment = "",
58 $author = "",
59 $owner = -1,
60 $question = ""
61 ) {
63 $this->parameters = array();
64 $this->width = 540;
65 $this->height = 400;
66 $this->applet = "";
67 }
68
75 public function isComplete(): bool
76 {
77 if (strlen($this->title)
78 && ($this->author)
79 && ($this->question)
80 && ($this->getMaximumPoints() > 0)
81 && (strlen($this->getApplet()))
82 ) {
83 return true;
84 }
85 return false;
86 }
87
93 public function saveToDb($original_id = ""): void
94 {
97 parent::saveToDb();
98 }
99
101 {
102 global $DIC;
103 $ilDB = $DIC['ilDB'];
104 $ilDB->manipulateF(
105 "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
106 array( "integer" ),
107 array( $this->getId() )
108 );
109 $ilDB->manipulateF(
110 "INSERT INTO " . $this->getAdditionalTableName(
111 ) . " (question_fi, width, height, applet, params) VALUES (%s, %s, %s, %s, %s)",
112 array( "integer", "integer", "integer", "text", "text" ),
113 array(
114 $this->getId(),
115 (strlen($this->getWidth())) ? $this->getWidth() : 550,
116 (strlen($this->getHeight())) ? $this->getHeight() : 400,
117 $this->getApplet(),
118 serialize($this->getParameters())
119 )
120 );
121
122 try {
123 $this->moveAppletIfExists();
124 } catch (\ilFileUtilsException $e) {
125 \ilLoggerFactory::getRootLogger()->error($e->getMessage());
126 }
127 }
128
133 protected function moveAppletIfExists(): void
134 {
135 if (ilSession::get('flash_upload_filename') != null &&
136 file_exists(ilSession::get('flash_upload_filename')) && is_file(ilSession::get('flash_upload_filename'))
137 ) {
138 $path = $this->getFlashPath();
140
141 \ilFileUtils::rename(ilSession::get('flash_upload_filename'), $path . $this->getApplet());
142 ilSession::clear('flash_upload_filename');
143 }
144 }
145
153 public function loadFromDb($question_id): void
154 {
155 global $DIC;
156 $ilDB = $DIC['ilDB'];
157 $result = $ilDB->queryF(
158 "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",
159 array("integer"),
160 array($question_id)
161 );
162 if ($result->numRows() == 1) {
163 $data = $ilDB->fetchAssoc($result);
164 $this->setId($question_id);
165 $this->setNrOfTries($data['nr_of_tries']);
166 $this->setTitle((string) $data["title"]);
167 $this->setComment((string) $data["description"]);
168 $this->setSuggestedSolution($data["solution_hint"]);
169 $this->setOriginalId($data["original_id"]);
170 $this->setObjId($data["obj_fi"]);
171 $this->setAuthor($data["author"]);
172 $this->setOwner($data["owner"]);
173 $this->setPoints($data["points"]);
174
175 include_once("./Services/RTE/classes/class.ilRTE.php");
176 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc((string) $data["question_text"], 1));
177
178 try {
179 $this->setLifecycle(ilAssQuestionLifecycle::getInstance($data['lifecycle']));
182 }
183
184 try {
185 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
187 }
188
189 // load additional data
190 $result = $ilDB->queryF(
191 "SELECT * FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
192 array("integer"),
193 array($question_id)
194 );
195 if ($result->numRows() == 1) {
196 $data = $ilDB->fetchAssoc($result);
197 $this->setWidth($data["width"]);
198 $this->setHeight($data["height"]);
199 $this->setApplet($data["applet"]);
200 $this->parameters = unserialize($data["params"], ["allowed_classes" => false]);
201 if (!is_array($this->parameters)) {
202 $this->clearParameters();
203 }
204 ilSession::clear('flash_upload_filename');
205 }
206 }
207 parent::loadFromDb($question_id);
208 }
209
217 public function duplicate(bool $for_test = true, string $title = "", string $author = "", string $owner = "", $testObjId = null): int
218 {
219 if ($this->id <= 0) {
220 // The question has not been saved. It cannot be duplicated
221 return -1;
222 }
223 // duplicate the question in database
224 $this_id = $this->getId();
225 $thisObjId = $this->getObjId();
226
227 $clone = $this;
228 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
230 $clone->id = -1;
231
232 if ((int) $testObjId > 0) {
233 $clone->setObjId($testObjId);
234 }
235
236 if ($title) {
237 $clone->setTitle($title);
238 }
239
240 if ($author) {
241 $clone->setAuthor($author);
242 }
243 if ($owner) {
244 $clone->setOwner($owner);
245 }
246
247 if ($for_test) {
248 $clone->saveToDb($original_id);
249 } else {
250 $clone->saveToDb();
251 }
252
253 // copy question page content
254 $clone->copyPageOfQuestion($this_id);
255 // copy XHTML media objects
256 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
257 // duplicate the applet
258 $clone->duplicateApplet($this_id, $thisObjId);
259
260 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
261
262 return $clone->id;
263 }
264
272 public function copyObject($target_questionpool_id, $title = ""): int
273 {
274 if ($this->getId() <= 0) {
275 throw new RuntimeException('The question has not been saved. It cannot be duplicated');
276 }
277 // duplicate the question in database
278 $clone = $this;
279 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
281 $clone->id = -1;
282 $source_questionpool_id = $this->getObjId();
283 $clone->setObjId($target_questionpool_id);
284 if ($title) {
285 $clone->setTitle($title);
286 }
287 $clone->saveToDb();
288
289 // copy question page content
290 $clone->copyPageOfQuestion($original_id);
291 // copy XHTML media objects
292 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
293 // duplicate the applet
294 $clone->copyApplet($original_id, $source_questionpool_id);
295
296 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
297
298 return $clone->id;
299 }
300
301 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = ""): int
302 {
303 if ($this->getId() <= 0) {
304 throw new RuntimeException('The question has not been saved. It cannot be duplicated');
305 }
306
307 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
308
309 $sourceQuestionId = $this->id;
310 $sourceParentId = $this->getObjId();
311
312 // duplicate the question in database
313 $clone = $this;
314 $clone->id = -1;
315
316 $clone->setObjId($targetParentId);
317
318 if ($targetQuestionTitle) {
319 $clone->setTitle($targetQuestionTitle);
320 }
321
322 $clone->saveToDb();
323 // copy question page content
324 $clone->copyPageOfQuestion($sourceQuestionId);
325 // copy XHTML media objects
326 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
327 // duplicate the applet
328 $clone->copyApplet($sourceQuestionId, $sourceParentId);
329
330 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
331
332 return $clone->id;
333 }
334
338 protected function duplicateApplet(int $question_id, $objectId = null): void
339 {
340 $flashpath = $this->getFlashPath();
341 $flashpath_original = preg_replace("/([^\d])$this->id([^\d])/", "\${1}$question_id\${2}", $flashpath);
342
343 if ((int) $objectId > 0) {
344 $flashpath_original = str_replace("/$this->obj_id/", "/$objectId/", $flashpath_original);
345 }
346
347 if (!file_exists($flashpath)) {
348 ilFileUtils::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): void
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 ilFileUtils::makeDirParents($flashpath);
369 }
370 $filename = $this->getApplet();
371 if (!copy($flashpath_original . $filename, $flashpath . $filename)) {
372 print "flash applet could not be copied!!!! ";
373 }
374 }
375
382 public function getMaximumPoints(): float
383 {
384 return $this->points;
385 }
386
397 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
398 {
399 if ($returndetails) {
400 throw new ilTestException('return details not implemented for ' . __METHOD__);
401 }
402
403 global $DIC;
404 $ilDB = $DIC['ilDB'];
405
406 $found_values = array();
407 if (is_null($pass)) {
408 $pass = $this->getSolutionMaxPass($active_id);
409 }
410
411 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
412
413 $points = 0;
414 while ($data = $ilDB->fetchAssoc($result)) {
415 $points += $data["points"];
416 }
417
418 return $points;
419 }
420
422 {
423 $points = 0;
424 foreach ($previewSession->getParticipantsSolution() as $solution) {
425 if (isset($solution['points'])) {
426 $points += $solution['points'];
427 }
428 }
429
430 $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $points);
431
432 return $this->ensureNonNegativePoints($reachedPoints);
433 }
434
435 public function sendToHost($url, $data, $optional_headers = null): string
436 {
437 $params = array('http' => array(
438 'method' => 'POST',
439 'content' => $data
440 ));
441 if ($optional_headers !== null) {
442 $params['http']['header'] = $optional_headers;
443 }
444 $ctx = stream_context_create($params);
445 $fp = @fopen($url, 'rb', false, $ctx);
446 if (!$fp) {
447 throw new Exception("Problem with $url, " . error_get_last());
448 }
449 $response = @stream_get_contents($fp);
450 if ($response === false) {
451 throw new Exception("Problem reading data from $url, " . error_get_last());
452 }
453 return $response;
454 }
455
464 public function moveUploadedFile($tmpfile, $flashfile): string
465 {
466 $result = "";
467 if (!empty($tmpfile)) {
468 $flashfile = str_replace(" ", "_", $flashfile);
469 $flashpath = $this->getFlashPath();
470 if (!file_exists($flashpath)) {
471 ilFileUtils::makeDirParents($flashpath);
472 }
473 if (ilFileUtils::moveUploadedFile($tmpfile, $flashfile, $flashpath . $flashfile)) {
474 $result = $flashfile;
475 }
476 }
477 return $result;
478 }
479
480 public function deleteApplet(): void
481 {
482 @unlink($this->getFlashPath() . $this->getApplet());
483 $this->applet = "";
484 }
485
494 public function saveWorkingData($active_id, $pass = null, $authorized = true): bool
495 {
496 // nothing to save!
497
498 //$this->getProcessLocker()->requestUserSolutionUpdateLock();
499 // store in tst_solutions
500 //$this->getProcessLocker()->releaseUserSolutionUpdateLock();
501
502 return true;
503 }
504
505 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession): void
506 {
507 }
508
517 public function getQuestionType(): string
518 {
519 return "assFlashQuestion";
520 }
521
530 public function getAdditionalTableName(): string
531 {
532 return "qpl_qst_flash";
533 }
534
543 public function getAnswerTableName(): string
544 {
545 return "";
546 }
547
554 public function deleteAnswers($question_id): void
555 {
556 }
557
562 public function getRTETextWithMediaObjects(): string
563 {
564 $text = parent::getRTETextWithMediaObjects();
565 return $text;
566 }
567
571 public function setExportDetailsXLS(ilAssExcelFormatHelper $worksheet, int $startrow, int $active_id, int $pass): int
572 {
573 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
574
575 return $startrow + 1;
576 }
577
591 public function fromXML($item, int $questionpool_id, ?int $tst_id, &$tst_object, int &$question_counter, array $import_mapping, array &$solutionhints = []): array
592 {
593 include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assFlashQuestionImport.php";
594 $import = new assFlashQuestionImport($this);
595 return $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
596 }
597
605 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false): string
606 {
607 include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assFlashQuestionExport.php";
608 $export = new assFlashQuestionExport($this);
609 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
610 }
611
618 public function getBestSolution($active_id, $pass): array
619 {
620 $user_solution = array();
621 return $user_solution;
622 }
623
624 public function setHeight($a_height): void
625 {
626 if (!$a_height) {
627 $a_height = 400;
628 }
629 $this->height = $a_height;
630 }
631
632 public function getHeight(): int
633 {
634 return $this->height;
635 }
636
637 public function setWidth($a_width): void
638 {
639 if (!$a_width) {
640 $a_width = 550;
641 }
642 $this->width = $a_width;
643 }
644
645 public function getWidth(): int
646 {
647 return $this->width;
648 }
649
650 public function setApplet($a_applet): void
651 {
652 $this->applet = $a_applet;
653 }
654
655 public function getApplet(): string
656 {
657 return $this->applet;
658 }
659
660 public function addParameter($name, $value): void
661 {
662 $this->parameters[$name] = $value;
663 }
664
665 public function setParameters($params): void
666 {
667 if (is_array($params)) {
668 $this->parameters = $params;
669 } else {
670 $this->parameters = array();
671 }
672 }
673
674 public function removeParameter($name): void
675 {
676 unset($this->parameters[$name]);
677 }
678
679 public function clearParameters(): void
680 {
681 $this->parameters = array();
682 }
683
684 public function getParameters(): array
685 {
686 return $this->parameters;
687 }
688
689 public function isAutosaveable(): bool
690 {
691 return false;
692 }
693
694 // fau: testNav - new function getTestQuestionConfig()
699 // hey: refactored identifiers
701 // hey.
702 {
703 // hey: refactored identifiers
704 return parent::buildTestPresentationConfig()
705 // hey.
707 ->setBackgroundChangeDetectionEnabled(true);
708 }
709 // fau.
710}
$filename
Definition: buildRTE.php:78
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
setExportDetailsXLS(ilAssExcelFormatHelper $worksheet, int $startrow, int $active_id, int $pass)
{}
moveUploadedFile($tmpfile, $flashfile)
Uploads a flash file.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
saveToDb($original_id="")
Saves a assFlashQuestion object to a database.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
getAnswerTableName()
Returns the name of the answer table in the database.
isComplete()
Returns true, if a single choice question is complete for use.
fromXML($item, int $questionpool_id, ?int $tst_id, &$tst_object, int &$question_counter, array $import_mapping, array &$solutionhints=[])
Creates a question from a QTI file.
sendToHost($url, $data, $optional_headers=null)
getQuestionType()
Returns the question type of the question.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFlashQuestion constructor
duplicate(bool $for_test=true, string $title="", string $author="", string $owner="", $testObjId=null)
Duplicates an assFlashQuestion.
moveAppletIfExists()
Moves an applet file (maybe stored in the PHP session) to its final filesystem destination.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
copyApplet($question_id, $source_questionpool)
Copy the flash applet.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
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...
loadFromDb($question_id)
Loads a assFlashQuestion object from a database.
deleteAnswers($question_id)
Deletes datasets from answers tables.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
copyObject($target_questionpool_id, $title="")
Copies an assFlashQuestion object.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
duplicateApplet(int $question_id, $objectId=null)
buildTestPresentationConfig()
Get the test question configuration.
Abstract basic class which is to be extended by the concrete assessment question type classes.
float $points
The maximum available points for the question.
setOriginalId(?int $original_id)
string $question
The question text.
setId(int $id=-1)
setAdditionalContentEditingMode(?string $additionalContentEditingMode)
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
setQuestion(string $question="")
getFlashPath()
Returns the image path for web accessable flash files of a question.
getCurrentSolutionResultSet(int $active_id, int $pass, bool $authorized=true)
static _getOriginalId(int $question_id)
saveQuestionDataToDb(int $original_id=-1)
setAuthor(string $author="")
setComment(string $comment="")
setObjId(int $obj_id=0)
setSuggestedSolution(string $solution_id="", int $subquestion_index=0, bool $is_import=false)
Sets a suggested solution for the question.
getSolutionMaxPass(int $active_id)
setOwner(int $owner=-1)
setNrOfTries(int $a_nr_of_tries)
setLifecycle(ilAssQuestionLifecycle $lifecycle)
setTitle(string $title="")
setPoints(float $points)
ensureNonNegativePoints($points)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static rename(string $a_source, string $a_target)
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
static getRootLogger()
The unique root logger has a fixed error level.
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static get(string $a_var)
static clear(string $a_var)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setFormChangeDetectionEnabled($enableFormChangeDetection)
Set if the detection of form changes is enabled.
global $DIC
Definition: feed.php:28
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
Definition: ltiregstart.php:33
$path
Definition: ltiservices.php:32
if($format !==null) $name
Definition: metadata.php:247
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$url
$response