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';
82 $this->answers = array();
94 strlen($this->title) &&
97 count($this->answers) &&
140 $data = $ilDB->fetchAssoc(
$result);
141 $this->
setId($question_id);
150 include_once(
"./Services/RTE/classes/class.ilRTE.php");
152 $this->ordering_type = strlen($data[
"ordering_type"]) ? $data[
"ordering_type"] :
OQ_TERMS;
153 $this->thumb_geometry = $data[
"thumb_geometry"];
154 $this->element_height = $data[
"element_height"];
155 $this->
setEstimatedWorkingTime(substr($data[
"working_time"], 0, 2), substr($data[
"working_time"], 3, 2), substr($data[
"working_time"], 6, 2));
166 $result = $ilDB->queryF(
"SELECT * FROM qpl_a_ordering WHERE question_fi = %s ORDER BY solution_order ASC",
171 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerOrdering.php";
174 while ($data = $ilDB->fetchAssoc(
$result))
176 include_once(
"./Services/RTE/classes/class.ilRTE.php");
178 array_push($this->answers,
new ASS_AnswerOrdering($data[
"answertext"], $data[
"random_id"], $data[
'depth'] ? $data[
'depth'] : 0));
197 $this_id = $this->
getId();
201 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
205 if( (
int)$testObjId > 0 )
207 $clone->setObjId($testObjId);
232 $clone->copyPageOfQuestion($this_id);
234 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
236 $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
238 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
257 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
260 $source_questionpool_id = $this->
getObjId();
261 $clone->setObjId($target_questionpool_id);
274 $clone->copyImages(
$original_id, $source_questionpool_id);
276 $clone->onCopy($source_questionpool_id,
$original_id, $clone->getObjId(), $clone->getId());
289 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
292 $sourceParentId = $this->
getObjId();
298 $clone->setObjId($targetParentId);
300 if ($targetQuestionTitle)
302 $clone->setTitle($targetQuestionTitle);
307 $clone->copyPageOfQuestion($sourceQuestionId);
309 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
311 $clone->copyImages($sourceQuestionId, $sourceParentId);
313 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
318 function duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
323 $imagepath_original = $this->
getImagePath($src_question_id, $src_object_id);
324 $imagepath = $this->
getImagePath($dest_question_id, $dest_object_id);
326 if (!file_exists($imagepath)) {
329 foreach ($this->answers as $answer)
332 if (!@copy($imagepath_original .
$filename, $imagepath . $filename))
334 $ilLog->write(
"image could not be duplicated!!!!");
336 if (@file_exists($imagepath_original. $this->getThumbPrefix().
$filename))
340 $ilLog->write(
"image thumbnail could not be duplicated!!!!");
353 $imagepath_original = str_replace(
"/$this->id/images",
"/$question_id/images", $imagepath);
354 $imagepath_original = str_replace(
"/$this->obj_id/",
"/$source_questionpool/", $imagepath_original);
355 if (!file_exists($imagepath)) {
358 foreach ($this->answers as $answer)
361 if (!@copy($imagepath_original .
$filename, $imagepath . $filename))
363 $ilLog->write(
"Ordering Question image could not be copied: $imagepath_original$filename");
365 if (@file_exists($imagepath_original. $this->getThumbPrefix().
$filename))
369 $ilLog->write(
"Ordering Question image thumbnail could not be copied: $imagepath_original" . $this->
getThumbPrefix() . $filename);
414 function addAnswer($answertext =
"", $solution_order = -1 ,$depth = 0)
416 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerOrdering.php";
418 if (($solution_order >= 0) && ($solution_order < count($this->answers)))
420 $part1 = array_slice($this->answers, 0, $solution_order);
421 $part2 = array_slice($this->answers, $solution_order);
422 $this->answers = array_merge($part1, array($answer), $part2);
426 array_push($this->answers, $answer);
434 $temp = $this->answers[$position-1];
435 $this->answers[$position-1] = $this->answers[$position];
436 $this->answers[$position] = $temp;
442 if ($position < count($this->answers)-1)
444 $temp = $this->answers[$position+1];
445 $this->answers[$position+1] = $this->answers[$position];
446 $this->answers[$position] = $temp;
452 $random_number = mt_rand(1, 100000);
459 if ($answer->getRandomID() == $random_number)
466 return $random_number;
480 if ($index < 0)
return NULL;
481 if (count($this->answers) < 1)
return NULL;
482 if ($index >= count($this->answers))
return NULL;
483 return $this->answers[$index];
500 if (count($this->answers) < 1)
504 if ($index >= count($this->answers))
508 unset($this->answers[$index]);
509 $this->answers = array_values($this->answers);
510 for ($i = 0; $i < count($this->answers); $i++)
512 if ($this->answers[$i]->getOrder() > $index)
514 $this->answers[$i]->setOrder($i);
527 $this->answers = array();
539 return count($this->answers);
550 if (count($this->answers) == 0)
556 $max = $this->answers[0]->getSolutionOrder();
558 foreach ($this->answers as $key => $value)
560 if ($value->getSolutionOrder() > $max)
562 $max = $value->getSolutionOrder();
582 throw new ilTestException(
'return details not implemented for '.__METHOD__);
587 $found_value1 = array();
588 $found_value2 = array();
593 $result = $ilDB->queryF(
"SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
594 array(
'integer',
'integer',
'integer'),
597 $user_order = array();
598 $nested_solution =
false;
599 while ($data = $ilDB->fetchAssoc(
$result))
601 if ((strcmp($data[
"value1"],
"") != 0) && (strcmp($data[
"value2"],
"") != 0))
603 if(strchr( $data[
'value2'],
':') ==
true)
606 $current_solution = explode(
':', $data[
'value2']);
608 $user_order[$current_solution[0]][
'index'] = $data[
"value1"];
609 $user_order[$current_solution[0]][
'depth'] = $current_solution[1];
610 $user_order[$current_solution[0]][
'random_id'] = $current_solution[0];
612 $nested_solution =
true;
616 $user_order[$data[
"value2"]] = $data[
"value1"];
617 $nested_solution =
false;
626 $user_order = array_values($user_order);
632 foreach ($this->answers as $index => $answer)
634 if($nested_solution ==
true)
636 $random_id = $answer->getRandomID();
638 if($random_id == $user_order[$random_id][
'random_id']
639 && $answer->getOrderingDepth() == $user_order[$random_id][
'depth']
640 && $index == $user_order[$random_id][
'index'])
647 if ($index == $user_order[$index])
654 if ($correctcount == count($this->answers))
684 if (preg_match(
"/.*\\.(\\w+)$/",
$filename, $matches))
686 $extension = $matches[1];
688 return md5(
$filename) .
"." . $extension;
698 foreach ($contents as $f)
700 if (strcmp($f[
'type'],
'file') == 0)
705 if (strcmp($f[
'entry'], $answer->getAnswertext()) == 0) $found =
true;
706 if (strcmp($f[
'entry'], $this->
getThumbPrefix() . $answer->getAnswertext()) == 0) $found =
true;
747 function setImageFile($image_tempfilename, $image_filename, $previous_filename)
750 if (strlen($image_tempfilename))
752 $image_filename = str_replace(
" ",
"_", $image_filename);
754 if (!file_exists($imagepath))
758 $savename = $image_filename;
769 if (
$result && (strcmp($image_filename, $previous_filename) != 0) && (strlen($previous_filename)))
789 if (strlen(
$_POST[
"orderresult"]))
793 else if(strlen(
$_POST[
'answers_ordering']))
795 $answers_ordering =
$_POST[
'answers_ordering'];
796 $new_hierarchy = json_decode($answers_ordering);
797 $with_random_id =
true;
801 return serialize($this->leveled_ordering);
804 $order_values = array();
805 foreach (
$_POST as $key => $value)
807 if (preg_match(
"/^order_(\d+)/", $key, $matches))
809 if (strcmp($value,
"") != 0)
811 array_push($order_values, $value);
815 $check_order = array_flip($order_values);
816 if (count($check_order) != count($order_values))
840 if ($saveWorkingDataResult)
844 include_once
"./Modules/Test/classes/class.ilObjTest.php";
850 $affectedRows = $ilDB->manipulateF(
"DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
851 array(
'integer',
'integer',
'integer'),
854 if (array_key_exists(
"orderresult",
$_POST))
856 $orderresult =
$_POST[
"orderresult"];
857 if (strlen($orderresult))
859 $orderarray = explode(
":", $orderresult);
861 foreach ($orderarray as $index)
863 if (preg_match(
"/id_(\\d+)/", $index, $idmatch))
865 $randomid = $idmatch[1];
866 foreach ($this->
getAnswers() as $answeridx => $answer)
868 if ($answer->getRandomID() == $randomid)
870 $next_id = $ilDB->nextId(
'tst_solutions');
871 $affectedRows = $ilDB->insert(
"tst_solutions", array(
872 "solution_id" => array(
"integer", $next_id),
873 "active_fi" => array(
"integer", $active_id),
874 "question_fi" => array(
"integer", $this->
getId()),
875 "value1" => array(
"clob", $answeridx),
876 "value2" => array(
"clob", trim($ordervalue)),
877 "pass" => array(
"integer",
$pass),
878 "tstamp" => array(
"integer", time())
891 $answers_ordering =
$_POST[
'answers_ordering__participant'];
892 $user_solution_hierarchy = json_decode($answers_ordering);
893 $with_random_id =
true;
897 foreach($this->leveled_ordering as $random_id=>$depth)
899 $value_2 = implode(
':',array($random_id,$depth));
900 $next_id = $ilDB->nextId(
'tst_solutions');
902 $affectedRows = $ilDB->insert(
"tst_solutions", array(
903 "solution_id" => array(
"integer", $next_id),
904 "active_fi" => array(
"integer", $active_id),
905 "question_fi" => array(
"integer", $this->
getId()),
906 "value1" => array(
"clob", $index),
907 "value2" => array(
"clob", $value_2),
908 "pass" => array(
"integer",
$pass),
909 "tstamp" => array(
"integer", time())
917 foreach (
$_POST as $key => $value)
919 if (preg_match(
"/^order_(\d+)/", $key, $matches))
921 if (!(preg_match(
"/initial_value_\d+/", $value)))
925 foreach ($this->
getAnswers() as $answeridx => $answer)
927 if ($answer->getRandomID() == $matches[1])
929 $next_id = $ilDB->nextId(
'tst_solutions');
930 $affectedRows = $ilDB->insert(
"tst_solutions", array(
931 "solution_id" => array(
"integer", $next_id),
932 "active_fi" => array(
"integer", $active_id),
933 "question_fi" => array(
"integer", $this->
getId()),
934 "value1" => array(
"clob", $answeridx),
935 "value2" => array(
"clob", $value),
936 "pass" => array(
"integer",
$pass),
937 "tstamp" => array(
"integer", time())
952 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
960 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
967 return $saveWorkingDataResult;
978 array( $this->
getId() )
981 $ilDB->manipulateF(
"INSERT INTO " . $this->
getAdditionalTableName() .
" (question_fi, ordering_type, thumb_geometry, element_height)
982 VALUES (%s, %s, %s, %s)",
983 array(
"integer",
"text",
"integer",
"integer" ),
986 $this->ordering_type,
998 $ilDB->manipulateF(
"DELETE FROM qpl_a_ordering WHERE question_fi = %s",
1000 array( $this->
getId() )
1003 foreach ($this->answers as $key => $value)
1005 $answer_obj = $this->answers[$key];
1006 $next_id = $ilDB->nextId(
'qpl_a_ordering' );
1007 $ilDB->insert(
'qpl_a_ordering',
1009 'answer_id' => array(
'integer', $next_id ),
1010 'question_fi' => array(
'integer', $this->
getId() ),
1012 'answertext' => array(
'text', $answer_obj->getAnswertext()),
1013 'solution_order' => array(
'integer', $key ),
1014 'random_id' => array(
'integer', $answer_obj->getRandomID() ),
1015 'tstamp' => array(
'integer', time() ),
1016 'depth' => array(
'integer', $answer_obj->getOrderingDepth() )
1049 return "assOrderingQuestion";
1060 return "qpl_qst_ordering";
1071 return "qpl_a_ordering";
1081 foreach ($this->answers as $index => $answer)
1083 $answer_obj = $this->answers[$index];
1084 $text .= $answer_obj->getAnswertext();
1127 include_once (
"./Services/Excel/classes/class.ilExcelUtils.php");
1130 foreach ($solutions as $solution)
1132 $sol[$solution[
"value1"]] = $solution[
"value2"];
1135 $sol = array_keys($sol);
1140 foreach ($sol as $idx)
1142 foreach ($solutions as $solution)
1149 return $startrow + $i + 1;
1174 $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1194 $this->element_height = ($a_height < 20) ?
"" : $a_height;
1224 switch (strtoupper($path_info[
'extension']))
1245 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1252 $result[
'shuffle'] = (bool)
true;
1255 "onenotcorrect" => $this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false),
1256 "allcorrect" => $this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true)
1267 $answers[$counter] = $answer_obj->getAnswertext();
1272 foreach (
$answers as $order => $answer)
1274 array_push($arr, array(
1275 "answertext" => (
string) $answer,
1276 "order" => (
int) $order
1289 $answer = $this->answers[$index];
1290 if (is_object($answer))
1293 $answer->setAnswertext(
'');
1304 if($with_random_id ==
true)
1307 if(is_array($child->children))
1309 foreach($child->children as $grand_child)
1312 $this->leveled_ordering[$child->id] = $ordering_depth;
1319 $this->leveled_ordering[$child->id] = $ordering_depth;
1324 if(is_array($child->children))
1326 foreach($child->children as $grand_child)
1329 $this->leveled_ordering[] = $ordering_depth;
1336 $this->leveled_ordering[] = $ordering_depth;
1347 if($with_random_id ==
true)
1350 foreach($new_hierarchy as
$id)
1352 $ordering_depth = 0;
1353 $this->leveled_ordering[$id->id] = $ordering_depth;
1355 if(is_array($id->children))
1357 foreach($id->children as $child)
1366 foreach($new_hierarchy as
$id)
1368 $ordering_depth = 0;
1369 $this->leveled_ordering[] = $ordering_depth;
1371 if(is_array($id->children))
1373 foreach($id->children as $child)
1390 $res = $ilDB->queryF(
'SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY solution_order ASC',
1391 array(
'integer'), array($this->
getId()));
1392 while(
$row = $ilDB->fetchAssoc(
$res))
1394 $this->old_ordering_depth[] =
$row[
'depth'];
1407 $res = $ilDB->queryF(
'SELECT solution_order FROM qpl_a_ordering WHERE random_id = %s',
1408 array(
'integer'), array($a_random_id));
1411 return $row[
'solution_order'];
1422 $res = $ilDB->queryF(
'SELECT answertext FROM qpl_a_ordering WHERE random_id = %s',
1423 array(
'integer'), array($a_random_id));
1426 return $row[
'answertext'];
1433 $ilDB->update(
'qpl_a_ordering',
1434 array(
'solution_order'=> array(
'integer', $a_index),
1435 'depth' => array(
'integer', $a_depth)),
1436 array(
'answertext' => array(
'text', $a_answer_text)));