25 include_once
'./webservice/soap/classes/class.ilSoapAdministration.php';
36 $ilAccess = $DIC[
'ilAccess'];
38 $permission_ok =
false;
39 $result =
$ilDB->queryF(
40 "SELECT tst_tests.obj_fi FROM tst_active, tst_tests WHERE tst_active.active_id = %s AND tst_active.test_fi = tst_tests.test_id",
44 $row =
$ilDB->fetchAssoc($result);
46 $obj_id = $row[
'obj_fi'];
48 if ($ilAccess->checkAccess(
"write",
"", $ref_id)) {
49 $permission_ok =
true;
54 return $permission_ok;
57 public function isAllowedCall(
string $sid,
int $active_id,
bool $saveaction =
true): bool
64 $ilUser = $DIC[
'ilUser'];
71 $result =
$ilDB->queryF(
72 "SELECT * FROM tst_times WHERE active_fi = %s ORDER BY started DESC",
76 if ($result->numRows()) {
77 $row =
$ilDB->fetchAssoc($result);
78 if (preg_match(
"/(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})/", $row[
"started"], $matches)) {
79 $time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
85 $ilClientIniFile = $DIC[
'ilClientIniFile'];
86 $expires = $ilClientIniFile->readVariable(
'session',
'expire');
87 return $diff <= $expires;
96 $result =
$ilDB->queryF(
97 "SELECT user_fi FROM tst_active WHERE active_id = %s",
101 $row =
$ilDB->fetchAssoc($result);
103 return (
int) $row[
'user_fi'] === $ilUser->getId();
109 public function saveQuestion(
string $sid,
int $active_id,
int $question_id,
int $pass, array $solution)
118 return $this->
raiseError(
"The required user information is only available for active users.",
"");
123 $ilDB = $DIC[
'ilDB'];
124 $ilUser = $DIC[
'ilUser'];
126 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
128 $processLockerFactory->setQuestionId($question_id);
129 $processLockerFactory->setUserId($ilUser->getId());
130 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
132 $processLocker = $processLockerFactory->getLocker();
136 $processLocker->executePersistWorkingStateLockOperation(
function () use (
144 $processLocker->executeUserSolutionUpdateLockOperation(
function () use (
152 if (($active_id > 0) && ($question_id > 0) && ($pass > 0)) {
153 $affectedRows =
$ilDB->manipulateF(
154 "DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
155 array(
'integer',
'integer',
'integer'),
156 array($active_id, $question_id, $pass)
159 for ($i = 0, $iMax = count($solution); $i < $iMax; $i += 3) {
160 $next_id =
$ilDB->nextId(
'tst_solutions');
161 $affectedRows =
$ilDB->insert(
"tst_solutions", array(
162 "solution_id" => array(
"integer", $next_id),
163 "active_fi" => array(
"integer", $active_id),
164 "question_fi" => array(
"integer", $question_id),
165 "value1" => array(
"clob", $solution[$i]),
166 "value2" => array(
"clob", $solution[$i + 1]),
167 "points" => array(
"float", $solution[$i + 2]),
168 "pass" => array(
"integer", $pass),
169 "tstamp" => array(
"integer", time())
171 $totalrows += $affectedRows;
175 if ($totalrows !== 0) {
176 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
178 $question->setProcessLocker($processLocker);
179 $question->calculateResultsFromSolution($active_id, $pass);
183 if ($totalrows === 0) {
185 "Wrong solution data. ILIAS did not execute any database queries: Solution data: " . print_r(
207 return $this->
raiseError(
"The required user information is only available for active users.",
"");
211 if (preg_match(
"/<values>(.*?)<\/values>/is", $solution, $matches)) {
213 "/<value>(.*?)<\/value><value>(.*?)<\/value><points>(.*?)<\/points>/is",
218 foreach ($matches as $match) {
219 if (count($match) === 4) {
220 for ($i = 1, $iMax = count($match); $i < $iMax; $i++) {
221 $solutions[] = trim($match[$i]);
228 if (count($solutions) === 0) {
230 "Wrong solution data. ILIAS did not find one or more solution triplets: $solution",
236 if (($active_id > 0) && ($question_id > 0) && ($pass > 0)) {
237 $affectedRows =
$ilDB->manipulateF(
238 "DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
239 array(
'integer',
'integer',
'integer'),
240 array($active_id, $question_id, $pass)
244 for ($i = 0, $iMax = count($solutions); $i < $iMax; $i += 3) {
245 $next_id =
$ilDB->nextId(
'tst_solutions');
246 $affectedRows =
$ilDB->insert(
"tst_solutions", array(
247 "solution_id" => array(
"integer", $next_id),
248 "active_fi" => array(
"integer", $active_id),
249 "question_fi" => array(
"integer", $question_id),
250 "value1" => array(
"clob", $solutions[$i]),
251 "value2" => array(
"clob", $solutions[$i + 1]),
252 "points" => array(
"float", $solutions[$i + 2]),
253 "pass" => array(
"integer", $pass),
254 "tstamp" => array(
"integer", time())
256 $totalrows += $affectedRows;
258 if ($totalrows === 0) {
259 return $this->
raiseError(
"Wrong solution data. ILIAS did not execute any database queries",
'');
262 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
264 $question->calculateResultsFromSolution($active_id, $pass);
280 return $this->
raiseError(
"The required user information is only available for active users.",
"");
286 $ilDB = $DIC[
'ilDB'];
288 $use_previous_answers = 1;
290 $result =
$ilDB->queryF(
291 "SELECT tst_tests.use_previous_answers FROM tst_tests, tst_active WHERE tst_tests.test_id = tst_active.test_fi AND tst_active.active_id = %s",
295 if ($result->numRows()) {
296 $row =
$ilDB->fetchAssoc($result);
297 $use_previous_answers = $row[
"use_previous_answers"];
300 if ($use_previous_answers) {
301 $result =
$ilDB->queryF(
302 "SELECT MAX(pass) maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
303 array(
'integer',
'integer'),
304 array($active_id, $question_id)
306 if ($result->numRows() === 1) {
307 $row =
$ilDB->fetchAssoc($result);
308 $lastpass = (
int) $row[
"maxpass"];
314 if (($active_id > 0) && ($question_id > 0) && ($lastpass > 0)) {
315 $result =
$ilDB->queryF(
316 "SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
317 array(
'integer',
'integer',
'integer'),
318 array($active_id, $question_id, $lastpass)
320 if ($result->numRows()) {
321 while ($row =
$ilDB->fetchAssoc($result)) {
322 $solution[] = $row[
"value1"];
323 $solution[] = $row[
"value2"];
324 $solution[] = $row[
"points"];
343 return $this->
raiseError(
"The required user information is only available for active users.",
"");
349 $ilDB = $DIC[
'ilDB'];
351 $result =
$ilDB->queryF(
352 "SELECT user_fi, test_fi FROM tst_active WHERE active_id = %s",
356 $row =
$ilDB->fetchAssoc($result);
357 $user_id = $row[
"user_fi"];
358 $test_id = $row[
"test_fi"];
360 $result =
$ilDB->queryF(
361 "SELECT anonymity FROM tst_tests WHERE test_id = %s",
365 $row =
$ilDB->fetchAssoc($result);
366 $anonymity = $row[
"anonymity"];
368 $result =
$ilDB->queryF(
369 "SELECT firstname, lastname, title, login FROM usr_data WHERE usr_id = %s",
375 if ($result->numRows() === 0) {
376 $userdata[
"fullname"] =
$lng->txt(
"deleted_user");
377 $userdata[
"title"] =
"";
378 $userdata[
"firstname"] =
"";
379 $userdata[
"lastname"] =
$lng->txt(
"anonymous");
380 $userdata[
"login"] =
"";
384 $userdata[
"fullname"] =
$lng->txt(
"anonymous");
385 $userdata[
"title"] =
"";
386 $userdata[
"firstname"] =
"";
387 $userdata[
"lastname"] =
$lng->txt(
"anonymous");
388 $userdata[
"login"] =
"";
390 $userdata[
"fullname"] = trim(
$data[
"title"] .
" " .
$data[
"firstname"] .
" " .
$data[
"lastname"]);
391 $userdata[
"title"] = $data[
"title"];
392 $userdata[
"firstname"] = $data[
"firstname"];
393 $userdata[
"lastname"] = $data[
"lastname"];
394 $userdata[
"login"] = $data[
"login"];
397 return array_values($userdata);
412 return $this->
raiseError(
"The required user information is only available for active users.",
"");
418 $ilDB = $DIC[
'ilDB'];
419 $questioninfo = $DIC->testQuestionPool()->questionInfo();
421 $result =
$ilDB->queryF(
422 "SELECT tst_tests.random_test FROM tst_active, tst_tests WHERE tst_active.active_id = %s AND tst_tests.test_id = tst_active.test_fi",
426 if ($result->numRows() !== 1) {
429 $row =
$ilDB->fetchAssoc($result);
430 $is_random = $row[
"random_test"];
432 include_once
"./Modules/Test/classes/class.ilTestSequence.php";
434 return $sequence->getSequenceForQuestion($question_id);
449 return $this->
raiseError(
"The required user information is only available for active users.",
"");
455 $ilDB = $DIC[
'ilDB'];
456 $questioninfo = $DIC->testQuestionPool()->questionInfo();
458 $result =
$ilDB->queryF(
459 "SELECT tst_tests.random_test FROM tst_active, tst_tests WHERE tst_active.active_id = %s AND tst_tests.test_id = tst_active.test_fi",
463 if ($result->numRows() !== 1) {
466 $row =
$ilDB->fetchAssoc($result);
467 $is_random = $row[
"random_test"];
469 include_once
"./Modules/Test/classes/class.ilTestSequence.php";
471 $result =
$ilDB->queryF(
472 "SELECT question_fi, points FROM tst_test_result WHERE active_fi = %s AND pass = %s",
473 array(
'integer',
'integer'),
474 array($active_id, $pass)
476 $reachedpoints = array();
477 while ($row =
$ilDB->fetchAssoc($result)) {
478 $reachedpoints[$row[
"question_fi"]] = $row[
"points"];
481 $pointsforposition = array();
482 foreach ($sequence->getUserSequence() as $seq) {
484 $qid = $sequence->getQuestionForSequence($seq);
485 if ($qid == $question_id) {
488 $pointsforposition[] = $reachedpoints[$qid];
492 return $pointsforposition;
507 return $this->
raiseError(
"The required user information is only available for active users.",
"");
513 $ilDB = $DIC[
'ilDB'];
514 $questioninfo = $DIC->testQuestionPool()->questionInfo();
516 $result =
$ilDB->queryF(
517 "SELECT tst_tests.random_test FROM tst_active, tst_tests WHERE tst_active.active_id = %s AND tst_tests.test_id = tst_active.test_fi",
521 if ($result->numRows() !== 1) {
524 $row =
$ilDB->fetchAssoc($result);
525 $is_random = $row[
"random_test"];
527 include_once
"./Modules/Test/classes/class.ilTestSequence.php";
529 return $sequence->getUserQuestionCount();
543 if (!($test_ref_id > 0)) {
545 'No test id given. Aborting!',
551 $rbacsystem = $DIC[
'rbacsystem'];
552 $tree = $DIC[
'tree'];
553 $ilLog = $DIC[
'ilLog'];
556 return $this->
raiseError(
'no permission. Aborting!',
'Client');
561 'Test is trashed. Aborting!',
567 return $this->
raiseError(
'No test found for id: ' . $test_ref_id,
'Client');
569 if ($tst->getType() !==
'tst') {
571 'Object with ref_id ' . $test_ref_id .
' is not of type test. Aborting',
577 if (isset($a_user_ids[
'item'])) {
578 $a_user_ids = $a_user_ids[
'item'];
581 include_once
'./Modules/Test/classes/class.ilObjTest.php';
582 include_once
'./Modules/Test/classes/class.ilTestParticipantData.php';
583 require_once
'Modules/Test/classes/class.ilTestParticipantAccessFilter.php';
585 $part->setParticipantAccessFilter(
586 ilTestParticipantAccessFilter::getManageParticipantsUserFilter($test_ref_id)
588 $part->setUserIdsFilter((array) $a_user_ids);
589 $part->load($tst->getTestId());
590 $tst->removeTestResults($part);
606 if (!($test_ref_id > 0)) {
608 'No test id given. Aborting!',
614 $rbacsystem = $DIC[
'rbacsystem'];
615 $tree = $DIC[
'tree'];
616 $ilLog = $DIC[
'ilLog'];
620 'Test is trashed. Aborting!',
627 'No test found for id: ' . $test_ref_id,
632 $permission_ok =
false;
634 if ($rbacsystem->checkAccess(
'write', $ref_id)) {
635 $permission_ok =
true;
643 if (!$permission_ok) {
645 'No permission to edit the object with id: ' . $test_ref_id,
650 include_once
'./webservice/soap/classes/class.ilXMLResultSet.php';
651 include_once
'./webservice/soap/classes/class.ilXMLResultSetWriter.php';
654 $xmlResultSet->addColumn(
"user_id");
655 $xmlResultSet->addColumn(
"login");
656 $xmlResultSet->addColumn(
"firstname");
657 $xmlResultSet->addColumn(
"lastname");
658 $xmlResultSet->addColumn(
"matriculation");
660 include_once
'./Modules/Test/classes/class.ilObjTest.php';
661 $test_obj =
new ilObjTest($obj_id,
false);
662 $participants = $test_obj->getTestParticipants();
664 require_once
'Modules/Test/classes/class.ilTestParticipantAccessFilter.php';
665 require_once
'Modules/Test/classes/class.ilTestParticipantList.php';
666 $accessFilter = ilTestParticipantAccessFilter::getAccessResultsUserFilter($test_ref_id);
668 $participantList->initializeFromDbRows($participants);
669 $participantList = $participantList->getAccessFilteredList($accessFilter);
670 $participantList = $participantList->getScoredParticipantList();
671 foreach ($participants as $activeId => $part) {
672 if ($participantList->isActiveIdInList($activeId)) {
673 $participants[$activeId][
'passed'] = $participantList->getParticipantByActiveId($activeId)->getScoring()->isPassed();
677 unset($participants[$activeId]);
681 $data = $test_obj->getAllTestResults($participants,
false);
683 $xmlResultSet->addColumn(
"maximum_points");
684 $xmlResultSet->addColumn(
"received_points");
685 $xmlResultSet->addColumn(
"passed");
687 $titles = array_shift(
$data);
688 foreach (
$data as $row) {
690 $xmlRow->setValue(0, $row[
"user_id"]);
691 $xmlRow->setValue(1, $row[
"login"]);
692 $xmlRow->setValue(2, $row[
"firstname"]);
693 $xmlRow->setValue(3, $row[
"lastname"]);
694 $xmlRow->setValue(4, $row[
"matriculation"]);
695 $xmlRow->setValue(5, $row[
"max_points"]);
696 $xmlRow->setValue(6, $row[
"reached_points"]);
697 $xmlRow->setValue(7, $row[
"passed"]);
698 $xmlResultSet->addRow($xmlRow);
701 $data = $test_obj->getDetailedTestResults($participants);
703 $xmlResultSet->addColumn(
"question_id");
704 $xmlResultSet->addColumn(
"question_title");
705 $xmlResultSet->addColumn(
"maximum_points");
706 $xmlResultSet->addColumn(
"received_points");
707 $xmlResultSet->addColumn(
"passed");
708 foreach (
$data as $row) {
710 $xmlRow->setValue(0, $row[
"user_id"]);
711 $xmlRow->setValue(1, $row[
"login"]);
712 $xmlRow->setValue(2, $row[
"firstname"]);
713 $xmlRow->setValue(3, $row[
"lastname"]);
714 $xmlRow->setValue(4, $row[
"matriculation"]);
715 $xmlRow->setValue(5, $row[
"question_id"]);
716 $xmlRow->setValue(6, $row[
"question_title"]);
717 $xmlRow->setValue(7, $row[
"max_points"]);
718 $xmlRow->setValue(8, $row[
"reached_points"]);
719 $xmlRow->setValue(9, $row[
"passed"]);
720 $xmlResultSet->addRow($xmlRow);
726 return $xmlWriter->getXML();
731 return $this->
getTestAccess($refId)->checkManageParticipantsAccess();
736 return $this->
getTestAccess($refId)->checkParticipantsResultsAccess();
741 require_once
'Modules/Test/classes/class.ilTestAccess.php';
isAllowedCall(string $sid, int $active_id, bool $saveaction=true)
XML Writer for XMLResultSet.
getTestResults(string $sid, int $test_ref_id, bool $sum_only)
getQuestionSolution(string $sid, int $active_id, int $question_id, int $pass)
static _getAllReferences(int $id)
get all reference ids for object ID
raiseError(string $a_message, $a_code)
Row Class for XMLResultSet.
getTestAccess(int $refId)
saveQuestionSolution(string $sid, int $active_id, int $question_id, int $pass, int $solution)
removeTestResults(string $sid, int $test_ref_id, array $a_user_ids)
static instantiateQuestion(int $question_id)
static _enabledAssessmentLogging()
checkParticipantsResultsAccess(int $refId)
checkManageParticipantsAccess(int $refId)
getNrOfQuestionsInPass(string $sid, int $active_id, int $pass)
checkSession(string $sid)
static _isInTrash(int $ref_id)
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
static _lookupObjectId(int $ref_id)
static _getTestIDFromObjectID($object_id)
Returns the ILIAS test id for a given object id.
saveQuestion(string $sid, int $active_id, int $question_id, int $pass, array $solution)
hasWritePermissionForTest(int $active_id)
getPositionOfQuestion(string $sid, int $active_id, int $question_id, int $pass)
getPreviousReachedPoints(string $sid, int $active_id, int $question_id, int $pass)
getTestUserData(string $sid, int $active_id)