ILIAS  trunk Revision v13.0_alpha-62-g3b72d83f2e5
ilLSPlayer Class Reference

Implementation of KioskMode Player. More...

+ Collaboration diagram for ilLSPlayer:

Public Member Functions

 __construct (protected ilLSLearnerItemsQueries $ls_items, protected LSControlBuilder $control_builder, protected LSUrlBuilder $url_builder, protected ilLSViewFactory $view_factory, protected ilKioskPageRenderer $page_renderer, protected Factory $ui_factory, protected ScreenContext $current_context, protected Refinery\Factory $refinery, protected ilLanguage $lng, protected ilCtrlInterface $ctrl, protected ?LSNavigator $navigator=null, protected int $mode=ilLearningSequenceSettings::MODE_LINEAR, protected ?LSOItemPath $item_path=null, protected ?LSOAdaptiveBoundaries $boundaries=null, protected int $lso_obj_id=0, protected int $usr_id=0, protected ?LSOLearningMapPosition $position=null, protected ?LSChoicePageBuilder $choice_page_builder=null, protected ?Closure $learning_map=null)
 
 play (RequestWrapper $get)
 
 getCurrentItemLearningProgress ()
 

Data Fields

const PARAM_LSO_COMMAND = 'lsocmd'
 
const PARAM_LSO_PARAMETER = 'lsov'
 
const LSO_CMD_NEXT = 'lsonext'
 
const LSO_CMD_GOTO = 'lsogoto'
 
const LSO_CMD_JUMP = 'lsojump'
 
const LSO_CMD_SUSPEND = 'lsosuspend'
 
const LSO_CMD_FINISH = 'lsofinish'
 
const LSO_CMD_CHOICE = 'lsochoice'
 
const LSO_CMD_STAY = 'lsostay'
 
const REDIRECT_PREFIX = 'REDIRECT::'
 
const GS_DATA_LS_KIOSK_MODE = 'ls_kiosk_mode'
 
const GS_DATA_LS_TITLE = 'ls_title'
 
const GS_DATA_LS_CONTENT = 'ls_content'
 
const GS_DATA_LS_MAINBARCONTROLS = 'ls_mainbar_controls'
 
const GS_DATA_LS_METABARCONTROLS = 'ls_metabar_controls'
 

Protected Member Functions

 getLearningMapHtml (int $ls_ref_id)
 The learning map of the current user, without the panel around it - it is shown inside the modal of the main bar entry. More...
 
 getCurrentItem (array $items)
 
 getNextAvailableItem (array $items, LSLearnerItem $current_item)
 
 updateViewState (ILIAS\KioskMode\State $state, ILIAS\KioskMode\View $view, RequestWrapper $get)
 
 getNextItem (array $items, LSLearnerItem $current_item, int $direction)
 $direction is either -1 or 1; More...
 
 isItemAvailableForSequenceNavigation (array $items, LSLearnerItem $current_item, LSLearnerItem $target_item, int $direction)
 
 getPosition ()
 
 findItemByRefId (array $items, int $ref_id)
 
 buildDefaultControls (LSControlBuilder $control_builder, LSLearnerItem $item, int $item_position, array $items)
 
 renderComponentView ($state, ILIAS\KioskMode\View $view)
 
 isAdaptive ()
 Whether the player runs in adaptive mode with the required collaborators (navigator, path repository and boundaries) available. More...
 
 getAdaptiveStartObjId ()
 
 getAdaptiveEndObjId ()
 
 getAdaptiveCurrentItem (array $items)
 Determines the current object in adaptive mode from the walked path. More...
 
 getAdaptiveNextItem (array $items, LSLearnerItem $current_item, ?int $direction)
 Handles "next"/"back" in adaptive mode. More...
 
 jumpAdaptive (array $items, LSLearnerItem $current_item, ?int $param)
 Jumps right to the chosen object in adaptive mode (learning map). More...
 
 gotoAdaptive (array $items, LSLearnerItem $current_item, ?int $param)
 
 getAdaptiveSituation (array $items, LSLearnerItem $item)
 Classifies the situation of the given object in adaptive mode: 'end', 'blocked', 'deadend', 'branch' or 'straight'. More...
 
 landsOnInterstitialPage (array $items, LSLearnerItem $item)
 Whether arriving on the item (by a step back or by resuming) shows its interstitial page instead of the object: on a branch, or on a dead end that is one structurally as well. More...
 
 amendAdaptiveContent (array $content, array $items, LSLearnerItem $item)
 Amends the rendered content with adaptive hints or a choice panel. More...
 
 buildAdaptiveChoiceContent (array $items, LSLearnerItem $item)
 Builds the branch-selection content (one card per allowed successor) using the reusable LSChoicePageBuilder template. More...
 
 buildAdaptiveDeadEndContent ()
 
 buildAdaptiveControls (LSControlBuilder $control_builder, LSLearnerItem $item, array $items)
 Builds the navigation controls for adaptive mode based on the situation and the length of the walked path. More...
 
 buildAdaptiveChoiceControls (LSControlBuilder $control_builder)
 Builds the navigation controls for the adaptive interstitial page (branch selection / dead-end notice): only a way back to the object is offered; advancing happens via the choice buttons in the content. More...
 
 txt (string $key)
 
 getAdaptiveDeadEndSvg ()
 

Private Attributes

const string PLAYER_CSS = 'assets/css/lso_player.css'
 

Detailed Description

Implementation of KioskMode Player.

Definition at line 37 of file class.ilLSPlayer.php.

Constructor & Destructor Documentation

◆ __construct()

