19 declare(strict_types=1);
36 private const CMD_SHOW =
'showManScoringByQuestionParticipantsTable';
37 private const CMD_SAVE =
'saveManScoringByQuestion';
48 $this->
lng->loadLanguageModule(
'form');
50 $this->
ctrl->saveParameterByClass(self::class,
'q_id');
51 $uri = ILIAS_HTTP_PATH .
'/' . $this->
ctrl->getLinkTargetByClass(
52 [\ilObjTestGUI::class, self::class],
55 $this->
ctrl->clearParameterByClass(self::class,
'q_id');
62 $this->action_parameter_token,
65 [
'manual_scoring',
'by_question'],
73 return self::CMD_SHOW;
78 return 'man_scoring_by_qst';
88 $globally_enabled = $this->
object->getGlobalSettings()->isManualScoringEnabled();
89 $access_granted = $this->test_access->checkScoreParticipantsAccess()
90 || $this->test_access->checkScoreParticipantsAccessAnon();
91 if (!($globally_enabled && $access_granted)) {
92 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'cannot_edit_test'),
true);
93 $this->
ctrl->redirectByClass([\ilRepositoryGUI::class, \ilObjTestGUI::class, \ilInfoScreenGUI::class]);
96 $test_question_properties = $this->testquestionsrepository
97 ->getQuestionPropertiesForTest($this->
object);
99 if ($test_question_properties === []) {
100 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'manscoring_questions_not_found'));
105 $this->ui_factory->dropdown()->standard(
108 $this->
lng->txt(
'select_question')
112 $question_id = $this->testrequest->getQuestionId();
113 if ($question_id === 0) {
114 $question_id = reset($test_question_properties)->getQuestionId();
120 $this->action_parameter_token,
126 $affected_rows = $this->testrequest->raw($this->row_id_token->getName());
133 $this->
user->getDateTimeFormat(),
134 $this->
http->request(),
136 $this->
ctrl->getLinkTargetByClass(
137 [\ilObjTestGUI::class, self::class],
143 $this->participant_access_filter,
147 $this->
object->getAnonymity() || !$this->test_access->checkScoreParticipantsAccess(),
151 if ($modal !==
null) {
152 $content[] = $modal->withOnLoad($modal->getShowSignal());
155 $this->tpl->setContent($this->ui_renderer->render($content));
160 $active_id = $this->testrequest->getActiveId();
161 $question_id = $this->testrequest->getQuestionId();
162 $attempt = $this->testrequest->getPassId();
163 if ($active_id === 0 || $question_id === 0
164 || !$this->test_access->checkScoreParticipantsAccessForActiveId($active_id, $this->object->getTestId())) {
165 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'cannot_edit_test'),
true);
166 $this->
ctrl->redirectByClass(\ilObjTestGUI::class);
169 $question_gui = $this->
object->createQuestionGUI(
'', $question_id);
170 $previously_reached_points = $question_gui->getObject()->getReachedPoints($active_id, $attempt);
171 $available_points = $question_gui->getObject()->getMaximumPoints();
177 $previously_reached_points,
181 if (!$form->checkInput()) {
182 $form->setValuesByPost();
194 if (isset($feedback[
'finalized_evaluation'])
195 && $feedback[
'finalized_evaluation'] === 1) {
196 $new_reached_points = $previously_reached_points;
197 $feedback_text = $feedback[
'feedback'];
199 $new_reached_points = $this->
refinery->kindlyTo()->float()
200 ->transform($form->getInput(
'points'));
202 $form->getInput(
'feedback'),
207 if ($new_reached_points !== $previously_reached_points) {
208 \assQuestion::_setReachedPoints(
222 $finalized = $this->
refinery->byTrying([
223 $this->
refinery->kindlyTo()->bool(),
225 ])->
transform($form->getInput(
'finalized'));
226 $this->
object->saveManualFeedback(
234 if ($this->
logger->isLoggingEnabled()) {
235 $this->
logger->logScoringInteraction(
236 $this->
logger->getInteractionFactory()->buildScoringInteraction(
239 $this->
user->getId(),
241 TestScoringInteractionTypes::QUESTION_GRADED,
246 ->getAdditionalInformationGenerator()->getTrueFalseTagForBool($finalized)
252 $this->tpl->setOnScreenMessage(
255 $this->
lng->txt(
'tst_saved_manscoring_by_question_successfully'),
256 $question_gui->getObject()->getTitleForHTMLOutput(),
265 $row_info_array = explode(
'_', $row_id);
267 if (count($row_info_array) !== 2) {
268 $this->
http->close();
271 [$active_id, $attempt] = $this->
refinery->container()->mapValues(
275 if (!$this->
getTestAccess()->checkScoreParticipantsAccessForActiveId($active_id, $this->
object->getTestId())) {
276 $this->
http->close();
279 $this->
http->saveResponse(
280 $this->
http->response()->withBody(
282 $this->ui_renderer->renderAsync(
283 $this->buildFeedbackModal($question_id, $active_id, $attempt)
288 $this->
http->sendResponse();
289 $this->
http->close();
298 $question_gui = $this->
object->createQuestionGUI(
'', $question_id);
306 $reached_points = $question_gui->getObject()->getReachedPoints($active_id, $attempt);
307 $available_points = $question_gui->getObject()->getMaximumPoints();
308 $content[] = $this->ui_factory->panel()->standard(
309 $this->
lng->txt(
'scoring'),
310 $this->ui_factory->legacy()->content(
312 $this->
lng->txt(
'part_received_a_of_b_points'),
320 if ($this->
object->getShowSolutionSuggested() && $suggested_solution !==
'') {
321 $content[] = $this->ui_factory->legacy()->content(
322 $this->ui_factory->panel()->standard(
323 $this->
lng->txt(
'solution_hint'),
329 $content[] = $this->ui_factory->legacy()->content(($form ?? $this->
buildForm(
337 return $this->ui_factory->modal()->roundtrip(
348 return $this->ui_factory->panel()->standard(
349 $question_gui->
getObject()->getTitleForHTMLOutput(),
350 $this->ui_factory->legacy()->content(
357 $this->object->getShowSolutionFeedback(),
368 return $this->ui_factory->panel()->standard(
369 $this->
lng->txt(
'autosavecontent'),
370 $this->ui_factory->legacy()->content(
377 $this->object->getShowSolutionFeedback(),
385 $usr_id = $this->
object->_getUserIdFromActiveId($active_id);
386 if ($this->
object->getAnonymity() ===
true 387 || in_array($usr_id, $this->
object->getAnonOnlyParticipantIds())
389 return $this->
lng->txt(
'answers_of')
393 return $this->
lng->txt(
'answers_of') .
' ' . $this->
object->getCompleteEvaluationData()
394 ->getParticipant($active_id)
402 float $reached_points,
403 float $available_points
406 $finalized = isset($feedback[
'finalized_evaluation'])
407 && $feedback[
'finalized_evaluation'] === 1;
409 $form = new \ilPropertyFormGUI();
410 $form->setFormAction($this->
buildFormTarget($question_id, $active_id, $attempt));
411 $form->setTitle($this->
lng->txt(
'manscoring'));
412 $form->addCommandButton(self::CMD_SAVE, $this->
lng->txt(
'save'));
416 $feedback_input = new \ilNonEditableValueGUI(
417 $this->
lng->txt(
'set_manual_feedback'),
422 $feedback_input = new \ilTextAreaInputGUI(
423 $this->
lng->txt(
'set_manual_feedback'),
426 $feedback_input->setUseRte(
true);
428 $feedback_input->setValue($feedback[
'feedback'] ??
'');
429 $form->addItem($feedback_input);
431 $reached_points_input = new \ilNumberInputGUI(
432 $this->
lng->txt(
'tst_change_points_for_question'),
435 $reached_points_input->allowDecimals(
true);
436 $reached_points_input->setSize(5);
437 $reached_points_input->setMaxValue($available_points,
true);
438 $reached_points_input->setMinValue(0);
439 $reached_points_input->setDisabled($finalized);
440 $reached_points_input->setValue((
string) $reached_points);
441 $reached_points_input->setClientSideValidation(
true);
442 $form->addItem($reached_points_input);
444 $finalized_input = new \ilCheckboxInputGUI(
445 $this->
lng->txt(
'finalized_evaluation'),
448 $finalized_input->setChecked($finalized);
449 $form->addItem($finalized_input);
459 $this->
ctrl->setParameterByClass(self::class,
'q_id', $question_id);
460 $this->
ctrl->setParameterByClass(self::class,
'active_id', $active_id);
461 $this->
ctrl->setParameterByClass(self::class,
'pass_id', $attempt);
462 $target = $this->
ctrl->getFormAction($this, self::CMD_SAVE);
463 $this->
ctrl->clearParameterByClass(self::class,
'q_id');
464 $this->
ctrl->clearParameterByClass(self::class,
'active_id');
465 $this->
ctrl->clearParameterByClass(self::class,
'pass_id');
478 $this->
ctrl->setParameterByClass(self::class,
'q_id', $v->getGeneralQuestionProperties()->getQuestionId());
479 return $this->ui_factory->link()->standard(
481 $this->
ctrl->getLinkTargetByClass(self::class, $this->getDefaultCommand())
486 $this->
ctrl->clearParameterByClass(self::class,
'q_id');
492 $question_properties = $test_question_properties->getGeneralQuestionProperties();
493 $lang_var = $question_properties->getAvailablePoints() === 1.0 ? $this->
lng->txt(
'point') : $this->
lng->txt(
'points');
494 return "{$this->refinery->encode()->htmlSpecialCharsAsEntities()->transform($question_properties->getTitle())} " 495 .
"({$question_properties->getAvailablePoints()} {$lang_var}) " 496 .
"[{$this->lng->txt('question_id_short')}: {$question_properties->getQuestionId()}]";
501 $math_jax_setting = new \ilSetting(
'MathJax');
502 if ($math_jax_setting->get(
'enable')) {
503 $this->tpl->addJavaScript($math_jax_setting->get(
'path_to_mathjax'));
513 $this->tpl->addJavaScript(
'node_modules/tinymce/tinymce.min.js');
514 $this->tpl->addOnLoadCode(
" 517 document.getElementById('ilContentContainer'), 518 {childList: true, subtree: true} 521 const o = new MutationObserver( 526 selector: 'textarea.RTEditor', 529 fix_list_elements: true, 533 toolbar: 'bold italic underline strikethrough | undo redo | bullist numlist', 534 toolbar_mode: 'sliding', 535 init_instance_callback: () => {aO(o);} saveManScoringByQuestion()
showManScoringByQuestionParticipantsTable(?RoundTripModal $modal=null)
buildFeedbackModal(int $question_id, int $active_id, int $attempt, ?\ilPropertyFormGUI $form=null)
getAutoSavedSolutionOutput(int $active_id, int $pass, bool $graphical_output=false, bool $result_output=false, bool $show_question_only=true, bool $show_feedback=false, bool $show_correct_solution=false, bool $show_manual_scoring=false, bool $show_question_text=true, bool $show_autosave_title=false, bool $show_inline_feedback=false)
static _getSuggestedSolutionOutput(int $question_id)
Interface Observer Contains several chained tasks and infos about them.
URLBuilderToken $row_id_token
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
acquireParameters(array $namespace, string ... $names)
TestScoringInteractionTypes
getAnswerDetail(int $question_id, string $row_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
buildQuestionTitleWithPoints(TestQuestionProperties $test_question_properties)
buildSolutionPanel(\assQuestionGUI $question_gui, int $active_id, int $attempt)
static getSingleManualFeedback(int $active_id, int $question_id, int $pass)
static http()
Fetches the global http state from ILIAS.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
buildSelectableQuestionsArray(array $question_data)
URLBuilderToken $action_parameter_token
static ofString(string $string)
Creates a new stream with an initial value.
const TAB_ID_MANUAL_SCORING
__construct(\ilObjTest $object, private readonly \ilUIService $ui_service)
getModalTitle(int $active_id, int $attempt)
__construct(Container $dic, ilPlugin $plugin)
static _getUsedHTMLTagsAsString(string $module='')
static _getParticipantId(int $active_id)
Get user id for active id.
static buildExamId($active_id, $pass, $test_obj_id=null)
buildFormTarget(int $question_id, int $active_id, int $attempt)
getSolutionOutput(int $active_id, ?int $pass=null, bool $graphical_output=false, bool $result_output=false, bool $show_question_only=true, bool $show_feedback=false, bool $show_correct_solution=false, bool $show_manual_scoring=false, bool $show_question_text=true, bool $show_inline_feedback=true)
buildForm(int $attempt, int $active_id, int $question_id, float $reached_points, float $available_points)
buildAutosavedSolutionPanel(assQuestionGUI $question_gui, int $active_id, int $attempt)
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)