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