1<?php 2 3declare(strict_types=1); 4 5use ILIAS\KioskMode\ControlBuilder; 6use ILIAS\KioskMode\LocatorBuilder; 7use ILIAS\KioskMode\TOCBuilder; 8use ILIAS\KioskMode\URLBuilder; 9 10use ILIAS\UI\Factory; 11 12/** 13 * Class LSControlBuilder 14 */ 15class LSControlBuilder implements ControlBuilder 16{ 17 const CMD_START_OBJECT = 'start_legacy_obj'; 18 const CMD_CHECK_CURRENT_ITEM_LP = 'ccilp'; 19 20 /** 21 * @var Component|null 22 */ 23 protected $exit_control; 24 25 /** 26 * @var Component|null 27 */ 28 protected $previous_control; 29 30 /** 31 * @var Component|null 32 */ 33 protected $next_control; 34 35 /** 36 * @var Component|null 37 */ 38 protected $done_control; 39 40 /** 41 * @var Component[] 42 */ 43 protected $controls = []; 44 45 /** 46 * @var Component[] 47 */ 48 protected $toggles = []; 49 50 /** 51 * @var Component[] 52 */ 53 protected $mode_controls = []; 54 55 /** 56 * @var TOCBuilder|null 57 */ 58 protected $toc; 59 60 /** 61 * @var LocatorBuilder|null 62 */ 63 protected $loc; 64 65 /** 66 * @var Factory 67 */ 68 protected $ui_factory; 69 70 /** 71 * @var URLBuilder 72 */ 73 protected $url_builder; 74 75 /** 76 * @var Component|null 77 */ 78 protected $start; 79 80 /** 81 * @var string | null 82 */ 83 protected $additional_js; 84 85 /** 86 * @var LSGlobalSettings 87 */ 88 protected $global_settings; 89 90 public function __construct( 91 Factory $ui_factory, 92 LSURLBuilder $url_builder, 93 ilLanguage $language, 94 LSGlobalSettings $global_settings 95 ) { 96 $this->ui_factory = $ui_factory; 97 $this->url_builder = $url_builder; 98 $this->lng = $language; 99 $this->global_settings = $global_settings; 100 } 101 102 public function getExitControl() 103 { 104 return $this->exit_control; 105 } 106 107 public function getPreviousControl() 108 { 109 return $this->previous_control; 110 } 111 112 public function getNextControl() 113 { 114 return $this->next_control; 115 } 116 117 public function getDoneControl() 118 { 119 return $this->done_control; 120 } 121 122 public function getToggles() 123 { 124 return $this->toggles; 125 } 126 127 public function getModeControls() 128 { 129 return $this->mode_controls; 130 } 131 132 public function getControls() : array 133 { 134 return $this->controls; 135 } 136 137 public function getLocator() 138 { 139 return $this->loc; 140 } 141 142 public function getToc() 143 { 144 return $this->toc; 145 } 146 147 /** 148 * @inheritdoc 149 */ 150 public function exit(string $command) : ControlBuilder 151 { 152 if ($this->exit_control) { 153 throw new \LogicException("Only one exit-control per view...", 1); 154 } 155 $cmd = $this->url_builder->getHref($command); 156 157 $label = 'lso_player_suspend'; 158 if ($command === ilLSPlayer::LSO_CMD_FINISH) { 159 $label = 'lso_player_finish'; 160 } 161 162 $exit_button = $this->ui_factory->button()->bulky( 163 $this->ui_factory->symbol()->glyph()->close(), 164 $this->lng->txt($label), 165 $cmd 166 ); 167 168 $this->exit_control = $exit_button; 169 return $this; 170 } 171 172 /** 173 * @inheritdoc 174 */ 175 public function next(string $command, int $parameter = null) : ControlBuilder 176 { 177 if ($this->next_control) { 178 throw new \LogicException("Only one next-control per view...", 1); 179 } 180 $label = $this->lng->txt('lso_player_next'); 181 $cmd = $this->url_builder->getHref($command, $parameter); 182 $btn = $this->ui_factory->button()->standard($label, $cmd); 183 if ($command === '') { 184 $btn = $btn->withUnavailableAction(); 185 } 186 $this->next_control = $btn; 187 return $this; 188 } 189 190 /** 191 * @inheritdoc 192 */ 193 public function previous(string $command, int $parameter = null) : ControlBuilder 194 { 195 if ($this->previous_control) { 196 throw new \LogicException("Only one previous-control per view...", 1); 197 } 198 $label = $this->lng->txt('lso_player_previous'); 199 $cmd = $this->url_builder->getHref($command, $parameter); 200 $btn = $this->ui_factory->button()->standard($label, $cmd); 201 if ($command === '') { 202 $btn = $btn->withUnavailableAction(); 203 } 204 $this->previous_control = $btn; 205 return $this; 206 } 207 208 /** 209 * @inheritdoc 210 */ 211 public function done(string $command, int $parameter = null) : ControlBuilder 212 { 213 if ($this->done_control) { 214 throw new \LogicException("Only one done-control per view...", 1); 215 } 216 $label = $this->lng->txt('lso_player_done'); 217 $cmd = $this->url_builder->getHref($command, $parameter); 218 $btn = $this->ui_factory->button()->primary($label, $cmd); 219 $this->done_control = $btn; 220 return $this; 221 } 222 223 /** 224 * @inheritdoc 225 */ 226 public function generic(string $label, string $command, int $parameter = null) : ControlBuilder 227 { 228 $cmd = $this->url_builder->getHref($command, $parameter); 229 $this->controls[] = $this->ui_factory->button()->standard($label, $cmd); 230 return $this; 231 } 232 233 /** 234 * A toggle can be used to switch some behaviour in the view on or of. 235 */ 236 public function toggle(string $label, string $on_command, string $off_command) : ControlBuilder 237 { 238 throw new \Exception("NYI: Toggles", 1); 239 240 $cmd_on = $this->url_builder->getHref($on_command, 0); 241 $cmd_off = $this->url_builder->getHref($off_command, 0); 242 //build toggle and add to $this->toggles 243 //return $this; 244 } 245 246 /** 247 * @inheritdoc 248 */ 249 public function mode(string $command, array $labels) : ControlBuilder 250 { 251 $actions = []; 252 foreach ($labels as $parameter => $label) { 253 $actions[$label] = $this->url_builder->getHref($command, $parameter); 254 } 255 $this->mode_controls[] = $this->ui_factory->viewControl()->mode($actions, ''); 256 return $this; 257 } 258 259 /** 260 * @inheritdoc 261 */ 262 public function locator(string $command) : LocatorBuilder 263 { 264 if ($this->loc) { 265 throw new \LogicException("Only one locator per view...", 1); 266 } 267 $this->loc = new LSLocatorBuilder($command, $this); 268 return $this->loc; 269 } 270 271 /** 272 * @inheritdoc 273 */ 274 public function tableOfContent( 275 string $label, 276 string $command, 277 int $parameter = null, 278 $state = null 279 ) : TOCBuilder { 280 if ($this->toc) { 281 throw new \LogicException("Only one ToC per view...", 1); 282 } 283 $this->toc = new LSTOCBuilder($this, $command, $label, $parameter, $state); 284 return $this->toc; 285 } 286 287 /** 288 * Add a "start"-button as primary. 289 * This is NOT regular behavior, but a special feature for the LegacyView 290 * of LearningSequence's sub-objects that do not implement a KioskModeView. 291 * 292 * The start-control is exclusively used to open an ILIAS-Object in a new windwow/tab. 293 */ 294 public function start(string $label, string $url, int $parameter = null) : ControlBuilder 295 { 296 if ($this->start) { 297 throw new \LogicException("Only one start-control per view...", 1); 298 } 299 $this_cmd = $this->url_builder->getHref(self::CMD_START_OBJECT, $parameter); 300 $lp_cmd = str_replace( 301 '&cmd=view&', 302 '&cmd=' . self::CMD_CHECK_CURRENT_ITEM_LP . '&', 303 $this_cmd 304 ); 305 306 $this->setListenerJS($lp_cmd, $this_cmd); 307 $this->start = $this->ui_factory->button() 308 ->primary($label, '') 309 ->withOnLoadCode(function ($id) use ($url) { 310 $interval = $this->global_settings->getPollingIntervalMilliseconds(); 311 return "$('#{$id}').on('click', function(ev) { 312 var il_ls_win = window.open('$url'); 313 window._lso_current_item_lp = -1; 314 window.setInterval(lso_checkLPOfObject, $interval); 315 })"; 316 }); 317 318 return $this; 319 } 320 321 public function getStartControl() 322 { 323 return $this->start; 324 } 325 326 public function getAdditionalJS() : string 327 { 328 return $this->additional_js; 329 } 330 331 protected function setListenerJS( 332 string $check_lp_url, 333 string $on_lp_change_url 334 ) { 335 $this->additional_js = 336<<<JS 337function lso_checkLPOfObject() 338{ 339 if(! il.UICore.isPageVisible()) { 340 return; 341 } 342 343 $.ajax({ 344 url: "$check_lp_url", 345 }).done(function(data) { 346 if(window._lso_current_item_lp === -1) { 347 window._lso_current_item_lp = data; 348 } 349 if (window._lso_current_item_lp !== data) { 350 location.replace('$on_lp_change_url'); 351 } 352 }); 353} 354JS; 355 } 356} 357