ilLSPlayer::__construct ( protected ilLSLearnerItemsQueries  $ls_items,
protected LSControlBuilder  $control_builder,
protected LSUrlBuilder  $url_builder,
protected ilLSViewFactory  $view_factory,
protected ilKioskPageRenderer  $page_renderer,
protected Factory  $ui_factory,
protected ScreenContext  $current_context,
protected Refinery\Factory  $refinery,
protected ilLanguage  $lng,
protected ilCtrlInterface  $ctrl,
protected ?LSNavigator  $navigator = null,
protected int  $mode = ilLearningSequenceSettings::MODE_LINEAR,
protected ?LSOItemPath  $item_path = null,
protected ?LSOAdaptiveBoundaries  $boundaries = null,
protected int  $lso_obj_id = 0,
protected int  $usr_id = 0,
protected ?LSOLearningMapPosition  $position = null,
protected ?LSChoicePageBuilder  $choice_page_builder = null,
protected ?Closure  $learning_map = null 
)

Definition at line 58 of file class.ilLSPlayer.php.

78 {
79 }

Member Function Documentation

◆ amendAdaptiveContent()

ilLSPlayer::amendAdaptiveContent ( array  $content,
array  $items,
LSLearnerItem  $item 
)
protected

Amends the rendered content with adaptive hints or a choice panel.

Parameters
Component[]$content
LSLearnerItem[]$items
Returns
Component[]

Definition at line 698 of file class.ilLSPlayer.php.

698 : array
699 {
700 switch ($this->getAdaptiveSituation($items, $item)) {
701 case 'blocked':
702 $content[] = $this->ui_factory->messageBox()->info(
703 $this->txt('lso_player_next_object_blocked')
704 );
705 break;
706 default:
707 // Branch selection and dead-end notice are no longer appended
708 // here; they are rendered on their own interstitial page
709 // (see LSO_CMD_CHOICE handling in play()).
710 break;
711 }
712 return $content;
713 }
txt(string $key)
getAdaptiveSituation(array $items, LSLearnerItem $item)
Classifies the situation of the given object in adaptive mode: 'end', 'blocked', 'deadend',...

Referenced by play().

+ Here is the caller graph for this function:

◆ buildAdaptiveChoiceContent()

ilLSPlayer::buildAdaptiveChoiceContent ( array  $items,
LSLearnerItem  $item 
)
protected

Builds the branch-selection content (one card per allowed successor) using the reusable LSChoicePageBuilder template.

Parameters
LSLearnerItem[]$items
Returns
Component[]

Definition at line 722 of file class.ilLSPlayer.php.

722 : array
723 {
724 $successors = $this->position->getSuccessors($items, $item);
725 return $this->choice_page_builder->build($successors);
726 }

Referenced by play().

+ Here is the caller graph for this function:

◆ buildAdaptiveChoiceControls()

ilLSPlayer::buildAdaptiveChoiceControls ( LSControlBuilder  $control_builder)
protected

Builds the navigation controls for the adaptive interstitial page (branch selection / dead-end notice): only a way back to the object is offered; advancing happens via the choice buttons in the content.

Definition at line 798 of file class.ilLSPlayer.php.

801 if (!$control_builder->getExitControl()) {
802 $control_builder = $control_builder->exit(self::LSO_CMD_SUSPEND);
803 }
804 if (!$control_builder->getPreviousControl()) {
805 $control_builder = $control_builder->previous(self::LSO_CMD_STAY, null);
806 }
807 // No "next" control on the interstitial page: advancing happens via the
808 // choice cards; on a dead end there is nothing to advance to at all.
809 return $control_builder;
810 }
previous(string $command, ?int $parameter=null)
A previous control allows the user to go back to the previous item in the object.
exit(string $command)
An exit control allows the user to gracefully leave the object providing the kiosk mode.
Build controls for the view.

References LSControlBuilder\exit().

Referenced by play().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildAdaptiveControls()

ilLSPlayer::buildAdaptiveControls ( LSControlBuilder  $control_builder,
LSLearnerItem  $item,
array  $items 
)
protected

Builds the navigation controls for adaptive mode based on the situation and the length of the walked path.

Parameters
LSLearnerItem[]$items

Definition at line 755 of file class.ilLSPlayer.php.

760 $situation = $this->getAdaptiveSituation($items, $item);
761 $path_length = $this->position->getPathLength();
762
763 if (!$control_builder->getExitControl()) {
764 $cmd = ($situation === 'end') ? self::LSO_CMD_FINISH : self::LSO_CMD_SUSPEND;
765 $control_builder = $control_builder->exit($cmd);
766 }
767
768 if (!$control_builder->getPreviousControl()) {
769 $cmd = ($path_length > 1) ? self::LSO_CMD_NEXT : '';
770 $control_builder = $control_builder->previous($cmd, -1);
771 }
772
773 if (!$control_builder->getNextControl()) {
774 $cmd = '';
775 $param = 1;
776 if ($situation === 'end') {
778 $param = null;
779 } elseif ($situation === 'straight') {
780 $cmd = self::LSO_CMD_NEXT;
781 } elseif ($situation === 'branch' || $situation === 'deadend') {
782 // "Weiter" leads to the dedicated interstitial page (choice or
783 // dead-end notice) instead of advancing directly.
785 $param = null;
786 }
787 $control_builder = $control_builder->next($cmd, $param);
788 }
789
790 return $control_builder;
791 }
next(string $command, ?int $parameter=null)
A next control allows the user to progress to the next item in the object.
const LSO_CMD_CHOICE
const LSO_CMD_FINISH
$param
Definition: xapitoken.php:44

References LSControlBuilder\exit().

Referenced by play().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildAdaptiveDeadEndContent()

ilLSPlayer::buildAdaptiveDeadEndContent ( )
protected
Returns
Component[]

Definition at line 731 of file class.ilLSPlayer.php.

