19 declare(strict_types=1);
68 protected function buildSubTabs(
string $active_sub_tab =
'man_scoring_by_qst'): void
70 $this->
tabs->addSubTab(
72 $this->
lng->txt(
'tst_man_scoring_by_qst'),
73 $this->
ctrl->getLinkTargetByClass([\ilObjTestGUI::class, TestScoringByQuestionGUI::class],
'showManScoringByQuestionParticipantsTable')
75 $this->
tabs->addSubTab(
77 $this->
lng->txt(
'tst_man_scoring_by_part'),
78 $this->
ctrl->getLinkTargetByClass([\ilObjTestGUI::class, self::class],
'showManScoringParticipantsTable')
80 $this->
tabs->setSubTabActive($active_sub_tab);
85 if (!$this->testrequest->isset(
'active_id') || $this->testrequest->int(
'active_id') === 0) {
86 $this->tpl->setOnScreenMessage(
'failure',
'no active id given!',
true);
87 $this->
ctrl->redirectByClass([\ilRepositoryGUI::class, \ilObjTestGUI::class, \ilInfoScreenGUI::class]);
90 return $this->testrequest->int(
'active_id');
95 $max_pass = $this->
object->_getMaxPass($active_id);
98 if ($this->testrequest->isset(
'pass')) {
99 $pass_from_request = $this->testrequest->int(
'pass');
100 if ($pass_from_request >= 0
101 && $pass_from_request <= $max_pass
103 return $pass_from_request;
111 return $this->
object->_getResultPass($active_id);
119 if (!$this->
getTestAccess()->checkScoreParticipantsAccess()) {
120 \ilObjTestGUI::accessViolationRedirect();
123 if (!$this->
object->getGlobalSettings()->isManualScoringEnabled()) {
125 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
"manscoring_not_allowed"),
true);
126 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
143 return 'man_scoring';
149 $this->tpl->setContent($table->getHTML());
155 $table->resetOffset();
156 $table->writeFilterToSession();
164 $table->resetOffset();
165 $table->resetFilter();
174 if (!$this->
getTestAccess()->checkScoreParticipantsAccessForActiveId($active_id, $this->
object->getTestId())) {
175 \ilObjTestGUI::accessViolationRedirect();
184 $user_id = $this->
object->_getUserIdFromActiveId($active_id);
185 $user_fullname = $this->
object->userLookupFullName(
$user_id,
false,
true);
186 $table_title = sprintf($this->
lng->txt(
'tst_pass_overview_for_participant'), $user_fullname);
187 $table->setTitle($table_title);
189 $passOverviewData = $this->service->getPassOverviewData($active_id);
190 $table->setData($passOverviewData[
'passes']);
192 $content_html .= $table->getHTML() .
'<br />';
194 if ($form ===
null) {
199 $content_html .= $form->getHTML();
201 $this->tpl->setContent($content_html);
208 if (!$this->
getTestAccess()->checkScoreParticipantsAccessForActiveId($active_id, $this->
object->getTestId())) {
209 \ilObjTestGUI::accessViolationRedirect();
217 $form->setValuesByPost();
219 if (!$form->checkInput()) {
220 $this->tpl->setOnScreenMessage(
'failure', sprintf($this->
lng->txt(
'tst_save_manscoring_failed'), $pass + 1));
225 $maxPointsByQuestionId = [];
226 $max_points_exceeded =
false;
227 foreach (array_keys($question_gui_list) as $question_id) {
228 $reached_points = $form->getItemByPostVar(
"question__{$question_id}__points")->getValue();
229 $max_points = $this->questionrepository->getForQuestionId($question_id)->getAvailablePoints();
231 if ($reached_points > $max_points) {
232 $max_points_exceeded =
true;
234 $form->getItemByPostVar(
"question__{$question_id}__points")->setAlert(sprintf(
235 $this->
lng->txt(
'tst_manscoring_maxpoints_exceeded_input_alert'),
240 $maxPointsByQuestionId[$question_id] = $max_points;
243 if ($max_points_exceeded) {
244 $this->tpl->setOnScreenMessage(
'failure', sprintf($this->
lng->txt(
'tst_save_manscoring_failed'), $pass + 1));
249 foreach (array_keys($question_gui_list) as $question_id) {
250 $reached_points = $this->
refinery->kindlyTo()->float()->transform(
251 $form->getItemByPostVar(
"question__{$question_id}__points")->getValue()
254 $finalized = (bool) $form->getItemByPostVar(
"{$question_id}__evaluated")->getchecked();
259 if ($reached_points != $old_points) {
264 $maxPointsByQuestionId[$question_id],
271 (
string) $form->getItemByPostVar(
"question__{$question_id}__feedback")->getValue(),
276 $this->
object->saveManualFeedback(
284 if ($this->
logger->isLoggingEnabled()) {
285 $this->
logger->getInteractionFactory()->buildScoringInteraction(
288 $this->
user->getId(),
290 TestScoringInteractionTypes::QUESTION_GRADED,
295 ->getAdditionalInformationGenerator()->getTrueFalseTagForBool(
true)
300 $notificationData[$question_id] = [
301 'points' => $reached_points,
'feedback' => $feedback_text
310 $manScoringDone = $form->getItemByPostVar(
"manscoring_done")->getChecked();
313 $manScoringNotify = $form->getItemByPostVar(
"manscoring_notify")->getChecked();
314 if ($manScoringNotify) {
315 $notification = new \ilTestManScoringParticipantNotification(
316 $this->
object->_getUserIdFromActiveId($active_id),
317 $this->
object->getRefId()
320 $notification->setAdditionalInformation([
321 'test_title' => $this->
object->getTitle(),
322 'test_pass' => $pass + 1,
323 'questions_gui_list' => $question_gui_list,
324 'questions_scoring_data' => $notificationData
327 $notification->send();
331 $scorer->setPreserveManualScores(
true);
332 $scorer->recalculateSolution($active_id, $pass);
334 if ($this->
object->getAnonymity() == 0) {
336 $name_real_or_anon = $user_name[
'firstname'] .
' ' . $user_name[
'lastname'];
338 $name_real_or_anon = $this->
lng->txt(
'anonymous');
340 $this->tpl->setOnScreenMessage(
'success', sprintf($this->
lng->txt(
'tst_saved_manscoring_successfully'), $pass + 1, $name_real_or_anon),
true);
341 if ($redirect ==
true) {
342 $this->
ctrl->redirect($this,
'showManScoringParticipantScreen');
356 if ($participant[
'active_id'] == $this->testrequest->raw(
'active_id')) {
357 $nextIndex = $index + 1;
364 $this->
ctrl->redirect($this,
'showManScoringParticipantScreen');
367 $this->
ctrl->redirectByClass(self::class,
'showManScoringParticipantsTable');
374 $this->
ctrl->redirectByClass(self::class,
'showManScoringParticipantsTable');
379 array $question_gui_list,
382 bool $initValues =
false 384 $this->
ctrl->setParameter($this,
'active_id', $active_id);
385 $this->
ctrl->setParameter($this,
'pass', $pass);
387 $form = new \ilPropertyFormGUI();
388 $form->setFormAction($this->
ctrl->getFormAction($this));
390 $form->setTitle(sprintf($this->
lng->txt(
'manscoring_results_pass'), $pass + 1));
391 $form->setTableWidth(
'100%');
393 foreach ($question_gui_list as $question_id => $question_gui) {
394 $question_header = sprintf(
395 $this->
lng->txt(
'tst_manscoring_question_section_header'),
396 $question_gui->getObject()->getTitleForHTMLOutput()
398 $question_solution = $question_gui->getSolutionOutput($active_id, $pass,
false,
false,
true,
false,
false,
true);
399 $best_solution = $question_gui->getObject()->getSuggestedSolutionOutput();
404 if (isset($feedback[
'finalized_evaluation']) && $feedback[
'finalized_evaluation'] == 1) {
408 $sect = new \ilFormSectionHeaderGUI();
409 $sect->setTitle($question_header .
' [' . $this->
lng->txt(
'question_id_short') .
': ' . $question_gui->getObject()->getId() .
']');
410 $form->addItem($sect);
412 $cust = new \ilCustomInputGUI($this->
lng->txt(
'tst_manscoring_input_question_and_user_solution'));
413 $cust->setHtml($question_solution);
414 $form->addItem($cust);
416 $text = new \ilTextInputGUI($this->
lng->txt(
'tst_change_points_for_question'),
"question__{$question_id}__points");
421 $text->setDisabled($disabled);
423 $form->addItem($text);
425 $nonedit = new \ilNonEditableValueGUI($this->
lng->txt(
'tst_manscoring_input_max_points_for_question'),
"question__{$question_id}__maxpoints");
427 $nonedit->setValue($this->questionrepository->getForQuestionId($question_id)->getAvailablePoints());
429 $form->addItem($nonedit);
431 $area = new \ilTextAreaInputGUI($this->
lng->txt(
'set_manual_feedback'),
"question__{$question_id}__feedback");
432 $area->setUseRTE(
true);
437 $area->setDisabled($disabled);
439 $form->addItem($area);
441 $check = new \ilCheckboxInputGUI($this->
lng->txt(
'finalized_evaluation'),
"{$question_id}__evaluated");
447 if (strlen(trim($best_solution))) {
448 $cust = new \ilCustomInputGUI($this->
lng->txt(
'tst_show_solution_suggested'));
449 $cust->setHtml($best_solution);
450 $form->addItem($cust);
454 $sect = new \ilFormSectionHeaderGUI();
455 $sect->setTitle($this->
lng->txt(
'tst_participant'));
456 $form->addItem($sect);
458 $check = new \ilCheckboxInputGUI($this->
lng->txt(
'set_manscoring_done'),
'manscoring_done');
464 $check = new \ilCheckboxInputGUI($this->
lng->txt(
'tst_manscoring_user_notification'),
'manscoring_notify');
467 $form->addCommandButton(
'saveManScoringParticipantScreen', $this->
lng->txt(
'save'));
468 $form->addCommandButton(
'saveReturnManScoringParticipantScreen', $this->
lng->txt(
'save_return'));
469 $form->addCommandButton(
'saveNextManScoringParticipantScreen', $this->
lng->txt(
'save_and_next'));
476 $test_result_data = $this->
object->getTestResult($active_id, $pass);
478 $man_scoring_question_gui_list = [];
480 foreach ($test_result_data as $question_data) {
481 if (!isset($question_data[
'qid'])) {
485 if (!isset($question_data[
'type'])) {
489 $man_scoring_question_gui_list[ $question_data[
'qid'] ] = $this->
object 490 ->createQuestionGUI(
'', $question_data[
'qid']);
493 return $man_scoring_question_gui_list;
501 $participant_list = new \ilTestParticipantList($this->
object, $this->
user, $this->
lng, $this->db);
502 $participant_list->initializeFromDbRows(
503 $this->
object->getTestParticipantsForManualScoring(
504 $table->getFilterItemByPostVar(
'participant_status')->getValue()
509 $participant_list->getAccessFilteredList(
510 $this->participant_access_filter->getScoreParticipantsUserFilter($this->ref_id)
511 )->getScoringTableRows()
const PART_FILTER_MANSCORING_NONE
const PART_FILTER_MANSCORING_DONE
fetchPassParameter(int $active_id)
static _setReachedPoints(int $active_id, int $question_id, float $points, float $maxpoints, int $pass, bool $manualscoring)
Sets the points, a learner has reached answering the question Additionally objective results are upda...
static _getParticipantId($active_id)
Get user id for active id.
buildManScoringParticipantsTable(bool $with_data=false)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static _lookupName(int $a_user_id)
lookup user name
saveReturnManScoringParticipantScreen()
TestScoringInteractionTypes
static isManScoringDone(int $active_id)
buildManScoringParticipantForm(array $question_gui_list, int $active_id, int $pass, bool $initValues=false)
saveManScoringParticipantScreen(bool $redirect=true)
Base Exception for all Exceptions relating to Modules/Test.
getManScoringQuestionGuiList(int $active_id, int $pass)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
saveNextManScoringParticipantScreen()
static getSingleManualFeedback(int $active_id, int $question_id, int $pass)
resetManScoringParticipantsFilter()
static setManScoringDone(int $activeId, bool $manScoringDone)
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.
ilTestAccess $test_access
showManScoringParticipantScreen(?\ilPropertyFormGUI $form=null)
const TAB_ID_MANUAL_SCORING
executeCommand()
execute command
__construct(\ilObjTest $object)
ilTestParticipantData $participantData
__construct(Container $dic, ilPlugin $plugin)
showManScoringParticipantsTable()
buildSubTabs(string $active_sub_tab='man_scoring_by_qst')
Service GUI class for tests.
const PART_FILTER_ALL_USERS
setTestAccess($test_access)
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
applyManScoringParticipantsFilter()