ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 
163 
164  $tpl->setContent($table->getHTML());
165  }
166 
168  {
170 
171  $table->resetOffset();
172  $table->writeFilterToSession();
173 
175  }
176 
178  {
180 
181  $table->resetOffset();
182  $table->resetFilter();
183 
185  }
186 
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));
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));
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 
292  $activeId,
293  $questionId,
294  $reachedPoints,
295  $maxPointsByQuestionId[$questionId],
296  $pass,
297  1,
298  $this->object->areObligationsEnabled()
299  );
300 
301  $feedback = ilUtil::stripSlashes(
302  $form->getItemByPostVar("question__{$questionId}__feedback")->getValue(),
303  false,
305  );
306 
307  $this->object->saveManualFeedback($activeId, $questionId, $pass, $feedback);
308 
309  $notificationData[$questionId] = array(
310  'points' => $reachedPoints, 'feedback' => $feedback
311  );
312  }
313 
314  include_once "./Modules/Test/classes/class.ilObjTestAccess.php";
315  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
317  $this->object->getId(),
319  );
320 
321  $manScoringDone = $form->getItemByPostVar("manscoring_done")->getChecked();
322  ilTestService::setManScoringDone($activeId, $manScoringDone);
323 
324  $manScoringNotify = $form->getItemByPostVar("manscoring_notify")->getChecked();
325  if ($manScoringNotify) {
326  require_once 'Modules/Test/classes/notifications/class.ilTestManScoringParticipantNotification.php';
327 
328  $notification = new ilTestManScoringParticipantNotification(
329  $this->object->_getUserIdFromActiveId($activeId),
330  $this->object->getRefId()
331  );
332 
333  $notification->setAdditionalInformation(array(
334  'test_title' => $this->object->getTitle(),
335  'test_pass' => $pass + 1,
336  'questions_gui_list' => $questionGuiList,
337  'questions_scoring_data' => $notificationData
338  ));
339 
340  $notification->send();
341  }
342 
343  require_once './Modules/Test/classes/class.ilTestScoring.php';
344  $scorer = new ilTestScoring($this->object);
345  $scorer->setPreserveManualScores(true);
346  $scorer->recalculateSolutions();
347 
348  if ($this->object->getAnonymity() == 0) {
350  $name_real_or_anon = $user_name['firstname'] . ' ' . $user_name['lastname'];
351  } else {
352  $name_real_or_anon = $lng->txt('anonymous');
353  }
354  ilUtil::sendSuccess(sprintf($lng->txt('tst_saved_manscoring_successfully'), $pass + 1, $name_real_or_anon), true);
355  if ($redirect == true) {
356  $ilCtrl->redirect($this, 'showManScoringParticipantScreen');
357  } else {
358  return true;
359  }
360  }
361 
363  {
364  global $DIC;
365  $ilCtrl = $DIC['ilCtrl'];
366 
368 
369  if ($this->saveManScoringParticipantScreen(false)) {
370  $participantData = $table->getInternalyOrderedDataValues();
371 
372  $nextIndex = null;
373  foreach ($participantData as $index => $participant) {
374  if ($participant['active_id'] == $_GET['active_id']) {
375  $nextIndex = $index + 1;
376  break;
377  }
378  }
379 
380  if ($nextIndex && isset($participantData[$nextIndex])) {
381  $ilCtrl->setParameter($this, 'active_id', $participantData[$nextIndex]['active_id']);
382  $ilCtrl->redirect($this, 'showManScoringParticipantScreen');
383  }
384 
385  $ilCtrl->redirectByClass("iltestscoringgui", "showManScoringParticipantsTable");
386  }
387  }
388 
390  {
391  global $DIC;
392  $ilCtrl = $DIC['ilCtrl'];
393 
394  if ($this->saveManScoringParticipantScreen(false)) {
395  $ilCtrl->redirectByClass("iltestscoringgui", "showManScoringParticipantsTable");
396  }
397  }
398 
399  private function buildManScoringParticipantForm($questionGuiList, $activeId, $pass, $initValues = false)
400  {
401  global $DIC;
402  $ilCtrl = $DIC['ilCtrl'];
403  $lng = $DIC['lng'];
404 
405  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
406  require_once 'Services/Form/classes/class.ilFormSectionHeaderGUI.php';
407  require_once 'Services/Form/classes/class.ilCustomInputGUI.php';
408  require_once 'Services/Form/classes/class.ilCheckboxInputGUI.php';
409  require_once 'Services/Form/classes/class.ilTextInputGUI.php';
410  require_once 'Services/Form/classes/class.ilTextAreaInputGUI.php';
411 
412  $ilCtrl->setParameter($this, 'active_id', $activeId);
413  $ilCtrl->setParameter($this, 'pass', $pass);
414 
415  $form = new ilPropertyFormGUI();
416  $form->setFormAction($ilCtrl->getFormAction($this));
417 
418  $form->setTitle(sprintf($lng->txt('manscoring_results_pass'), $pass + 1));
419  $form->setTableWidth('100%');
420 
422  foreach ($questionGuiList as $questionId => $questionGUI) {
423  $questionHeader = sprintf($lng->txt('tst_manscoring_question_section_header'), $questionGUI->object->getTitle());
424  $questionSolution = $questionGUI->getSolutionOutput($activeId, $pass, false, false, true, false, false, true);
425  $bestSolution = $questionGUI->object->getSuggestedSolutionOutput();
426 
427  $sect = new ilFormSectionHeaderGUI();
428  $sect->setTitle($questionHeader . ' [' . $this->lng->txt('question_id_short') . ': ' . $questionGUI->object->getId() . ']');
429  $form->addItem($sect);
430 
431  $cust = new ilCustomInputGUI($lng->txt('tst_manscoring_input_question_and_user_solution'));
432  $cust->setHtml($questionSolution);
433  $form->addItem($cust);
434 
435  if ($questionGUI->supportsIntermediateSolutionOutput() && $questionGUI->hasIntermediateSolution($activeId, $pass)) {
436  $questionGUI->setUseIntermediateSolution(true);
437  $intermediateSolution = $questionGUI->getSolutionOutput($activeId, $pass, false, false, true, false, false, true);
438  $questionGUI->setUseIntermediateSolution(false);
439  $cust = new ilCustomInputGUI($lng->txt('autosavecontent'));
440  $cust->setHtml($intermediateSolution);
441  $form->addItem($cust);
442  }
443 
444  $text = new ilTextInputGUI($lng->txt('tst_change_points_for_question'), "question__{$questionId}__points");
445  if ($initValues) {
446  $text->setValue(assQuestion::_getReachedPoints($activeId, $questionId, $pass));
447  }
448  $form->addItem($text);
449 
450  $nonedit = new ilNonEditableValueGUI($lng->txt('tst_manscoring_input_max_points_for_question'), "question__{$questionId}__maxpoints");
451  if ($initValues) {
452  $nonedit->setValue(assQuestion::_getMaximumPoints($questionId));
453  }
454  $form->addItem($nonedit);
455 
456  $area = new ilTextAreaInputGUI($lng->txt('set_manual_feedback'), "question__{$questionId}__feedback");
457  $area->setUseRTE(true);
458  if ($initValues) {
459  $area->setValue($this->object->getManualFeedback($activeId, $questionId, $pass));
460  }
461  $form->addItem($area);
462 
463  if (strlen(trim($bestSolution))) {
464  $cust = new ilCustomInputGUI($lng->txt('tst_show_solution_suggested'));
465  $cust->setHtml($bestSolution);
466  $form->addItem($cust);
467  }
468  }
469 
470  $sect = new ilFormSectionHeaderGUI();
471  $sect->setTitle($lng->txt('tst_participant'));
472  $form->addItem($sect);
473 
474  $check = new ilCheckboxInputGUI($lng->txt('set_manscoring_done'), 'manscoring_done');
475  if ($initValues && ilTestService::isManScoringDone($activeId)) {
476  $check->setChecked(true);
477  }
478  $form->addItem($check);
479 
480  $check = new ilCheckboxInputGUI($lng->txt('tst_manscoring_user_notification'), 'manscoring_notify');
481  $form->addItem($check);
482 
483  $form->addCommandButton('saveManScoringParticipantScreen', $lng->txt('save'));
484  $form->addCommandButton('saveReturnManScoringParticipantScreen', $lng->txt('save_return'));
485  $form->addCommandButton('saveNextManScoringParticipantScreen', $lng->txt('save_and_next'));
486 
487  return $form;
488  }
489 
491  {
492  }
493 
497  private function buildManScoringParticipantsTable($withData = false)
498  {
499  require_once 'Modules/Test/classes/tables/class.ilTestManScoringParticipantsTableGUI.php';
501 
502  if ($withData) {
503  $participantStatusFilterValue = $table->getFilterItemByPostVar('participant_status')->getValue();
504 
505  require_once 'Modules/Test/classes/class.ilTestParticipantList.php';
506  $participantList = new ilTestParticipantList($this->object);
507 
508  $participantList->initializeFromDbRows(
509  $this->object->getTestParticipantsForManualScoring($participantStatusFilterValue)
510  );
511 
512  $participantList = $participantList->getAccessFilteredList(
514  );
515 
516  $table->setData($participantList->getParticipantsTableRows());
517  }
518 
519  return $table;
520  }
521 }
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.
global $DIC
Definition: saml.php:7
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
$index
Definition: metadata.php:60
Scoring class for tests.
executeCommand()
execute command
static accessViolationRedirect()
static _getMaximumPoints($question_id)
Returns the maximum points, a learner can reach answering the question.
global $ilCtrl
Definition: ilias.php:18
setChecked($a_checked)
Set Checked.
if(isset($_POST['submit'])) $form
static _mananuallyScoreableQuestionTypesExists()
Returns the fact wether manually scoreable question types exist or not.
$text
Definition: errorreport.php:18
This class represents a text property in a property form.
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.
This class represents a text area property in a property form.
Service GUI class for tests.
if(empty($password)) $table
Definition: pwgen.php:24
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...