731 : array
732 {
733 return [
734 $this->ui_factory->legacy()->content(
735 '<div class="lso-player-dead-end">'
736 . '<p class="lso-player-dead-end__message">'
737 . htmlspecialchars($this->txt('lso_player_dead_end_line_1')) . '<br>'
738 . htmlspecialchars($this->txt('lso_player_dead_end_line_2')) . '<br>'
739 . htmlspecialchars($this->txt('lso_player_dead_end_line_3'))
740 . '</p>'
741 . '<div class="lso-player-dead-end__illustration" aria-hidden="true">'
742 . $this->getAdaptiveDeadEndSvg()
743 . '</div>'
744 . '</div>'
745 )
746 ];
747 }

Referenced by play().

+ Here is the caller graph for this function:

◆ buildDefaultControls()

ilLSPlayer::buildDefaultControls ( LSControlBuilder  $control_builder,
LSLearnerItem  $item,
int  $item_position,
array  $items 
)
protected

Definition at line 528 of file class.ilLSPlayer.php.

534 $is_first = $item_position === 0;
535 $is_last = $item_position === count($items) - 1;
536
537 if (!$control_builder->getExitControl()) {
539 if ($is_last) {
541 }
542 $control_builder = $control_builder->exit($cmd);
543 }
544
545 if (!$control_builder->getPreviousControl()) {
546 $direction_prev = -1;
547 $cmd = ''; //disables control
548
549 if (!$is_first) {
550 $available = $this->isItemAvailableForSequenceNavigation(
551 $items,
552 $item,
553 $this->getNextItem($items, $item, $direction_prev),
554 $direction_prev
555 );
556
557 if ($available) {
558 $cmd = self::LSO_CMD_NEXT;
559 }
560 }
561
562 $control_builder = $control_builder
563 ->previous($cmd, $direction_prev);
564 }
565
566 if (!$control_builder->getNextControl()) {
567 $direction_next = 1;
568 $cmd = '';
569 $param = $direction_next;
570
571 if ($is_last) {
573 $param = null;
574 } else {
575 $available = $this->isItemAvailableForSequenceNavigation(
576 $items,
577 $item,
578 $this->getNextItem($items, $item, $direction_next),
579 $direction_next
580 );
581
582 if ($available) {
583 $cmd = self::LSO_CMD_NEXT;
584 }
585 }
586
587 $control_builder = $control_builder
588 ->next($cmd, $param);
589 }
590
591 return $control_builder;
592 }
const LSO_CMD_SUSPEND
getNextItem(array $items, LSLearnerItem $current_item, int $direction)
$direction is either -1 or 1;
isItemAvailableForSequenceNavigation(array $items, LSLearnerItem $current_item, LSLearnerItem $target_item, int $direction)

References LSControlBuilder\exit().

Referenced by play().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ findItemByRefId()

ilLSPlayer::findItemByRefId ( array  $items,
int  $ref_id 
)
protected
Returns
array <int, LSLearnerItem> position=>item

Definition at line 518 of file class.ilLSPlayer.php.

518 : array
519 {
520 foreach ($items as $index => $item) {
521 if ($item->getRefId() === $ref_id) {
522 return [$index, $item];
523 }
524 }
525 throw new \Exception("This is not a valid item.", 1);
526 }

Referenced by getCurrentItem(), and play().

+ Here is the caller graph for this function:

◆ getAdaptiveCurrentItem()

ilLSPlayer::getAdaptiveCurrentItem ( array  $items)
protected

Determines the current object in adaptive mode from the walked path.

Parameters
LSLearnerItem[]$items

Definition at line 632 of file class.ilLSPlayer.php.

633 {
634 return $this->position->getCurrentItem($items);
635 }
Add learning progress and availability information to the LSItem.

Referenced by play().

+ Here is the caller graph for this function:

◆ getAdaptiveDeadEndSvg()

ilLSPlayer::getAdaptiveDeadEndSvg ( )
protected

Definition at line 823 of file class.ilLSPlayer.php.

823 : string
824 {
825 $svg = file_get_contents(dirname(__DIR__, 2) . '/resources/images/player/dead_end.svg');
826 if ($svg === false) {
827 throw new \RuntimeException('Unable to load dead-end SVG asset.');
828 }
829
830 return $svg;
831 }

◆ getAdaptiveEndObjId()

ilLSPlayer::getAdaptiveEndObjId ( )
protected

Definition at line 622 of file class.ilLSPlayer.php.

622 : int
623 {
624 return $this->position->getEndObjId();
625 }

◆ getAdaptiveNextItem()

ilLSPlayer::getAdaptiveNextItem ( array  $items,
LSLearnerItem  $current_item,
?int  $direction 
)
protected

Handles "next"/"back" in adaptive mode.

Parameters
LSLearnerItem[]$items

Definition at line 642 of file class.ilLSPlayer.php.

643 {
644 return $this->position->advance($items, $current_item, $direction);
645 }

Referenced by play().

+ Here is the caller graph for this function:

◆ getAdaptiveSituation()

ilLSPlayer::getAdaptiveSituation ( array  $items,
LSLearnerItem  $item 
)
protected

Classifies the situation of the given object in adaptive mode: 'end', 'blocked', 'deadend', 'branch' or 'straight'.

Parameters
LSLearnerItem[]$items

Definition at line 671 of file class.ilLSPlayer.php.

671 : string
672 {
673 return $this->position->getSituation($items, $item);
674 }

Referenced by play().

+ Here is the caller graph for this function:

◆ getAdaptiveStartObjId()

ilLSPlayer::getAdaptiveStartObjId ( )
protected

Definition at line 617 of file class.ilLSPlayer.php.

617 : int
618 {
619 return $this->position->getStartObjId();
620 }

◆ getCurrentItem()

ilLSPlayer::getCurrentItem ( array  $items)
protected
Parameters
arrayLSLearnerItem[]

Definition at line 406 of file class.ilLSPlayer.php.

