ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilTestScoringGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
5 include_once "./Modules/Test/classes/class.ilTestServiceGUI.php";
6 
18 {
21  const PART_FILTER_ALL_USERS = 3; // default
24  //const PART_FILTER_MANSCORING_PENDING = 6;
25 
29  protected $testAccess;
30 
39  public function __construct(ilObjTest $a_object)
40  {
41  parent::__construct($a_object);
42  }
43 
47  public function getTestAccess()
48  {
49  return $this->testAccess;
50  }
51 
55  public function setTestAccess($testAccess)
56  {
57  $this->testAccess = $testAccess;
58  }
59 
63  protected function buildSubTabs($active_sub_tab = 'man_scoring_by_qst')
64  {
68  global $DIC;
69  $ilTabs = $DIC['ilTabs'];
70 
71  $ilTabs->addSubTab('man_scoring_by_qst', $this->lng->txt('tst_man_scoring_by_qst'), $this->ctrl->getLinkTargetByClass('ilTestScoringByQuestionsGUI', 'showManScoringByQuestionParticipantsTable'));
72  $ilTabs->addSubTab('man_scoring', $this->lng->txt('tst_man_scoring_by_part'), $this->ctrl->getLinkTargetByClass('ilTestScoringGUI', 'showManScoringParticipantsTable'));
73  $ilTabs->setSubTabActive($active_sub_tab);
74  }
75 
76  private function fetchActiveIdParameter()
77  {
78  global $DIC;
79  $ilCtrl = $DIC['ilCtrl'];
80 
81  // fetch active_id
82 
83  if (!isset($_GET['active_id']) || !(int) $_GET['active_id']) {
84  // allow only write access
85  ilUtil::sendFailure('no active id given!', true);
86  $ilCtrl->redirectByClass("ilobjtestgui", "infoScreen");
87  } else {
88  $activeId = (int) $_GET['active_id'];
89  }
90 
91  return $activeId;
92  }
93 
94  private function fetchPassParameter($activeId)
95  {
96  // fetch pass nr
97 
98  $maxPass = $this->object->_getMaxPass($activeId);
99  if (isset($_GET["pass"]) && 0 <= (int) $_GET["pass"] && $maxPass >= (int) $_GET["pass"]) {
100  $pass = $_GET["pass"];
101  } elseif ($this->object->getPassScoring() == SCORE_LAST_PASS) {
102  $pass = $maxPass;
103  } else {
104  $pass = $this->object->_getResultPass($activeId);
105  }
106 
107  return $pass;
108  }
109 
113  public function executeCommand()
114  {
115  global $DIC; /* @var ILIAS\DI\Container $DIC */
116 
117  if (!$this->getTestAccess()->checkScoreParticipantsAccess()) {
119  }
120 
121  require_once 'Modules/Test/classes/class.ilObjAssessmentFolder.php';
123  // allow only if at least one question type is marked for manual scoring
124  ilUtil::sendFailure($this->lng->txt("manscoring_not_allowed"), true);
125  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
126  }
127 
128  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_MANUAL_SCORING);
129  $this->buildSubTabs($this->getActiveSubTabId());
130 
131  $nextClass = $this->ctrl->getNextClass($this);
132  $command = $this->ctrl->getCmd($this->getDefaultCommand());
133 
134  switch ($nextClass) {
135  default:
136  $this->$command();
137  break;
138  }
139  }
140 
144  protected function getDefaultCommand()
145  {
146  return 'manscoring';
147  }
148 
152  protected function getActiveSubTabId()
153  {
154  return 'man_scoring';
155  }
156 
158  {
159  global $DIC;
160  $tpl = $DIC['tpl'];
161 
162  $table = $this->buildManScoringParticipantsTable(true);
163 
164  $tpl->setContent($table->getHTML());
165  }
166 
168  {
169  $table = $this->buildManScoringParticipantsTable(false);
170 
171  $table->resetOffset();
172  $table->writeFilterToSession();
173 
175  }
176 
178  {
179  $table = $this->buildManScoringParticipantsTable(false);
180 
181  $table->resetOffset();
182  $table->resetFilter();
183 
185  }
186 
187  private function showManScoringParticipantScreen(ilPropertyFormGUI $form = null)
188  {
189  global $DIC;
190  $tpl = $DIC['tpl'];
191  $lng = $DIC['lng'];
192 
193  $activeId = $this->fetchActiveIdParameter();
194 
195  if (!$this->getTestAccess()->checkScoreParticipantsAccessForActiveId($activeId)) {
197  }
198 
199  $pass = $this->fetchPassParameter($activeId);
200 
201  $contentHTML = '';
202 
203  // pass overview table
204  require_once 'Modules/Test/classes/tables/class.ilTestPassManualScoringOverviewTableGUI.php';
205  $table = new ilTestPassManualScoringOverviewTableGUI($this, 'showManScoringParticipantScreen');
206 
207  $userId = $this->object->_getUserIdFromActiveId($activeId);
208  $userFullname = $this->object->userLookupFullName($userId, false, true);
209  $tableTitle = sprintf($lng->txt('tst_pass_overview_for_participant'), $userFullname);
210  $table->setTitle($tableTitle);
211 
212  $passOverviewData = $this->service->getPassOverviewData($activeId);
213  $table->setData($passOverviewData['passes']);
214 
215  $contentHTML .= $table->getHTML() . '<br />';
216 
217  // pass scoring form
218 
219  if ($form === null) {
220  $questionGuiList = $this->service->getManScoringQuestionGuiList($activeId, $pass);
221  $form = $this->buildManScoringParticipantForm($questionGuiList, $activeId, $pass, true);
222  }
223 
224  $contentHTML .= $form->getHTML();
225 
226  // set content
227 
228  $tpl->setContent($contentHTML);
229  }
230 
235  private function saveManScoringParticipantScreen($redirect = true)
236  {
237  global $DIC;
238  $ilCtrl = $DIC['ilCtrl'];
239  $lng = $DIC['lng'];
240 
241  $activeId = $this->fetchActiveIdParameter();
242 
243  if (!$this->getTestAccess()->checkScoreParticipantsAccessForActiveId($activeId)) {
245  }
246 
247  $pass = $this->fetchPassParameter($activeId);
248 
249  $questionGuiList = $this->service->getManScoringQuestionGuiList($activeId, $pass);
250  $form = $this->buildManScoringParticipantForm($questionGuiList, $activeId, $pass, false);
251 
252  $form->setValuesByPost();
253 
254  if (!$form->checkInput()) {
255  ilUtil::sendFailure(sprintf($lng->txt('tst_save_manscoring_failed'), $pass + 1));
256  $this->showManScoringParticipantScreen($form);
257  return false;
258  }
259 
260  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
261 
262  $maxPointsByQuestionId = array();
263  $maxPointsExceeded = false;
264  foreach ($questionGuiList as $questionId => $questionGui) {
265  $reachedPoints = $form->getItemByPostVar("question__{$questionId}__points")->getValue();
266  $maxPoints = assQuestion::_getMaximumPoints($questionId);
267 
268  if ($reachedPoints > $maxPoints) {
269  $maxPointsExceeded = true;
270 
271  $form->getItemByPostVar("question__{$questionId}__points")->setAlert(sprintf(
272  $lng->txt('tst_manscoring_maxpoints_exceeded_input_alert'),
273  $maxPoints
274  ));
275  }
276 
277  $maxPointsByQuestionId[$questionId] = $maxPoints;
278  }
279 
280  if ($maxPointsExceeded) {
281  ilUtil::sendFailure(sprintf($lng->txt('tst_save_manscoring_failed'), $pass + 1));
282  $this->showManScoringParticipantScreen($form);
283  return false;
284  }
285 
286  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
287 
288  foreach ($questionGuiList as $questionId => $questionGui) {
289  $reachedPoints = $form->getItemByPostVar("question__{$questionId}__points")->getValue();
290 
291  $finalized = (bool) $form->getItemByPostVar("{$questionId}__evaluated")->getchecked();
292 
293  // fix #35543: save manual points only if they differ from the existing points
294  // this prevents a question being set to "answered" if only feedback is entered
295  $oldPoints = assQuestion::_getReachedPoints($activeId, $questionId, $pass);
296  if ($reachedPoints != $oldPoints) {
298  $activeId,
299  $questionId,
300  $reachedPoints,
301  $maxPointsByQuestionId[$questionId],
302  $pass,
303  1,
304  $this->object->areObligationsEnabled()
305  );
306  }
307 
308  $feedback = ilUtil::stripSlashes(
309  $form->getItemByPostVar("question__{$questionId}__feedback")->getValue(),
310  false,
312  );
313 
314  $this->object->saveManualFeedback($activeId, $questionId, $pass, $feedback, $finalized, true);
315 
316  $notificationData[$questionId] = array(
317  'points' => $reachedPoints, 'feedback' => $feedback
318  );
319  }
320 
321  include_once "./Modules/Test/classes/class.ilObjTestAccess.php";
322  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
324  $this->object->getId(),
326  );
327 
328  $manScoringDone = $form->getItemByPostVar("manscoring_done")->getChecked();
329  ilTestService::setManScoringDone($activeId, $manScoringDone);
330 
331  $manScoringNotify = $form->getItemByPostVar("manscoring_notify")->getChecked();
332  if ($manScoringNotify) {
333  require_once 'Modules/Test/classes/notifications/class.ilTestManScoringParticipantNotification.php';
334 
335  $notification = new ilTestManScoringParticipantNotification(
336  $this->object->_getUserIdFromActiveId($activeId),
337  $this->object->getRefId()
338  );
339 
340  $notification->setAdditionalInformation(array(
341  'test_title' => $this->object->getTitle(),
342  'test_pass' => $pass + 1,
343  'questions_gui_list' => $questionGuiList,
344  'questions_scoring_data' => $notificationData
345  ));
346 
347  $notification->send();
348  }
349 
350  require_once './Modules/Test/classes/class.ilTestScoring.php';
351  $scorer = new ilTestScoring($this->object);
352  $scorer->setPreserveManualScores(true);
353  $scorer->recalculateSolutions();
354 
355  if ($this->object->getAnonymity() == 0) {
357  $name_real_or_anon = $user_name['firstname'] . ' ' . $user_name['lastname'];
358  } else {
359  $name_real_or_anon = $lng->txt('anonymous');
360  }
361  ilUtil::sendSuccess(sprintf($lng->txt('tst_saved_manscoring_successfully'), $pass + 1, $name_real_or_anon), true);
362  if ($redirect == true) {
363  $ilCtrl->redirect($this, 'showManScoringParticipantScreen');
364  } else {
365  return true;
366  }
367  }
368 
370  {
371  global $DIC;
372  $ilCtrl = $DIC['ilCtrl'];
373 
374  $table = $this->buildManScoringParticipantsTable(true);
375 
376  if ($this->saveManScoringParticipantScreen(false)) {
377  $participantData = $table->getInternalyOrderedDataValues();
378 
379  $nextIndex = null;
380  foreach ($participantData as $index => $participant) {
381  if ($participant['active_id'] == $_GET['active_id']) {
382  $nextIndex = $index + 1;
383  break;
384  }
385  }
386 
387  if ($nextIndex && isset($participantData[$nextIndex])) {
388  $ilCtrl->setParameter($this, 'active_id', $participantData[$nextIndex]['active_id']);
389  $ilCtrl->redirect($this, 'showManScoringParticipantScreen');
390  }
391 
392  $ilCtrl->redirectByClass("iltestscoringgui", "showManScoringParticipantsTable");
393  }
394  }
395 
397  {
398  global $DIC;
399  $ilCtrl = $DIC['ilCtrl'];
400 
401  if ($this->saveManScoringParticipantScreen(false)) {
402  $ilCtrl->redirectByClass("iltestscoringgui", "showManScoringParticipantsTable");
403  }
404  }
405 
406  private function buildManScoringParticipantForm($questionGuiList, $activeId, $pass, $initValues = false)
407  {
408  global $DIC;
409  $ilCtrl = $DIC['ilCtrl'];
410  $lng = $DIC['lng'];
411 
412  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
413  require_once 'Services/Form/classes/class.ilFormSectionHeaderGUI.php';
414  require_once 'Services/Form/classes/class.ilCustomInputGUI.php';
415  require_once 'Services/Form/classes/class.ilCheckboxInputGUI.php';
416  require_once 'Services/Form/classes/class.ilTextInputGUI.php';
417  require_once 'Services/Form/classes/class.ilTextAreaInputGUI.php';
418 
419  $ilCtrl->setParameter($this, 'active_id', $activeId);
420  $ilCtrl->setParameter($this, 'pass', $pass);
421 
422  $form = new ilPropertyFormGUI();
423  $form->setFormAction($ilCtrl->getFormAction($this));
424 
425  $form->setTitle(sprintf($lng->txt('manscoring_results_pass'), $pass + 1));
426  $form->setTableWidth('100%');
427 
429  foreach ($questionGuiList as $questionId => $questionGUI) {
430  $questionHeader = sprintf($lng->txt('tst_manscoring_question_section_header'), $questionGUI->object->getTitle());
431  $questionSolution = $questionGUI->getSolutionOutput($activeId, $pass, false, false, true, false, false, true);
432  $bestSolution = $questionGUI->object->getSuggestedSolutionOutput();
433  $feedback = $this->object->getSingleManualFeedback($activeId, $questionId, $pass);
434  $disabled = false;
435  if (isset($feedback['finalized_evaluation']) && $feedback['finalized_evaluation'] == 1) {
436  $disabled = true;
437  }
438 
439  $sect = new ilFormSectionHeaderGUI();
440  $sect->setTitle($questionHeader . ' [' . $this->lng->txt('question_id_short') . ': ' . $questionGUI->object->getId() . ']');
441  $form->addItem($sect);
442 
443  $cust = new ilCustomInputGUI($lng->txt('tst_manscoring_input_question_and_user_solution'));
444  $cust->setHtml($questionSolution);
445  $form->addItem($cust);
446 
447  if ($questionGUI->supportsIntermediateSolutionOutput() && $questionGUI->hasIntermediateSolution($activeId, $pass)) {
448  $questionGUI->setUseIntermediateSolution(true);
449  $intermediateSolution = $questionGUI->getSolutionOutput($activeId, $pass, false, false, true, false, false, true);
450  $questionGUI->setUseIntermediateSolution(false);
451  $cust = new ilCustomInputGUI($lng->txt('autosavecontent'));
452  $cust->setHtml($intermediateSolution);
453  $form->addItem($cust);
454  }
455 
456  $text = new ilTextInputGUI($lng->txt('tst_change_points_for_question'), "question__{$questionId}__points");
457  if ($initValues) {
458  $text->setValue(assQuestion::_getReachedPoints($activeId, $questionId, $pass));
459  }
460  if($disabled){
461  $text->setDisabled($disabled);
462  }
463  $form->addItem($text);
464 
465  $nonedit = new ilNonEditableValueGUI($lng->txt('tst_manscoring_input_max_points_for_question'), "question__{$questionId}__maxpoints");
466  if ($initValues) {
467  $nonedit->setValue(assQuestion::_getMaximumPoints($questionId));
468  }
469  $form->addItem($nonedit);
470 
471  $area = new ilTextAreaInputGUI($lng->txt('set_manual_feedback'), "question__{$questionId}__feedback");
472  $area->setUseRTE(true);
473  if ($initValues) {
474  $area->setValue($this->object->getSingleManualFeedback($activeId, $questionId, $pass)['feedback']);
475  }
476  if($disabled){
477  $area->setDisabled($disabled);
478  }
479  $form->addItem($area);
480 
481  $check = new ilCheckboxInputGUI($lng->txt('finalized_evaluation'), "{$questionId}__evaluated");
482  if ($disabled) {
483  $check->setChecked(true);
484  }
485  $form->addItem($check);
486 
487  if (strlen(trim($bestSolution))) {
488  $cust = new ilCustomInputGUI($lng->txt('tst_show_solution_suggested'));
489  $cust->setHtml($bestSolution);
490  $form->addItem($cust);
491  }
492  }
493 
494  $sect = new ilFormSectionHeaderGUI();
495  $sect->setTitle($lng->txt('tst_participant'));
496  $form->addItem($sect);
497 
498  $check = new ilCheckboxInputGUI($lng->txt('set_manscoring_done'), 'manscoring_done');
499  if ($initValues && ilTestService::isManScoringDone($activeId)) {
500  $check->setChecked(true);
501  }
502  $form->addItem($check);
503 
504  $check = new ilCheckboxInputGUI($lng->txt('tst_manscoring_user_notification'), 'manscoring_notify');
505  $form->addItem($check);
506 
507  $form->addCommandButton('saveManScoringParticipantScreen', $lng->txt('save'));
508  $form->addCommandButton('saveReturnManScoringParticipantScreen', $lng->txt('save_return'));
509  $form->addCommandButton('saveNextManScoringParticipantScreen', $lng->txt('save_and_next'));
510 
511  return $form;
512  }
513 
515  {
516  }
517 
521  private function buildManScoringParticipantsTable($withData = false)
522  {
523  require_once 'Modules/Test/classes/tables/class.ilTestManScoringParticipantsTableGUI.php';
524  $table = new ilTestManScoringParticipantsTableGUI($this);
525 
526  if ($withData) {
527  $participantStatusFilterValue = $table->getFilterItemByPostVar('participant_status')->getValue();
528 
529  require_once 'Modules/Test/classes/class.ilTestParticipantList.php';
530  $participantList = new ilTestParticipantList($this->object);
531 
532  $participantList->initializeFromDbRows(
533  $this->object->getTestParticipantsForManualScoring($participantStatusFilterValue)
534  );
535 
536  $participantList = $participantList->getAccessFilteredList(
538  );
539 
540  $table->setData($participantList->getParticipantsTableRows());
541  }
542 
543  return $table;
544  }
545 }
showManScoringParticipantScreen(ilPropertyFormGUI $form=null)
static _lookupName($a_user_id)
lookup user name
static setManScoringDone($activeId, $manScoringDone)
stores the flag wether manscoring is done for the given test active or not within the global settings...
setHtml($a_html)
Set Html.
static _getParticipantId($active_id)
Get user id for active id.
static _getUsedHTMLTagsAsString($a_module="")
Returns a string of all allowed HTML tags for text editing.
This class represents a property form user interface.
const SCORE_LAST_PASS
$_GET["client_id"]
This class represents a section header in a property form.
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
setValue($a_value)
Set Value.
static isManScoringDone($activeId)
reads the flag wether manscoring is done for the given test active or not from the global settings (s...
This class represents a checkbox property in a property form.
__construct(ilObjTest $a_object)
ilTestScoringGUI constructor
Scoring class for tests.
executeCommand()
execute command
static accessViolationRedirect()
static _getMaximumPoints($question_id)
Returns the maximum points, a learner can reach answering the question.
$index
Definition: metadata.php:128
setChecked($a_checked)
Set Checked.
static _mananuallyScoreableQuestionTypesExists()
Returns the fact wether manually scoreable question types exist or not.
global $DIC
Definition: goto.php:24
saveManScoringParticipantScreen($redirect=true)
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
buildManScoringParticipantsTable($withData=false)
Class ilTestScoring.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
This class represents a custom property in a property form.
This class represents a non editable value in a property form.
__construct(Container $dic, ilPlugin $plugin)
This class represents a text area property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getReachedPoints($active_id, $question_id, $pass=null)
Returns the points, a learner has reached answering the question.
setAdditionalInformation(array $a_info)
Additional information for creating notification mails.
static _setReachedPoints($active_id, $question_id, $points, $maxpoints, $pass, $manualscoring, $obligationsEnabled)
Sets the points, a learner has reached answering the question Additionally objective results are upda...