ILIAS  trunk Revision v13.0_alpha-62-g3b72d83f2e5
class.ilObjQuestionPreviewGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21use ILIAS\Questions\AnswerForm\Factory as AnswerFormFactory;
25use ILIAS\Questions\Question\Views\Participant as QuestionParticipantView;
30use ILIAS\Data\Factory as DataFactory;
33use ILIAS\Data\UUID\Factory as UuidFactory;
35use ILIAS\HTTP\Services as HTTPServices;
38use ILIAS\Refinery\Factory as Refinery;
43use ILIAS\UI\Factory as UIFactory;
44use ILIAS\UI\Renderer as UIRenderer;
47
52{
53 private const array PARAMETER_NAMENSPACE = ['q', 'p'];
54 private const string ACTION_TOKEN_STRING = 'a';
55 private const string ROW_ID_TOKEN_STRING = 'r';
56
57 private const string CMD_DEFAULT = 'show';
58 private const string CMD_SHOW_QUESTION = 'showQuestion';
59 private const string CMD_RESPOND = 'respond';
60 private const string CMD_DELETE_RESPONSES = 'deleteResponses';
61
62 private const string TEMPLATE_VARIABLE_FORM_ACTION = 'FORM_ACTION';
63 private const string TEMPLATE_VARIABLE_QUESTION_OUTPUT = 'QUESTION_OUTPUT';
64 private const string TEMPLATE_VARIABLE_SUBMIT_BUTTON_LABEL = 'SUBMIT_BUTTON_LABEL';
65
66 private readonly Repository $repository;
67 private readonly AnswerFormFactory $answer_form_factory;
69
71
72 private readonly ilCtrl $ctrl;
73 private readonly Language $lng;
74 private readonly HTTPServices $http;
76 private readonly ilObjUser $current_user;
77 private readonly ilTabsGUI $tabs_gui;
78 private readonly ilToolbarGUI $toolbar;
79 private readonly UIFactory $ui_factory;
80 private readonly UIRenderer $ui_renderer;
81 private readonly \ilUIService $ui_service;
82 private readonly Refinery $refinery;
83 private readonly DataFactory $data_factory;
84 private readonly UuidFactory $uuid_factory;
85
86 private readonly URLBuilder $url_builder;
89
91
92 public function __construct(
93 private readonly int $object_id
94 ) {
96 global $DIC;
97 $this->ctrl = $DIC['ilCtrl'];
98 $this->lng = $DIC['lng'];
99 $this->tpl = $DIC['tpl'];
100 $this->current_user = $DIC['user']->getLoggedInUser();
101 $this->tabs_gui = $DIC['ilTabs'];
102 $this->toolbar = $DIC['ilToolbar'];
103 $this->http = $DIC['http'];
104 $this->ui_factory = $DIC['ui.factory'];
105 $this->ui_renderer = $DIC['ui.renderer'];
106 $this->ui_service = $DIC->uiService();
107 $this->refinery = $DIC['refinery'];
108 $this->data_factory = new DataFactory();
109 $this->uuid_factory = new UuidFactory();
110
111 $this->temp_attempt_repository = new AttemptRepository(
112 $DIC['ilDB'],
113 $this->uuid_factory
114 );
115
116 [
120 ] = $this->getUrlBuilder()->acquireParameters(
121 self::PARAMETER_NAMENSPACE,
122 self::ACTION_TOKEN_STRING,
123 self::ROW_ID_TOKEN_STRING
124 );
125
126 $this->view_configuration = new ViewConfiguration(
127 $this->lng,
128 $this->refinery,
129 $this->ui_factory,
130 $this->http->wrapper()->query(),
131 $url_builder,
132 $DIC['ilToolbar']
133 );
134
135 $this->url_builder = $this->view_configuration
136 ->getURLBuilderWithPreservedConfigurationParameter();
137
143 $local_dic = LocalDIC::dic();
144 $this->repository = $local_dic[Repository::class];
145 $this->answer_form_factory = $local_dic[AnswerFormFactory::class];
146 $this->participant_view = $local_dic[PublicInterface::class]
147 ->getParticipantView(
148 $this->view_configuration->getCurrentConfiguration(),
149 $this->object_id
150 );
151 }
152
153 public function executeCommand(): void
154 {
155 $cmd = $this->ctrl->getCmd();
156
157 $table_action = $this->http->wrapper()->query()->retrieve(
158 $this->action_token->getName(),
159 $this->refinery->byTrying([
160 $this->refinery->kindlyTo()->string(),
161 $this->refinery->always(null)
162 ])
163 );
164
165 if ($table_action !== null) {
166 $cmd = $table_action;
167 }
168
169 if ($cmd === null || $cmd === '') {
170 $cmd = self::CMD_DEFAULT;
171 }
172 $cmd .= 'Cmd';
173 $this->$cmd();
174 }
175
176 private function showCmd(): void
177 {
178 $this->view_configuration->initializeToolbar();
179
180 $filter = $this->buildFilter(
181 $this->ctrl->getLinkTargetByClass(
182 $this->getClassPath()
183 )
184 );
185
186 $this->tpl->setContent(
187 $this->ui_renderer->render([
188 $filter,
189 $this->ui_factory->table()->data(
190 $this,
191 $this->lng->txt('questions'),
192 [
193 OverviewTableColumns::Title->value
194 => $this->ui_factory->table()->column()->link(
195 $this->lng->txt('title')
196 ),
197 OverviewTableColumns::AnswerFormTypes->value
198 => $this->ui_factory->table()->column()->text(
199 $this->lng->txt('contained_answer_form_types')
200 )->withIsOptional(true, true)
201 ->withIsSortable(false),
202 ],
203 )->withRange(new Range(0, 20))
204 ->withFilter(
205 $this->ui_service->filter()->getData($filter)
206 )->withRequest($this->http->request())
207 ])
208 );
209 }
210
211 private function showQuestionCmd(): void
212 {
213 $is_async = $this->view_configuration->isAsync();
214 $question_id = $this->retrieveQuestionIdFromQuery();
215 $attempt = $this->temp_attempt_repository->get(
216 $this->current_user->getId()
217 );
218
219 if ($question_id === null) {
220 $this->tpl->setOnScreenMessage(
221 GlobalTemplate::MESSAGE_TYPE_FAILURE,
222 $this->lng->txt('invalid')
223 );
224 $this->showCmd();
225 }
226
227 $this->tabs_gui->clearTargets();
228 $this->tabs_gui->setBackTarget(
229 $this->lng->txt('back'),
230 $this->view_configuration->getURLBuilderWithPreservedConfigurationParameter(
231 $this->getUrlBuilder()
232 )->buildURI()->__toString()
233 );
234
235 $this->toolbar->addComponent(
236 $this->ui_factory->button()->standard(
237 $this->lng->txt('delete_responses'),
238 $this->view_configuration->getURLBuilderWithPreservedConfigurationParameter(
239 $this->getUrlBuilderWithPreservedQuestionParameter(
240 $question_id,
241 self::CMD_DELETE_RESPONSES
242 )
243 )->buildURI()->__toString()
244 )
245 );
246
247 $view = $this->participant_view->getQuestionView(
248 $question_id,
249 $attempt?->getAttemptId(),
250 true,
251 false,
252 $is_async ? true : false,
253 $is_async ? true : false
254 );
255
256 if ($attempt === null) {
257 $this->temp_attempt_repository->storeNew(
258 $this->current_user->getId(),
259 $view->getAttemptId()
260 );
261 }
262
263 $content = [
264 $this->ui_factory->panel()->standard(
265 $this->lng->txt('question'),
266 $is_async
267 ? $view->getUI()
268 : $this->ui_factory->legacy()->content(
269 $this->buildQuestionForm($view, $question_id)
270 )
271 )
272 ];
273
274 if (!$is_async && $attempt?->isQuestionSolved($question_id) ?? false) {
275 $content[] = $this->ui_factory->panel()->standard(
276 $this->lng->txt('feedback'),
277 $this->participant_view->getQuestionView(
278 $question_id,
279 $attempt->getAttemptId(),
280 false,
281 true,
282 true,
283 true
284 )->getUI()
285 );
286 }
287
288 $this->tpl->setContent(
289 $this->ui_renderer->render(
290 $content
291 )
292 );
293 }
294
295 private function respondCmd(): void
296 {
297 $question_id = $this->retrieveQuestionIdFromQuery();
298 $attempt = $this->temp_attempt_repository->get(
299 $this->current_user->getId()
300 );
301
302 if ($question_id === null || $attempt === null) {
303 $this->tpl->setOnScreenMessage(
304 GlobalTemplate::MESSAGE_TYPE_FAILURE,
305 $this->lng->txt('invalid')
306 );
307 $this->showCmd();
308 }
309
310 $this->participant_view->persistResponse(
311 $question_id,
312 $attempt->getAttemptId()
313 );
314
315 $this->temp_attempt_repository->storeSolved(
316 $attempt->withAdditionalSolvedQuestion($question_id)
317 );
318
319 $this->ctrl->redirectToURL(
320 $this->view_configuration->getURLBuilderWithPreservedConfigurationParameter(
321 $this->getUrlBuilderWithPreservedQuestionParameter(
322 $question_id,
323 self::CMD_SHOW_QUESTION
324 )
325 )->buildURI()->__toString()
326 );
327 }
328
329 private function deleteResponsesCmd(): void
330 {
331 $question_id = $this->retrieveQuestionIdFromQuery();
332 $attempt = $this->temp_attempt_repository->get(
333 $this->current_user->getId()
334 );
335
336 if ($question_id === null || $attempt === null) {
337 $this->tpl->setOnScreenMessage(
338 GlobalTemplate::MESSAGE_TYPE_FAILURE,
339 $this->lng->txt('invalid')
340 );
341 $this->showCmd();
342 }
343
344 $this->participant_view->deleteResponsesFor(
345 $attempt->getAttemptId(),
346 $question_id
347 );
348
349 $this->temp_attempt_repository->storeSolved(
350 $attempt->withQuestionRemovedFromSolved($question_id)
351 );
352
353 $this->ctrl->redirectToURL(
354 $this->view_configuration->getURLBuilderWithPreservedConfigurationParameter(
355 $this->getUrlBuilderWithPreservedQuestionParameter(
356 $question_id,
357 self::CMD_SHOW_QUESTION
358 )
359 )->buildURI()->__toString()
360 );
361 }
362
363 #[\Override]
364 public function getRows(
365 DataRowBuilder $row_builder,
366 array $visible_column_ids,
368 Order $order,
369 mixed $additional_viewcontrol_data,
370 mixed $filter_data,
371 mixed $additional_parameters
372 ): \Generator {
373 foreach ($this->repository->getQuestionDataOnlyForAllQuestions(
374 $range,
375 $order,
376 $filter_data
377 ) as $question) {
378 yield $row_builder->buildDataRow(
379 $question->getid()->toString(),
380 [
381 OverviewTableColumns::Title->value => $this->ui_factory->link()->standard(
382 $question->getTitle(),
383 $this->view_configuration
384 ->getURLBuilderWithPreservedConfigurationParameter()
385 ->withParameter($this->action_token, self::CMD_SHOW_QUESTION)
386 ->withParameter($this->row_id_token, $question->getid()->toString())
387 ->buildURI()
388 ->__toString()
389 ),
390 OverviewTableColumns::AnswerFormTypes->value => implode(
391 '<br>',
392 $question->getListOfContainedAnswerFormTypeLabels($this->lng)
393 )
394 ]
395 );
396 }
397 }
398
399 #[\Override]
400 public function getTotalRowCount(
401 mixed $additional_viewcontrol_data,
402 mixed $filter_data,
403 mixed $additional_parameters
404 ): ?int {
405 return $this->repository->getQuestionsCount($filter_data);
406 }
407
408 private function buildFilter(
409 string $action
410 ): Filter {
411 $filter_inputs = OverviewTableColumns::getFilterInputs(
412 $this->lng,
413 $this->ui_factory->input()->field(),
414 $this->answer_form_factory->getAnswerFormTypesArrayForSelect(
415 $this->lng
416 )
417 );
418
419 $active = array_fill(0, count($filter_inputs), true);
420
421 $filter = $this->ui_service->filter()->standard(
422 'question_table_filter_id',
423 $action,
424 $filter_inputs,
425 $active,
426 true,
427 true
428 );
429
430 $request = $this->http->request();
431 return $request->getMethod() === 'POST'
432 ? $filter->withRequest($request)
433 : $filter;
434 }
435
437 {
438 return $this->http->wrapper()->query()->retrieve(
439 $this->row_id_token->getName(),
440 $this->refinery->byTrying([
441 $this->refinery->custom()->transformation(
442 function (string $v): Uuid {
443 try {
444 return $this->uuid_factory->fromString($v);
445 } catch (Throwable $e) {
447 sprintf('The value could not be transformed into a Uuid'),
448 'not_valid'
449 );
450 }
451 }
452 ),
453 $this->refinery->always(null)
454 ])
455 );
456 }
457
458 private function getUrlBuilder(
459 ?string $cmd = null
460 ): URLBuilder {
461 return new URLBuilder(
462 $this->data_factory->uri(
463 ILIAS_HTTP_PATH . '/' . $this->ctrl->getLinkTargetByClass(
464 $this->getClassPath(),
465 $cmd
466 )
467 )
468 );
469 }
470
472 Uuid $question_id,
473 string $cmd
474 ): URLBuilder {
475 [$url_builder, $row_id_parameter] = $this->getUrlBuilder($cmd)
476 ->acquireParameter(
477 self::PARAMETER_NAMENSPACE,
478 self::ROW_ID_TOKEN_STRING
479 );
480
481 return $url_builder->withParameter(
482 $row_id_parameter,
483 $question_id->toString()
484 );
485 }
486
487 private function buildQuestionForm(
488 QuestionParticipantView $view,
489 Uuid $question_id
490 ): string {
491 $tpl = new \ilTemplate(
492 'tpl.qsts_preview_presentation_interactive.html',
493 true,
494 true,
495 'components/ILIAS/Questions'
496 );
497
499 self::TEMPLATE_VARIABLE_FORM_ACTION,
500 $this->view_configuration->getURLBuilderWithPreservedConfigurationParameter(
501 $this->getUrlBuilderWithPreservedQuestionParameter(
502 $question_id,
503 self::CMD_RESPOND
504 )
505 )->buildURI()
506 ->__toString()
507 );
508
510 self::TEMPLATE_VARIABLE_QUESTION_OUTPUT,
511 $this->ui_renderer->render($view->getUI())
512 );
513
515 self::TEMPLATE_VARIABLE_SUBMIT_BUTTON_LABEL,
516 $this->lng->txt('send')
517 );
518
519 return $tpl->get();
520 }
521
522 private function getClassPath(): array
523 {
524 return [ilObjQuestionsGUI::class, ilObjQuestionPreviewGUI::class];
525 }
526}
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
Both the subject and the direction need to be specified when expressing an order.
Definition: Order.php:29
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:29
Class Services.
Definition: Services.php:43
withParameter(URLBuilderToken $token, string|array $value)
Change an acquired parameter's value if the supplied token is valid.
Definition: URLBuilder.php:166
Class ilCtrl provides processing control methods.
@ilCtrl_isCalledBy ilObjQuestionPreviewGUI: ilObjQuestionsGUI
readonly AnswerFormFactory $answer_form_factory
readonly AttemptRepository $temp_attempt_repository
getUrlBuilderWithPreservedQuestionParameter(Uuid $question_id, string $cmd)
readonly URLBuilderToken $row_id_token
buildQuestionForm(QuestionParticipantView $view, Uuid $question_id)
readonly ViewConfiguration $view_configuration
getRows(DataRowBuilder $row_builder, array $visible_column_ids, Range $range, Order $order, mixed $additional_viewcontrol_data, mixed $filter_data, mixed $additional_parameters)
This is called by the table to retrieve rows; map data-records to rows using the $row_builder e....
readonly URLBuilderToken $action_token
readonly ilGlobalTemplateInterface $tpl
getTotalRowCount(mixed $additional_viewcontrol_data, mixed $filter_data, mixed $additional_parameters)
Mainly for the purpose of pagination-support, it is important to know about the total number of recor...
User class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
special template class to simplify handling of ITX/PEAR
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
foreach( $report as $row)
return['3gp', '7z', 'ai', 'aif', 'aifc', 'aiff', 'au', 'arw', 'avi', 'backup', 'bak', 'bas', 'bpmn', 'bpmn2', 'bmp', 'bib', 'bibtex', 'bz', 'bz2', 'c', 'c++', 'cc', 'cct', 'cdf', 'cer', 'class', 'cls', 'conf', 'cpp', 'crt', 'crs', 'crw', 'cr2', 'css', 'cst', 'csv', 'cur', 'db', 'dcr', 'des', 'dng', 'doc', 'docx', 'dot', 'dotx', 'dtd', 'dvi', 'el', 'eps', 'epub', 'f', 'f77', 'f90', 'flv', 'for', 'g3', 'gif', 'gl', 'gan', 'ggb', 'gsd', 'gsm', 'gtar', 'gz', 'gzip', 'h', 'hpp', 'htm', 'html', 'htmls', 'ibooks', 'ico', 'ics', 'ini', 'ipynb', 'java', 'jbf', 'jpeg', 'jpg', 'js', 'jsf', 'jso', 'json', 'latex', 'lang', 'less', 'log', 'lsp', 'ltx', 'm1v', 'm2a', 'm2v', 'm3u', 'm4a', 'm4v', 'markdown', 'm', 'mat', 'md', 'mdl', 'mdown', 'mid', 'min', 'midi', 'mobi', 'mod', 'mov', 'movie', 'mp2', 'mp3', 'mp4', 'mpa', 'mpeg', 'mpg', 'mph', 'mpga', 'mpp', 'mpt', 'mpv', 'mpx', 'mv', 'mw', 'mv4', 'nb', 'nbp', 'nef', 'nif', 'niff', 'obj', 'obm', 'odt', 'ods', 'odp', 'odg', 'odf', 'oga', 'ogg', 'ogv', 'old', 'p', 'pas', 'pbm', 'pcl', 'pct', 'pcx', 'pdf', 'pgm', 'pic', 'pict', 'png', 'por', 'pov', 'project', 'properties', 'ppa', 'ppm', 'pps', 'ppsx', 'ppt', 'pptx', 'ppz', 'ps', 'psd', 'pwz', 'qt', 'qtc', 'qti', 'qtif', 'r', 'ra', 'ram', 'rar', 'rast', 'rda', 'rev', 'rexx', 'ris', 'rf', 'rgb', 'rm', 'rmd', 'rmi', 'rmm', 'rmp', 'rt', 'rtf', 'rtx', 'rv', 's', 's3m', 'sav', 'sbs', 'sec', 'sdml', 'sgm', 'sgml', 'smi', 'smil', 'srt', 'sps', 'spv', 'stl', 'svg', 'swa', 'swf', 'swz', 'tar', 'tex', 'texi', 'texinfo', 'text', 'tgz', 'tif', 'tiff', 'ttf', 'txt', 'tmp', 'uvproj', 'vdf', 'vimeo', 'viv', 'vivo', 'vrml', 'vsdx', 'vtt', 'wav', 'webm', 'wmv', 'wmx', 'wmz', 'woff', 'wwd', 'xhtml', 'xif', 'xls', 'xlsx', 'xmind', 'xml', 'xsl', 'xsd', 'zip']
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
toString()
Converts this UUID into a string representation.
setVariable(string $variable, $value='')
Sets the given variable to the given value.
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
This describes a standard filter.
Definition: Standard.php:27
buildDataRow(string $id, array $record)
An entity that renders components to a string output.
Definition: Renderer.php:31
$request
@ilCtrl_Calls ilObjLearningSequenceContentGUI: ilObjLearningSequenceConditionsGUI
Definition: ltiauth.php:39
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
readonly ilGlobalTemplateInterface $tpl
global $DIC
Definition: shib_login.php:26