407 {
408 $current_item = $items[0];
409 $current_item_ref_id = $this->ls_items->getCurrentItemRefId();
410 if ($current_item_ref_id !== 0) {
411 $valid_ref_ids = array_map(
412 fn($item) => $item->getRefId(),
413 array_values($this->ls_items->getItems())
414 );
415 if (in_array($current_item_ref_id, $valid_ref_ids)) {
416 list(, $current_item) = $this->findItemByRefId($items, $current_item_ref_id);
417 }
418 }
419 return $current_item;
420 }
findItemByRefId(array $items, int $ref_id)

References findItemByRefId().

Referenced by play().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getCurrentItemLearningProgress()

ilLSPlayer::getCurrentItemLearningProgress ( )

Definition at line 812 of file class.ilLSPlayer.php.

812 : int
813 {
814 $item = $this->getCurrentItem($this->ls_items->getItems());
815 return $item->getLearningProgressStatus();
816 }
getCurrentItem(array $items)

References LSLearnerItem\getLearningProgressStatus().

+ Here is the call graph for this function:

◆ getLearningMapHtml()

ilLSPlayer::getLearningMapHtml ( int  $ls_ref_id)
protected

The learning map of the current user, without the panel around it - it is shown inside the modal of the main bar entry.

Which map is built (adaptive graph or sequential chain) is decided by the operation mode.

Definition at line 390 of file class.ilLSPlayer.php.

390 : string
391 {
392 if ($this->learning_map === null) {
393 return '';
394 }
395
396 $this->page_renderer->addCss(\ILIAS\LearningSequence\LearningMap\LSOLearningMapRenderer::CSS);
397 $this->page_renderer->addJs(\ILIAS\LearningSequence\LearningMap\LSOLearningMapRenderer::JS, true);
398
399 return ($this->learning_map)();
400 }
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.

Referenced by play().

+ Here is the caller graph for this function:

◆ getNextAvailableItem()

ilLSPlayer::getNextAvailableItem ( array  $items,
LSLearnerItem  $current_item 
)
protected

Definition at line 422 of file class.ilLSPlayer.php.

425 : ?LSLearnerItem {
426 if ($current_item->getAvailability() === Step::AVAILABLE) {
427 return $current_item;
428 }
429 $position = $this->getPosition();
430 if ($position !== null) {
431 $current_obj_id = ilObject::_lookupObjId($current_item->getRefId());
432 if ($position->hasVisited($current_obj_id)) {
433 return $current_item;
434 }
435 }
436
437 $new_next_item = null;
438 $idx = array_search($current_item, $items);
439
440 for ($i = $idx - 1; $i >= 0; $i--) {
441 if ($items[$i]->getAvailability() === Step::AVAILABLE) {
442 $new_next_item = $items[$i];
443 continue;
444 }
445 }
446 if ($new_next_item === null) {
447 for ($i = $idx + 1; $i < count($items); $i++) {
448 if ($items[$i]->getAvailability() === Step::AVAILABLE) {
449 $new_next_item = $items[$i];
450 continue;
451 }
452 }
453 }
454 return $new_next_item;
455 }
getRefId()
Definition: LSItem.php:93
static _lookupObjId(int $ref_id)

Referenced by play().

+ Here is the caller graph for this function:

◆ getNextItem()

ilLSPlayer::getNextItem ( array  $items,
LSLearnerItem  $current_item,
int  $direction 
)
protected

$direction is either -1 or 1;

Definition at line 473 of file class.ilLSPlayer.php.

474 {
475 list($position) = $this->findItemByRefId($items, $current_item->getRefId());
476 $next = $position + $direction;
477 if ($next >= 0 && $next < count($items)) {
478 return $items[$next];
479 }
480 return $current_item;
481 }

References LSItem\getRefId().

Referenced by play().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getPosition()

ilLSPlayer::getPosition ( )
protected

Definition at line 510 of file class.ilLSPlayer.php.

511 {
512 return $this->position ?? null;
513 }
Tracks a user's position and visit history in a learning map.

◆ gotoAdaptive()

ilLSPlayer::gotoAdaptive ( array  $items,
LSLearnerItem  $current_item,
?int  $param 
)
protected
Parameters
LSLearnerItem[]$items

Definition at line 660 of file class.ilLSPlayer.php.

661 {
662 return $this->position->goTo($items, $current_item, $param);
663 }

References $param.

Referenced by play().

+ Here is the caller graph for this function:

◆ isAdaptive()

ilLSPlayer::isAdaptive ( )
protected

Whether the player runs in adaptive mode with the required collaborators (navigator, path repository and boundaries) available.

Definition at line 608 of file class.ilLSPlayer.php.

608 : bool
609 {
610 return $this->mode === ilLearningSequenceSettings::MODE_ADAPTIVE
611 && $this->navigator instanceof LSNavigator
612 && $this->item_path !== null
613 && $this->boundaries !== null
614 && $this->position !== null;
615 }
Abstraction of the navigation between the objects of a learning sequence.
Definition: LSNavigator.php:31

References ilLearningSequenceSettings\MODE_ADAPTIVE.

Referenced by play().

+ Here is the caller graph for this function:

◆ isItemAvailableForSequenceNavigation()

ilLSPlayer::isItemAvailableForSequenceNavigation ( array  $items,
LSLearnerItem  $current_item,
LSLearnerItem  $target_item,
int  $direction 
)
protected
Parameters
LSLearnerItem[]$items

Definition at line 486 of file class.ilLSPlayer.php.

491 : bool {
492 if ($target_item->getAvailability() === Step::AVAILABLE) {
493 return true;
494 }
495 // Only used in the linear mode: the post condition of the current
496 // item alone decides whether the learner may proceed.
497 if ($direction > 0) {
498 return false;
499 }
500 $position = $this->getPosition();
501 if ($position === null) {
502 return false;
503 }
504 if ($target_item->getRefId() === $current_item->getRefId()) {
505 return true;
506 }
507 return $position->hasVisited(ilObject::_lookupObjId($target_item->getRefId()));
508 }

