ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilPortfolioPageGUI.php
Go to the documentation of this file.
1 <?php
2 
27 {
28  public const EMBEDDED_NO_OUTPUT = -99;
29  protected bool $enable_comments;
30  protected int $portfolio_id;
31  protected \ILIAS\Portfolio\StandardGUIRequest $port_request;
32 
33  protected bool $embedded = false;
35  protected ilTree $tree;
36  protected array $js_onload_code = array();
37  protected array $additional = array();
38  protected array $export_material = array("js" => array(), "images" => array(), "files" => array());
39  protected static int $initialized = 0;
40  protected static bool $calender_initialized = false;
41  protected int $requested_ppage;
42 
43  public function __construct(
44  int $a_portfolio_id,
45  int $a_id = 0,
46  int $a_old_nr = 0,
47  bool $a_enable_comments = true
48  ) {
49  global $DIC;
50 
51  $this->tpl = $DIC["tpl"];
52  $this->ctrl = $DIC->ctrl();
53  $this->user = $DIC->user();
54  $this->obj_definition = $DIC["objDefinition"];
55  $this->access = $DIC->access();
56  $this->tree = $DIC->repositoryTree();
57  $this->lng = $DIC->language();
58  $tpl = $DIC["tpl"];
59  $this->port_request = $DIC->portfolio()
60  ->internal()
61  ->gui()
62  ->standardRequest();
63 
64  $this->portfolio_id = $a_portfolio_id;
65  $this->enable_comments = $a_enable_comments;
66 
67  parent::__construct($this->getParentType(), $a_id, $a_old_nr);
68  $this->getPageObject()->setPortfolioId($this->portfolio_id);
69 
70  // content style
71 
72  $tpl->setCurrentBlock("SyntaxStyle");
74  "LOCATION_SYNTAX_STYLESHEET",
76  );
78 
79  $tpl->setCurrentBlock("ContentStyle");
81  "LOCATION_CONTENT_STYLESHEET",
83  );
85 
86  $this->requested_ppage = $this->port_request->getPortfolioPageId();
87  }
88 
89  public function getParentType(): string
90  {
91  return "prtf";
92  }
93 
94  protected function getPageContentUserId(int $a_user_id): int
95  {
96  // user id from content-xml
97  return $a_user_id;
98  }
99 
100  protected function getPortfolioPage(): ilPortfolioPage
101  {
103  $page = $this->getPageObject();
104  return $page;
105  }
106 
107  public function executeCommand(): string
108  {
109  $ilCtrl = $this->ctrl;
110  $ilUser = $this->user;
111 
112  $next_class = $this->ctrl->getNextClass($this);
113  $cmd = $this->ctrl->getCmd();
114 
115  switch ($next_class) {
116  case "ilobjbloggui":
117  // #12879 - we need the wsp-id for the keywords
118  $wsp_tree = new ilWorkspaceTree($ilUser->getId());
119  $blog_obj_id = (int) $this->getPageObject()->getTitle();
120  $blog_node_id = $wsp_tree->lookupNodeId($blog_obj_id);
121 
122  $blog_gui = new ilObjBlogGUI($blog_node_id, ilObject2GUI::WORKSPACE_NODE_ID);
123  $blog_gui->disableNotes(!$this->enable_comments);
124  $blog_gui->prtf_embed = true; // disables prepareOutput()/getStandardTemplate() in blog
125  $ilCtrl->forwardCommand($blog_gui);
126  return $blog_gui->getRenderedContent();
127 
128  case "ilcalendarmonthgui":
129  $this->ctrl->saveParameter($this, "chuid");
130  // booking action
131  if ($cmd && $cmd !== "preview") {
132  $categories = ilCalendarCategories::_getInstance();
133  if ($categories->getMode() === 0) {
134  $chuid = $this->port_request->getConsultationHourUserId();
135  if ($chuid > 0) {
136  $categories->setCHUserId($chuid);
137  }
138  $categories->initialize(ilCalendarCategories::MODE_PORTFOLIO_CONSULTATION, 0, true);
139  }
140 
141  $req_seed = $this->port_request->getCalendarSeed();
142  if ($req_seed !== "") {
143  $seed = new ilDate($req_seed, IL_CAL_DATE);
144  } else {
145  $seed = new ilDate(time(), IL_CAL_UNIX);
146  }
147 
148  $month_gui = new ilCalendarMonthGUI($seed);
149  return (string) $ilCtrl->forwardCommand($month_gui);
150  }
151 
152  // calendar month navigation
153  //$ilCtrl->setParameter($this, "cmd", "preview");
154  return (string) self::EMBEDDED_NO_OUTPUT;
155  default:
156  $this->setPresentationTitle($this->getPageObject()->getTitle());
157  return (string) parent::executeCommand();
158  }
159  }
160 
161  public function showPage(): string
162  {
163  $ilUser = $this->user;
164 
165  if (!$this->getPageObject()) {
166  return "";
167  }
168 
169  if ($this->getPageObject()->getType() === ilPortfolioPage::TYPE_BLOG) {
170  return $this->renderBlog($ilUser->getId(), (int) $this->getPageObject()->getTitle());
171  }
172 
173  $this->setTemplateOutput(false);
174  // $this->setPresentationTitle($this->getPageObject()->getTitle());
175  return parent::showPage();
176  }
177 
178  public function getTabs(string $a_activate = ""): void
179  {
180  if (!$this->embedded) {
181  parent::getTabs($a_activate);
182  }
183  }
184 
188  public function setEmbedded(bool $a_value): void
189  {
190  $this->embedded = $a_value;
191  }
192 
196  public function setAdditional(array $a_additional): void
197  {
198  $this->additional = $a_additional;
199  }
200 
204  public function getAdditional(): array
205  {
206  return $this->additional;
207  }
208 
209  public function getJsOnloadCode(): array
210  {
211  return $this->js_onload_code;
212  }
213 
214  public function postOutputProcessing(string $a_output): string
215  {
216  $parts = array(
217  "Profile" => array("0-9", "a-z", "0-9a-z_;\W"), // user, mode, fields
218  "Verification" => array("0-9", "a-z", "0-9"), // user, type, id
219  "Blog" => array("0-9", "0-9", "0-9;\W"), // user, blog id, posting ids
220  "BlogTeaser" => array("0-9", "0-9", "0-9;\W"), // user, blog id, posting ids
221  "Skills" => array("0-9", "0-9"), // user, skill id
222  "SkillsTeaser" => array("0-9", "0-9"), // user, skill id
223  "ConsultationHours" => array("0-9", "a-z", "0-9;\W"), // user, mode, group ids
224  "ConsultationHoursTeaser" => array("0-9", "a-z", "0-9;\W"), // user, mode, group ids
225  "MyCourses" => array("0-9", "a-z*"), // user, sort
226  "MyCoursesTeaser" => array("0-9", "a-z*") // user, sort
227  );
228 
229  foreach ($parts as $type => $def) {
230  // #15732 - allow optional parts
231  $def_parts = array();
232  foreach ($def as $part) {
233  $is_opt = (substr($part, -1) === "*");
234  if (!$is_opt) {
235  $def_parts[] = "#";
236  $end_marker = "+";
237  } else {
238  $def_parts[] = "#*";
239  $end_marker = "*";
240  $part = substr($part, 0, -1);
241  }
242  $def_parts[] = "([" . $part . "]" . $end_marker . ")";
243  }
244  $def = implode("", $def_parts);
245 
246  if (preg_match_all(
247  "/" . $this->pl_start . $type . $def . $this->pl_end . "/",
248  $a_output,
249  $blocks
250  )) {
251  foreach ($blocks[0] as $idx => $block) {
252  switch ($type) {
253  case "Profile":
254  case "Blog":
255  case "BlogTeaser":
256  case "Skills":
257  case "SkillsTeaser":
258  case "ConsultationHours":
259  case "ConsultationHoursTeaser":
260  case "MyCourses":
261  case "MyCoursesTeaser":
262  $subs = null;
263  if (trim(($blocks[3][$idx] ?? ""))) {
264  foreach (explode(";", $blocks[3][$idx]) as $sub) {
265  if (trim($sub)) {
266  $subs[] = trim($sub);
267  }
268  }
269  }
270  $snippet = $this->{"render" . $type}(
271  $blocks[1][$idx],
272  $blocks[2][$idx],
273  $subs
274  );
275  break;
276 
277  default:
278  $snippet = $this->{"render" . $type}(
279  $blocks[1][$idx],
280  $blocks[2][$idx],
281  $blocks[3][$idx]
282  );
283  break;
284  }
285 
286  $snippet = $this->renderPageElement($type, $snippet);
287  $a_output = str_replace($block, $snippet, $a_output);
288  }
289  }
290  }
291 
292  $a_output = $this->makePlaceHoldersClickable($a_output);
293 
294  return $a_output;
295  }
296 
297  protected function renderPageElement(
298  string $a_type,
299  string $a_html
300  ): string {
301  return trim($a_html);
302  }
303 
304  protected function renderTeaser(
305  string $a_type,
306  string $a_title,
307  string $a_options = ""
308  ): string {
309  $options = "";
310  if ($a_options) {
311  $options = '<div class="il_Footer">' . $this->lng->txt("prtf_page_element_teaser_settings") .
312  ": " . $a_options . '</div>';
313  }
314 
315  return '<div style="margin:5px" class="ilBox"><h3>' . $a_title . '</h3>' .
316  '<div class="il_Description_no_margin">' . $this->lng->txt("prtf_page_element_teaser_" . $a_type) . '</div>' .
317  $options . '</div>';
318  }
319 
320  protected function renderProfile(
321  int $a_user_id,
322  string $a_type,
323  array $a_fields = null
324  ): string {
325  $ilCtrl = $this->ctrl;
326 
327  $user_id = $this->getPageContentUserId($a_user_id);
328 
329  $pub_profile = new ilPublicUserProfileGUI($user_id);
330  $pub_profile->setEmbedded(true, ($this->getOutputMode() === "offline"));
331 
332  // full circle: additional was set in the original public user profile call
333  $pub_profile->setAdditional($this->getAdditional());
334 
335  if ($a_type === "manual" && is_array($a_fields) && count($a_fields) > 0) {
336  $prefs = array();
337  foreach ($a_fields as $field) {
338  $field = trim($field);
339  if ($field) {
340  $prefs["public_" . $field] = "y";
341  }
342  }
343 
344  $pub_profile->setCustomPrefs($prefs);
345  }
346 
347  if ($this->getOutputMode() !== "offline") {
348  return $ilCtrl->getHTML($pub_profile);
349  }
350 
351  return $pub_profile->getEmbeddable();
352  }
353 
357  protected function renderVerification(
358  int $a_user_id,
359  string $a_type,
360  int $a_id
361  ): string {
362  $objDefinition = $this->obj_definition;
363 
364  $outputMode = $this->getOutputMode();
365 
366  // not used
367  // $user_id = $this->getPageContentUserId($a_user_id);
368  if ($a_type === 'crta' && $outputMode === 'offline') {
369  $fileService = new ilPortfolioCertificateFileService();
370 
371  $certificatePdfFile = $fileService->createCertificateFilePath($a_user_id, $a_id);
372  $this->export_material["files"][] = $certificatePdfFile;
373 
374  $url = 'files/' . basename($certificatePdfFile);
375 
376  $userCertificateRepository = new ilUserCertificateRepository();
377 
378  return $this->createPersistentCertificateUrl($a_id, $userCertificateRepository, $url);
379  }
380 
381  if ($a_type === 'crta' && $outputMode === 'print') {
382  $userCertificateRepository = new ilUserCertificateRepository();
383  $url = $this->getPagePermaLink();
384 
385  return $this->createPersistentCertificateUrl($a_id, $userCertificateRepository, $url);
386  }
387 
388  if ($a_type === 'crta') {
389  $this->ctrl->setParameter($this, "dlid", $a_id);
390  $url = $this->ctrl->getLinkTarget($this, "dl" . $a_type);
391  $this->ctrl->setParameter($this, "dlid", "");
392 
393  $userCertificateRepository = new ilUserCertificateRepository();
394 
395  return $this->createPersistentCertificateUrl($a_id, $userCertificateRepository, $url);
396  }
397 
398  if (!ilObject::_exists($a_id)) {
399  return $this->lng->txt('deleted');
400  }
401 
402  $class = "ilObj" . $objDefinition->getClassName($a_type) . "GUI";
403  $verification = new $class($a_id, ilObject2GUI::WORKSPACE_OBJECT_ID);
404 
405  if ($outputMode === "print") {
406  $url = $this->getPagePermaLink();
407  } elseif ($outputMode !== "offline") {
408  // direct download link
409  $this->ctrl->setParameter($this, "dlid", $a_id);
410  $url = $this->ctrl->getLinkTarget($this, "dl" . $a_type);
411  $this->ctrl->setParameter($this, "dlid", "");
412  } else {
413  $file = $verification->getObject()->getFilePath();
414  $url = "files/" . basename($file);
415 
416  $this->export_material["files"][] = $file;
417  }
418 
419  return $verification->render(true, $url);
420  }
421 
422  protected function dltstv(): void
423  {
424  $id = $this->port_request->getVerificationId();
425  if ($id) {
427  $verification->downloadFromPortfolioPage($this->getPortfolioPage());
428  }
429  }
430 
431  protected function dlexcv(): void
432  {
433  $id = $this->port_request->getVerificationId();
434  if ($id) {
436  $verification->downloadFromPortfolioPage($this->getPortfolioPage());
437  }
438  }
439 
440  protected function dlcrsv(): void
441  {
442  $id = $this->port_request->getVerificationId();
443  if ($id) {
445  $verification->downloadFromPortfolioPage($this->getPortfolioPage());
446  }
447  }
448 
449  protected function dlcmxv(): void
450  {
451  $id = $this->port_request->getVerificationId();
452  if ($id) {
454  $verification->downloadFromPortfolioPage($this->getPortfolioPage());
455  }
456  }
457 
458  protected function dlltiv(): void
459  {
460  $id = $this->port_request->getVerificationId();
461  if ($id) {
463  $verification->downloadFromPortfolioPage($this->getPortfolioPage());
464  }
465  }
466 
467  protected function dlscov(): void
468  {
469  $id = $this->port_request->getVerificationId();
470  if ($id) {
472  $verification->downloadFromPortfolioPage($this->getPortfolioPage());
473  }
474  }
475 
476  protected function dlcrta(): void
477  {
478  $objectId = $this->port_request->getVerificationId();
479  if ($objectId) {
481  $object->downloadFromPortfolioPage($this->getPortfolioPage(), $objectId, $this->user->getId());
482  }
483  }
484 
485  protected function renderBlog(
486  int $a_user_id,
487  int $a_blog_id,
488  array $a_posting_ids = null
489  ): string {
490  $ilCtrl = $this->ctrl;
491 
492  // not used
493  // $user_id = $this->getPageContentUserId($a_user_id);
494 
495  // full blog (separate tab/page)
496  if (!$a_posting_ids) {
497  if (ilObject::_lookupType($a_blog_id) !== "blog") {
498  return "";
499  }
500  $blog = new ilObjBlogGUI($a_blog_id, ilObject2GUI::WORKSPACE_OBJECT_ID);
501  $blog->disableNotes(!$this->enable_comments);
502  $blog->setContentStyleSheet();
503 
504  if ($this->getOutputMode() !== "offline") {
505  return $ilCtrl->getHTML($blog);
506  }
507  }
508  // embedded postings
509  else {
510  $html = array();
511 
512  $html[] = ilObjBlog::_lookupTitle($a_blog_id);
513 
514  foreach ($a_posting_ids as $post) {
515  $page = new ilBlogPostingGUI(0, null, $post);
516  if ($this->getOutputMode() !== "offline") {
517  $page->setOutputMode(ilPageObjectGUI::PREVIEW);
518  } else {
519  $page->setOutputMode("offline");
520  }
521  $html[] = $page->showPage();
522  }
523 
524  return implode("\n", $html);
525  }
526  return "";
527  }
528 
529  protected function renderBlogTeaser(
530  int $a_user_id,
531  int $a_blog_id,
532  array $a_posting_ids = null
533  ): string {
534  // not used
535  // $user_id = $this->getPageContentUserId($a_user_id);
536 
537  $postings = "";
538  if ($a_posting_ids) {
539  $postings = array("<ul>");
540  foreach ($a_posting_ids as $post) {
541  $post = new ilBlogPosting($post);
542  $postings[] = "<li>" . $post->getTitle() . " - " .
543  ilDatePresentation::formatDate($post->getCreated()) . "</li>";
544  }
545  $postings[] = "</ul>";
546  $postings = implode("\n", $postings);
547  }
548 
549  return $this->renderTeaser("blog", $this->lng->txt("obj_blog") . ' "' .
550  ilObject::_lookupTitle($a_blog_id) . '"', $postings);
551  }
552 
553  protected function renderSkills(
554  int $a_user_id,
555  int $a_skills_id
556  ): string {
557  if ($this->getOutputMode() === "preview") {
558  return $this->renderSkillsTeaser($a_user_id, $a_skills_id);
559  }
560 
561  $user_id = $this->getPageContentUserId($a_user_id);
562 
563  $gui = new ilPersonalSkillsGUI();
564  if ($this->getOutputMode() === "offline") {
565  $gui->setOfflineMode("./files/");
566  }
567  return $gui->getSkillHTML($a_skills_id, $user_id);
568  }
569 
570  protected function renderSkillsTeaser(
571  int $a_user_id,
572  int $a_skills_id
573  ): string {
574  // not used
575  // $user_id = $this->getPageContentUserId($a_user_id);
576 
577  return $this->renderTeaser("skills", $this->lng->txt("skills") . ' "' .
578  ilSkillTreeNode::_lookupTitle($a_skills_id) . '"');
579  }
580 
581  protected function renderConsultationHoursTeaser(
582  int $a_user_id,
583  string $a_mode,
584  ?array $a_group_ids = null
585  ): string {
586  // not used
587  // $user_id = $this->getPageContentUserId($a_user_id);
588  if ($a_mode === "auto") {
589  $mode = $this->lng->txt("cont_cach_mode_automatic");
590  $groups = null;
591  } else {
592  $mode = $this->lng->txt("cont_cach_mode_manual");
593 
594  $groups = array();
595  foreach ($a_group_ids as $grp_id) {
596  $groups[] = ilConsultationHourGroups::lookupTitle($grp_id);
597  }
598  $groups = " (" . implode(", ", $groups) . ")";
599  }
600 
601  $this->lng->loadLanguageModule("dateplaner");
602  return $this->renderTeaser(
603  "consultation_hours",
604  $this->lng->txt("app_consultation_hours"),
605  $mode . $groups
606  );
607  }
608 
609  protected function renderConsultationHours(
610  int $a_user_id,
611  string $a_mode,
612  ?array $a_group_ids = null
613  ): string {
614  $ilUser = $this->user;
615  if ($this->getOutputMode() === "preview") {
616  return $this->renderConsultationHoursTeaser($a_user_id, $a_mode, $a_group_ids);
617  }
618 
619  if ($this->getOutputMode() === "offline") {
620  return "";
621  }
622 
623  if ($this->getOutputMode() === "print") {
624  return "";
625  }
626 
627  $user_id = $this->getPageContentUserId($a_user_id);
628 
629  // only if not owner
630  $bkid = 0;
631  if ($ilUser->getId() !== $user_id) {
632  $bkid = $user_id;
633  }
634  $this->ctrl->setParameter($this, "chuid", $user_id);
635 
636  if ($a_mode !== "manual") {
637  $a_group_ids = null;
638  }
639  ilCalendarCategories::_getInstance()->setCHUserId($user_id);
640  if (!self::$calender_initialized) {
643  0,
644  true
645  );
646  self::$calender_initialized = true;
647  }
648 
649  $seed = $this->port_request->getCalendarSeed();
650  if ($seed === "") {
651  $seed = new ilDate(time(), IL_CAL_UNIX);
652  } else {
653  $seed = new ilDate($seed, IL_CAL_DATE);
654  }
655 
656  $month_gui = new ilCalendarMonthGUI($seed);
657  if ($bkid > 0) {
658  $month_gui->setBkId($bkid);
659  }
660  $month_gui->setConsulationHoursUserId($user_id);
661 
662  // custom schedule filter: handle booking group ids
663  $filter = new ilCalendarScheduleFilterBookings($user_id, $a_group_ids);
664  $month_gui->addScheduleFilter($filter);
665 
666  $this->tpl->addCss(ilUtil::getStyleSheetLocation('filesystem', 'delos.css', 'Services/Calendar'));
667 
668  $this->lng->loadLanguageModule("dateplaner");
669  return '<h3>' . $this->lng->txt("app_consultation_hours") . '</h3>' .
670  $this->ctrl->getHTML($month_gui);
671  }
672 
673  protected function isMyCoursesActive(): bool
674  {
675  $prfa_set = new ilSetting("prfa");
676  return (bool) $prfa_set->get("mycrs", true);
677  }
678 
679  protected function renderMyCoursesTeaser(
680  int $a_user_id,
681  $a_default_sorting
682  ): string {
683  // not used
684  // $user_id = $this->getPageContentUserId($a_user_id);
685 
686  $title = $this->isMyCoursesActive()
687  ? "my_courses"
688  : "my_courses_inactive";
689 
690  return $this->renderTeaser(
691  $title,
692  $this->lng->txt("prtf_page_element_my_courses_title")
693  );
694  }
695 
696  protected function renderMyCourses(
697  int $a_user_id,
698  string $a_default_sorting
699  ): string {
700  $ilAccess = $this->access;
701  $ilUser = $this->user;
702  $ilCtrl = $this->ctrl;
703 
704  if ($this->getOutputMode() === "preview") {
705  return $this->renderMyCoursesTeaser($a_user_id, $a_default_sorting);
706  }
707 
708  if (!$this->isMyCoursesActive()) {
709  return "";
710  }
711 
712  $img_path = null;
714 
715  $user_id = $this->getPageContentUserId($a_user_id);
716 
717  // sorting pref
718  $req_sorting = $this->port_request->getCourseSorting();
719  if (in_array($req_sorting, array("alpha", "loc"))) {
720  $ilUser->writePref("prtf_mcrs_sort", $req_sorting);
721  }
722  $sorting = $ilUser->getPref("prtf_mcrs_sort");
723  if (!$sorting) {
724  $sorting = $a_default_sorting;
725  }
726 
727  $data = $this->getCoursesOfUser($user_id, ($sorting === "loc"));
728  if (count($data)) {
729  if ($sorting !== "loc") {
730  $data = ilArrayUtil::sortArray($data, "title", "ASC");
731  } else {
732  $data = ilArrayUtil::sortArray($data, "path_sort", "ASC");
733  }
734 
735  $tpl = new ilTemplate("tpl.pc_my_courses.html", true, true, "Modules/Portfolio");
736  $tpl->setVariable("TITLE", $this->lng->txt("prtf_page_element_my_courses_title"));
737  $tpl->setVariable("INFO", $this->lng->txt("prtf_page_element_my_courses_info")); // #14464
738 
739  $this->lng->loadLanguageModule("trac");
740  $this->lng->loadLanguageModule("crs");
741 
742  // sorting
743  if ($this->getOutputMode() !== "print") {
744  $options = array(
745  "alpha" => $this->lng->txt("cont_mycourses_sortorder_alphabetical"),
746  "loc" => $this->lng->txt("cont_mycourses_sortorder_location")
747  );
748  $tpl->setVariable(
749  "SORT_SELECT",
751  $sorting,
752  "srt",
753  $options,
754  false,
755  true,
756  0,
757  "",
758  ["onchange" => "form.submit()"]
759  )
760  );
761  $tpl->setVariable("SORT_FORM", $this->getCourseSortAction($ilCtrl));
762  }
763 
764  $old_path = null;
765 
766  foreach ($data as $course) {
767  if (($sorting === "loc") && $course["path"] != $old_path) {
768  $tpl->setCurrentBlock("path_bl");
769  $tpl->setVariable("PATH", $course["path"]);
771 
772  $old_path = $course["path"];
773  }
774 
775  if (isset($course["lp_status"])) {
776  $lp_icon_rendered = $lp_icons->renderIconForStatus($course["lp_status"]);
777 
778  $tpl->setCurrentBlock("lp_bl");
779  $tpl->setVariable("LP_ICON", $lp_icon_rendered);
781  }
782 
783  $do_links = false;
784  if ($ilUser->getId() !== ANONYMOUS_USER_ID) {
785  $do_links = $ilAccess->checkAccessOfUser($ilUser->getId(), "read", "", $course["ref_id"], "crs") ||
786  ($ilAccess->checkAccessOfUser($ilUser->getId(), "visible", "", $course["ref_id"], "crs") &&
787  $ilAccess->checkAccessOfUser($ilUser->getId(), "join", "", $course["ref_id"], "crs"));
788  }
789 
790  if (isset($course["objectives"])) {
791  $loc_settings = ilLOSettings::getInstanceByObjId($course["obj_id"]);
792  $has_initial_test = (bool) $loc_settings->getInitialTest();
793 
794  foreach ($course["objectives"] as $objtv) {
795  if ($do_links) {
796  $params = array("oobj" => $objtv["id"]);
797  $url = ilLink::_getLink($course["ref_id"], "crs", $params);
798 
799  // #15510
800  $url .= "#objtv_acc_" . $objtv["id"];
801 
802  if ($this->getOutputMode() !== "print") {
803  $tpl->touchBlock("objective_dnone");
804  }
805 
806  $tpl->setCurrentBlock("objective_link_bl");
807 
808  if (trim($objtv["desc"] ?? "") !== "") {
809  $desc = nl2br($objtv["desc"]);
810  $tt_id = "objtvtt_" . $objtv["id"] . "_" . (self::$initialized);
811 
812  ilTooltipGUI::addTooltip($tt_id, $desc, "", "bottom center", "top center", false);
813 
814  $tpl->setVariable("OBJECTIVE_LINK_ID", $tt_id);
815  }
816 
817  $tpl->setVariable("OBJECTIVE_LINK_URL", $url);
818  $tpl->setVariable("OBJECTIVE_LINK_TITLE", $objtv["title"]);
819  } else {
820  $tpl->setCurrentBlock("objective_nolink_bl");
821  $tpl->setVariable("OBJECTIVE_NOLINK_TITLE", $objtv["title"]);
822  }
824 
825  $objtv_icon = ilObject::_getIcon($objtv["id"], 'big', "lobj");
826  if ($img_path) {
827  $objtv_icon = $img_path . basename($objtv_icon);
828  }
829 
830  $tpl->setCurrentBlock("objective_bl");
831  $tpl->setVariable("OBJTV_ICON_URL", $objtv_icon);
832  $tpl->setVariable("OBJTV_ICON_ALT", $this->lng->txt("crs_objectives"));
833 
834  if (isset($objtv["type"])) {
835  $tpl->setVariable(
836  "LP_OBJTV_PROGRESS",
838  $has_initial_test,
839  $objtv["id"],
840  $objtv,
841  true,
842  false,
843  self::$initialized
844  )
845  );
846  }
847 
849  }
850 
851  $tpl->setCurrentBlock("objectives_bl");
852  $tpl->setVariable("OBJTV_LIST_CRS_ID", $course["obj_id"]);
854  }
855 
856  // always check against current user
857  if ($do_links) {
858  $tpl->setCurrentBlock("course_link_bl");
859  $tpl->setVariable("COURSE_LINK_TITLE", $course["title"]);
860  $tpl->setVariable("COURSE_LINK_URL", ilLink::_getLink($course["ref_id"]));
861  } else {
862  $tpl->setCurrentBlock("course_nolink_bl");
863  $tpl->setVariable("COURSE_NOLINK_TITLE", $course["title"]);
864  }
866 
867  $crs_icon = ilObject::_getIcon($course["obj_id"], 'small', 'crs');
868  if ($img_path) {
869  $crs_icon = $img_path . basename($crs_icon);
870  }
871 
872  $tpl->setCurrentBlock("course_bl");
873 
874  if (isset($course["objectives"])) {
875  $tpl->setVariable("TOGGLE_CLASS", "ilPCMyCoursesToggle");
876  } else {
877  $tpl->setVariable("NO_TOGGLE", ' style="visibility:hidden;"');
878  }
879 
880  $tpl->setVariable("CRS_ICON_URL", $crs_icon);
881  $tpl->setVariable("CRS_ICON_ALT", $this->lng->txt("obj_crs"));
883  }
884 
885  // #15508
886  if (!self::$initialized) {
887  $GLOBALS["tpl"]->addJavaScript("Modules/Portfolio/js/ilPortfolio.js");
888  $GLOBALS["tpl"]->addOnLoadCode("ilPortfolio.init()");
889  }
890  self::$initialized++;
891 
892  return $tpl->get();
893  }
894  return "";
895  }
896 
900  protected function getCourseSortAction(ilCtrl $ctrl): string
901  {
902  return $ctrl->getFormActionByClass("ilobjportfoliogui", "preview");
903  }
904 
905  protected function getCoursesOfUser(
906  int $a_user_id,
907  bool $a_add_path = false
908  ): array {
909  $tree = $this->tree;
910 
911  // see ilPDSelectedItemsBlockGUI
912 
913  $items = ilParticipants::_getMembershipByType($a_user_id, ['crs']);
914 
915  $repo_title = $tree->getNodeData(ROOT_FOLDER_ID);
916  $repo_title = $repo_title["title"];
917  if ($repo_title == "ILIAS") {
918  $repo_title = $this->lng->txt("repository");
919  }
920 
921  $references = $lp_obj_refs = array();
922  foreach ($items as $obj_id) {
924  if (is_array($ref_id) && count($ref_id)) {
925  $ref_id = array_pop($ref_id);
926  if (!$tree->isDeleted($ref_id)) {
927  $visible = false;
928  $active = ilObjCourseAccess::_isActivated($obj_id, $visible, false);
929  if ($active && $visible) {
930  $references[$ref_id] = array(
931  'ref_id' => $ref_id,
932  'obj_id' => $obj_id,
933  'title' => ilObject::_lookupTitle($obj_id)
934  );
935 
936  if ($a_add_path) {
937  $path = array();
938  foreach ($tree->getPathFull($ref_id) as $item) {
939  $path[] = $item["title"];
940  }
941  // top level comes first
942  if (count($path) === 2) {
943  $path[0] = 0;
944  } else {
945  $path[0] = 1;
946  }
947  $references[$ref_id]["path_sort"] = implode("__", $path);
948  array_shift($path);
949  array_pop($path);
950  if (!count($path)) {
951  array_unshift($path, $repo_title);
952  }
953  $references[$ref_id]["path"] = implode(" &rsaquo; ", $path);
954  }
955 
956  $lp_obj_refs[$obj_id] = $ref_id;
957  }
958  }
959  }
960  }
961 
962  // get lp data for valid courses
963 
964  if (count($lp_obj_refs)) {
965  // listing the objectives should NOT depend on any LP status / setting
966  foreach ($lp_obj_refs as $obj_id => $ref_id) {
967  // only if set in DB (default mode is not relevant
969  $references[$ref_id]["objectives"] = $this->parseObjectives($obj_id, $a_user_id);
970  }
971  }
972 
973  // LP must be active, personal and not anonymized
977  // see ilLPProgressTableGUI
978  $lp_data = ilTrQuery::getObjectsStatusForUser($a_user_id, $lp_obj_refs);
979  foreach ($lp_data as $item) {
980  $ref_id = $item["ref_ids"];
981  $references[$ref_id]["lp_status"] = $item["status"];
982  }
983  }
984  }
985 
986  return $references;
987  }
988 
989  protected function parseObjectives(
990  int $a_obj_id,
991  int $a_user_id
992  ): array {
993  $res = array();
994 
995  // we need the collection for the correct order
997  $coll_objtv = $coll_objtv->getItems();
998  if ($coll_objtv) {
999  // #13373
1000  $lo_results = $this->parseLOUserResults($a_obj_id, $a_user_id);
1001 
1002  $lo_ass = ilLOTestAssignments::getInstance($a_obj_id);
1003 
1004  $tmp = array();
1005 
1006  foreach ($coll_objtv as $objective_id) {
1008  $title = ilCourseObjective::lookupObjectiveTitle($objective_id, true);
1009 
1010  $tmp[$objective_id] = array(
1011  "id" => $objective_id,
1012  "title" => $title["title"],
1013  "desc" => $title["description"],
1014  "itest" => $lo_ass->getTestByObjective($objective_id, ilLOSettings::TYPE_TEST_INITIAL),
1015  "qtest" => $lo_ass->getTestByObjective($objective_id, ilLOSettings::TYPE_TEST_QUALIFIED)
1016  );
1017 
1018  if (array_key_exists($objective_id, $lo_results)) {
1019  $lo_result = $lo_results[$objective_id];
1020  $tmp[$objective_id]["user_id"] = $lo_result["user_id"];
1021  $tmp[$objective_id]["result_perc"] = $lo_result["result_perc"] ?? null;
1022  $tmp[$objective_id]["limit_perc"] = $lo_result["limit_perc"] ?? null;
1023  $tmp[$objective_id]["status"] = $lo_result["status"] ?? null;
1024  $tmp[$objective_id]["type"] = $lo_result["type"] ?? null;
1025  $tmp[$objective_id]["initial"] = $lo_result["initial"] ?? null;
1026  }
1027  }
1028 
1029  // order
1030  foreach ($coll_objtv as $objtv_id) {
1031  $res[] = $tmp[$objtv_id];
1032  }
1033  }
1034 
1035  return $res;
1036  }
1037 
1038  // see ilContainerObjectiveGUI::parseLOUserResults()
1039  protected function parseLOUserResults(
1040  int $a_course_obj_id,
1041  int $a_user_id
1042  ): array {
1043  $res = array();
1044  $initial_status = "";
1045 
1046  $lur = new ilLOUserResults($a_course_obj_id, $a_user_id);
1047  foreach ($lur->getCourseResultsForUserPresentation() as $objective_id => $types) {
1048  // show either initial or qualified for objective
1049  if (isset($types[ilLOUserResults::TYPE_INITIAL])) {
1050  $initial_status = $types[ilLOUserResults::TYPE_INITIAL]["status"];
1051  }
1052 
1053  // qualified test has priority
1054  if (isset($types[ilLOUserResults::TYPE_QUALIFIED])) {
1055  $result = $types[ilLOUserResults::TYPE_QUALIFIED];
1056  $result["type"] = ilLOUserResults::TYPE_QUALIFIED;
1057  $result["initial"] = $types[ilLOUserResults::TYPE_INITIAL] ?? null;
1058  } else {
1059  $result = $types[ilLOUserResults::TYPE_INITIAL];
1060  $result["type"] = ilLOUserResults::TYPE_INITIAL;
1061  }
1062 
1063  $result["initial_status"] = $initial_status;
1064 
1065  $res[$objective_id] = $result;
1066  }
1067 
1068  return $res;
1069  }
1070 
1071  public function getExportMaterial(): array
1072  {
1073  return $this->export_material;
1074  }
1075 
1076  public function makePlaceHoldersClickable(string $a_html): string
1077  {
1078  $ilCtrl = $this->ctrl;
1079  $lng = $this->lng;
1080  $ilUser = $this->user;
1081 
1082  $end = 0;
1083  $start = strpos($a_html, "{{{{{PlaceHolder#");
1084  if (is_int($start)) {
1085  $end = strpos($a_html, "}}}}}", $start);
1086  }
1087  while ($end > 0) {
1088  $param = substr($a_html, $start + 17, $end - $start - 17);
1089  $param = explode("#", $param);
1090 
1091  $html = $param[2];
1092  switch ($param[2]) {
1093  case "Text":
1094  $html = $lng->txt("cont_text_placeh");
1095  break;
1096 
1097  case "Media":
1098  $html = $lng->txt("cont_media_placeh");
1099  break;
1100 
1101  case "Question":
1102  $html = $lng->txt("cont_question_placeh");
1103  break;
1104 
1105  case "Verification":
1106  $html = $lng->txt("cont_verification_placeh");
1107  break;
1108  }
1109 
1110  // only if not owner
1111  if ($ilUser->getId() === ilObjPortfolio::_lookupOwner($this->portfolio_id)
1112  && $this->getOutputMode() === "presentation") {
1113  switch ($param[2]) {
1114  case "Text":
1115  $ilCtrl->setParameterByClass("ilportfoliopagegui", "prt_id", $this->port_request->getPortfolioId());
1116  $ilCtrl->setParameterByClass("ilportfoliopagegui", "ppage", $this->getId());
1117  $ilCtrl->setParameterByClass("ilportfoliopagegui", "pl_pc_id", $param[0]);
1118  $ilCtrl->setParameterByClass("ilportfoliopagegui", "pl_hier_id", $param[1]);
1119  $href = $ilCtrl->getLinkTargetByClass("ilportfoliopagegui", "insertJSAtPlaceholder");
1120  $html = "<a href='" . $href . "'>" . $html . "</a>";
1121  break;
1122 
1123  case "Media":
1124  $ilCtrl->setParameterByClass("ilpcmediaobjectgui", "prt_id", $this->port_request->getPortfolioId());
1125  $ilCtrl->setParameterByClass("ilpcmediaobjectgui", "ppage", $this->getId());
1126  $ilCtrl->setParameterByClass("ilpcmediaobjectgui", "pl_pc_id", $param[0]);
1127  $ilCtrl->setParameterByClass("ilpcmediaobjectgui", "pl_hier_id", $param[1]);
1128  $ilCtrl->setParameterByClass("ilpcmediaobjectgui", "subCmd", "insertNew");
1129  $href = $ilCtrl->getLinkTargetByClass(array("ilPortfolioPageGUI", "ilPageEditorGUI", "ilPCPlaceHolderGUI", "ilpcmediaobjectgui"), "insert");
1130  $html = "<a href='" . $href . "'>" . $html . "</a>";
1131  break;
1132 
1133  /* see #34170, may need a different change, keep code to monitor
1134  case "Verification":
1135  $ilCtrl->setParameterByClass("ilPCVerificationGUI", "prt_id", $this->port_request->getPortfolioId());
1136  $ilCtrl->setParameterByClass("ilPCVerificationGUI", "ppage", $this->getId());
1137  $ilCtrl->setParameterByClass("ilPCVerificationGUI", "pl_pc_id", $param[0]);
1138  $ilCtrl->setParameterByClass("ilPCVerificationGUI", "pl_hier_id", $param[1]);
1139  $ilCtrl->setParameterByClass("ilPCVerificationGUI", "subCmd", "insertNew");
1140  $href = $ilCtrl->getLinkTargetByClass(array("ilPortfolioPageGUI", "ilPageEditorGUI", "ilPCPlaceHolderGUI", "ilPCVerificationGUI"), "insert");
1141  $html = "<a href='" . $href . "'>" . $html . "</a>";
1142  break;
1143  */
1144  }
1145  }
1146 
1147  $h2 = substr($a_html, 0, $start) .
1148  $html .
1149  substr($a_html, $end + 5);
1150  $a_html = $h2;
1151 
1152  $start = strpos($a_html, "{{{{{PlaceHolder#", $start + 5);
1153  $end = 0;
1154  if (is_int($start)) {
1155  $end = strpos($a_html, "}}}}}", $start);
1156  }
1157  }
1158  return $a_html;
1159  }
1160 
1161  public function getViewPageLink(): string
1162  {
1163  global $DIC;
1164 
1165  $ctrl = $DIC->ctrl();
1166 
1167  $ctrl->setParameterByClass("ilobjportfoliogui", "user_page", $this->requested_ppage);
1168  return $ctrl->getLinkTargetByClass("ilobjportfoliogui", "preview");
1169  }
1170 
1171  public function getViewPageText(): string
1172  {
1173  return $this->lng->txt("preview");
1174  }
1175 
1176  public function getPagePermaLink(): string
1177  {
1179  return ilLink::_getStaticLink($pid, "prtf", true, "_" . $this->getId());
1180  }
1181 
1183  int $a_id,
1184  ilUserCertificateRepository $userCertificateRepository,
1185  string $url
1186  ): string {
1187  try {
1188  $presentation = $userCertificateRepository->fetchActiveCertificateForPresentation($this->user->getId(), $a_id);
1189  } catch (Exception $e) {
1190  return "";
1191  }
1192  $caption = $this->lng->txt('certificate') . ': ';
1193  $caption .= $this->lng->txt($presentation->getUserCertificate()->getObjType()) . ' ';
1194  $caption .= '"' . $presentation->getObjectTitle() . '"';
1195 
1196  return '<div><a href="' . $url . '">' . $caption . '</a></div>';
1197  }
1198 
1199  public function getCommentsHTMLExport(): string
1200  {
1201  $notes_gui = new ilCommentGUI(
1202  $this->portfolio_id,
1203  $this->getPageObject()->getId(),
1204  "pfpg"
1205  );
1206  $notes_gui->enablePublicNotes(true);
1207  $notes_gui->setRepositoryMode(false);
1208  $notes_gui->setExportMode();
1209  return $notes_gui->getListHTML();
1210  }
1211 
1212  public function finishEditing(): void
1213  {
1214  $this->ctrl->redirectByClass("ilObjPortfolioGUI", "view");
1215  }
1216 }
getTabs(string $a_activate="")
static lookupTitle(int $a_group_id)
Lookup group title.
$res
Definition: ltiservices.php:69
getCourseSortAction(ilCtrl $ctrl)
Get course sort action.
getNodeData(int $a_node_id, ?int $a_tree_pk=null)
get all information of a node.
getLinkTargetByClass( $a_class, string $a_cmd=null, string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Calendar schedule filter for consultation hour bookings.
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
const ANONYMOUS_USER_ID
Definition: constants.php:27
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
ilObjectDefinition $obj_definition
const ROOT_FOLDER_ID
Definition: constants.php:32
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:64
touchBlock(string $block)
overwrites ITX::touchBlock.
renderConsultationHours(int $a_user_id, string $a_mode, ?array $a_group_ids=null)
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
Definition: ltiregstart.php:33
getAdditional()
Get Additonal Information.
Class ilBlogPosting GUI class.
static _getAllReferences(int $id)
get all reference ids for object ID
Class ilPageObjectGUI.
renderMyCourses(int $a_user_id, string $a_default_sorting)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
isDeleted(int $a_node_id)
This is a wrapper for isSaved() with a more useful name.
static getInstance(int $variant=ilLPStatusIcons::ICON_VARIANT_DEFAULT, ?\ILIAS\UI\Renderer $renderer=null, ?\ILIAS\UI\Factory $factory=null)
__construct(int $a_portfolio_id, int $a_id=0, int $a_old_nr=0, bool $a_enable_comments=true)
static _lookupTitle(int $a_obj_id, int $a_tref_id=0)
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
static formSelect( $selected, string $varname, array $options, bool $multiple=false, bool $direct_text=false, int $size=0, string $style_class="", array $attribs=[], bool $disabled=false)
Builds a select form field with options and shows the selected option first.
setParameterByClass(string $a_class, string $a_parameter, $a_value)
renderBlog(int $a_user_id, int $a_blog_id, array $a_posting_ids=null)
ILIAS COPage InternalGUIService $gui
static _lookupOwner(int $obj_id)
Lookup owner user ID for object ID.
renderMyCoursesTeaser(int $a_user_id, $a_default_sorting)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
renderProfile(int $a_user_id, string $a_type, array $a_fields=null)
setVariable(string $variable, $value='')
Sets the given variable to the given value.
postOutputProcessing(string $a_output)
const IL_CAL_UNIX
static getStyleSheetLocation(string $mode="output", string $a_css_name="", string $a_css_location="")
get full style sheet file name (path inclusive) of current user
static buildObjectiveProgressBar(bool $a_has_initial_test, int $a_objective_id, array $a_lo_result, bool $a_list_mode=false, bool $a_sub=false, string $a_tt_suffix=null)
Render progressbar(s) for given objective and result data.
getPathFull(int $a_endnode_id, int $a_startnode_id=0)
get path from a given startnode to a given endnode if startnode is not given the rootnode is startnod...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$path
Definition: ltiservices.php:32
getCoursesOfUser(int $a_user_id, bool $a_add_path=false)
static _lookupViewMode(int $a_id)
setTemplateOutput(bool $a_output=true)
renderConsultationHoursTeaser(int $a_user_id, string $a_mode, ?array $a_group_ids=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
createPersistentCertificateUrl(int $a_id, ilUserCertificateRepository $userCertificateRepository, string $url)
global $DIC
Definition: feed.php:28
Personal skills GUI class.
ILIAS Portfolio StandardGUIRequest $port_request
parses the objects.xml it handles the xml-description of all ilias objects
setEmbedded(bool $a_value)
Set embedded mode: will suppress tabs.
GUI class for course verification.
GUI class for public user profile presentation.
parseLOUserResults(int $a_course_obj_id, int $a_user_id)
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
$ref_id
Definition: ltiauth.php:67
__construct(VocabulariesInterface $vocabularies)
static _lookupTitle(int $obj_id)
$GLOBALS["DIC"]
Definition: wac.php:31
Class ilObjBlogGUI.
ilGlobalTemplateInterface $tpl
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getFormActionByClass( $a_class, string $a_fallback_cmd=null, string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
$param
Definition: xapitoken.php:46
ilAccessHandler $access
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$url
Definition: ltiregstart.php:35
setPresentationTitle(string $a_title="")
makePlaceHoldersClickable(string $a_html)
static lookupObjectiveTitle(int $a_objective_id, bool $a_add_description=false)
static _getInstance($a_usr_id=0)
get singleton instance
static addTooltip(string $a_el_id, string $a_text, string $a_container="", string $a_my="bottom center", string $a_at="top center", bool $a_use_htmlspecialchars=true)
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
static _isActivated(int $a_obj_id, ?bool &$a_visible_flag=null, bool $a_mind_member_view=true)
static getInstanceByObjId(int $a_obj_id)
renderPageElement(string $a_type, string $a_html)
setCurrentBlock(string $part=self::DEFAULT_BLOCK)
Sets the template to the given block.
static getObjectsStatusForUser(int $a_user_id, array $obj_refs)
const IL_CAL_DATE
GUI class for test verification.
Comment GUI.
static findPortfolioForPage(int $a_page_id)
Get portfolio id of page id.
static getInstance(int $a_container_id)
getPageContentUserId(int $a_user_id)
parseCurrentBlock(string $block_name=self::DEFAULT_BLOCK)
Parses the given block.
static _getMembershipByType(int $a_usr_id, array $a_type, bool $a_only_member_role=false)
get membership by type Get course or group membership
renderSkillsTeaser(int $a_user_id, int $a_skills_id)
static _lookupType(int $id, bool $reference=false)
$post
Definition: ltitoken.php:49
renderVerification(int $a_user_id, string $a_type, int $a_id)
renderTeaser(string $a_type, string $a_title, string $a_options="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setAdditional(array $a_additional)
Set Additonal Information.
renderSkills(int $a_user_id, int $a_skills_id)
renderBlogTeaser(int $a_user_id, int $a_blog_id, array $a_posting_ids=null)
fetchActiveCertificateForPresentation(int $userId, int $objectId)
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)