ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilLMTOCExplorerGUI.php
Go to the documentation of this file.
1 <?php
2 
25 {
26  protected string $lang;
27  protected int $highlight_node = 0;
28  protected bool $export_all_languages;
30  protected array $complete_tree = [];
31  protected array $activation_data = [];
32  protected ilSetting $lm_set;
34  protected int $focus_id = 0;
36  protected ilLMTracker $tracker;
37 
42  public function __construct(
43  $a_parent_obj,
44  string $a_parent_cmd,
45  ilLMPresentationService $service,
46  string $a_lang = "-",
47  int $a_focus_id = 0,
48  bool $export_all_languages = false
49  ) {
50  global $DIC;
51 
52  $this->service = $service;
53  $this->user = $DIC->user();
54  $this->lm = $service->getLearningModule();
55  $this->linker = $service->getLinker();
56  $this->tracker = $service->getTracker();
57 
58  $exp_id = (!$this->getOfflineMode() && $this->lm->getProgressIcons())
59  ? "ilLMProgressTree"
60  : "";
61  parent::__construct($a_parent_obj, $a_parent_cmd, $this->lm, $exp_id);
62  $this->lm_set = new ilSetting("lm");
63  $this->lang = $a_lang;
64  if ($a_focus_id > 0) {
65  $this->setSecondaryHighlightedNodes(array($a_focus_id));
66  }
67  if ($this->lm->getTOCMode() != "pages") {
68  $this->setTypeWhiteList(array("st", "du"));
69  }
70  $this->focus_id = $a_focus_id;
71  $this->export_all_languages = $export_all_languages;
72 
73  $this->activation_repo = new ilPageActivationDBRepository();
74 
75  $this->initTreeData();
76  }
77 
78  protected function initTreeData(): void
79  {
80  $nodes = $this->tree->getCompleteTree();
81  foreach ($nodes as $node) {
82  $this->complete_tree["childs"][$node["parent"]][] = $node;
83  $this->complete_tree["parent"][$node["child"]] = $node["parent"];
84  $this->complete_tree["nodes"][$node["child"]] = $node;
85  }
86 
87  $page_ids = array_column($this->complete_tree["nodes"], "child");
88  $this->activation_data = $this->activation_repo->get(
89  "lm",
90  $page_ids,
91  (bool) $this->lm_set->get("time_scheduled_page_activation"),
93  );
94  $this->initVisibilityData($this->tree->readRootId());
95  }
96 
97  protected function initVisibilityData(
98  int $node_id
99  ): void {
100  $current_node = $this->complete_tree["nodes"][$node_id];
101 
102  if (isset($this->complete_tree["childs"][$node_id])) {
103  foreach ($this->complete_tree["childs"][$node_id] as $node) {
104  $this->initVisibilityData($node["child"]);
105  }
106  }
107 
108  // pages are visible if they are active or activation info should be shown
109  if ($current_node["type"] == "pg") {
110  $this->complete_tree["visibility"][$node_id] = ($this->activation_data[$node_id]["active"] ||
111  $this->activation_data[$node_id]["show_info"]);
112  } elseif ($current_node["type"] == "st") {
113  // make chapters visible as soon as there is one visible child
114  $this->complete_tree["visibility"][$node_id] = false;
115  if (isset($this->complete_tree["childs"][$node_id])) {
116  foreach ($this->complete_tree["childs"][$node_id] as $node) {
117  if (isset($this->complete_tree["visibility"][$node["child"]]) &&
118  $this->complete_tree["visibility"][$node["child"]]) {
119  $this->complete_tree["visibility"][$node_id] = true;
120  }
121  }
122  }
123  } else {
124  $this->complete_tree["visibility"][$node_id] = true;
125  }
126  }
127 
128  public function getRootNode(): array
129  {
130  $root_id = $this->getTree()->readRootId();
131  if ($this->focus_id > 0 && $this->getTree()->isInTree($this->focus_id) &&
132  ilLMObject::_lookupType($this->focus_id) == "st") {
133  // $root_id = $this->focus_id;
134  }
135  return $this->getTree()->getNodeData($root_id);
136  }
137 
138  public function setTracker(ilLMTracker $a_val): void
139  {
140  $this->tracker = $a_val;
141  }
142 
143  public function getTracker(): ilLMTracker
144  {
145  return $this->tracker;
146  }
147 
148  public function setHighlightNode(int $a_val): void
149  {
150  $this->highlight_node = $a_val;
151  }
152 
153  public function getHighlightNode(): int
154  {
155  return $this->highlight_node;
156  }
157 
161  public function isNodeHighlighted($a_node): bool
162  {
163  if ($a_node["child"] == $this->getHighlightNode()) {
164  return true;
165  }
166  return false;
167  }
168 
172  public function getNodeContent($a_node): string
173  {
174  if ($a_node["child"] == $this->getNodeId($this->getRootNode())) {
175  return $this->service->getPresentationStatus()->getLMPresentationTitle();
176  }
177 
178  if ($a_node["type"] == "st") {
180  $a_node["child"],
182  $this->lm->isActiveNumbering(),
183  false,
184  false,
185  $this->lm->getId(),
186  $this->lang,
187  true
188  );
189  } elseif ($a_node["type"] == "pg") {
191  $a_node["child"],
192  $this->lm->getPageHeader(),
193  $this->lm->isActiveNumbering(),
194  (bool) $this->lm_set->get("time_scheduled_page_activation"),
195  true,
196  $this->lm->getId(),
197  $this->lang,
198  true
199  );
200  } elseif ($a_node["child"] == $this->getNodeId($this->getRootNode())) {
201  return $this->lm->getTitle();
202  }
203 
204  return $a_node["title"];
205  }
206 
207 
211  public function getNodeIcon($a_node): string
212  {
213  // overwrite chapter icons with lp info?
214  if (!$this->getOfflineMode() && $a_node["type"] == "st") {
215  $icon = $this->checkLPIcon($a_node["child"]);
216  if ($icon != "") {
217  return $icon;
218  }
219  }
220 
221  // use progress icons (does not depend on lp mode)
222  if (!$this->getOfflineMode() && $this->lm->getProgressIcons()) {
223  return $this->tracker->getIconForLMObject($a_node, $this->highlight_node);
224  }
225 
226  if ($a_node["type"] == "du") {
227  $a_node["type"] = "lm";
228  }
229  $a_name = "standard/icon_" . $a_node["type"] . ".svg";
230  if ($a_node["type"] == "pg") {
231  $lm_set = new ilSetting("lm");
232  $active = ilLMPage::_lookupActive(
233  $a_node["child"],
234  $this->lm->getType(),
235  (bool) $lm_set->get("time_scheduled_page_activation")
236  );
237 
238  // is page scheduled?
239  $img_sc = ($lm_set->get("time_scheduled_page_activation") &&
240  ilLMPage::_isScheduledActivation($a_node["child"], $this->lm->getType()) && !$active
241  && !$this->getOfflineMode())
242  ? "_sc"
243  : "";
244 
245  $a_name = "standard/icon_pg" . $img_sc . ".svg";
246 
247  if (!$active && !$this->getOfflineMode()) {
248  $a_name = "standard/icon_pg_d" . $img_sc . ".svg";
249  }
250  }
251 
252  return ilUtil::getImagePath($a_name, false, "output", $this->getOfflineMode());
253  }
254 
258  public function isNodeClickable($a_node): bool
259  {
260  $ilUser = $this->user;
261 
262  $orig_node_id = $a_node["child"];
263 
264  // if navigation is restricted based on correct answered questions
265  // check if we have preceeding pages including unsanswered/incorrect answered questions
266  if (!$this->getOfflineMode()) {
267  if ($this->lm->getRestrictForwardNavigation()) {
268  if ($this->getTracker()->hasPredIncorrectAnswers($orig_node_id)) {
269  return false;
270  }
271  }
272  }
273 
274  if ($a_node["type"] == "st") {
275  if (!$this->getOfflineMode()) {
276  if ($this->lm->getTOCMode() != "pages") {
277  $a_node = $this->getTree()->fetchSuccessorNode($a_node["child"], "pg");
278  } else {
279  // faster, but needs pages to be in explorer
280  $a_node = $this->getSuccessorNode($a_node["child"], "pg");
281  }
282  if (($a_node["child"] ?? 0) == 0) {
283  return false;
284  }
285  } else {
286  // get next activated page
287  $found = false;
288  while (!$found) {
289  if ($this->lm->getTOCMode() != "pages") {
290  $a_node = $this->getTree()->fetchSuccessorNode($a_node["child"], "pg");
291  } else {
292  $a_node = $this->getSuccessorNode($a_node["child"], "pg");
293  }
294  $active = ilLMPage::_lookupActive(
295  $a_node["child"],
296  $this->lm->getType(),
297  (bool) $this->lm_set->get("time_scheduled_page_activation")
298  );
299 
300  if ($a_node["child"] > 0 && !$active) {
301  $found = false;
302  } else {
303  $found = true;
304  }
305  }
306  if ($a_node["child"] <= 0) {
307  return false;
308  } else {
309  $path = $this->getTree()->getPathId($a_node["child"]);
310  if (!in_array($orig_node_id, $path)) {
311  return false;
312  }
313  }
314  }
315  }
316 
317  if ($a_node["type"] == "pg") {
318  // check public area mode
319  if ($ilUser->getId() == ANONYMOUS_USER_ID && !ilLMObject::_isPagePublic($a_node["child"], true)) {
320  return false;
321  }
322  }
323 
324  return true;
325  }
326 
327 
331  public function getNodeIconAlt($a_node): string
332  {
333  return "";
334  }
335 
339  public function getNodeHref($a_node): string
340  {
341  if (!$this->getOfflineMode()) {
342  return $this->linker->getLink("", $a_node["child"]);
343  //return parent::buildLinkTarget($a_node_id, $a_type);
344  } else {
345  if ($a_node["type"] != "pg") {
346  // get next activated page
347  $found = false;
348  while (!$found) {
349  $a_node = $this->getTree()->fetchSuccessorNode($a_node["child"], "pg");
350  $active = ilLMPage::_lookupActive(
351  $a_node["child"],
352  $this->lm->getType(),
353  (bool) $this->lm_set->get("time_scheduled_page_activation")
354  );
355 
356  if ($a_node["child"] > 0 && !$active) {
357  $found = false;
358  } else {
359  $found = true;
360  }
361  }
362  }
363 
364  $lang_suffix = "";
365  if ($this->export_all_languages) {
366  if ($this->lang != "" && $this->lang != "-") {
367  $lang_suffix = "_" . $this->lang;
368  }
369  }
370 
371  if ($nid = ilLMPageObject::getExportId($this->lm->getId(), $a_node["child"])) {
372  return "lm_pg_" . $nid . $lang_suffix . ".html";
373  }
374  return "lm_pg_" . $a_node["child"] . $lang_suffix . ".html";
375  }
376  }
377 
381  public function isNodeVisible($a_node): bool
382  {
383  return (bool) $this->complete_tree["visibility"][$a_node["child"]];
384  }
385 
386  //
387  // Learning Sequence TOC
388  //
389 
390  public function renderLSToc(\LSTOCBuilder $toc): void
391  {
392  $this->renderLSTocNode($toc, null);
393  }
394 
395  protected function renderLSTocNode(\LSTOCBuilder $toc, ?array $current_node = null): void
396  {
397  $root = false;
398  if ($current_node == 0) {
399  $root = true;
400  $current_node = $this->tree->getNodeData($this->tree->readRootId());
401  }
402 
403  $children = $this->getChildren($current_node);
404  if (count($children) > 0) {
405  if ($root) {
406  $node_toc = $toc;
407  } else {
408  // current workaround
410  $node_icon = $this->getNodeIcon($current_node);
411  if (strpos($node_icon, "complete")) {
413  }
414 
415  $node_toc = $toc->node($current_node["title"], $current_node["child"], $lp);
416  }
417  foreach ($this->getChildren($current_node) as $child) {
418  $this->renderLSTocNode($node_toc, $child);
419  }
420  $node_toc->end();
421  } else {
422  $highlight = $this->isNodeHighlighted($current_node);
423  $toc->item($current_node["title"], $current_node["child"], null, $highlight);
424  }
425  }
426 }
static _lookupActive(int $a_id, string $a_parent_type, bool $a_check_scheduled_activation=false, string $a_lang="-")
lookup activation status
ilPageActivationDBRepository $activation_repo
static _getPresentationTitle(int $a_st_id, string $a_mode=self::CHAPTER_TITLE, bool $a_include_numbers=false, bool $a_time_scheduled_activation=false, bool $a_force_content=false, int $a_lm_id=0, string $a_lang="-", bool $a_include_short=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _isPagePublic(int $a_node_id, bool $a_check_public_mode=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
get(string $a_keyword, ?string $a_default_value=null)
get setting
const ANONYMOUS_USER_ID
Definition: constants.php:27
static _isScheduledActivation(int $a_id, string $a_parent_type, string $a_lang="-")
Check whether page is activated by time schedule.
static getExportId(int $a_lm_id, int $a_lmobj_id, string $a_type="pg")
setTypeWhiteList(array $a_val)
Set type white list.
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
ilLMPresentationService $service
renderLSToc(\LSTOCBuilder $toc)
$path
Definition: ltiservices.php:32
global $DIC
Definition: feed.php:28
getSuccessorNode( $a_node_id, string $a_type="")
Get successor node (currently only(!) based on lft/rgt tree values)
__construct(VocabulariesInterface $vocabularies)
Class LSTOCBuilder.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getNodeId($a_node)
Get id for node.
ilLMPresentationLinker $linker
setTracker(ilLMTracker $a_val)
static _getPresentationTitle(int $a_pg_id, string $a_mode=self::CHAPTER_TITLE, bool $a_include_numbers=false, bool $a_time_scheduled_activation=false, bool $a_force_content=false, int $a_lm_id=0, string $a_lang="-", bool $a_include_short=false)
presentation title doesn&#39;t have to be page title, it may be chapter title + page title or chapter tit...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupType(int $a_obj_id, int $a_lm_id=0)
node(string $label, int $parameter=null, int $lp=null)
Build a sub tree in the TOC.If a parameter is provided, the node in the TOC can be accessed itself...
getChildren($record, $environment=null)
Get a list of records (that list can also be empty).
setSecondaryHighlightedNodes(array $a_val)
Set secondary (background) highlighted nodes.
item(string $label, int $parameter, $state=null, bool $current=false)
Build an entry in the TOC.The parameter will be appended to the command when updating the state...
renderLSTocNode(\LSTOCBuilder $toc, ?array $current_node=null)
__construct( $a_parent_obj, string $a_parent_cmd, ilLMPresentationService $service, string $a_lang="-", int $a_focus_id=0, bool $export_all_languages=false)
Constructor.
Main service init and factory.