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';
84 $this->answers = array();
96 strlen($this->title) &&
99 count($this->answers) &&
142 $data = $ilDB->fetchAssoc(
$result);
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"];
157 $this->
setEstimatedWorkingTime(substr($data[
"working_time"], 0, 2), substr($data[
"working_time"], 3, 2), substr($data[
"working_time"], 6, 2));
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";
176 while ($data = $ilDB->fetchAssoc(
$result))
178 include_once(
"./Services/RTE/classes/class.ilRTE.php");
180 array_push($this->answers,
new ASS_AnswerOrdering($data[
"answertext"], $data[
"random_id"], $data[
'depth'] ? $data[
'depth'] : 0));
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)
334 if (!@copy($imagepath_original .
$filename, $imagepath . $filename))
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)
363 if (!@copy($imagepath_original .
$filename, $imagepath . $filename))
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();
595 $result = $this->getCurrentSolutionResultSet($active_id,
$pass);
596 $user_order = array();
597 $nested_solution =
false;
598 while ($data = $ilDB->fetchAssoc(
$result))
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;
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";
839 $affectedRows = $this->removeCurrentSolution($active_id,
$pass);
844 $this->saveCurrentSolution($active_id,
$pass, $val1, trim($val2));
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";
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'];
1452 $res = $ilDB->queryF(
'SELECT answertext FROM qpl_a_ordering WHERE random_id = %s',
1453 array(
'integer'), array($a_random_id));
1456 return $row[
'answertext'];
1463 $ilDB->update(
'qpl_a_ordering',
1464 array(
'solution_order'=> array(
'integer', $a_index),
1465 'depth' => array(
'integer', $a_depth)),
1466 array(
'answertext' => array(
'text', $a_answer_text)));
1481 require_once
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1513 $data = $ilDB->queryF(
1514 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = (
1515 SELECT MAX(step) FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s
1516 ) ORDER BY value1 ASC ",
1517 array(
"integer",
"integer",
"integer",
"integer",
"integer",
"integer"),
1522 $elements = array();
1523 while(
$row = $ilDB->fetchAssoc($data))
1526 $newKey = explode(
":",
$row[
"value2"]);
1528 foreach($this->
getAnswers() as $key => $answer)
1532 if($key ==
$row[
"value1"])
1534 $elements[$key] =
$row[
"value2"];
1540 if($answer->getRandomId() == $newKey[0])
1542 $elements[$key] =
$row[
"value1"];
1551 foreach(array_values($elements) as $element)
1553 $result->addKeyValue($element, $element);