ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilTestPassResultsTable.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
28 
34 {
35  private const ENV = 'e';
36  private const LNG = 'l';
37  private const URL_NAMESPACE = ['taresult', 'vc'];
38  private const PARAM_MODE = 'm';
39  private const MODE_OPT_ALL = "all";
40  private const MODE_OPT_CORRECT = "ok";
41  private const MODE_OPT_INCORRECT = "fail";
42  private const PARAM_SORT = 's';
43  private const SORT_OPT_ORDEROFAPPEARANCE = 'ooa';
44  private const SORT_OPT_POSSIBLESCORE = 'ms';
45 
46  protected Presentation $table;
47 
48  public function __construct(
49  UIFactory $ui_factory,
50  protected UIRenderer $ui_renderer,
51  protected Refinery $refinery,
52  protected HTTPService $http,
53  DataFactory $data_factory,
55  protected ilTestPassResult $test_results,
56  string $title
57  ) {
58  list($mode, $sortation) = $this->getViewControlsParameter();
59  $results = $this->applyControls($mode, $sortation, $test_results->getQuestionResults());
60  $target = new URLBuilder($data_factory->uri($http->request()->getUri()->__toString()));
61 
62  $this->table = $ui_factory->table()->presentation(
63  $title,
64  $this->getViewControls($ui_factory, $lng, $target, $mode, $sortation),
65  $this->getMapping()
66  )
67  ->withEnvironment([
68  self::ENV => $test_results->getSettings(),
69  self::LNG => $lng
70  ])
71  ->withData($results);
72  }
73 
74  public function render(): string
75  {
76  return $this->ui_renderer->render($this->table);
77  }
78 
82  protected function applyControls(
83  string $mode,
84  string $sortation,
85  array $question_results
86  ) {
87  switch ($mode) {
88  case self::MODE_OPT_CORRECT:
89  $filter = static fn($qr) => $qr->getCorrect() === ilQuestionResult::CORRECT_FULL;
90  break;
91  case self::MODE_OPT_INCORRECT:
92  $filter = static fn($qr) => $qr->getCorrect() !== ilQuestionResult::CORRECT_FULL;
93  break;
94  case self::MODE_OPT_ALL:
95  default:
96  $filter = static fn($qr) => true;
97  }
98  $question_results = array_filter($question_results, $filter);
99 
100  if ($sortation === self::SORT_OPT_POSSIBLESCORE) {
101  usort(
102  $question_results,
104  );
105  $question_results = array_reverse($question_results);
106  }
107  return $question_results;
108  }
109 
110  protected function getViewControlNamespace(): array
111  {
112  $namespace = self::URL_NAMESPACE;
113  $namespace[] = (string) $this->test_results->getActiveId();
114  $namespace[] = (string) $this->test_results->getPass();
115  return $namespace;
116  }
117 
118  protected function getViewControlsParameter(): array
119  {
120  $request = $this->http->wrapper()->query();
121  $pre = implode(URLBuilder::SEPARATOR, $this->getViewControlNamespace()) . URLBuilder::SEPARATOR;
122 
123  $mode = $request->has($pre . self::PARAM_MODE) ?
124  $request->retrieve($pre . self::PARAM_MODE, $this->refinery->kindlyTo()->string()) : self::MODE_OPT_ALL;
125 
126  $sortation = $request->has($pre . self::PARAM_SORT) ?
127  $request->retrieve($pre . self::PARAM_SORT, $this->refinery->kindlyTo()->string()) : self::SORT_OPT_ORDEROFAPPEARANCE;
128 
129  return [$mode, $sortation];
130  }
131 
135  protected function getViewControls(
136  UIFactory $ui_factory,
138  URLBuilder $target,
139  string $mode,
140  string $sortation
141  ): array {
142  $builder = $target->acquireParameter($this->getViewControlNamespace(), self::PARAM_MODE);
143  [$target, $token] = $builder;
144 
145  $modes = [
146  $lng->txt('resulttable_all') => $target->withParameter($token, self::MODE_OPT_ALL)->buildURI()->__toString(),
147  $lng->txt('resulttable_correct') => $target->withParameter($token, self::MODE_OPT_CORRECT)->buildURI()->__toString(),
148  $lng->txt('resulttable_incorrect') => $target->withParameter($token, self::MODE_OPT_INCORRECT)->buildURI()->__toString(),
149  ];
150  $check = [self::MODE_OPT_ALL, self::MODE_OPT_CORRECT, self::MODE_OPT_INCORRECT];
151  $active = array_search($mode, $check);
152 
153  $vc_mode = $ui_factory->viewControl()->mode($modes, $lng->txt('ta_resulttable_vc_mode_aria'))
154  ->withActive(array_keys($modes)[$active]);
155 
156  $options = [
157  self::SORT_OPT_ORDEROFAPPEARANCE => $lng->txt('resulttable_vc_sort_iooa'),
158  self::SORT_OPT_POSSIBLESCORE => $lng->txt('resulttable_vc_sort_posscore')
159  ];
160 
161  $pre = implode(URLBuilder::SEPARATOR, $this->getViewControlNamespace()) . URLBuilder::SEPARATOR;
162  $vc_sort = $ui_factory->viewControl()->sortation($options)->withTargetURL(
163  $target->buildURI()->__toString(),
164  $pre . self::PARAM_SORT
165  )
166  ->withLabel($options[$sortation]);
167 
168  return [
169  $vc_mode,
170  $vc_sort
171  ];
172  }
173 
174  protected function getMapping(): \Closure
175  {
176  return function ($row, $question_result, $ui_factory, $environment) {
177  $env = $environment[self::ENV];
178  $lng = $environment[self::LNG];
179 
180  $title = htmlspecialchars($question_result->getTitle());
181 
182  $important_fields = [
183  $lng->txt('position') => (string) ($question_result->getPosition() + 1),
184  $lng->txt('question_id') => (string) $question_result->getId(),
185  $lng->txt('question_type') => $lng->txt($question_result->getType()),
186  $lng->txt('points') => sprintf(
187  '%s/%s (%s%%)',
188  (string) $question_result->getUserScore(),
189  (string) $question_result->getQuestionScore(),
190  (string) $question_result->getUserScorePercent()
191  )
192  ];
193 
194  $stats_fields = $important_fields;
195  $stats_fields[$lng->txt('tst_question_hints_requested_hint_count_header')] = (string) $question_result->getNumberOfRequestedHints();
196  $stats = $ui_factory->listing()->characteristicValue()->text($stats_fields);
197 
198 
199  $feedback = $ui_factory->listing()->descriptive([
200  $lng->txt('tst_feedback') => $question_result->getFeedback()
201  ]);
202 
203  $contents = [];
204 
205  $contents[] = $stats;
206  if ($env->getShowFeedback()) {
207  $contents[] = $feedback;
208  }
209 
210  if ($recap = $question_result->getContentForRecapitulation()) {
211  $contents[] = $ui_factory->listing()->descriptive([
212  $lng->txt('suggested_solution') => $recap
213  ]);
214  }
215 
216  $listing = [
217  $lng->txt('tst_header_participant') => $question_result->getUserAnswer()
218  ];
219  if ($autosave_content = $question_result->getAutosavedAnswer()) {
220  $listing[$lng->txt('autosavecontent')] = $autosave_content;
221  }
222 
223  $answer_contents = [
224  $ui_factory->listing()->descriptive($listing)
225  ];
226  if ($env->getShowBestSolution()) {
227  $answer_contents[] = $ui_factory->listing()->descriptive([
228  $lng->txt('tst_header_solution') => $question_result->getBestSolution()
229  ]);
230  }
231 
232  $answers = $ui_factory->layout()->alignment()->horizontal()->evenlyDistributed(...$answer_contents);
233  $contents[] = $answers;
234 
235  $content = $ui_factory->layout()->alignment()->vertical(...$contents);
236 
237  switch ($question_result->getCorrect()) {
239  $icon_name = 'icon_ok.svg';
240  $label = $lng->txt("answer_is_right");
241  break;
243  $icon_name = 'icon_mostly_ok.svg';
244  $label = $lng->txt("answer_is_not_correct_but_positive");
245  break;
247  $icon_name = 'icon_not_ok.svg';
248  $label = $lng->txt("answer_is_wrong");
249  break;
250  }
251  $path = ilUtil::getImagePath('standard/' . $icon_name);
252  $correct_icon = $ui_factory->symbol()->icon()->custom(
253  $path,
254  $label
255  );
256 
257  return $row
258  ->withHeadline($title)
259  ->withLeadingSymbol($correct_icon)
260  ->withImportantFields($important_fields)
261  ->withContent($content);
262  };
263  }
264 }
if($err=$client->getError()) $namespace
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
buildURI()
Get a URI representation of the full URL including query string and fragment/hash.
Definition: URLBuilder.php:211
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
__construct(UIFactory $ui_factory, protected UIRenderer $ui_renderer, protected Refinery $refinery, protected HTTPService $http, DataFactory $data_factory, ilLanguage $lng, protected ilTestPassResult $test_results, string $title)
$path
Definition: ltiservices.php:32
static http()
Fetches the global http state from ILIAS.
applyControls(string $mode, string $sortation, array $question_results)
$lng
$token
Definition: xapitoken.php:70
$results
$http
Definition: raiseError.php:7
getViewControls(UIFactory $ui_factory, ilLanguage $lng, URLBuilder $target, string $mode, string $sortation)
return []
withParameter(URLBuilderToken $token, string|array $value)
Change an acquired parameter&#39;s value if the supplied token is valid.
Definition: URLBuilder.php:165
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$check
Definition: buildRTE.php:81
acquireParameter(array $namespace, string $name, ?string $initial_value=null)
Add a new parameter with a namespace and get its token for subsequent changes.
Definition: URLBuilder.php:118
URLBuilder.
Definition: URLBuilder.php:39
Refinery Factory $refinery