4require_once
'./Modules/TestQuestionPool/classes/class.assQuestion.php';
5require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
6require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
8require_once
'./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9require_once
'./Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
84 $this->answers = array();
96 strlen($this->title) &&
99 count($this->answers) &&
143 $this->
setId($question_id);
152 include_once(
"./Services/RTE/classes/class.ilRTE.php");
154 $this->ordering_type = strlen(
$data[
"ordering_type"]) ?
$data[
"ordering_type"] :
OQ_TERMS;
155 $this->thumb_geometry =
$data[
"thumb_geometry"];
156 $this->element_height =
$data[
"element_height"];
168 $result =
$ilDB->queryF(
"SELECT * FROM qpl_a_ordering WHERE question_fi = %s ORDER BY solution_order ASC",
173 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerOrdering.php";
178 include_once(
"./Services/RTE/classes/class.ilRTE.php");
183 parent::loadFromDb($question_id);
199 $this_id = $this->
getId();
203 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
207 if( (
int)$testObjId > 0 )
209 $clone->setObjId($testObjId);
234 $clone->copyPageOfQuestion($this_id);
236 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
238 $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
240 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
259 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
262 $source_questionpool_id = $this->
getObjId();
263 $clone->setObjId($target_questionpool_id);
276 $clone->copyImages(
$original_id, $source_questionpool_id);
278 $clone->onCopy($source_questionpool_id,
$original_id, $clone->getObjId(), $clone->getId());
291 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
294 $sourceParentId = $this->
getObjId();
300 $clone->setObjId($targetParentId);
302 if ($targetQuestionTitle)
304 $clone->setTitle($targetQuestionTitle);
309 $clone->copyPageOfQuestion($sourceQuestionId);
311 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
313 $clone->copyImages($sourceQuestionId, $sourceParentId);
315 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
320 function duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
325 $imagepath_original = $this->
getImagePath($src_question_id, $src_object_id);
326 $imagepath = $this->
getImagePath($dest_question_id, $dest_object_id);
328 if (!file_exists($imagepath)) {
331 foreach ($this->answers as $answer)
336 $ilLog->write(
"image could not be duplicated!!!!");
338 if (@file_exists($imagepath_original. $this->getThumbPrefix().
$filename))
342 $ilLog->write(
"image thumbnail could not be duplicated!!!!");
355 $imagepath_original = str_replace(
"/$this->id/images",
"/$question_id/images", $imagepath);
356 $imagepath_original = str_replace(
"/$this->obj_id/",
"/$source_questionpool/", $imagepath_original);
357 if (!file_exists($imagepath)) {
360 foreach ($this->answers as $answer)
365 $ilLog->write(
"Ordering Question image could not be copied: $imagepath_original$filename");
367 if (@file_exists($imagepath_original. $this->getThumbPrefix().
$filename))
371 $ilLog->write(
"Ordering Question image thumbnail could not be copied: $imagepath_original" . $this->
getThumbPrefix() . $filename);
416 function addAnswer($answertext =
"", $solution_order = -1 ,$depth = 0)
418 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerOrdering.php";
420 if (($solution_order >= 0) && ($solution_order < count($this->answers)))
422 $part1 = array_slice($this->answers, 0, $solution_order);
423 $part2 = array_slice($this->answers, $solution_order);
424 $this->answers = array_merge($part1, array($answer), $part2);
428 array_push($this->answers, $answer);
436 $temp = $this->answers[$position-1];
437 $this->answers[$position-1] = $this->answers[$position];
438 $this->answers[$position] = $temp;
444 if ($position < count($this->answers)-1)
446 $temp = $this->answers[$position+1];
447 $this->answers[$position+1] = $this->answers[$position];
448 $this->answers[$position] = $temp;
454 $random_number = mt_rand(1, 100000);
461 if ($answer->getRandomID() == $random_number)
468 return $random_number;
482 if ($index < 0)
return NULL;
483 if (count($this->answers) < 1)
return NULL;
484 if ($index >= count($this->answers))
return NULL;
485 return $this->answers[$index];
502 if (count($this->answers) < 1)
506 if ($index >= count($this->answers))
510 unset($this->answers[$index]);
511 $this->answers = array_values($this->answers);
512 for ($i = 0; $i < count($this->answers); $i++)
514 if ($this->answers[$i]->getOrder() > $index)
516 $this->answers[$i]->setOrder($i);
529 $this->answers = array();
541 return count($this->answers);
552 if (count($this->answers) == 0)
558 $max = $this->answers[0]->getSolutionOrder();
560 foreach ($this->answers as $key => $value)
562 if ($value->getSolutionOrder() > $max)
564 $max = $value->getSolutionOrder();
584 throw new ilTestException(
'return details not implemented for '.__METHOD__);
589 $found_value1 = array();
590 $found_value2 = array();
596 $user_order = array();
597 $nested_solution =
false;
600 if ((strcmp(
$data[
"value1"],
"") != 0) && (strcmp(
$data[
"value2"],
"") != 0))
602 if(strchr(
$data[
'value2'],
':') ==
true)
605 $current_solution = explode(
':',
$data[
'value2']);
607 $user_order[$current_solution[0]][
'index'] =
$data[
"value1"];
608 $user_order[$current_solution[0]][
'depth'] = $current_solution[1];
609 $user_order[$current_solution[0]][
'random_id'] = $current_solution[0];
611 $nested_solution =
true;
615 $user_order[
$data[
"value2"]] =
$data[
"value1"];
616 $nested_solution =
false;
628 $user_order = array();
629 $nested_solution =
false;
632 if ((strcmp($val1,
"") != 0) && (strcmp($val2,
"") != 0))
634 if(strchr( $val2,
':') ==
true)
636 $current_solution = explode(
':', $val2);
638 $user_order[$current_solution[0]][
'index'] = $val1;
639 $user_order[$current_solution[0]][
'depth'] = $current_solution[1];
640 $user_order[$current_solution[0]][
'random_id'] = $current_solution[0];
642 $nested_solution =
true;
646 $user_order[$val2] = $val1;
647 $nested_solution =
false;
677 if (preg_match(
"/.*\\.(\\w+)$/",
$filename, $matches))
679 $extension = $matches[1];
681 return md5(
$filename) .
"." . $extension;
691 foreach ($contents as $f)
693 if (strcmp($f[
'type'],
'file') == 0)
698 if (strcmp($f[
'entry'], $answer->getAnswertext()) == 0) $found =
true;
699 if (strcmp($f[
'entry'], $this->
getThumbPrefix() . $answer->getAnswertext()) == 0) $found =
true;
726 $deletename = $$filename;
740 function setImageFile($image_tempfilename, $image_filename, $previous_filename)
743 if (strlen($image_tempfilename))
745 $image_filename = str_replace(
" ",
"_", $image_filename);
747 if (!file_exists($imagepath))
751 $savename = $image_filename;
762 if (
$result && (strcmp($image_filename, $previous_filename) != 0) && (strlen($previous_filename)))
782 if (strlen(
$_POST[
"orderresult"]))
786 else if(strlen(
$_POST[
'answers_ordering']))
788 $answers_ordering =
$_POST[
'answers_ordering'];
789 $new_hierarchy = json_decode($answers_ordering);
790 $with_random_id =
true;
794 return serialize($this->leveled_ordering);
797 $order_values = array();
798 foreach (
$_POST as $key => $value)
800 if (preg_match(
"/^order_(\d+)/", $key, $matches))
802 if (strcmp($value,
"") != 0)
804 array_push($order_values, $value);
808 $check_order = array_flip($order_values);
809 if (count($check_order) != count($order_values))
829 if ($saveWorkingDataResult)
833 include_once
"./Modules/Test/classes/class.ilObjTest.php";
852 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
860 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
867 return $saveWorkingDataResult;
886 array( $this->
getId() )
889 $ilDB->manipulateF(
"INSERT INTO " . $this->
getAdditionalTableName() .
" (question_fi, ordering_type, thumb_geometry, element_height)
890 VALUES (%s, %s, %s, %s)",
891 array(
"integer",
"text",
"integer",
"integer" ),
894 $this->ordering_type,
906 $ilDB->manipulateF(
"DELETE FROM qpl_a_ordering WHERE question_fi = %s",
908 array( $this->
getId() )
911 foreach ($this->answers as $key => $value)
913 $answer_obj = $this->answers[$key];
914 $next_id =
$ilDB->nextId(
'qpl_a_ordering' );
915 $ilDB->insert(
'qpl_a_ordering',
917 'answer_id' => array(
'integer', $next_id ),
918 'question_fi' => array(
'integer', $this->
getId() ),
920 'answertext' => array(
'text', $answer_obj->getAnswertext()),
921 'solution_order' => array(
'integer', $key ),
922 'random_id' => array(
'integer', $answer_obj->getRandomID() ),
923 'tstamp' => array(
'integer', time() ),
924 'depth' => array(
'integer', $answer_obj->getOrderingDepth() )
957 return "assOrderingQuestion";
968 return "qpl_qst_ordering";
979 return "qpl_a_ordering";
988 $text = parent::getRTETextWithMediaObjects();
989 foreach ($this->answers as $index => $answer)
991 $answer_obj = $this->answers[$index];
992 $text .= $answer_obj->getAnswertext();
1035 include_once (
"./Services/Excel/classes/class.ilExcelUtils.php");
1038 foreach ($solutions as $solution)
1040 $sol[$solution[
"value1"]] = $solution[
"value2"];
1043 $sol = array_keys($sol);
1048 foreach ($sol as $idx)
1050 foreach ($solutions as $solution)
1057 return $startrow + $i + 1;
1082 $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1102 $this->element_height = ($a_height < 20) ?
"" : $a_height;
1132 switch (strtoupper($path_info[
'extension']))
1153 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1160 $result[
'shuffle'] = (bool)
true;
1163 'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false)),
1164 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true))
1175 $answers[$counter] = $answer_obj->getAnswertext();
1180 foreach (
$answers as $order => $answer)
1182 array_push($arr, array(
1183 "answertext" => (
string) $answer,
1184 "order" => (
int) $order
1197 $answer = $this->answers[$index];
1198 if (is_object($answer))
1201 $answer->setAnswertext(
'');
1209 $solutionSubmit = array();
1211 if(array_key_exists(
"orderresult",
$_POST))
1213 $orderresult =
$_POST[
"orderresult"];
1214 if(strlen($orderresult))
1216 $orderarray = explode(
":", $orderresult);
1218 foreach($orderarray as $index)
1221 if(preg_match(
"/id_(\\d+)/", $index, $idmatch))
1223 $randomid = $idmatch[1];
1224 foreach($this->
getAnswers() as $answeridx => $answer)
1226 if($answer->getRandomID() == $randomid)
1228 $solutionSubmit[$answeridx] = $ordervalue;
1238 $answers_ordering =
$_POST[
'answers_ordering__participant'];
1239 $user_solution_hierarchy = json_decode($answers_ordering);
1240 $with_random_id =
true;
1244 foreach($this->leveled_ordering as $random_id => $depth)
1246 $value_2 = implode(
':', array($random_id, $depth));
1247 $solutionSubmit[$index] = $value_2;
1253 foreach(
$_POST as $key => $value)
1256 if(preg_match(
"/^order_(\d+)/", $key, $matches))
1258 if(!(preg_match(
"/initial_value_\d+/", $value)))
1262 foreach($this->
getAnswers() as $answeridx => $answer)
1264 if($answer->getRandomID() == $matches[1])
1266 $solutionSubmit[$answeridx] = $value;
1275 return $solutionSubmit;
1288 $user_order = array_values($user_order);
1294 foreach($this->answers as $index => $answer)
1296 if($nested_solution ==
true)
1298 $random_id = $answer->getRandomID();
1300 if($random_id == $user_order[$random_id][
'random_id'] && $answer->getOrderingDepth() == $user_order[$random_id][
'depth'] && $index == $user_order[$random_id][
'index'])
1306 if($index == $user_order[$index])
1313 if($correctcount == count($this->answers))
1328 if($with_random_id ==
true)
1331 if(is_array($child->children))
1333 foreach($child->children as $grand_child)
1336 $this->leveled_ordering[$child->id] = $ordering_depth;
1343 $this->leveled_ordering[$child->id] = $ordering_depth;
1348 if(is_array($child->children))
1350 foreach($child->children as $grand_child)
1353 $this->leveled_ordering[] = $ordering_depth;
1360 $this->leveled_ordering[] = $ordering_depth;
1371 if($with_random_id ==
true)
1374 if(is_array($new_hierarchy))
1376 foreach($new_hierarchy as
$id)
1378 $ordering_depth = 0;
1379 $this->leveled_ordering[
$id->id] = $ordering_depth;
1381 if(is_array(
$id->children))
1383 foreach(
$id->children as $child)
1393 if(is_array($new_hierarchy))
1395 foreach($new_hierarchy as
$id)
1397 $ordering_depth = 0;
1398 $this->leveled_ordering[] = $ordering_depth;
1400 if(is_array(
$id->children))
1402 foreach(
$id->children as $child)
1420 $res =
$ilDB->queryF(
'SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY solution_order ASC',
1421 array(
'integer'), array($this->
getId()));
1422 while(
$row = $ilDB->fetchAssoc(
$res))
1424 $this->old_ordering_depth[] =
$row[
'depth'];
1437 $res =
$ilDB->queryF(
'SELECT solution_order FROM qpl_a_ordering WHERE random_id = %s',
1438 array(
'integer'), array($a_random_id));
1441 return $row[
'solution_order'];
1453 $res =
$ilDB->queryF(
'SELECT answertext FROM qpl_a_ordering WHERE random_id = %s AND question_fi = %s',
1454 array(
'integer',
'integer'), array($a_random_id, $a_question_id));
1457 return $row[
'answertext'];
1464 $ilDB->update(
'qpl_a_ordering',
1465 array(
'solution_order'=> array(
'integer', $a_index),
1466 'depth' => array(
'integer', $a_depth)),
1467 array(
'answertext' => array(
'text', $a_answer_text)));
1482 require_once
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1514 $maxStep = $this->lookupMaxStep($active_id,
$pass);
1516 if( $maxStep !==
null )
1519 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s ORDER BY value1 ASC ",
1520 array(
"integer",
"integer",
"integer",
"integer"),
1521 array($active_id,
$pass, $this->
getId(), $maxStep)
1527 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s ORDER BY value1 ASC ",
1528 array(
"integer",
"integer",
"integer"),
1533 $elements = array();
1537 $newKey = explode(
":",
$row[
"value2"]);
1539 foreach($this->
getAnswers() as $key => $answer)
1544 if($key ==
$row[
"value1"])
1546 $elements[$key] =
$row[
"value2"];
1552 if($answer->getRandomId() == $newKey[0])
1554 $elements[$key] =
$row[
"value1"];
1563 foreach(array_values($elements) as $element)
1565 $result->addKeyValue($element, $element);
1601 parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1602 $this->
duplicateImages($dupQuestionId, $dupParentObjId, $origQuestionId, $origParentObjId);
Class for ordering question answers.
Class for ordering questions.
getOperators($expression)
Get all available operations for a specific question.
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
getDepthRecursive($child, $ordering_depth, $with_random_id=false)
getAnswer($index=0)
Returns an ordering answer with a given index.
getExpressionTypes()
Get all available expression types for a specific question.
getQuestionType()
Returns the question type of the question.
setThumbGeometry($a_geometry)
copyImages($question_id, $source_questionpool)
getAnswerTableName()
Returns the name of the answer table in the database.
setLeveledOrdering($new_hierarchy, $with_random_id=false)
lookupAnswerTextByRandomId($a_random_id, $a_question_id)
toJSON()
Returns a JSON representation of the question.
& getAnswers()
Returns the answers array.
setOrderingType($ordering_type=OQ_TERMS)
Sets the ordering question type.
deleteImagefile($filename)
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
setImageFile($image_tempfilename, $image_filename, $previous_filename)
Sets the image file and uploads the image to the object's image directory.
flushAnswers()
Deletes all answers.
isComplete()
Returns true, if a ordering question is complete for use.
saveToDb($original_id="")
Saves a assOrderingQuestion object to a database.
setElementHeight($a_height)
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
Reworks the allready saved working data if neccessary.
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $ordering_type=OQ_TERMS)
assOrderingQuestion constructor
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
deleteAnswer($index=0)
Deletes an answer with a given index.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assOrderingQuestion.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getAdditionalTableName()
Returns the name of the additional question data table in the database.
getMaxSolutionOrder()
Returns the maximum solution order of all ordering answers.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
updateLeveledOrdering($a_index, $a_answer_text, $a_depth)
getOrderingType()
Returns the ordering question type.
loadFromDb($question_id)
Loads a assOrderingQuestion object from a database.
addAnswer($answertext="", $solution_order=-1, $depth=0)
Adds an answer for an ordering choice question.
getEncryptedFilename($filename)
lookupSolutionOrderByRandomid($a_random_id)
duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
{}
removeAnswerImage($index)
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
copyObject($target_questionpool_id, $title="")
Copies an assOrderingQuestion object.
generateThumbForFile($path, $file)
calculateReachedPointsForSolution($user_order, $nested_solution)
moveAnswerDown($position)
getAnswerCount()
Returns the number of answers.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass.
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
setId($id=-1)
Sets the id of the assQuestion object.
setOriginalId($original_id)
setObjId($obj_id=0)
Set the object id of the container object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
saveQuestionDataToDb($original_id="")
getId()
Gets the id of the assQuestion object.
getObjId()
Get the object id of the container object.
setTitle($title="")
Sets the title string of the assQuestion object.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
setAuthor($author="")
Sets the authors name of the assQuestion object.
getPoints()
Returns the maximum available points for the question.
getOutputType()
Gets the output type.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
removeCurrentSolution($active_id, $pass, $authorized=true, $ignoredSolutionIds=array())
getTitle()
Gets the title string of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
setNrOfTries($a_nr_of_tries)
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true)
setQuestion($question="")
Sets the question string of the question object.
getImagePathWeb()
Returns the web image path for web accessable images of a question.
getParticipantsSolution()
setParticipantsSolution($participantSolution)
_convert_text($a_text, $a_target="has been removed")
_getLogLanguage()
retrieve the log language for assessment logging
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static getOperatorsByExpression($expression)
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...
Base Exception for all Exceptions relating to Modules/Test.
Class ilUserQuestionResult.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getDir($a_dir, $a_rec=false, $a_sub_dir="")
get directory
static convertImage($a_from, $a_to, $a_target_format="", $a_geometry="", $a_background_color="")
convert image
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
const OQ_PICTURES
Ordering question constants.
Class iQuestionCondition.
const PercentageResultExpression
const OrderingResultExpression
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
const NumericResultExpression
const EmptyAnswerExpression
Interface ilObjAnswerScoringAdjustable.
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
Interface ilObjQuestionScoringAdjustable.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.