19 declare(strict_types=1);
21 require_once
'Modules/Test/classes/inc.AssessmentConstants.php';
35 return 'showManScoringByQuestionParticipantsTable';
40 return 'man_scoring_by_qst';
50 if (!$this->testAccess->checkScoreParticipantsAccess()) {
51 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'cannot_edit_test'),
true);
52 $this->
ctrl->redirectByClass(
'ilobjtestgui',
'infoScreen');
59 $mathJaxSetting =
new ilSetting(
'MathJax');
61 if ($mathJaxSetting->get(
"enable")) {
62 $this->tpl->addJavaScript($mathJaxSetting->get(
"path_to_mathjax"));
65 $this->tpl->addJavaScript(
"./Services/JavaScript/js/Basic.js");
66 $this->tpl->addJavaScript(
"./Services/Form/js/Form.js");
67 $this->tpl->addJavascript(
'./Services/UIComponent/Modal/js/Modal.js');
68 $this->
lng->toJSMap([
'answer' => $this->
lng->txt(
'answer')]);
72 $qst_id = (
int) $table->getFilterItemByPostVar(
'question')->getValue();
73 $passNr = $table->getFilterItemByPostVar(
'pass')->getValue();
74 $finalized_filter = $table->getFilterItemByPostVar(
'finalize_evaluation')->getValue();
75 $answered_filter = $table->getFilterItemByPostVar(
'only_answered')->getChecked();
77 $selected_questionData = null;
78 $complete_feedback = $this->
object->getCompleteManualFeedback($qst_id);
80 if (is_numeric($qst_id)) {
81 $info = $this->questioninfo->getQuestionInfo($qst_id);
82 $selected_questionData = $info;
85 if ($selected_questionData && is_numeric($passNr)) {
86 $data = $this->
object->getCompleteEvaluationData(
false);
87 $participants =
$data->getParticipants();
91 $this->participant_access_filter->getScoreParticipantsUserFilter($this->ref_id)
96 $participant = $participants[$active_id];
97 $testResultData = $this->
object->getTestResult($active_id, $passNr - 1);
99 foreach ($testResultData as $questionData) {
101 $is_answered = (bool) ($questionData[
'answered'] ??
false);
102 $finalized_evaluation = (bool) ($questionData[
'finalized_evaluation'] ??
false);
104 if (isset($complete_feedback[$active_id][$passNr - 1][$qst_id])) {
105 $feedback = $complete_feedback[$active_id][$passNr - 1][$qst_id];
108 if (!isset($questionData[
'qid'])
109 || $questionData[
'qid'] !== $selected_questionData[
'question_id']
110 || $finalized_filter === self::ONLY_FINALIZED && !$finalized_evaluation
111 || $finalized_filter === self::EXCEPT_FINALIZED && $finalized_evaluation
112 || $answered_filter ===
true && !$is_answered) {
117 'pass_id' => $passNr - 1,
118 'active_id' => $active_id,
119 'qst_id' => $questionData[
'qid'],
122 (
int) $questionData[
'qid'],
125 'maximum_points' => $this->questioninfo->getMaximumPoints((
int) $questionData[
'qid']),
126 'name' => $participant->getName()
131 $table->disable(
'header');
134 $table->setTitle($this->
lng->txt(
'tst_man_scoring_by_qst'));
136 if ($selected_questionData) {
137 $maxpoints = $this->questioninfo->getMaximumPoints((
int) $selected_questionData[
'question_id']);
138 $table->setCurQuestionMaxPoints($maxpoints);
139 $maxpoints_txt =
' (' . $maxpoints .
' ' . $this->
lng->txt(
'points') .
')';
140 if ($maxpoints == 1) {
141 $maxpoints_txt =
' (' . $maxpoints .
' ' . $this->
lng->txt(
'point') .
')';
145 $this->
lng->txt(
'tst_man_scoring_by_qst') .
': ' . $selected_questionData[
'title'] . $maxpoints_txt .
146 ' [' . $this->
lng->txt(
'question_id_short') .
': ' . $selected_questionData[
'question_id'] .
']' 150 $table->setData($table_data);
151 $this->tpl->setContent($table->getHTML());
156 $transform_scoring = $this->
refinery->custom()->transformation(
function ($value) use (&$transform_scoring) {
157 if (is_array($value)) {
158 foreach ($value as
$key => $val) {
159 $value[
$key] = $transform_scoring->transform($val);
161 } elseif (is_string($value)) {
162 $value = $this->
refinery->byTrying([
163 $this->
refinery->kindlyTo()->float(),
165 ])->transform($value);
167 throw new \ILIAS\Refinery\ConstraintViolationException(
168 sprintf(
'The value "%s" is no array or string.', var_export($value,
true)),
169 'value_is_no_array_or_string',
170 var_export($value,
true)
177 $transform_finalization = $this->
refinery->custom()->transformation(
178 function ($value) use (&$transform_finalization) {
179 if (is_array($value)) {
180 foreach ($value as
$key => $val) {
181 $value[
$key] = $transform_finalization->transform($val);
183 } elseif (is_string($value)) {
184 $value = $this->
refinery->byTrying([
185 $this->
refinery->kindlyTo()->bool(),
187 ])->transform($value);
189 throw new \ILIAS\Refinery\ConstraintViolationException(
190 sprintf(
'The value "%s" is no array or string.', var_export($value,
true)),
191 'value_is_no_array_or_string',
192 var_export($value,
true)
200 $scoring = $this->
http->wrapper()->post()->retrieve(
204 $this->refinery->always([])
207 $finalization = $this->
http->wrapper()->post()->retrieve(
210 $transform_finalization,
211 $this->refinery->always([])
215 $pass = key($scoring);
216 $active_data = current($scoring);
217 $active_ids = array_keys($active_data);
219 if (!$this->testAccess->checkScoreParticipantsAccessForActiveId(current($active_ids))) {
221 $this->
http->saveResponse(
222 $this->
http->response()->withBody(
226 $this->
http->sendResponse();
227 $this->
http->close();
230 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'cannot_edit_test'),
true);
231 $this->
ctrl->redirectByClass(
'ilobjtestgui',
'infoScreen');
234 if ($scoring === []) {
235 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'tst_save_manscoring_failed_unknown'));
242 $maxPointsByQuestionId = [];
246 $this->participant_access_filter->getScoreParticipantsUserFilter($this->ref_id)
250 $changed_one =
false;
251 $lastAndHopefullyCurrentQuestionId = null;
254 $questions = $active_data[$active_id];
255 if (!is_array($questions)) {
260 if (!$this->
object->getTestResult($active_id, $pass)) {
264 $update_participant =
false;
267 foreach ($questions as $qst_id => $reached_points_string) {
268 $reached_points = $this->
refinery->kindlyTo()->float()
269 ->transform($reached_points_string);
270 if (!isset($manPointsPost[$pass])) {
271 $manPointsPost[$pass] = [];
273 if (!isset($manPointsPost[$pass][$active_id])) {
274 $manPointsPost[$pass][$active_id] = [];
286 if (isset($current_feedback_info[
'finalized_evaluation']) && $current_feedback_info[
'finalized_evaluation'] === 1) {
288 $feedback_text = $current_feedback_info[
'feedback'];
291 $maxPointsByQuestionId[$qst_id] = $this->questioninfo->getMaximumPoints($qst_id);
292 $manPointsPost[$pass][$active_id][$qst_id] = $reached_points;
293 if ($reached_points > $maxPointsByQuestionId[$qst_id]) {
294 $this->tpl->setOnScreenMessage(
296 sprintf($this->
lng->txt(
'tst_save_manscoring_failed'), $pass + 1),
314 if ($reached_points !== $old_points) {
319 $maxPointsByQuestionId[$qst_id],
322 $this->
object->areObligationsEnabled(),
328 if ($update_participant) {
336 $lastAndHopefullyCurrentQuestionId = $qst_id;
339 $correction_feedback = [];
340 $correction_points = 0;
345 if ($lastAndHopefullyCurrentQuestionId) {
347 $qTitle = $question->getTitleForHTMLOutput();
351 $this->
lng->txt(
'tst_saved_manscoring_by_question_successfully'),
356 $this->tpl->setOnScreenMessage(
'success', $msg,
true);
358 if (isset($active_id) && $lastAndHopefullyCurrentQuestionId) {
361 $lastAndHopefullyCurrentQuestionId,
366 $lastAndHopefullyCurrentQuestionId,
372 if ($ajax && is_array($correction_feedback)) {
373 $finalized_by_usr_id = $correction_feedback[
'finalized_by_usr_id'];
374 if (!$finalized_by_usr_id) {
375 $finalized_by_usr_id = $this->
user->getId();
378 $correction_feedback[
'finalized_on_date'] =
'';
380 if (is_int($correction_feedback[
'finalized_tstamp'])) {
382 $correction_feedback[
'finalized_on_date'] = $time->get(
IL_CAL_DATETIME);
385 if (!$correction_feedback[
'feedback']) {
386 $correction_feedback[
'feedback'] = [];
388 if ($correction_feedback[
'finalized_evaluation'] == 1) {
389 $correction_feedback[
'finalized_evaluation'] = $this->
lng->txt(
'yes');
391 $correction_feedback[
'finalized_evaluation'] = $this->
lng->txt(
'no');
392 $correction_feedback[
'finalized_by'] =
'';
395 $this->
http->saveResponse(
396 $this->
http->response()->withBody(
400 'feedback' => $correction_feedback,
401 'points' => $correction_points,
403 'yes' => $this->
lng->txt(
'yes'),
404 'no' => $this->
lng->txt(
'no')
412 $this->
http->sendResponse();
413 $this->
http->close();
422 $table->resetOffset();
423 $table->writeFilterToSession();
430 $table->resetOffset();
431 $table->resetFilter();
437 $active_id = $this->testrequest->getActiveId();
438 $pass = $this->testrequest->getPassId();
439 $question_id = (
int) $this->testrequest->raw(
'qst_id');
441 if (!$this->
getTestAccess()->checkScoreParticipantsAccessForActiveId($active_id)) {
442 $this->
http->close();
445 $data = $this->
object->getCompleteEvaluationData(
false);
446 $participant =
$data->getParticipant($active_id);
447 $question_gui = $this->
object->createQuestionGUI(
'', $question_id);
448 $tmp_tpl =
new ilTemplate(
'tpl.il_as_tst_correct_solution_output.html',
true,
true,
'Modules/Test');
449 if ($this->
object->getAutosave()) {
450 $aresult_output = $question_gui->getAutoSavedSolutionOutput(
456 $this->
object->getShowSolutionFeedback(),
461 if ($aresult_output) {
462 $tmp_tpl->setVariable(
'TEXT_ASOLUTION_OUTPUT', $this->
lng->txt(
'autosavecontent'));
463 $tmp_tpl->setVariable(
'ASOLUTION_OUTPUT', $aresult_output);
466 $result_output = $question_gui->getSolutionOutput(
472 $this->
object->getShowSolutionFeedback(),
476 $max_points = $question_gui->object->getMaximumPoints();
483 $question_gui->object->getReachedPoints($active_id, $pass),
486 $this->
appendFormToModal($tmp_tpl, $pass, $active_id, $question_id, $max_points);
487 $tmp_tpl->setVariable(
'TEXT_YOUR_SOLUTION', $this->
lng->txt(
'answers_of') .
' ' . $participant->getName());
489 if ($this->
object->getShowSolutionSuggested() && strlen($suggested_solution) > 0) {
490 $tmp_tpl->setVariable(
'TEXT_SOLUTION_HINT', $this->
lng->txt(
"solution_hint"));
494 $tmp_tpl->setVariable(
'TEXT_SOLUTION_OUTPUT', $this->
lng->txt(
'question'));
495 $tmp_tpl->setVariable(
'TEXT_RECEIVED_POINTS', $this->
lng->txt(
'scoring'));
496 $add_title =
' [' . $this->
lng->txt(
'question_id_short') .
': ' . $question_id .
']';
497 $question_title = $this->
object->getQuestionTitle($question_gui->object->getTitleForHTMLOutput());
498 $lng = $this->
lng->txt(
'points');
499 if ($max_points == 1) {
500 $lng = $this->
lng->txt(
'point');
503 $tmp_tpl->setVariable(
505 $question_title .
' (' . $max_points .
' ' .
$lng .
')' . $add_title
507 $tmp_tpl->setVariable(
'SOLUTION_OUTPUT', $result_output);
509 $tmp_tpl->setVariable(
512 $this->
lng->txt(
'part_received_a_of_b_points'),
513 $question_gui->object->getReachedPoints($active_id, $pass),
518 $this->
http->saveResponse(
519 $this->
http->response()->withBody(
521 )->withHeader(\
ILIAS\
HTTP\Response\ResponseHeader::CONTENT_TYPE,
'text/html')
523 $this->
http->sendResponse();
524 $this->
http->close();
535 'TEXT_YOUR_SOLUTION',
536 $this->
lng->txt(
'answers_of') .
' ' . $participant_data->
getName()
540 $this->
object->getAnonymity() == 1 ||
541 ($this->
object->getAnonymity() == 2 && !$this->
access->checkAccess(
'write',
'', $this->
object->getRefId()))
544 'TEXT_YOUR_SOLUTION',
545 $this->
lng->txt(
'answers_of') .
' ' . $this->
lng->txt(
'anonymous')
552 $add_title =
' [' . $this->
lng->txt(
'question_id_short') .
': ' . $question_id .
']';
553 $question_title = $this->
object->getQuestionTitle($title);
554 $lng = $this->
lng->txt(
'points');
555 if ($max_points == 1) {
556 $lng = $this->
lng->txt(
'point');
561 $question_title .
' (' . $max_points .
' ' .
$lng .
')' . $add_title
567 $post_var =
'[' . $pass .
'][' . $active_id .
'][' . $question_id .
']';
568 $scoring_post_var =
'scoring' . $post_var;
573 $form->setFormAction($this->
ctrl->getFormAction($this,
'showManScoringByQuestionParticipantsTable'));
574 $form->setTitle($this->
lng->txt(
'manscoring'));
576 if (isset($feedback[
'finalized_evaluation']) && $feedback[
'finalized_evaluation'] == 1) {
579 $scoring_post_var = $scoring_post_var .
'_disabled';
580 $hidden_points->setValue((
string) $reached_points);
581 $form->addItem($hidden_points);
585 if (array_key_exists(
'feedback', $feedback)) {
586 $feedback_text = $feedback[
'feedback'];
591 $this->
lng->txt(
'set_manual_feedback'),
592 'm_feedback' . $post_var,
597 $feedback_input =
new ilTextAreaInputGUI($this->
lng->txt(
'set_manual_feedback'),
'm_feedback' . $post_var);
599 $feedback_input->
setValue($feedback_text);
600 $form->addItem($feedback_input);
603 $this->
lng->txt(
'tst_change_points_for_question'),
606 $reached_points_form->allowDecimals(
true);
607 $reached_points_form->setSize(5);
608 $reached_points_form->setMaxValue($max_points,
true);
609 $reached_points_form->setMinValue(0);
610 $reached_points_form->setDisabled($disable);
611 $reached_points_form->setValue((
string) $reached_points);
612 $reached_points_form->setClientSideValidation(
true);
613 $form->addItem($reached_points_form);
616 $hidden_points->setValue((
string) $max_points);
617 $form->addItem($hidden_points);
620 $hidden_points_name->setValue(
'scoring' . $post_var);
621 $form->addItem($hidden_points_name);
624 $hidden_feedback_name->setValue(
'm_feedback' . $post_var);
625 $form->addItem($hidden_feedback_name);
628 $post_id =
'__' . $pass .
'____' . $active_id .
'____' . $question_id .
'__';
629 $hidden_feedback_id->setValue(
'm_feedback' . $post_id);
630 $form->addItem($hidden_feedback_id);
632 $evaluated =
new ilCheckboxInputGUI($this->
lng->txt(
'finalized_evaluation'),
'evaluated' . $post_var);
633 if (isset($feedback[
'finalized_evaluation']) && (
int) $feedback[
'finalized_evaluation'] === 1) {
634 $evaluated->setChecked(
true);
636 $form->addItem($evaluated);
638 $form->addCommandButton(
'checkConstraintsBeforeSaving', $this->
lng->txt(
'save'));
646 $this->
ctrl->getLinkTarget($this,
'checkConstraintsBeforeSaving',
'',
true,
false)
649 'INFO_TEXT_MAX_POINTS_EXCEEDS',
650 sprintf($this->
lng->txt(
'tst_manscoring_maxpoints_exceeded_input_alert'), $max_points)
673 $this->
lng->txt(
'part_received_a_of_b_points'),
682 $feedback = $this->testrequest->raw(
'feedback');
683 if ($feedback === null || $feedback ===
'') {
684 $feedback = $this->testrequest->raw(
'm_feedback');
687 if ($feedback === null || $feedback ===
'') {
692 $feedback[$pass][$active_id][$qst_id],
707 bool $is_single_feedback
711 $finalized = $finalization[$pass][$active_id][$qst_id] ??
false;
714 $this->
object->saveManualFeedback(
729 return isset($finalization[$pass][$active_id][$qst_id]);
static _getParticipantId($active_id)
Get user id for active id.
static _getRichTextEditor()
Returns the identifier for the Rich Text Editor.
static _getSuggestedSolutionOutput(int $question_id)
ilTestManScoringParticipantsBySelectedQuestionAndPassTableGUI
static _lookupFullname(int $a_user_id)
Class ChatMainBarProvider .
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
const TAB_ID_MANUAL_SCORING
appendQuestionTitleToModal(ilTemplate $tmp_tpl, int $question_id, float $max_points, string $title)
appendSolutionAndPointsToModal(ilTemplate $tmp_tpl, $result_output, $reached_points, $max_points)
applyManScoringByQuestionFilter()
setValue(string $a_value)
static instantiateQuestion(int $question_id)
static getSingleManualFeedback(int $active_id, int $question_id, int $pass)
setParticipantAccessFilter(Closure $participantAccessFilter)
static http()
Fetches the global http state from ILIAS.
setVariable($variable, $value='')
Sets a variable value.
appendFormToModal(ilTemplate $tmp_tpl, int $pass, int $active_id, int $question_id, float $max_points)
setActiveIdsFilter(array $active_ids_filter)
static _getReachedPoints(int $active_id, int $question_id, int $pass)
static _getUsedHTMLTagsAsString(string $a_module="")
Returns a string of all allowed HTML tags for text editing.
doesValueExistsInPostArray(array $finalization, int $active_id, int $qst_id, int $pass)
checkConstraintsBeforeSaving()
resetManScoringByQuestionFilter()
appendUserNameToModal(ilTemplate $tmp_tpl, ilTestEvaluationUserData $participant_data)
ilTestParticipantData $participantData
static initjQuery(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
This class represents a text area property in a property form.
showManScoringByQuestionParticipantsTable(array $manPointsPost=[])
__construct(ilObjTest $a_object)
static _setReachedPoints(int $active_id, int $question_id, float $points, float $maxpoints, int $pass, bool $manualscoring, bool $obligationsEnabled, ?int $test_id=null)
Sets the points, a learner has reached answering the question Additionally objective results are upda...
retrieveFeedback(int $active_id, int $qst_id, int $pass)
saveFinalization(array $finalization, int $active_id, int $qst_id, int $pass, ?string $feedback, bool $is_single_feedback)
static initPanel(bool $a_resize=false, ?ilGlobalTemplateInterface $a_main_tpl=null)
Init yui panel used in Modules/Test, Services/TermsOfService (Jan 2022)
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
static initOverlay(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Overlay module used in Modules/Test, Services/TermsOfService, Services/Tracking, Services/UIComponent.
saveManScoringByQuestion(bool $ajax=false)