ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
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  // preconditions
114  if (!ilObjContentObject::_checkPreconditionsOfPage($this->lm->getRefId(), $this->lm->getId(), $this->current_page)) {
115  $status = self::STATUS_FAILED_PRECONDITIONS;
116  }
117 
118  // if navigation is restricted based on correct answered questions
119  // check if we have preceeding pages including unsanswered/incorrect answered questions
120  if (!$this->offline) {
121  if ($this->lm->getRestrictForwardNavigation()) {
122  if ($this->tracker->hasPredIncorrectAnswers($this->current_page)) {
123  $status = self::STATUS_CORRECT_ANSWER_MISSING;
124  }
125  }
126  }
127 
128  // no active page found in chapter
129  if ($this->chapter_has_no_active_page &&
130  ilLMObject::_lookupType($this->requested_obj_id) == "st") {
131  $status = self::STATUS_NO_PAGE_IN_CHAPTER;
132  }
133 
134  if ($this->deactivated_page) {
135  $status = self::STATUS_DEACTIVATED_PAGE;
136  }
137 
138  if ($this->current_page == 0) {
139  $status = self::STATUS_NO_PAGE_FOUND;
140  }
141  return $status;
142  }
143 
144  protected function initSearchHighlighting(): void
145  {
146  $user = $this->user;
147 
148  if ($this->search_string != "" && !$this->offline) {
149  $cache = ilUserSearchCache::_getInstance($user->getId());
150  $cache->switchSearchType(ilUserSearchCache::LAST_QUERY);
151  $search_string = $cache->getQuery();
152 
153  // advanced search?
154  if (is_array($search_string)) {
155  $search_string = $search_string["lom_content"];
156  }
157 
158  $p = new ilQueryParser($search_string);
159  $p->parse();
160 
161  $words = $p->getQuotedWords();
162  if (is_array($words)) {
163  foreach ($words as $w) {
164  ilTextHighlighterGUI::highlight("ilLMPageContent", $w);
165  }
166  }
167  }
168  }
169 
170  public function render(
171  int $a_head_foot_page_id = 0
172  ): string {
173  $ilUser = $this->user;
174 
175  $head = $foot = "";
176 
177  $this->initHelp();
178 
179  switch ($this->determineStatus()) {
180  case self::STATUS_NO_ACCESS:
181  return $this->renderNoPageAccess();
182 
183  case self::STATUS_NO_PUBLIC_ACCESS:
184  return $this->renderNoPublicAccess();
185 
186  case self::STATUS_FAILED_PRECONDITIONS:
187  return $this->renderPreconditionsOfPage();
188 
189  case self::STATUS_CORRECT_ANSWER_MISSING:
190  return $this->renderNavRestrictionDueToQuestions();
191 
192  case self::STATUS_NO_PAGE_IN_CHAPTER:
193  return $this->renderNoPageInChapterMessage();
194 
195  case self::STATUS_DEACTIVATED_PAGE:
196  return $this->renderDeactivatedPageMessage();
197 
198  case self::STATUS_NO_PAGE_FOUND:
199  return $this->renderNoPageFoundMessage();
200  }
201 
202  // page id is e.g. > 0 when footer or header page is processed
203  if ($a_head_foot_page_id == 0) {
204  $page_id = $this->current_page;
205  $this->initSearchHighlighting();
206  } else {
207  $page_id = $a_head_foot_page_id;
208  }
209 
210  // check if page is out of focus
211  $focus_mess = $this->renderFocusMessage();
212  $page_object_gui = $this->getLMPageGUI($page_id);
213 
214  // @todo 6.0 (factor this out (maybe to ilLMPageGUI)
215  $this->parent_gui->basicPageGuiInit($page_object_gui);
216 
217  $page_object = $page_object_gui->getPageObject();
218  $page_object->buildDom();
219  $page_object->registerOfflineHandler($this);
220 
221  $page_object_gui->setTemplateOutput(false);
222 
223  // Update course items
224  ilCourseLMHistory::_updateLastAccess($ilUser->getId(), $this->lm->getRefId(), $page_id);
225 
226  // read link targets
227  $page_object_gui->setPageLinker($this->linker);
228 
229  // get lm page object
230  $lm_pg_obj = new ilLMPageObject($this->lm, $page_id);
231  $lm_pg_obj->setLMId($this->lm->getId());
232 
233  // determine target frames for internal links
234  $page_object_gui->setLinkFrame($this->requested_frame);
235 
236  // page title and tracking (not for header or footer page)
237  if ($page_id == 0 || ($page_id != $this->lm->getHeaderPage() &&
238  $page_id != $this->lm->getFooterPage())) {
239  $page_object_gui->setPresentationTitle(
241  $lm_pg_obj->getId(),
242  $this->lm->getPageHeader(),
243  $this->lm->isActiveNumbering(),
244  (bool) $this->lm_set->get("time_scheduled_page_activation"),
245  false,
246  0,
248  )
249  );
250 
251  // track access
252  if ($page_id != 0 && !$this->offline) {
253  $this->tracker->trackAccess($page_id, $ilUser->getId());
254  }
255  } else {
256  $page_object_gui->setEnabledPageFocus(false);
257  $page_object_gui->getPageConfig()->setEnableSelfAssessment(false);
258  }
259 
260  // ADDED FOR CITATION
261  $page_object_gui->setLinkParams("ref_id=" . $this->lm->getRefId());
262  $page_object_gui->setTemplateTargetVar("PAGE_CONTENT");
263  // @todo 6.0
264  // $page_object_gui->setSourcecodeDownloadScript($this->getSourcecodeDownloadLink());
265 
266  $ret = $page_object_gui->presentation($page_object_gui->getOutputMode());
267 
268  // process header
269  if ($this->lm->getHeaderPage() > 0 &&
270  $page_id != $this->lm->getHeaderPage() &&
271  ($page_id == 0 || $page_id != $this->lm->getFooterPage())) {
272  if (ilLMObject::_exists($this->lm->getHeaderPage())) {
273  $head = $this->render($this->lm->getHeaderPage());
274  }
275  }
276 
277  // process footer
278  if ($this->lm->getFooterPage() > 0 &&
279  $page_id != $this->lm->getFooterPage() &&
280  ($page_id == 0 || $page_id != $this->lm->getHeaderPage())) {
281  if (ilLMObject::_exists($this->lm->getFooterPage())) {
282  $foot = $this->render($this->lm->getFooterPage());
283  }
284  }
285  return $head . $focus_mess . $ret . $foot;
286  }
287 
288  public function getLMPageGUI(int $a_id): ilLMPageGUI
289  {
290  if ($this->lang != "-" && ilPageObject::_exists("lm", $a_id, $this->lang)) {
291  $page_gui = new ilLMPageGUI($a_id, 0, false, $this->lang, $this->concrete_lang);
292  } else {
293  if ($this->lang != "-" && ilPageObject::_exists("lm", $a_id, $this->ot->getFallbackLanguage())) {
294  $page_gui = new ilLMPageGUI($a_id, 0, false, $this->ot->getFallbackLanguage(), $this->concrete_lang);
295  } else {
296  $page_gui = new ilLMPageGUI($a_id, 0, false, "", $this->concrete_lang);
297  }
298  }
299  if ($this->offline) {
300  $page_gui->setOutputMode(ilPageObjectGUI::OFFLINE);
301  }
302  return $page_gui;
303  }
304 
305  public function handleCodeParagraph(
306  int $page_id,
307  int $paragraph_id,
308  string $title,
309  string $text
310  ): void {
311  $directory = $this->parent_gui->getOfflineDirectory() . "/codefiles/" . $page_id . "/" . $paragraph_id;
312  ilFileUtils::makeDirParents($directory);
313  $file = $directory . "/" . $title;
314  if (!($fp = fopen($file, "w+"))) {
315  die("<strong>Error</strong>: Could not open \"" . $file . "\" for writing" .
316  " in <strong>" . __FILE__ . "</strong> on line <strong>" . __LINE__ . "</strong><br />");
317  }
318  chmod($file, 0770);
319  fwrite($fp, $text);
320  fclose($fp);
321  }
322 
323  protected function renderFocusMessage(): string
324  {
325  $focus_mess = "";
326  if ($this->focus_id > 0) {
327  $path = $this->lm_tree->getPathId($this->current_page);
328 
329  // out of focus
330  if (!in_array($this->focus_id, $path)) {
331  $mtpl = new ilTemplate(
332  "tpl.out_of_focus_message.html",
333  true,
334  true,
335  "components/ILIAS/LearningModule"
336  );
337  $mtpl->setVariable("MESSAGE", $this->lng->txt("cont_out_of_focus_message"));
338  $mtpl->setVariable("TXT_SHOW_CONTENT", $this->lng->txt("cont_show_content_after_focus"));
339 
340  if ($this->requested_focus_return == 0 || ilObject::_lookupType((int) $this->requested_focus_return, true) != "crs") {
341  $mtpl->setVariable("TXT_BACK_BEGINNING", $this->lng->txt("cont_to_focus_beginning"));
342  $this->ctrl->setParameter($this->parent_gui, "obj_id", $this->focus_id);
343  $mtpl->setVariable("LINK_BACK_TO_BEGINNING", $this->ctrl->getLinkTarget($this->parent_gui, "layout"));
344  $this->ctrl->setParameter($this->parent_gui, "obj_id", $this->requested_obj_id);
345  } else {
346  $mtpl->setVariable("TXT_BACK_BEGINNING", $this->lng->txt("cont_to_focus_return_crs"));
347  $mtpl->setVariable("LINK_BACK_TO_BEGINNING", ilLink::_getLink($this->requested_focus_return));
348  }
349 
350  $this->ctrl->setParameter($this->parent_gui, "focus_id", null);
351  $mtpl->setVariable("LINK_SHOW_CONTENT", $this->ctrl->getLinkTarget($this->parent_gui, "layout"));
352  $this->ctrl->setParameter($this->parent_gui, "focus_id", $this->requested_obj_id);
353 
354  $focus_mess = $mtpl->get();
355  } else {
356  $succ_page_id = $this->navigation_status->getSuccessorPageId();
357  $path2 = array();
358  if ($succ_page_id > 0) {
359  $path2 = $this->lm_tree->getPathId($succ_page_id);
360  }
361  if ($succ_page_id == 0 || !in_array($this->focus_id, $path2)) {
362  $mtpl = new ilTemplate(
363  "tpl.out_of_focus_message.html",
364  true,
365  true,
366  "components/ILIAS/LearningModule"
367  );
368  $mtpl->setVariable("MESSAGE", $this->lng->txt("cont_out_of_focus_message_last_page"));
369  $mtpl->setVariable("TXT_SHOW_CONTENT", $this->lng->txt("cont_show_content_after_focus"));
370 
371  if ($this->requested_focus_return == 0 || ilObject::_lookupType($this->requested_focus_return, true) != "crs") {
372  $mtpl->setVariable("TXT_BACK_BEGINNING", $this->lng->txt("cont_to_focus_beginning"));
373  $this->ctrl->setParameter($this->parent_gui, "obj_id", $this->focus_id);
374  $mtpl->setVariable("LINK_BACK_TO_BEGINNING", $this->ctrl->getLinkTarget($this->parent_gui, "layout"));
375  $this->ctrl->setParameter($this->parent_gui, "obj_id", $this->requested_obj_id);
376  } else {
377  $mtpl->setVariable("TXT_BACK_BEGINNING", $this->lng->txt("cont_to_focus_return_crs"));
378  $mtpl->setVariable("LINK_BACK_TO_BEGINNING", ilLink::_getLink($this->requested_focus_return));
379  }
380 
381  $this->ctrl->setParameter($this->parent_gui, "focus_id", null);
382  $mtpl->setVariable("LINK_SHOW_CONTENT", $this->ctrl->getLinkTarget($this->parent_gui, "layout"));
383  $this->ctrl->setParameter($this->parent_gui, "focus_id", $this->requested_obj_id);
384 
385  $focus_mess = $mtpl->get();
386  }
387  }
388  }
389  return $focus_mess;
390  }
391 
392 
396  protected function renderNoPageAccess(): string
397  {
398  return $this->renderMessageScreen($this->lng->txt("msg_no_page_access"));
399  }
400 
404  protected function renderMessageScreen(string $a_content): string
405  {
406  // content style
407  $tpl = new ilTemplate("tpl.page_message_screen.html", true, true, "components/ILIAS/LearningModule");
408  $tpl->setVariable("TXT_PAGE_NO_PUBLIC_ACCESS", $a_content);
409 
410  return $tpl->get();
411  }
412 
416  protected function renderNoPublicAccess(): string
417  {
418  return $this->renderMessageScreen($this->lng->txt("msg_page_no_public_access"));
419  }
420 
425  protected function renderNavRestrictionDueToQuestions(): string
426  {
427  return $this->renderMessageScreen($this->lng->txt("cont_no_page_access_unansw_q"));
428  }
429 
433  protected function renderNoPageInChapterMessage(): string
434  {
435  $mtpl = new ilTemplate(
436  "tpl.no_content_message.html",
437  true,
438  true,
439  "components/ILIAS/LearningModule"
440  );
441  $mtpl->setVariable("MESSAGE", $this->lng->txt("cont_no_page_in_chapter"));
442  $mtpl->setVariable(
443  "ITEM_TITLE",
444  ilLMObject::_lookupTitle($this->requested_obj_id)
445  );
446  return $mtpl->get();
447  }
448 
452  protected function renderNoPageFoundMessage(): string
453  {
454  return $this->renderMessageScreen($this->lng->txt("cont_no_page"));
455  }
456 
457  protected function renderDeactivatedPageMessage(): string
458  {
459  $mtpl = new ilTemplate(
460  "tpl.no_content_message.html",
461  true,
462  true,
463  "components/ILIAS/LearningModule"
464  );
465  $m = $this->lng->txt("cont_page_currently_deactivated");
466  $act_data = ilLMPage::_lookupActivationData($this->current_page, $this->lm->getType());
467  if ($act_data["show_activation_info"] &&
468  (ilUtil::now() < $act_data["activation_start"])) {
469  $m .= "<p>" . sprintf(
470  $this->lng->txt("cont_page_activation_on"),
472  new ilDateTime($act_data["activation_start"], IL_CAL_DATETIME)
473  )
474  ) .
475  "</p>";
476  }
477  $mtpl->setVariable("MESSAGE", $m);
478  $mtpl->setVariable(
479  "ITEM_TITLE",
480  ilLMObject::_lookupTitle($this->current_page)
481  );
482  return $mtpl->get();
483  }
484 
485 
489  public function renderPreconditionsOfPage(): string
490  {
491  $succ_node = "";
492  $conds = ilObjContentObject::_getMissingPreconditionsOfPage($this->lm->getRefId(), $this->lm->getId(), $this->current_page);
493  $topchap = ilObjContentObject::_getMissingPreconditionsTopChapter($this->lm->getRefId(), $this->lm->getId(), $this->current_page);
494 
495  $ptpl = new ilTemplate("tpl.page_preconditions.html", true, true, "components/ILIAS/LearningModule");
496 
497  // list all missing preconditions
498  foreach ($conds as $cond) {
499  $obj_link = ilLink::_getLink($cond["trigger_ref_id"]);
500  $ptpl->setCurrentBlock("condition");
501  $ptpl->setVariable("VAL_ITEM", ilObject::_lookupTitle($cond["trigger_obj_id"]));
502  $ptpl->setVariable("LINK_ITEM", $obj_link);
503  if ($cond["operator"] == "passed") {
504  $cond_str = $this->lng->txt("passed");
505  } else {
506  $cond_str = $this->lng->txt("condition_" . $cond["operator"]);
507  }
508  $ptpl->setVariable("VAL_CONDITION", $cond_str . " " . $cond["value"]);
509  $ptpl->parseCurrentBlock();
510  }
511 
512  $ptpl->setVariable(
513  "TXT_MISSING_PRECONDITIONS",
514  sprintf(
515  $this->lng->txt("cont_missing_preconditions"),
516  ilLMObject::_lookupTitle($topchap)
517  )
518  );
519  $ptpl->setVariable("TXT_ITEM", $this->lng->txt("object"));
520  $ptpl->setVariable("TXT_CONDITION", $this->lng->txt("condition"));
521 
522  // output skip chapter link
523  $parent = $this->lm_tree->getParentId($topchap);
524  $childs = $this->lm_tree->getChildsByType($parent, "st");
525  $j = -2;
526  $i = 1;
527  foreach ($childs as $child) {
528  if ($child["child"] == $topchap) {
529  $j = $i;
530  }
531  if ($i++ == ($j + 1)) {
532  $succ_node = $this->lm_tree->fetchSuccessorNode($child["child"], "pg");
533  }
534  }
535  if ($succ_node != "") {
536  $link = "<br /><a href=\"" .
537  $this->linker->getLink("layout", $succ_node["obj_id"], $this->requested_frame) .
538  "\">" . $this->lng->txt("cont_skip_chapter") . "</a>";
539  $ptpl->setVariable("LINK_SKIP_CHAPTER", $link);
540  }
541 
542  return $ptpl->get();
543  }
544 }
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.
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
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
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
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Main service init and factory.