ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilLMContentRendererGUI.php
Go to the documentation of this file.
1 <?php
2 
23 {
24  public const STATUS_ACCESS = 0;
25  public const STATUS_NO_ACCESS = 1;
26  public const STATUS_NO_PUBLIC_ACCESS = 2;
27  public const STATUS_FAILED_PRECONDITIONS = 3;
29  public const STATUS_NO_PAGE_IN_CHAPTER = 5;
30  public const STATUS_DEACTIVATED_PAGE = 6;
31  public const STATUS_NO_PAGE_FOUND = 7;
33 
34  protected ?int $requested_focus_return;
35  protected int $requested_obj_id = 0;
36  protected ?string $search_string;
37  protected ?int $focus_id;
38  protected bool $deactivated_page;
41  protected ilObjUser $user;
42  protected ilHelpGUI $help;
43  protected ?int $current_page = null;
45  protected ilLanguage $lng;
46  protected bool $offline;
47  protected ilLMTracker $tracker;
48  protected ilCtrl $ctrl;
49  protected ilLMTree $lm_tree;
51  protected ilSetting $lm_set;
52  protected string $lang;
54  protected string $requested_frame;
56  protected string $concrete_lang = "";
57 
58  public function __construct(
60  ilLMPresentationGUI $parent_gui,
61  ilLanguage $lng,
62  ilCtrl $ctrl,
63  ilAccessHandler $access,
64  ilObjUser $user,
65  ilHelpGUI $help,
66  int $requested_obj_id
67  ) {
68  $this->access = $access;
69  $this->user = $user;
70  $this->help = $help;
71  $this->ctrl = $ctrl;
72  $this->lm_tree = $service->getLMTree();
73  $this->lang = $service->getPresentationStatus()->getLang();
74  $this->current_page = $service->getNavigationStatus()->getCurrentPage();
75  $this->lm = $service->getLearningModule();
76  $this->lm_set = $service->getSettings();
77  $this->lng = $lng;
78  $this->offline = $service->getPresentationStatus()->offline;
79  $this->tracker = $service->getTracker();
80  $this->linker = $service->getLinker();
81  $this->parent_gui = $parent_gui;
82  $this->chapter_has_no_active_page = $service->getNavigationStatus()->isChapterWithoutActivePage();
83  $this->deactivated_page = $service->getNavigationStatus()->isDeactivatedPage();
84  $this->focus_id = $service->getPresentationStatus()->getFocusId();
85  $this->concrete_lang = $service->getPresentationStatus()->getConcreteLang();
86  $this->search_string = $service->getPresentationStatus()->getSearchString();
87  $this->requested_obj_id = $requested_obj_id;
88  $this->requested_focus_return = $service->getPresentationStatus()->getFocusReturn();
89  $this->requested_frame = $service->getRequest()->getFrame();
90  $this->navigation_status = $service->getNavigationStatus();
91  $this->ot = ilObjectTranslation::getInstance($this->lm->getId());
92  }
93 
94  protected function initHelp(): void
95  {
96  $ilHelp = $this->help;
97  $ilHelp->setScreenIdComponent("lm");
98  $ilHelp->setScreenId("content");
99  $ilHelp->setSubScreenId("content");
100  }
101 
102  protected function determineStatus(): int
103  {
104  $user = $this->user;
105 
106  $status = self::STATUS_ACCESS;
107  // check page id
108  $requested_page_lm = ilLMPage::lookupParentId($this->current_page, "lm");
109  if ($requested_page_lm != $this->lm->getId()) {
110  $status = self::STATUS_NO_ACCESS;
111  }
112 
113 
114  // check if page is (not) visible in public area
115  if ($user->getId() == ANONYMOUS_USER_ID &&
116  $this->lm->getPublicAccessMode() == 'selected') {
117  if (!ilLMObject::_isPagePublic($this->current_page)) {
118  $status = self::STATUS_NO_PUBLIC_ACCESS;
119  }
120  }
121 
122  // preconditions
123  if (!ilObjContentObject::_checkPreconditionsOfPage($this->lm->getRefId(), $this->lm->getId(), $this->current_page)) {
124  $status = self::STATUS_FAILED_PRECONDITIONS;
125  }
126 
127  // if navigation is restricted based on correct answered questions
128  // check if we have preceeding pages including unsanswered/incorrect answered questions
129  if (!$this->offline) {
130  if ($this->lm->getRestrictForwardNavigation()) {
131  if ($this->tracker->hasPredIncorrectAnswers($this->current_page)) {
132  $status = self::STATUS_CORRECT_ANSWER_MISSING;
133  }
134  }
135  }
136 
137  // no active page found in chapter
138  if ($this->chapter_has_no_active_page &&
139  ilLMObject::_lookupType($this->requested_obj_id) == "st") {
140  $status = self::STATUS_NO_PAGE_IN_CHAPTER;
141  }
142 
143  if ($this->deactivated_page) {
144  $status = self::STATUS_DEACTIVATED_PAGE;
145  }
146 
147  if ($this->current_page == 0) {
148  $status = self::STATUS_NO_PAGE_FOUND;
149  }
150 
151  return $status;
152  }
153 
154  protected function initSearchHighlighting(): void
155  {
156  $user = $this->user;
157 
158  if ($this->search_string != "" && !$this->offline) {
159  $cache = ilUserSearchCache::_getInstance($user->getId());
160  $cache->switchSearchType(ilUserSearchCache::LAST_QUERY);
161  $search_string = $cache->getQuery();
162 
163  // advanced search?
164  if (is_array($search_string)) {
165  $search_string = $search_string["lom_content"];
166  }
167 
168  $p = new ilQueryParser($search_string);
169  $p->parse();
170 
171  $words = $p->getQuotedWords();
172  if (is_array($words)) {
173  foreach ($words as $w) {
174  ilTextHighlighterGUI::highlight("ilLMPageContent", $w);
175  }
176  }
177  }
178  }
179 
180  public function render(
181  int $a_head_foot_page_id = 0
182  ): string {
183  $ilUser = $this->user;
184 
185  $head = $foot = "";
186 
187  $this->initHelp();
188 
189  switch ($this->determineStatus()) {
190  case self::STATUS_NO_ACCESS:
191  return $this->renderNoPageAccess();
192 
193  case self::STATUS_NO_PUBLIC_ACCESS:
194  return $this->renderNoPublicAccess();
195 
196  case self::STATUS_FAILED_PRECONDITIONS:
197  return $this->renderPreconditionsOfPage();
198 
199  case self::STATUS_CORRECT_ANSWER_MISSING:
200  return $this->renderNavRestrictionDueToQuestions();
201 
202  case self::STATUS_NO_PAGE_IN_CHAPTER:
203  return $this->renderNoPageInChapterMessage();
204 
205  case self::STATUS_DEACTIVATED_PAGE:
206  return $this->renderDeactivatedPageMessage();
207 
208  case self::STATUS_NO_PAGE_FOUND:
209  return $this->renderNoPageFoundMessage();
210  }
211 
212  // page id is e.g. > 0 when footer or header page is processed
213  if ($a_head_foot_page_id == 0) {
214  $page_id = $this->current_page;
215  $this->initSearchHighlighting();
216  } else {
217  $page_id = $a_head_foot_page_id;
218  }
219 
220  // check if page is out of focus
221  $focus_mess = $this->renderFocusMessage();
222  $page_object_gui = $this->getLMPageGUI($page_id);
223 
224  // @todo 6.0 (factor this out (maybe to ilLMPageGUI)
225  $this->parent_gui->basicPageGuiInit($page_object_gui);
226 
227  $page_object = $page_object_gui->getPageObject();
228  $page_object->buildDom();
229  $page_object->registerOfflineHandler($this);
230 
231  $page_object_gui->setTemplateOutput(false);
232 
233  // Update course items
234  ilCourseLMHistory::_updateLastAccess($ilUser->getId(), $this->lm->getRefId(), $page_id);
235 
236  // read link targets
237  $page_object_gui->setPageLinker($this->linker);
238 
239  // get lm page object
240  $lm_pg_obj = new ilLMPageObject($this->lm, $page_id);
241  $lm_pg_obj->setLMId($this->lm->getId());
242 
243  // determine target frames for internal links
244  $page_object_gui->setLinkFrame($this->requested_frame);
245 
246  // page title and tracking (not for header or footer page)
247  if ($page_id == 0 || ($page_id != $this->lm->getHeaderPage() &&
248  $page_id != $this->lm->getFooterPage())) {
249  $page_object_gui->setPresentationTitle(
251  $lm_pg_obj->getId(),
252  $this->lm->getPageHeader(),
253  $this->lm->isActiveNumbering(),
254  (bool) $this->lm_set->get("time_scheduled_page_activation"),
255  false,
256  0,
258  )
259  );
260 
261  // track access
262  if ($page_id != 0 && !$this->offline) {
263  $this->tracker->trackAccess($page_id, $ilUser->getId());
264  }
265  } else {
266  $page_object_gui->setEnabledPageFocus(false);
267  $page_object_gui->getPageConfig()->setEnableSelfAssessment(false);
268  }
269 
270  // ADDED FOR CITATION
271  $page_object_gui->setLinkParams("ref_id=" . $this->lm->getRefId());
272  $page_object_gui->setTemplateTargetVar("PAGE_CONTENT");
273  // @todo 6.0
274  // $page_object_gui->setSourcecodeDownloadScript($this->getSourcecodeDownloadLink());
275 
276  $ret = $page_object_gui->presentation($page_object_gui->getOutputMode());
277 
278  // process header
279  if ($this->lm->getHeaderPage() > 0 &&
280  $page_id != $this->lm->getHeaderPage() &&
281  ($page_id == 0 || $page_id != $this->lm->getFooterPage())) {
282  if (ilLMObject::_exists($this->lm->getHeaderPage())) {
283  $head = $this->render($this->lm->getHeaderPage());
284  }
285  }
286 
287  // process footer
288  if ($this->lm->getFooterPage() > 0 &&
289  $page_id != $this->lm->getFooterPage() &&
290  ($page_id == 0 || $page_id != $this->lm->getHeaderPage())) {
291  if (ilLMObject::_exists($this->lm->getFooterPage())) {
292  $foot = $this->render($this->lm->getFooterPage());
293  }
294  }
295  return $head . $focus_mess . $ret . $foot;
296  }
297 
298  public function getLMPageGUI(int $a_id): ilLMPageGUI
299  {
300  if ($this->lang != "-" && ilPageObject::_exists("lm", $a_id, $this->lang)) {
301  $page_gui = new ilLMPageGUI($a_id, 0, false, $this->lang, $this->concrete_lang);
302  } else {
303  if ($this->lang != "-" && ilPageObject::_exists("lm", $a_id, $this->ot->getFallbackLanguage())) {
304  $page_gui = new ilLMPageGUI($a_id, 0, false, $this->ot->getFallbackLanguage(), $this->concrete_lang);
305  } else {
306  $page_gui = new ilLMPageGUI($a_id, 0, false, "", $this->concrete_lang);
307  }
308  }
309  if ($this->offline) {
310  $page_gui->setOutputMode(ilPageObjectGUI::OFFLINE);
311  }
312  return $page_gui;
313  }
314 
315  public function handleCodeParagraph(
316  int $page_id,
317  int $paragraph_id,
318  string $title,
319  string $text
320  ): void {
321  $directory = $this->parent_gui->getOfflineDirectory() . "/codefiles/" . $page_id . "/" . $paragraph_id;
322  ilFileUtils::makeDirParents($directory);
323  $file = $directory . "/" . $title;
324  if (!($fp = fopen($file, "w+"))) {
325  die("<strong>Error</strong>: Could not open \"" . $file . "\" for writing" .
326  " in <strong>" . __FILE__ . "</strong> on line <strong>" . __LINE__ . "</strong><br />");
327  }
328  chmod($file, 0770);
329  fwrite($fp, $text);
330  fclose($fp);
331  }
332 
333  protected function renderFocusMessage(): string
334  {
335  $focus_mess = "";
336  if ($this->focus_id > 0) {
337  $path = $this->lm_tree->getPathId($this->current_page);
338 
339  // out of focus
340  if (!in_array($this->focus_id, $path)) {
341  $mtpl = new ilTemplate(
342  "tpl.out_of_focus_message.html",
343  true,
344  true,
345  "Modules/LearningModule"
346  );
347  $mtpl->setVariable("MESSAGE", $this->lng->txt("cont_out_of_focus_message"));
348  $mtpl->setVariable("TXT_SHOW_CONTENT", $this->lng->txt("cont_show_content_after_focus"));
349 
350  if ($this->requested_focus_return == 0 || ilObject::_lookupType((int) $this->requested_focus_return, true) != "crs") {
351  $mtpl->setVariable("TXT_BACK_BEGINNING", $this->lng->txt("cont_to_focus_beginning"));
352  $this->ctrl->setParameter($this->parent_gui, "obj_id", $this->focus_id);
353  $mtpl->setVariable("LINK_BACK_TO_BEGINNING", $this->ctrl->getLinkTarget($this->parent_gui, "layout"));
354  $this->ctrl->setParameter($this->parent_gui, "obj_id", $this->requested_obj_id);
355  } else {
356  $mtpl->setVariable("TXT_BACK_BEGINNING", $this->lng->txt("cont_to_focus_return_crs"));
357  $mtpl->setVariable("LINK_BACK_TO_BEGINNING", ilLink::_getLink($this->requested_focus_return));
358  }
359 
360  $this->ctrl->setParameter($this->parent_gui, "focus_id", null);
361  $mtpl->setVariable("LINK_SHOW_CONTENT", $this->ctrl->getLinkTarget($this->parent_gui, "layout"));
362  $this->ctrl->setParameter($this->parent_gui, "focus_id", $this->requested_obj_id);
363 
364  $focus_mess = $mtpl->get();
365  } else {
366  $succ_page_id = $this->navigation_status->getSuccessorPageId();
367  $path2 = array();
368  if ($succ_page_id > 0) {
369  $path2 = $this->lm_tree->getPathId($succ_page_id);
370  }
371  if ($succ_page_id == 0 || !in_array($this->focus_id, $path2)) {
372  $mtpl = new ilTemplate(
373  "tpl.out_of_focus_message.html",
374  true,
375  true,
376  "Modules/LearningModule"
377  );
378  $mtpl->setVariable("MESSAGE", $this->lng->txt("cont_out_of_focus_message_last_page"));
379  $mtpl->setVariable("TXT_SHOW_CONTENT", $this->lng->txt("cont_show_content_after_focus"));
380 
381  if ($this->requested_focus_return == 0 || ilObject::_lookupType($this->requested_focus_return, true) != "crs") {
382  $mtpl->setVariable("TXT_BACK_BEGINNING", $this->lng->txt("cont_to_focus_beginning"));
383  $this->ctrl->setParameter($this->parent_gui, "obj_id", $this->focus_id);
384  $mtpl->setVariable("LINK_BACK_TO_BEGINNING", $this->ctrl->getLinkTarget($this->parent_gui, "layout"));
385  $this->ctrl->setParameter($this->parent_gui, "obj_id", $this->requested_obj_id);
386  } else {
387  $mtpl->setVariable("TXT_BACK_BEGINNING", $this->lng->txt("cont_to_focus_return_crs"));
388  $mtpl->setVariable("LINK_BACK_TO_BEGINNING", ilLink::_getLink($this->requested_focus_return));
389  }
390 
391  $this->ctrl->setParameter($this->parent_gui, "focus_id", null);
392  $mtpl->setVariable("LINK_SHOW_CONTENT", $this->ctrl->getLinkTarget($this->parent_gui, "layout"));
393  $this->ctrl->setParameter($this->parent_gui, "focus_id", $this->requested_obj_id);
394 
395  $focus_mess = $mtpl->get();
396  }
397  }
398  }
399  return $focus_mess;
400  }
401 
402 
406  protected function renderNoPageAccess(): string
407  {
408  return $this->renderMessageScreen($this->lng->txt("msg_no_page_access"));
409  }
410 
414  protected function renderMessageScreen(string $a_content): string
415  {
416  // content style
417  $tpl = new ilTemplate("tpl.page_message_screen.html", true, true, "Modules/LearningModule");
418  $tpl->setVariable("TXT_PAGE_NO_PUBLIC_ACCESS", $a_content);
419 
420  return $tpl->get();
421  }
422 
426  protected function renderNoPublicAccess(): string
427  {
428  return $this->renderMessageScreen($this->lng->txt("msg_page_no_public_access"));
429  }
430 
435  protected function renderNavRestrictionDueToQuestions(): string
436  {
437  return $this->renderMessageScreen($this->lng->txt("cont_no_page_access_unansw_q"));
438  }
439 
443  protected function renderNoPageInChapterMessage(): string
444  {
445  $mtpl = new ilTemplate(
446  "tpl.no_content_message.html",
447  true,
448  true,
449  "Modules/LearningModule"
450  );
451  $mtpl->setVariable("MESSAGE", $this->lng->txt("cont_no_page_in_chapter"));
452  $mtpl->setVariable(
453  "ITEM_TITLE",
454  ilLMObject::_lookupTitle($this->requested_obj_id)
455  );
456  return $mtpl->get();
457  }
458 
462  protected function renderNoPageFoundMessage(): string
463  {
464  return $this->renderMessageScreen($this->lng->txt("cont_no_page"));
465  }
466 
467  protected function renderDeactivatedPageMessage(): string
468  {
469  $mtpl = new ilTemplate(
470  "tpl.no_content_message.html",
471  true,
472  true,
473  "Modules/LearningModule"
474  );
475  $m = $this->lng->txt("cont_page_currently_deactivated");
476  $act_data = ilLMPage::_lookupActivationData($this->requested_obj_id, $this->lm->getType());
477  if ($act_data["show_activation_info"] &&
478  (ilUtil::now() < $act_data["activation_start"])) {
479  $m .= "<p>" . sprintf(
480  $this->lng->txt("cont_page_activation_on"),
482  new ilDateTime($act_data["activation_start"], IL_CAL_DATETIME)
483  )
484  ) .
485  "</p>";
486  }
487  $mtpl->setVariable("MESSAGE", $m);
488  $mtpl->setVariable(
489  "ITEM_TITLE",
490  ilLMObject::_lookupTitle($this->requested_obj_id)
491  );
492  return $mtpl->get();
493  }
494 
495 
499  public function renderPreconditionsOfPage(): string
500  {
501  $succ_node = "";
502  $conds = ilObjContentObject::_getMissingPreconditionsOfPage($this->lm->getRefId(), $this->lm->getId(), $this->current_page);
503  $topchap = ilObjContentObject::_getMissingPreconditionsTopChapter($this->lm->getRefId(), $this->lm->getId(), $this->current_page);
504 
505  $ptpl = new ilTemplate("tpl.page_preconditions.html", true, true, "Modules/LearningModule");
506 
507  // list all missing preconditions
508  foreach ($conds as $cond) {
509  $obj_link = ilLink::_getLink($cond["trigger_ref_id"]);
510  $ptpl->setCurrentBlock("condition");
511  $ptpl->setVariable("VAL_ITEM", ilObject::_lookupTitle($cond["trigger_obj_id"]));
512  $ptpl->setVariable("LINK_ITEM", $obj_link);
513  if ($cond["operator"] == "passed") {
514  $cond_str = $this->lng->txt("passed");
515  } else {
516  $cond_str = $this->lng->txt("condition_" . $cond["operator"]);
517  }
518  $ptpl->setVariable("VAL_CONDITION", $cond_str . " " . $cond["value"]);
519  $ptpl->parseCurrentBlock();
520  }
521 
522  $ptpl->setVariable(
523  "TXT_MISSING_PRECONDITIONS",
524  sprintf(
525  $this->lng->txt("cont_missing_preconditions"),
526  ilLMObject::_lookupTitle($topchap)
527  )
528  );
529  $ptpl->setVariable("TXT_ITEM", $this->lng->txt("object"));
530  $ptpl->setVariable("TXT_CONDITION", $this->lng->txt("condition"));
531 
532  // output skip chapter link
533  $parent = $this->lm_tree->getParentId($topchap);
534  $childs = $this->lm_tree->getChildsByType($parent, "st");
535  $j = -2;
536  $i = 1;
537  foreach ($childs as $child) {
538  if ($child["child"] == $topchap) {
539  $j = $i;
540  }
541  if ($i++ == ($j + 1)) {
542  $succ_node = $this->lm_tree->fetchSuccessorNode($child["child"], "pg");
543  }
544  }
545  if ($succ_node != "") {
546  $link = "<br /><a href=\"" .
547  $this->linker->getLink("layout", $succ_node["obj_id"], $this->requested_frame) .
548  "\">" . $this->lng->txt("cont_skip_chapter") . "</a>";
549  $ptpl->setVariable("LINK_SKIP_CHAPTER", $link);
550  }
551 
552  return $ptpl->get();
553  }
554 }
static _getMissingPreconditionsOfPage(int $cont_ref_id, int $cont_obj_id, int $page_id)
gets all missing preconditions of page
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...
renderNoPageAccess()
Render info message, if page is not accessible in public area.
renderNoPageInChapterMessage()
Render no page in chapter message.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const IL_CAL_DATETIME
const ANONYMOUS_USER_ID
Definition: constants.php:27
static _getInstance(int $a_usr_id)
Help GUI class.
renderMessageScreen(string $a_content)
Render message screen.
renderNavRestrictionDueToQuestions()
Render message if navigation to page is not allowed due to unanswered questions.
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
static _lookupActivationData(int $a_id, string $a_parent_type, string $a_lang="-")
Lookup activation data.
render(int $a_head_foot_page_id=0)
static _updateLastAccess(int $a_user_id, int $a_lm_ref_id, int $a_page_id)
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static now()
Return current timestamp in Y-m-d H:i:s format.
$path
Definition: ltiservices.php:32
static _lookupTitle(int $a_obj_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilLMNavigationStatus $navigation_status
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupTitle(int $obj_id)
renderPreconditionsOfPage()
Render preconditions of the page.
static _checkPreconditionsOfPage(int $cont_ref_id, int $cont_obj_id, int $page_id)
checks whether the preconditions of a page are fulfilled or not
static _exists(string $a_parent_type, int $a_id, string $a_lang="", bool $a_no_cache=false)
Checks whether page exists.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setScreenIdComponent(string $a_comp)
Extension of ilPageObjectGUI for learning modules.
handleCodeParagraph(int $page_id, int $paragraph_id, string $title, string $text)
static getInstance(int $obj_id)
static lookupParentId(int $a_id, string $a_type)
getSettings()
Get learning module settings.
renderNoPageFoundMessage()
Render no page found message.
__construct(ilLMPresentationService $service, ilLMPresentationGUI $parent_gui, ilLanguage $lng, ilCtrl $ctrl, ilAccessHandler $access, ilObjUser $user, ilHelpGUI $help, int $requested_obj_id)
static _exists(int $a_id)
checks wether a lm content object with specified id exists or not
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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)
renderNoPublicAccess()
Render info message, if page is not accessible in public area.
static _lookupType(int $id, bool $reference=false)
$service
Definition: ltiservices.php:43
static _getMissingPreconditionsTopChapter(int $cont_obj_ref_id, int $cont_obj_id, int $page_id)
get top chapter of page for that any precondition is missing
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Main service init and factory.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...