Referenced by play().

+ Here is the caller graph for this function:

◆ jumpAdaptive()

ilLSPlayer::jumpAdaptive ( array  $items,
LSLearnerItem  $current_item,
?int  $param 
)
protected

Jumps right to the chosen object in adaptive mode (learning map).

Parameters
LSLearnerItem[]$items

Definition at line 652 of file class.ilLSPlayer.php.

653 {
654 return $this->position->jumpTo($items, $current_item, $param);
655 }

References $param.

Referenced by play().

+ Here is the caller graph for this function:

◆ landsOnInterstitialPage()

ilLSPlayer::landsOnInterstitialPage ( array  $items,
LSLearnerItem  $item 
)
protected

Whether arriving on the item (by a step back or by resuming) shows its interstitial page instead of the object: on a branch, or on a dead end that is one structurally as well.

Parameters
LSLearnerItem[]$items

Definition at line 683 of file class.ilLSPlayer.php.

683 : bool
684 {
685 $situation = $this->getAdaptiveSituation($items, $item);
686 return $situation === 'branch'
687 || ($situation === 'deadend'
688 && $this->position->getStructuralSituation($items, $item) === 'deadend');
689 }

Referenced by play().

+ Here is the caller graph for this function:

◆ play()

ilLSPlayer::play ( RequestWrapper  $get)

Definition at line 81 of file class.ilLSPlayer.php.

