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.ilObjAnswerScoringAdjustable.php';
8 require_once
'./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9 require_once
'./Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
10 require_once
'Modules/TestQuestionPool/interfaces/interface.ilAssSpecificFeedbackOptionLabelProvider.php';
116 $this->thumb_size = 150;
117 $this->answers = array();
119 $this->selectionLimit = null;
120 $this->feedback_setting = 0;
165 $this->ensureNoInvalidObligation($this->
getId());
176 if (strlen($answer->getImage())) {
202 switch (strtoupper($path_info[
'extension'])) {
225 $ilDB = $DIC[
'ilDB'];
235 $this->
setId($question_id);
244 include_once(
"./Services/RTE/classes/class.ilRTE.php");
250 $this->isSingleline = (
$data[
'allow_images']) ?
false :
true;
251 $this->lastChange =
$data[
'tstamp'];
253 $this->feedback_setting =
$data[
'feedback_setting'];
262 "SELECT * FROM qpl_a_mc WHERE question_fi = %s ORDER BY aorder ASC",
266 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.php";
270 if (!@file_exists($imagefilename)) {
271 $data[
"imagefile"] =
"";
273 include_once(
"./Services/RTE/classes/class.ilRTE.php");
279 parent::loadFromDb($question_id);
287 if ($this->
id <= 0) {
292 $this_id = $this->
getId();
296 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
300 if ((
int) $testObjId > 0) {
301 $clone->setObjId($testObjId);
322 $clone->copyPageOfQuestion($this_id);
324 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
326 $clone->duplicateImages($this_id, $thisObjId);
328 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
338 if ($this->
id <= 0) {
344 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
347 $source_questionpool_id = $this->
getObjId();
348 $clone->setObjId($target_questionpool_id);
358 $clone->copyImages(
$original_id, $source_questionpool_id);
360 $clone->onCopy($source_questionpool_id,
$original_id, $clone->getObjId(), $clone->getId());
367 if ($this->
id <= 0) {
372 include_once(
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
375 $sourceParentId = $this->
getObjId();
381 $clone->setObjId($targetParentId);
383 if ($targetQuestionTitle) {
384 $clone->setTitle($targetQuestionTitle);
389 $clone->copyPageOfQuestion($sourceQuestionId);
391 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
393 $clone->copyImages($sourceQuestionId, $sourceParentId);
395 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
439 $points_unchecked = 0.0,
443 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.php";
444 if (array_key_exists($order, $this->answers)) {
447 $newchoices = array();
448 for (
$i = 0;
$i < $order;
$i++) {
449 array_push($newchoices, $this->answers[
$i]);
451 array_push($newchoices, $answer);
452 for (
$i = $order;
$i < count($this->answers);
$i++) {
457 $this->answers = $newchoices;
461 array_push($this->answers, $answer);
473 return count($this->answers);
489 if (count($this->answers) < 1) {
492 if (
$index >= count($this->answers)) {
496 return $this->answers[
$index];
511 if (count($this->answers) < 1) {
514 if (
$index >= count($this->answers)) {
517 $answer = $this->answers[
$index];
518 if (strlen($answer->getImage())) {
521 unset($this->answers[
$index]);
522 $this->answers = array_values($this->answers);
523 for (
$i = 0;
$i < count($this->answers);
$i++) {
524 if ($this->answers[
$i]->getOrder() >
$index) {
525 $this->answers[
$i]->setOrder(
$i);
537 $this->answers = array();
549 foreach ($this->answers as
$key => $value) {
550 if ($value->getPoints() > $value->getPointsUnchecked()) {
551 $allpoints += $value->getPoints();
553 $allpoints += $value->getPointsUnchecked();
572 if ($returndetails) {
573 throw new ilTestException(
'return details not implemented for ' . __METHOD__);
577 $ilDB = $DIC[
'ilDB'];
579 $found_values = array();
580 if (is_null(
$pass)) {
585 if (strcmp(
$data[
"value1"],
"") != 0) {
586 array_push($found_values,
$data[
"value1"]);
601 $failureMsg = sprintf(
602 $this->lng->txt(
'ass_mc_sel_lim_exhausted_hint'),
617 if (!count($solutionSubmit) && !empty(
$_POST[
'tst_force_form_diff_input'])) {
636 $ilDB = $DIC[
'ilDB'];
638 if (is_null(
$pass)) {
639 include_once
"./Modules/Test/classes/class.ilObjTest.php";
645 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values, $active_id,
$pass, $authorized) {
650 foreach ($solutionSubmit as $value) {
651 if (strlen($value)) {
665 if ($entered_values) {
666 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
671 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
684 $ilDB = $DIC[
'ilDB'];
690 ) .
" WHERE question_fi = %s",
692 array( $this->
getId() )
696 $oldthumbsize =
$data[
'thumb_size'];
700 if (!$this->isSingleline) {
708 'shuffle' => array(
'text', $this->
getShuffle()),
709 'allow_images' => array(
'text', $this->isSingleline ? 0 : 1),
715 'question_fi' => array(
'integer', $this->
getId())
724 $ilDB = $DIC[
'ilDB'];
726 "DELETE FROM qpl_a_mc WHERE question_fi = %s",
728 array( $this->
getId() )
731 foreach ($this->answers as
$key => $value) {
732 $answer_obj = $this->answers[
$key];
733 $next_id =
$ilDB->nextId(
'qpl_a_mc');
735 "INSERT INTO qpl_a_mc (answer_id, question_fi, answertext, points, points_unchecked, aorder, imagefile, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
736 array(
'integer',
'integer',
'text',
'float',
'float',
'integer',
'text',
'integer' ),
741 $answer_obj->getPoints(),
742 $answer_obj->getPointsUnchecked(),
743 $answer_obj->getOrder(),
744 $answer_obj->getImage(),
756 parent::syncWithOriginal();
767 return "assMultipleChoice";
797 public function setImageFile($image_filename, $image_tempfilename =
"")
800 if (!empty($image_tempfilename)) {
801 $image_filename = str_replace(
" ",
"_", $image_filename);
803 if (!file_exists($imagepath)) {
806 if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath . $image_filename)) {
809 include_once
"./Services/MediaObjects/classes/class.ilObjMediaObject.php";
811 if (!preg_match(
"/^image/", $mimetype)) {
812 unlink($imagepath . $image_filename);
833 @unlink($imagepath . $image_filename);
834 $thumbpath = $imagepath . $this->
getThumbPrefix() . $image_filename;
838 public function duplicateImages($question_id, $objectId = null)
845 $imagepath_original = str_replace(
"/$this->id/images",
"/$question_id/images", $imagepath);
847 if ((
int) $objectId > 0) {
848 $imagepath_original = str_replace(
"/$this->obj_id/",
"/$objectId/", $imagepath_original);
851 foreach ($this->answers as $answer) {
854 if (!file_exists($imagepath)) {
858 if (file_exists($imagepath_original .
$filename)) {
859 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
861 "Could not clone source image '%s' to '%s' (srcQuestionId: %s|tgtQuestionId: %s|srcParentObjId: %s|tgtParentObjId: %s)",
862 $imagepath_original . $filename,
863 $imagepath . $filename,
872 if (file_exists($imagepath_original . $this->
getThumbPrefix() . $filename)) {
875 "Could not clone thumbnail source image '%s' to '%s' (srcQuestionId: %s|tgtQuestionId: %s|srcParentObjId: %s|tgtParentObjId: %s)",
889 public function copyImages($question_id, $source_questionpool)
894 $imagepath_original = str_replace(
"/$this->id/images",
"/$question_id/images", $imagepath);
895 $imagepath_original = str_replace(
"/$this->obj_id/",
"/$source_questionpool/", $imagepath_original);
896 foreach ($this->answers as $answer) {
899 if (!file_exists($imagepath)) {
902 if (!@copy($imagepath_original .
$filename, $imagepath . $filename)) {
903 $ilLog->write(
"image could not be duplicated!!!!",
$ilLog->ERROR);
904 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
906 if (@file_exists($imagepath_original . $this->
getThumbPrefix() . $filename)) {
908 $ilLog->write(
"image thumbnail could not be duplicated!!!!",
$ilLog->ERROR);
909 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
927 $originalObjId = parent::lookupParentObjId($this->
getOriginalId());
928 $imagepath_original = $this->
getImagePath($question_id, $originalObjId);
931 foreach ($this->answers as $answer) {
934 if (@file_exists($imagepath .
$filename)) {
935 if (!file_exists($imagepath)) {
938 if (!file_exists($imagepath_original)) {
941 if (!@copy($imagepath . $filename, $imagepath_original . $filename)) {
942 $ilLog->write(
"image could not be duplicated!!!!",
$ilLog->ERROR);
943 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
946 if (@file_exists($imagepath . $this->
getThumbPrefix() . $filename)) {
948 $ilLog->write(
"image thumbnail could not be duplicated!!!!",
$ilLog->ERROR);
949 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
961 $text = parent::getRTETextWithMediaObjects();
962 foreach ($this->answers as
$index => $answer) {
963 $text .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->
getId(), 0,
$index);
964 $answer_obj = $this->answers[
$index];
965 $text .= $answer_obj->getAnswertext();
983 parent::setExportDetailsXLS($worksheet, $startrow, $active_id,
$pass);
989 $worksheet->setCell($startrow +
$i, 0, $answer->getAnswertext());
990 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow +
$i));
992 foreach ($solution as $solutionvalue) {
993 if (
$id == $solutionvalue[
"value1"]) {
998 $worksheet->setCell($startrow +
$i, 1, 1);
1000 $worksheet->setCell($startrow +
$i, 1, 0);
1005 return $startrow +
$i + 1;
1015 $this->thumb_size = $a_size;
1034 require_once
'./Services/RTE/classes/class.ilRTE.php';
1044 'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false)),
1045 'allcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true))
1051 if ((
string) $answer_obj->getImage()) {
1054 array_push($answers, array(
1055 "answertext" => (
string) $this->
formatSAQuestion($answer_obj->getAnswertext()),
1056 "points_checked" => (
float) $answer_obj->getPointsChecked(),
1057 "points_unchecked" => (float) $answer_obj->getPointsUnchecked(),
1058 "order" => (int) $answer_obj->getOrder(),
1059 "image" => (string) $answer_obj->getImage(),
1061 $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), 0,
$key)
1080 $answer = $this->answers[
$index];
1081 if (is_object($answer)) {
1083 $answer->setImage(
'');
1092 $multilineAnswerSetting =
$ilUser->getPref(
"tst_multiline_answers");
1093 if ($multilineAnswerSetting != 1) {
1094 $multilineAnswerSetting = 0;
1096 return $multilineAnswerSetting;
1103 $ilUser->writePref(
"tst_multiline_answers", $a_setting);
1117 $this->feedback_setting = $a_feedback_setting;
1131 if ($this->feedback_setting) {
1140 return 'feedback_correct_sc_mc';
1158 return $numExistingSolutionRecords > 0;
1176 $ilDB = $DIC[
'ilDB'];
1179 SELECT SUM(points) points_for_checked_answers 1181 WHERE question_fi = %s AND points > 0 1188 return $row[
'points_for_checked_answers'] > 0;
1199 public function ensureNoInvalidObligation($questionId)
1203 $ilDB = $DIC[
'ilDB'];
1206 SELECT SUM(qpl_a_mc.points) points_for_checked_answers, 1209 FROM tst_test_question 1212 ON qpl_a_mc.question_fi = tst_test_question.question_fi 1214 WHERE tst_test_question.question_fi = %s 1215 AND tst_test_question.obligatory = 1 1217 GROUP BY test_question_id 1222 $updateTestQuestionIds = array();
1225 if (
$row[
'points_for_checked_answers'] <= 0) {
1226 $updateTestQuestionIds[] =
$row[
'test_question_id'];
1230 if (count($updateTestQuestionIds)) {
1231 $test_question_id__IN__updateTestQuestionIds =
$ilDB->in(
1233 $updateTestQuestionIds,
1239 UPDATE tst_test_question 1241 WHERE $test_question_id__IN__updateTestQuestionIds 1253 $solutionSubmit = array();
1255 if (preg_match(
"/^multiple_choice_result_(\d+)/",
$key)) {
1256 if (strlen($value)) {
1257 $solutionSubmit[] = $value;
1261 return $solutionSubmit;
1272 foreach ($this->answers as
$key => $answer) {
1273 if (in_array(
$key, $found_values)) {
1274 $points += $answer->getPoints();
1276 $points += $answer->getPointsUnchecked();
1280 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1282 if (($mc_scoring == 0) && (count($found_values) == 0)) {
1299 require_once
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1329 $ilDB = $DIC[
'ilDB'];
1332 $maxStep = $this->lookupMaxStep($active_id,
$pass);
1334 if ($maxStep !== null) {
1336 "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1337 array(
"integer",
"integer",
"integer",
"integer"),
1338 array($active_id,
$pass, $this->
getId(), $maxStep)
1342 "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1343 array(
"integer",
"integer",
"integer"),
1379 $config = parent::buildTestPresentationConfig();
1380 $config->setUseUnchangedAnswerLabel($this->lng->txt(
'tst_mc_label_none_above'));
flushAnswers()
Deletes all answers.
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
calculateReachedPointsForSolution($found_values, $active_id=0)
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getId()
Gets the id of the assQuestion object.
addAnswer( $answertext="", $points=0.0, $points_unchecked=0.0, $order=0, $answerimage="")
Adds a possible answer for a multiple choice question.
setLastChange($lastChange)
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
const PercentageResultExpression
toJSON()
Returns a JSON representation of the question.
Class iQuestionCondition.
generateThumbForFile($path, $file)
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
isComplete()
Returns true, if a multiple choice question is complete for use.
static getNumExistingSolutionRecords($activeId, $pass, $questionId)
returns the number of existing solution records for the given test active / pass and given question i...
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assMultipleChoiceQuestion.
copyObject($target_questionpool_id, $title="")
Copies an assMultipleChoice object.
const NumberOfResultExpression
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
const ExclusiveResultExpression
rebuildThumbnails()
Rebuild the thumbnail images with a new thumbnail size.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
Abstract basic class which is to be extended by the concrete assessment question type classes...
ASS_AnswerBinaryStateImage is a class for answers with a binary state indicator (checked/unchecked, set/unset) and an image file.
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
setSelectionLimit($selectionLimit)
setId($id=-1)
Sets the id of the assQuestion object.
getImagePathWeb()
Returns the web image path for web accessable images of a question.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
migrateToLmContent($content)
setOutputType($output_type=OUTPUT_ORDER)
Sets the output type of the assMultipleChoice object.
getQuestionType()
Returns the question type of the question.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setNrOfTries($a_nr_of_tries)
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
loadFromDb($question_id)
Loads a assMultipleChoice object from a database.
setShuffle($shuffle=true)
Sets the shuffle flag.
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...
Class for multiple choice tests.
getObjId()
Get the object id of the container object.
getSpecificFeedbackAllCorrectOptionLabel()
getShuffle()
Gets the shuffle flag.
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
Base Exception for all Exceptions relating to Modules/Test.
getMultilineAnswerSetting()
removeAnswerImage($index)
saveToDb($original_id="")
Saves a assMultipleChoice object to a database.
deleteAnswer($index=0)
Deletes an answer with a given index.
isAnswered($active_id, $pass=null)
returns boolean wether the question is answered during test pass or not
static _getLogLanguage()
retrieve the log language for assessment logging
setAuthor($author="")
Sets the authors name of the assQuestion object.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
foreach($_POST as $key=> $value) $res
Class ilUserQuestionResult.
getAnswerCount()
Returns the number of answers.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
getSpecificFeedbackSetting()
Gets the current feedback settings in effect for the question.
isForcedEmptySolution($solutionSubmit)
Interface ilObjAnswerScoringAdjustable.
getQuestion()
Gets the question string of the question object.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
static convertImage( $a_from, $a_to, $a_target_format="", $a_geometry="", $a_background_color="")
convert image
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $output_type=OUTPUT_ORDER)
assMultipleChoice constructor
syncImages()
Sync images of a MC question on synchronisation with the original question.
getOperators($expression)
Get all available operations for a specific question.
setIsSingleline($isSingleline)
getAnswer($index=0)
Returns an answer with a given index.
& getAnswers()
Returns a reference to the answers array.
setSpecificFeedbackSetting($a_feedback_setting)
Sets the feedback settings in effect for the question.
buildTestPresentationConfig()
deleteImage($image_filename)
Deletes an image file.
getExpressionTypes()
Get all available expression types for a specific question.
static getOperatorsByExpression($expression)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
setImageFile($image_filename, $image_tempfilename="")
Sets the image file and uploads the image to the object's image directory.
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
removeCurrentSolution($active_id, $pass, $authorized=true)
getAdditionalTableName()
Returns the name of the additional question data table in the database.
static _getMCScoring($active_id)
Gets the scoring type for multiple choice questions.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
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...
getAnswerTableName()
Returns the name of the answer table in the database.
getTitle()
Gets the title string of the assQuestion object.
getOutputType()
Gets the multiple choice output type which is either OUTPUT_ORDER (=0) or OUTPUT_RANDOM (=1)...
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
setComment($comment="")
Sets the comment string of the assQuestion object.
setMultilineAnswerSetting($a_setting=0)
copyImages($question_id, $source_questionpool)
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
const EmptyAnswerExpression