ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilLOEditorStatus.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=0);
20
22use ILIAS\UI\Renderer as UiRenderer;
24
30{
31 public const SECTION_UNDEFINED = 0;
32 public const SECTION_SETTINGS = 1;
33 public const SECTION_MATERIALS = 2;
34 public const SECTION_ITES = 3;
35 public const SECTION_QTEST = 4;
36 public const SECTION_OBJECTIVES = 5;
37 public const SECTION_OBJECTIVES_NEW = 6;
38
39 protected static ?self $instance = null;
40
42
44 protected array $failures_by_section = [];
45
47 protected array $error_by_section = [];
48
49 protected array $objectives = [];
50 protected int $forced_test_type = 0;
51
55 protected ?object $cmd_class = null;
56 protected string $html = '';
57
59 protected ilLanguage $lng;
60 protected ilTree $tree;
62 protected UiRenderer $ui_renderer;
63 protected UiWorkflow $workflow;
64 protected \ILIAS\Refinery\Factory $refinery;
65 protected \ILIAS\HTTP\Services $http;
66
67 public function __construct(ilObject $a_parent)
68 {
69 global $DIC;
70
71 $this->parent_obj = $a_parent;
73 $this->assignments = ilLOTestAssignments::getInstance($this->getParentObject()->getId());
74 $this->objectives = ilCourseObjective::_getObjectiveIds($this->getParentObject()->getId());
75
76 $this->ctrl = $DIC->ctrl();
77 $this->lng = $DIC->language();
78 $this->tree = $DIC->repositoryTree();
79 $this->tpl = $DIC->ui()->mainTemplate();
80 $this->workflow = $DIC->ui()->factory()->listing()->workflow();
81 $this->ui_renderer = $DIC->ui()->renderer();
82 $this->http = $DIC->http();
83 $this->refinery = $DIC->refinery();
84 }
85
86 public static function getInstance(ilObject $a_parent): self
87 {
88 if (self::$instance !== null) {
89 return self::$instance;
90 }
91 return self::$instance = new self($a_parent);
92 }
93
94 protected function initTestTypeFromQuery(): int
95 {
96 if ($this->forced_test_type > 0) {
98 }
99
100 if ($this->http->wrapper()->query()->has('tt')) {
101 return $this->http->wrapper()->query()->retrieve(
102 'tt',
103 $this->refinery->kindlyTo()->int()
104 );
105 }
106 return 0;
107 }
108
112 public function getObjectives(): array
113 {
114 return $this->objectives;
115 }
116
118 {
119 return $this->assignments;
120 }
121
122 public function setSection(int $a_section): void
123 {
124 $this->section = $a_section;
125 }
126
127 public function getSection(): int
128 {
129 return $this->section;
130 }
131
132 public function getFailures(int $a_section): array
133 {
134 return (array) ($this->failures_by_section[$a_section] ?? []);
135 }
136
137 protected function appendFailure(int $a_section, string $a_failure_msg_key, bool $is_error = false): void
138 {
139 $this->failures_by_section[$a_section][] = $a_failure_msg_key;
140 if ($is_error) {
141 $this->error_by_section[$a_section] = $a_section;
142 }
143 }
144
145 public function setCmdClass(object $a_cmd_class): void
146 {
147 $this->cmd_class = $a_cmd_class;
148 }
149
150 public function getCmdClass(): object
151 {
152 return $this->cmd_class;
153 }
154
155 public function getParentObject(): ilObject
156 {
157 return $this->parent_obj;
158 }
159
160 public function getSettings(): ilLOSettings
161 {
162 return $this->settings;
163 }
164
165 public function getFirstFailedStep(): string
166 {
167 if (!$this->getSettingsStatus()) {
168 return 'settings';
169 }
170 if (!$this->getObjectivesAvailableStatus()) {
171 return 'showObjectiveCreation';
172 }
173 if (!$this->getMaterialsStatus(false)) {
174 return 'materials';
175 }
176 if ($this->getSettings()->worksWithInitialTest()) {
177 if (!$this->getInitialTestStatus(false)) {
178 $this->forced_test_type = ilLOSettings::TYPE_TEST_INITIAL;
179 if ($this->getSettings()->hasSeparateInitialTests()) {
180 return 'testsOverviewInitial';
181 } else {
182 return 'testOverviewInitial';
183 }
184 }
185 }
186 if (!$this->getQualifiedTestStatus(false)) {
187 $this->forced_test_type = ilLOSettings::TYPE_TEST_QUALIFIED;
188 if ($this->getSettings()->hasSeparateQualifiedTests()) {
189 return 'testsOverviewQualified';
190 } else {
191 return 'testOverviewQualified';
192 }
193 }
194 return 'listObjectives';
195 }
196
197 public function getHTML(): string
198 {
199 $steps = [];
200 // Step 1
201 // course settings
202 $done = $this->getSettingsStatus();
203
204 $steps[] = $this->workflow->step(
205 $this->lng->txt('crs_objective_status_settings'),
206 implode(" ", $this->getFailureMessages(self::SECTION_SETTINGS)),
207 $this->ctrl->getLinkTarget($this->getCmdClass(), 'settings')
208 )->withStatus($this->determineStatus($done, self::SECTION_SETTINGS));
209
210 // Step 1.1
211 $done = $this->getObjectivesAvailableStatus(true);
212
213 $steps[] = $this->workflow->step(
214 $this->lng->txt('crs_objective_status_objective_creation'),
215 implode(" ", $this->getFailureMessages(self::SECTION_OBJECTIVES_NEW)),
216 $done
217 ? $this->ctrl->getLinkTarget($this->getCmdClass(), 'listObjectives')
218 : $this->ctrl->getLinkTarget($this->getCmdClass(), 'showObjectiveCreation')
219 )->withStatus($this->determineStatus($done, self::SECTION_OBJECTIVES_NEW));
220
221 // Step 2
222 // course material
223 $done = $this->getMaterialsStatus(true);
224 //$this->ctrl->setParameterByClass('ilobjcoursegui', 'cmd', 'enableAdministrationPanel');
225
226 $steps[] = $this->workflow->step(
227 $this->lng->txt('crs_objective_status_materials'),
228 implode(" ", $this->getFailureMessages(self::SECTION_MATERIALS)),
229 $this->ctrl->getLinkTargetByClass('ilobjcoursegui', 'enableAdministrationPanel')
230 )->withStatus($this->determineStatus($done, self::SECTION_MATERIALS));
231
232 // Step 3
233 // course itest
234 if (ilLOSettings::getInstanceByObjId($this->getParentObject()->getId())->worksWithInitialTest()) {
235 $done = $this->getInitialTestStatus();
236 $command = $this->getSettings()->hasSeparateInitialTests() ?
237 'testsOverview' :
238 'testOverview';
239 $this->ctrl->setParameter($this->getCmdClass(), 'tt', ilLOSettings::TYPE_TEST_INITIAL);
240
241 $steps[] = $this->workflow->step(
242 $this->lng->txt('crs_objective_status_itest'),
243 implode(" ", $this->getFailureMessages(self::SECTION_ITES)),
244 $this->ctrl->getLinkTarget($this->getCmdClass(), $command)
245 )->withStatus($this->determineStatus($done, self::SECTION_ITES));
246 }
247
248 // Step 4
249 // course qtest
250 $done = $this->getQualifiedTestStatus();
251 $command = $this->getSettings()->hasSeparateQualifiedTests() ?
252 'testsOverview' :
253 'testOverview';
254 $this->ctrl->setParameter($this->getCmdClass(), 'tt', ilLOSettings::TYPE_TEST_QUALIFIED);
255 $steps[] = $this->workflow->step(
256 $this->lng->txt('crs_objective_status_qtest'),
257 implode(" ", $this->getFailureMessages(self::SECTION_QTEST)),
258 $this->ctrl->getLinkTarget($this->getCmdClass(), $command)
259 )->withStatus($this->determineStatus($done, self::SECTION_QTEST));
260
261 // Step 5
262 // course qtest
263 $done = $this->getObjectivesStatus();
264 $this->ctrl->setParameter($this->getCmdClass(), 'tt', $this->initTestTypeFromQuery());
265
266 $steps[] = $this->workflow->step(
267 $this->lng->txt('crs_objective_status_objectives'),
268 implode(" ", $this->getFailureMessages(self::SECTION_OBJECTIVES)),
269 $this->ctrl->getLinkTarget($this->getCmdClass(), 'listObjectives')
270 )->withStatus($this->determineStatus($done, self::SECTION_OBJECTIVES));
271
272 $list = $this->workflow->linear(
273 $this->lng->txt('crs_objective_status_configure'),
274 $steps
275 )->withActive($this->determineActiveSection());
276 return $this->ui_renderer->render($list);
277 }
278
282 public function getFailureMessages(int $a_section): array
283 {
284 $mess = array();
285 foreach ($this->getFailures($a_section) as $failure_code) {
286 $mess[] = $this->lng->txt($failure_code);
287 }
288 return $mess;
289 }
290
291 public function determineStatus(bool $done, int $section): int
292 {
293 if ($done) {
294 return Step::SUCCESSFULLY;
295 } elseif ($this->hasSectionErrors($section)) {
296 return Step::UNSUCCESSFULLY;
297 } elseif ($this->section === $section) {
298 return Step::IN_PROGRESS;
299 } else {
300 return Step::NOT_STARTED;
301 }
302 }
303
304 public function determineActiveSection(): int
305 {
306 $itest_enabled = ilLOSettings::getInstanceByObjId($this->getParentObject()->getId())->worksWithInitialTest();
307 $active_map = array(
308 self::SECTION_SETTINGS => 0,
309 self::SECTION_OBJECTIVES_NEW => 1,
310 self::SECTION_MATERIALS => 2,
311 self::SECTION_ITES => 3,
312 self::SECTION_QTEST => $itest_enabled ? 4 : 3,
313 self::SECTION_OBJECTIVES => $itest_enabled ? 5 : 4
314 );
315
316 return $active_map[$this->section];
317 }
318
319 public function hasSectionErrors(int $a_section): bool
320 {
321 return isset($this->error_by_section[$a_section]);
322 }
323
324 protected function getSettingsStatus(): bool
325 {
326 return $this->getSettings()->settingsExist();
327 }
328
329 protected function getObjectivesAvailableStatus($a_set_errors = false): bool
330 {
331 $ret = count($this->getObjectives());
332
333 if (!$ret && $a_set_errors) {
334 $this->appendFailure(self::SECTION_OBJECTIVES_NEW, 'crs_no_objectives_created');
335 return false;
336 }
337 return true;
338 }
339
340 protected function getMaterialsStatus(bool $a_set_errors = true): bool
341 {
342 $childs = $this->tree->getChilds($this->getParentObject()->getRefId());
343 foreach ($childs as $tnode) {
344 if ($tnode['type'] == 'rolf') {
345 continue;
346 }
347 if ($tnode['child'] == $this->getSettings()->getInitialTest()) {
348 continue;
349 }
350 if ($tnode['child'] == $this->getSettings()->getQualifiedTest()) {
351 continue;
352 }
353 return true;
354 }
355 if ($a_set_errors) {
356 $this->appendFailure(self::SECTION_MATERIALS, 'crs_loc_err_stat_no_materials');
357 }
358 return false;
359 }
360
361 protected function getInitialTestStatus(bool $a_set_errors = true): bool
362 {
363 if ($this->getSettings()->hasSeparateInitialTests()) {
364 if (count($this->objectives) <= 0) {
365 return false;
366 }
367
368 foreach ($this->getObjectives() as $objective_id) {
369 $tst_ref = $this->getAssignments()->getTestByObjective($objective_id, ilLOSettings::TYPE_TEST_INITIAL);
370 if (!$this->tree->isInTree($tst_ref)) {
371 if ($a_set_errors) {
372 $this->appendFailure(self::SECTION_ITES, 'crs_loc_err_stat_no_it');
373 }
374 return false;
375 }
376 if (!$this->checkTestOnline($tst_ref)) {
377 if ($a_set_errors) {
378 $this->appendFailure(self::SECTION_ITES, 'crs_loc_err_stat_tst_offline', true);
379 }
380 return false;
381 }
382 }
383 return true;
384 }
385
386 $tst_ref = $this->getSettings()->getInitialTest();
387 if (!$this->tree->isInTree($tst_ref)) {
388 if ($a_set_errors) {
389 $this->appendFailure(self::SECTION_ITES, 'crs_loc_err_stat_no_it');
390 }
391 return false;
392 }
393 if (!$this->checkTestOnline($tst_ref)) {
394 if ($a_set_errors) {
395 $this->appendFailure(self::SECTION_ITES, 'crs_loc_err_stat_tst_offline', true);
396 }
397 return false;
398 }
399 return true;
400 }
401
402 protected function getQualifiedTestStatus(bool $a_set_errors = true): bool
403 {
404 if ($this->getSettings()->hasSeparateQualifiedTests()) {
405 if (count($this->objectives) <= 0) {
406 return false;
407 }
408
409 foreach ($this->getObjectives() as $objective_id) {
410 $tst_ref = $this->getAssignments()->getTestByObjective(
411 $objective_id,
413 );
414 if (!$this->tree->isInTree($tst_ref)) {
415 if ($a_set_errors) {
416 $this->appendFailure(self::SECTION_QTEST, 'crs_loc_err_stat_no_qt');
417 }
418 return false;
419 }
420 if (!$this->checkTestOnline($tst_ref)) {
421 if ($a_set_errors) {
422 $this->appendFailure(self::SECTION_QTEST, 'crs_loc_err_stat_tst_offline', true);
423 }
424 return false;
425 }
426 }
427 return true;
428 }
429 $tst_ref = $this->getSettings()->getQualifiedTest();
430 if (!$this->tree->isInTree($tst_ref)) {
431 if ($a_set_errors) {
432 $this->appendFailure(self::SECTION_QTEST, 'crs_loc_err_stat_no_qt');
433 }
434 return false;
435 }
436 if (!$this->checkTestOnline($tst_ref)) {
437 if ($a_set_errors) {
438 $this->appendFailure(self::SECTION_QTEST, 'crs_loc_err_stat_tst_offline', true);
439 }
440 return false;
441 }
442 return true;
443 }
444
445 protected function lookupQuestionsAssigned(int $a_test_ref_id): bool
446 {
448 foreach ($this->getObjectives() as $objective_id) {
450 $this->parent_obj->getId(),
451 $objective_id,
452 ilObject::_lookupObjId($a_test_ref_id)
453 );
454 if ($seq === []) {
455 return false;
456 }
457 }
458 } else {
459 foreach ($this->getObjectives() as $objective_id) {
461 ilObject::_lookupObjId($a_test_ref_id),
462 $objective_id
463 );
464 if ($qsts === []) {
465 return false;
466 }
467 }
468 }
469 return true;
470 }
471
472 protected function getObjectivesStatus(bool $a_set_errors = true): bool
473 {
474 if (!$this->getObjectivesAvailableStatus($a_set_errors)) {
475 return false;
476 }
477
478 $num_active = ilCourseObjective::_getCountObjectives($this->getParentObject()->getId(), true);
479 if ($num_active === 0) {
480 if ($a_set_errors) {
481 $this->appendFailure(self::SECTION_OBJECTIVES, 'crs_loc_err_no_active_lo');
482 }
483 return false;
484 }
485 foreach (ilCourseObjective::_getObjectiveIds($this->getParentObject()->getId(), true) as $objective_id) {
486 $obj = new ilCourseObjectiveMaterials($objective_id);
487 if ($obj->getMaterials() === []) {
488 if ($a_set_errors) {
489 $this->appendFailure(self::SECTION_OBJECTIVES, 'crs_loc_err_no_active_mat');
490 }
491 return false;
492 }
493 }
494 // check for assigned initial test questions
495 if ($this->getSettings()->worksWithInitialTest() && !$this->getSettings()->hasSeparateInitialTests()) {
496 // check for assigned questions
497 if (!$this->lookupQuestionsAssigned($this->getSettings()->getInitialTest())) {
498 if ($a_set_errors) {
499 $this->appendFailure(self::SECTION_OBJECTIVES, 'crs_loc_err_no_active_qst');
500 }
501 return false;
502 }
503 }
504 // check for assigned questions
505 if (!$this->getSettings()->hasSeparateQualifiedTests() && !$this->lookupQuestionsAssigned($this->getSettings()->getQualifiedTest())) {
506 if ($a_set_errors) {
507 $this->appendFailure(self::SECTION_OBJECTIVES, 'crs_loc_err_no_active_qst');
508 }
509 return false;
510 }
511 return true;
512 }
513
514 protected function getStartStatus(): bool
515 {
516 return true;
517 }
518
519 protected function checkNumberOfTries(): bool
520 {
521 $qt = $this->getSettings()->getQualifiedTest();
522 if (!$qt) {
523 return true;
524 }
525
526 $factory = new ilObjectFactory();
527 $tst = $factory->getInstanceByRefId($qt, false);
528
529 if (!$tst instanceof ilObjTest) {
530 return true;
531 }
532 $tries = $tst->getNrOfTries();
533 if (!$tries) {
534 return true;
535 }
536
537 $obj_tries = 0;
538 foreach ($this->getObjectives() as $objective) {
539 $obj_tries += ilCourseObjective::lookupMaxPasses($objective);
540 }
541 return $obj_tries <= $tries;
542 }
543
544 protected function checkTestOnline(int $a_ref_id): bool
545 {
547 }
548}
class ilCourseObjectiveMaterials
static lookupQuestionsByObjective(int $a_test_id, int $a_objective)
static _getCountObjectives(int $a_obj_id, bool $a_activated_only=false)
static lookupMaxPasses(int $a_objective_id)
static _getObjectiveIds(int $course_id, bool $a_activated_only=false)
Presentation of the status of single steps during the configuration process.
getObjectivesStatus(bool $a_set_errors=true)
hasSectionErrors(int $a_section)
setSection(int $a_section)
getFailureMessages(int $a_section)
ilGlobalTemplateInterface $tpl
getQualifiedTestStatus(bool $a_set_errors=true)
static getInstance(ilObject $a_parent)
determineStatus(bool $done, int $section)
getMaterialsStatus(bool $a_set_errors=true)
lookupQuestionsAssigned(int $a_test_ref_id)
appendFailure(int $a_section, string $a_failure_msg_key, bool $is_error=false)
getInitialTestStatus(bool $a_set_errors=true)
getObjectivesAvailableStatus($a_set_errors=false)
setCmdClass(object $a_cmd_class)
ilLOTestAssignments $assignments
checkTestOnline(int $a_ref_id)
ILIAS HTTP Services $http
getFailures(int $a_section)
__construct(ilObject $a_parent)
ILIAS Refinery Factory $refinery
static lookupSequences(int $a_container_id, int $a_objective_id, int $a_test_id)
Settings for LO courses.
static getInstanceByObjId(int $a_obj_id)
Settings for LO courses.
static getInstance(int $a_container_id)
static lookupRandomTest(int $a_test_obj_id)
language handling
static _isOffline(int $obj_id)
returns the objects's OFFline status
Class ilObjectFactory This class offers methods to get instances of the type-specific object classes ...
Class ilObject Basic functions for all objects.
static _lookupObjId(int $ref_id)
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
This is the interface for a workflow factory.
Definition: Factory.php:29
An entity that renders components to a string output.
Definition: Renderer.php:31
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static http()
Fetches the global http state from ILIAS.
global $DIC
Definition: shib_login.php:26