81 : ?string
82 {
83 $ls_ref_id = $this->ls_items->getLearningSequenceRefId();
84 $ls_obj_id = ilObject::_lookupObjId($ls_ref_id);
85 $ls_title = ilObject::_lookupTitle($ls_obj_id);
86
87 $items = $this->ls_items->getItems();
88
89 if (count($items) === 0) {
90 return null;
91 }
92
93 if ($this->isAdaptive()) {
94 $this->position->prepareForItems($items);
95 $this->navigator->preload($items);
96 $current_item = $this->getAdaptiveCurrentItem($items);
97 } else {
98 $current_item = $this->getNextAvailableItem($items, $this->getCurrentItem($items));
99 }
100 if ($current_item === null) {
101 return null;
102 }
103
104 $view = $this->view_factory->getViewFor($current_item);
105 $state = $this->ls_items->getStateFor($current_item, $view);
106 $state = $this->updateViewState($state, $view, $get);
107 //reload items after update viewState
108 $items = $this->ls_items->getItems();
109
110 $current_item_ref_id = $current_item->getRefId();
111 //now, digest parameter:
112 $command = null;
113 if ($get->has(self::PARAM_LSO_COMMAND)) {
114 $command = $get->retrieve(self::PARAM_LSO_COMMAND, $this->refinery->kindlyTo()->string());
115 }
116 $param = null;
117 if ($get->has(self::PARAM_LSO_PARAMETER)) {
118 $param = $get->retrieve(self::PARAM_LSO_PARAMETER, $this->refinery->kindlyTo()->int());
119 }
120
121 // When set, the branch selection / dead-end notice is rendered on its
122 // own interstitial page instead of being appended below the object.
123 $show_choice = ($command === self::LSO_CMD_CHOICE) && $this->isAdaptive();
124
125 if (!$this->isAdaptive() && $this->position !== null) {
126 $this->position->recordVisit($current_item->getRefId());
127 }
128
129 switch ($command) {
132 $this->ls_items->storeState($state, $current_item_ref_id, $current_item_ref_id);
133 return 'EXIT::' . $command;
135 if ($this->isAdaptive()) {
136 $next_item = $this->getAdaptiveNextItem($items, $current_item, $param);
137 break;
138 }
139 $next_item = $this->getNextItem($items, $current_item, $param);
140 if (!$this->isItemAvailableForSequenceNavigation($items, $current_item, $next_item, $param)) {
141 $next_item = $current_item;
142 }
143 break;
145 if ($this->isAdaptive()) {
146 $next_item = $this->gotoAdaptive($items, $current_item, $param);
147 break;
148 }
149 list(, $next_item) = $this->findItemByRefId($items, $param);
150 break;
152 // Coming from the learning map: the learner picked one specific
153 // object, which is not necessarily a successor of the object
154 // worked on last. Without this the player would silently stay
155 // where it was.
156 if ($this->isAdaptive()) {
157 $next_item = $this->jumpAdaptive($items, $current_item, $param);
158 break;
159 }
160 list(, $next_item) = $this->findItemByRefId($items, $param);
161 break;
162 case self::LSO_CMD_CHOICE: //stay on the object but show the interstitial page
163 case self::LSO_CMD_STAY: //return from the interstitial back to the object
164 $next_item = $current_item;
165 break;
166 default: //view-internal / unknown command
167 $next_item = $current_item;
168 }
169 //write State to DB
170 $this->ls_items->storeState($state, $current_item_ref_id, $next_item->getRefId());
171
172 // After a navigation step the player continues on a url without the
173 // navigation command, so reloading the page does not step on again.
174 // A step back onto a branch/dead-end object continues on its
175 // interstitial page, as it did before the redirect.
176 if (in_array($command, [self::LSO_CMD_NEXT, self::LSO_CMD_GOTO, self::LSO_CMD_JUMP], true)
177 && $next_item->getRefId() !== $current_item_ref_id
178 ) {
179 $continue_with = self::LSO_CMD_STAY;
180 $is_back_step = $command === self::LSO_CMD_NEXT && $param !== null && $param < 0;
181 if ($this->isAdaptive() && $is_back_step) {
182 $reloaded_items = $this->ls_items->getItems();
183 list(, $target_item) = $this->findItemByRefId($reloaded_items, $next_item->getRefId());
184 if ($this->landsOnInterstitialPage($reloaded_items, $target_item)) {
185 $continue_with = self::LSO_CMD_CHOICE;
186 }
187 }
188 return self::REDIRECT_PREFIX . $this->url_builder->getHref($continue_with);
189 }
190
191 //get proper view
192 if ($next_item != $current_item) {
193 $view = $this->view_factory->getViewFor($next_item);
194 $state = $this->ls_items->getStateFor($next_item, $view);
195 }
196
197 if (!$this->isAdaptive() && $this->position !== null) {
198 $this->position->recordVisit($next_item->getRefId());
199 }
200
201 //content
202 $obj_title = $next_item->getTitle();
203 $obj_description = $next_item->getDescription();
204 $icon = $this->ui_factory->symbol()->icon()->standard(
205 $next_item->getType(),
206 $next_item->getType(),
207 'medium'
208 );
209
210 $content = $this->renderComponentView($state, $view);
211
212 $panel = $this->ui_factory->panel()->standard(
213 '',
214 $content
215 );
216 $content = [$panel];
217
218 $items = $this->ls_items->getItems(); //reload items after renderComponentView content
219
220 //get position
221 list($item_position, $item) = $this->findItemByRefId($items, $next_item->getRefId());
222
223 // When resuming the player (no command, e.g. after leaving and
224 // re-entering) onto a branch/dead-end object, land directly on its
225 // interstitial page (choice / dead-end notice) instead of the object
226 // content. Steps back are redirected to that page above.
227 if ($this->isAdaptive() && $command === null) {
228 if ($this->landsOnInterstitialPage($items, $item)) {
229 $show_choice = true;
230 }
231 }
232
233 if ($this->isAdaptive() && !$show_choice) {
234 $content = $this->amendAdaptiveContent($content, $items, $item);
235 }
236 if ($this->isAdaptive() && $show_choice) {
237 $situation = $this->getAdaptiveSituation($items, $item);
238 if ($situation === 'branch') {
239 $obj_title = $this->choice_page_builder->getHeadline();
240 $obj_description = '';
241 $content = $this->buildAdaptiveChoiceContent($items, $item);
242 } elseif ($situation === 'deadend') {
243 $this->page_renderer->addCss(self::PLAYER_CSS);
244 $obj_title = $this->txt('lso_player_dead_end_title');
245 $obj_description = '';
246 $content = $this->buildAdaptiveDeadEndContent();
247 } else {
248 $show_choice = false;
249 $content = $this->amendAdaptiveContent($content, $items, $item);
250 }
251 }
252
253 $control_builder = $this->control_builder;
254 // On the interstitial pages (branch selection / dead-end notice) the
255 // object itself is not shown, so its view-controls (e.g. the
256 // "mark as completed"-button of a page) must not be built either.
257 if (!($this->isAdaptive() && $show_choice)) {
258 $view->buildControls($state, $control_builder);
259 }
260
261 if ($this->isAdaptive() && $show_choice) {
262 $control_builder = $this->buildAdaptiveChoiceControls($control_builder);
263 } elseif ($this->isAdaptive()) {
264 $control_builder = $this->buildAdaptiveControls($control_builder, $item, $items);
265 } else {
266 $control_builder = $this->buildDefaultControls($control_builder, $item, $item_position, $items);
267 }
268
269 $mainbar_controls = [];
270
271 // The learning map lives in the main bar and opens in a modal; the
272 // modal itself has to be part of the page, so it is appended to the
273 // content before the body is rendered.
274 $map_html = $this->getLearningMapHtml($ls_ref_id);
275 if ($map_html !== '') {
276 list($map_button, $map_modal) = $this->page_renderer->buildLearningMapEntry($map_html);
277 $mainbar_controls['learning_map'] = $map_button;
278 $content[] = $map_modal;
279 }
280
281 // Keep a stable header layout: reserve the rating slot even if rating is not available.
282 // Otherwise the navigation/buttons would shift vertically.
283 $obj_rating_html = '&nbsp;';
284 $obj_id = ilObject::_lookupObjId($next_item->getRefId());
285 if ($obj_id > 0 && !$show_choice) {
286 $obj_type = ilObject::_lookupType($obj_id);
288 if ($obj_type !== '' && ilRating::hasRatingInListGUI($obj_id, $obj_type)) {
289 $parent_ref_id = (int) $ls_ref_id;
290 $rating_container_id = 'lg_div_' . $next_item->getRefId() . '_pref_' . $parent_ref_id;
291
294 $next_item->getRefId(),
295 $obj_type,
296 $obj_id
297 );
298
299 $rating_gui = new ilRatingGUI();
300 $rating_gui->setObject($obj_id, $obj_type);
301 $rating_gui->setCtrlPath([
302 ilCommonActionDispatcherGUI::class,
303 ilRatingGUI::class
304 ]);
305 $rating_gui->setYourRatingText($this->lng->txt('rating_your_rating'));
306
307 global $DIC;
308
309 $rating_content = $rating_gui->getListGUIProperty(
310 $next_item->getRefId(),
311 $DIC->access()->checkAccess('read', '', $next_item->getRefId()),
312 $ajax_hash,
313 $parent_ref_id
314 );
315
316 $tpl = new ilTemplate(
317 'tpl.lso_kiosk_rating_container.html',
318 true,
319 true,
320 'components/ILIAS/LearningSequence'
321 );
322 $tpl->setVariable('CONTAINER_ID', $rating_container_id);
323 $tpl->setVariable('CHILD_REF_ID', (string) $next_item->getRefId());
324 $tpl->setVariable('AJAX_HASH', htmlspecialchars($ajax_hash, ENT_QUOTES));
325 $tpl->setVariable('RATING_CONTENT', $rating_content);
326 $obj_rating_html = $tpl->get();
327
328 $redraw_url = $this->ctrl->getLinkTargetByClass(
329 ilObjLearningSequenceLearnerGUI::class,
331 '',
332 true,
333 false
334 );
335
336 $rating_url = $this->ctrl->getLinkTargetByClass(
337 [
338 ilCommonActionDispatcherGUI::class,
339 ilRatingGUI::class
340 ],
341 'saveRating',
342 '',
343 true,
344 false
345 );
346
347 $this->page_renderer->addOnLoadCode(
348 "if (window.il && window.il.Object) {" .
349 " if (typeof window.il.Object.setRedrawListItemUrl === 'function') { window.il.Object.setRedrawListItemUrl(" . json_encode($redraw_url, JSON_THROW_ON_ERROR) . "); }" .
350 " if (typeof window.il.Object.setRatingUrl === 'function') { window.il.Object.setRatingUrl(" . json_encode($rating_url, JSON_THROW_ON_ERROR) . "); }" .
351 "}"
352 );
353 }
354 }
355
356 $rendered_body = $this->page_renderer->render(
357 $control_builder,
358 $obj_title,
359 $obj_description,
360 $icon,
361 $content,
362 $obj_rating_html
363 );
364
365 $metabar_controls = [
366 'exit' => $control_builder->getExitControl()
367 ];
368
369 $toc = $control_builder->getToc();
370 if ($toc) {
371 $toc_slate = $this->page_renderer->buildToCSlate($toc, $icon);
372 $mainbar_controls['toc'] = $toc_slate;
373 }
374
375 $cc = $this->current_context;
376 $cc->addAdditionalData(self::GS_DATA_LS_KIOSK_MODE, true);
377 $cc->addAdditionalData(self::GS_DATA_LS_TITLE, $ls_title);
378 $cc->addAdditionalData(self::GS_DATA_LS_METABARCONTROLS, $metabar_controls);
379 $cc->addAdditionalData(self::GS_DATA_LS_MAINBARCONTROLS, $mainbar_controls);
380 $cc->addAdditionalData(self::GS_DATA_LS_CONTENT, $rendered_body);
381
382 return null;
383 }
static buildAjaxHash(int $node_type, ?int $node_id, string $obj_type, int $obj_id, ?string $sub_type=null, ?int $sub_id=null, int $news_id=0)
Build ajax hash.
renderComponentView($state, ILIAS\KioskMode\View $view)
gotoAdaptive(array $items, LSLearnerItem $current_item, ?int $param)
buildAdaptiveControls(LSControlBuilder $control_builder, LSLearnerItem $item, array $items)
Builds the navigation controls for adaptive mode based on the situation and the length of the walked ...
buildAdaptiveChoiceContent(array $items, LSLearnerItem $item)
Builds the branch-selection content (one card per allowed successor) using the reusable LSChoicePageB...
landsOnInterstitialPage(array $items, LSLearnerItem $item)
Whether arriving on the item (by a step back or by resuming) shows its interstitial page instead of t...
getLearningMapHtml(int $ls_ref_id)
The learning map of the current user, without the panel around it - it is shown inside the modal of t...
amendAdaptiveContent(array $content, array $items, LSLearnerItem $item)
Amends the rendered content with adaptive hints or a choice panel.
jumpAdaptive(array $items, LSLearnerItem $current_item, ?int $param)
Jumps right to the chosen object in adaptive mode (learning map).
getAdaptiveNextItem(array $items, LSLearnerItem $current_item, ?int $direction)
Handles "next"/"back" in adaptive mode.
updateViewState(ILIAS\KioskMode\State $state, ILIAS\KioskMode\View $view, RequestWrapper $get)
buildAdaptiveChoiceControls(LSControlBuilder $control_builder)
Builds the navigation controls for the adaptive interstitial page (branch selection / dead-end notice...
buildDefaultControls(LSControlBuilder $control_builder, LSLearnerItem $item, int $item_position, array $items)
isAdaptive()
Whether the player runs in adaptive mode with the required collaborators (navigator,...
getNextAvailableItem(array $items, LSLearnerItem $current_item)
getAdaptiveCurrentItem(array $items)
Determines the current object in adaptive mode from the walked path.
static _lookupType(int $id, bool $reference=false)
static _lookupTitle(int $obj_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static preloadListGUIData(array $a_obj_ids)
Preload rating data for list guis.
static hasRatingInListGUI(int $a_obj_id, string $a_obj_type)
special template class to simplify handling of ITX/PEAR
retrieve(string $key, Transformation $transformation)
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.
readonly ilGlobalTemplateInterface $tpl
global $DIC
Definition: shib_login.php:26

References $DIC, $param, ILIAS\News\Common\Table\$tpl, ilObject\_lookupObjId(), ilObject\_lookupTitle(), ilObject\_lookupType(), amendAdaptiveContent(), buildAdaptiveChoiceContent(), buildAdaptiveChoiceControls(), buildAdaptiveControls(), buildAdaptiveDeadEndContent(), ilCommonActionDispatcherGUI\buildAjaxHash(), buildDefaultControls(), ilObjLearningSequenceLearnerGUI\CMD_REDRAW_LIST_ITEM, ILIAS\Repository\ctrl(), findItemByRefId(), ILIAS\UICore\GlobalTemplate\get(), getAdaptiveCurrentItem(), getAdaptiveNextItem(), getAdaptiveSituation(), getCurrentItem(), getLearningMapHtml(), getNextAvailableItem(), getNextItem(), gotoAdaptive(), ILIAS\HTTP\Wrapper\RequestWrapper\has(), ilRating\hasRatingInListGUI(), ILIAS\Repository\int(), isAdaptive(), isItemAvailableForSequenceNavigation(), jumpAdaptive(), landsOnInterstitialPage(), ILIAS\Repository\lng(), LSO_CMD_CHOICE, LSO_CMD_FINISH, LSO_CMD_GOTO, LSO_CMD_JUMP, LSO_CMD_NEXT, LSO_CMD_STAY, LSO_CMD_SUSPEND, ilRating\preloadListGUIData(), ILIAS\Repository\refinery(), renderComponentView(), ILIAS\HTTP\Wrapper\RequestWrapper\retrieve(), ILIAS\UICore\GlobalTemplate\setVariable(), txt(), ilCommonActionDispatcherGUI\TYPE_REPOSITORY, and updateViewState().

+ Here is the call graph for this function:

◆ renderComponentView()

ilLSPlayer::renderComponentView (   $state,
ILIAS\KioskMode\View  $view 
)
protected

Definition at line 594 of file class.ilLSPlayer.php.

594 : Component
595 {
596 return $view->render(
597 $state,
598 $this->ui_factory,
599 $this->url_builder,
600 []
601 );
602 }

Referenced by play().

+ Here is the caller graph for this function:

◆ txt()

ilLSPlayer::txt ( string  $key)
protected

Definition at line 818 of file class.ilLSPlayer.php.

818 : string
819 {
820 return $this->lng->txt($key);
821 }

References ILIAS\Repository\lng().

Referenced by play().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ updateViewState()

ilLSPlayer::updateViewState ( ILIAS\KioskMode\State  $state,
ILIAS\KioskMode\View  $view,
RequestWrapper  $get 
)
protected

Definition at line 457 of file class.ilLSPlayer.php.

462 if ($get->has(self::PARAM_LSO_COMMAND) && $get->has(self::PARAM_LSO_PARAMETER)) {
463 $command = $get->retrieve(self::PARAM_LSO_COMMAND, $this->refinery->kindlyTo()->string());
464 $param = $get->retrieve(self::PARAM_LSO_PARAMETER, $this->refinery->kindlyTo()->int());
465 $state = $view->updateGet($state, $command, $param);
466 }
467 return $state;
468 }
Keeps the state of a view in a simple stringly type key-value store.
Definition: State.php:27

References $param, ILIAS\Repository\refinery(), and ILIAS\HTTP\Wrapper\RequestWrapper\retrieve().

Referenced by play().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ GS_DATA_LS_CONTENT

const ilLSPlayer::GS_DATA_LS_CONTENT = 'ls_content'

Definition at line 54 of file class.ilLSPlayer.php.

Referenced by ilLSViewLayoutProvider\getContentModification().

◆ GS_DATA_LS_KIOSK_MODE

const ilLSPlayer::GS_DATA_LS_KIOSK_MODE = 'ls_kiosk_mode'

Definition at line 52 of file class.ilLSPlayer.php.

Referenced by ilLSViewLayoutProvider\isKioskModeEnabled().

◆ GS_DATA_LS_MAINBARCONTROLS

const ilLSPlayer::GS_DATA_LS_MAINBARCONTROLS = 'ls_mainbar_controls'

Definition at line 55 of file class.ilLSPlayer.php.

Referenced by ilLSViewLayoutProvider\getMainBarModification().

◆ GS_DATA_LS_METABARCONTROLS

const ilLSPlayer::GS_DATA_LS_METABARCONTROLS = 'ls_metabar_controls'

Definition at line 56 of file class.ilLSPlayer.php.

Referenced by ilLSViewLayoutProvider\getPageBuilderDecorator().

◆ GS_DATA_LS_TITLE

const ilLSPlayer::GS_DATA_LS_TITLE = 'ls_title'

Definition at line 53 of file class.ilLSPlayer.php.

Referenced by ilLSViewLayoutProvider\getPageBuilderDecorator().

◆ LSO_CMD_CHOICE

const ilLSPlayer::LSO_CMD_CHOICE = 'lsochoice'

Definition at line 48 of file class.ilLSPlayer.php.

Referenced by play().

◆ LSO_CMD_FINISH

const ilLSPlayer::LSO_CMD_FINISH = 'lsofinish'

Definition at line 47 of file class.ilLSPlayer.php.

Referenced by LSControlBuilder\exit(), LSControlBuilder\next(), and play().

◆ LSO_CMD_GOTO

const ilLSPlayer::LSO_CMD_GOTO = 'lsogoto'

Definition at line 44 of file class.ilLSPlayer.php.

Referenced by play().

◆ LSO_CMD_JUMP

const ilLSPlayer::LSO_CMD_JUMP = 'lsojump'

Definition at line 45 of file class.ilLSPlayer.php.

Referenced by play().

◆ LSO_CMD_NEXT

const ilLSPlayer::LSO_CMD_NEXT = 'lsonext'

Definition at line 43 of file class.ilLSPlayer.php.

Referenced by play().

◆ LSO_CMD_STAY

const ilLSPlayer::LSO_CMD_STAY = 'lsostay'

Definition at line 49 of file class.ilLSPlayer.php.

Referenced by play().

◆ LSO_CMD_SUSPEND

const ilLSPlayer::LSO_CMD_SUSPEND = 'lsosuspend'

Definition at line 46 of file class.ilLSPlayer.php.

Referenced by play().

◆ PARAM_LSO_COMMAND

const ilLSPlayer::PARAM_LSO_COMMAND = 'lsocmd'

Definition at line 39 of file class.ilLSPlayer.php.

◆ PARAM_LSO_PARAMETER

const ilLSPlayer::PARAM_LSO_PARAMETER = 'lsov'

Definition at line 40 of file class.ilLSPlayer.php.

◆ PLAYER_CSS

const string ilLSPlayer::PLAYER_CSS = 'assets/css/lso_player.css'
private

Definition at line 41 of file class.ilLSPlayer.php.

◆ REDIRECT_PREFIX

const ilLSPlayer::REDIRECT_PREFIX = 'REDIRECT::'

Definition at line 50 of file class.ilLSPlayer.php.


The documentation for this class was generated from the following file: