ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilObjBlogGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
32 
43 {
50  protected string $rendered_content = "";
51  protected \ILIAS\Notes\Service $notes;
52  protected \ILIAS\Blog\ReadingTime\BlogSettingsGUI $reading_time_gui;
54 
56  protected ilHelpGUI $help;
57  protected ilTabsGUI $tabs;
60 
61  protected string $month = "";
62  protected array $items = [];
63  protected string $keyword = "";
64  protected ?int $author = null;
65  protected bool $month_default = false;
66  protected int $blpg = 0;
67  protected int $old_nr = 0;
68  protected int $ppage = 0;
69  protected int $user_page = 0;
70  protected string $prvm; //preview mode (fsc|emb)
71  protected int $ntf = 0;
72  protected int $apid = 0;
73  protected string $new_type = "";
74  protected bool $disable_notes = false;
76  protected \ILIAS\DI\UIServices $ui;
77  protected \ILIAS\Style\Content\GUIService $content_style_gui;
78  protected \ILIAS\Style\Content\Object\ObjectFacade $content_style_domain;
79 
80  public function __construct(
81  int $a_id = 0,
82  int $a_id_type = self::REPOSITORY_NODE_ID,
83  int $a_parent_node_id = 0
84  ) {
85  global $DIC;
86 
87  // other services
88  $cs = $DIC->contentStyle();
89  $this->tool_context = $DIC->globalScreen()->tool()->context();
90  $this->notes = $DIC->notes();
91 
92  // internal service
93  $service = $DIC->blog()->internal();
94 
95  $this->domain = $domain = $service->domain();
96  $this->gui = $gui = $service->gui();
97 
98  $this->settings = $domain->settings();
99  $this->user = $domain->user();
100  $this->tree = $domain->repositoryTree();
101  $this->rbac_review = $domain->rbac()->review();
102  $this->rbacadmin = $domain->rbac()->admin();
103  $this->lng = $domain->lng();
104 
105  $gui = $service->gui();
106  $this->gui = $gui;
107  $this->help = $gui->help();
108  $this->tabs = $gui->tabs();
109  $this->toolbar = $gui->toolbar();
110  $this->ui = $gui->ui();
111  $this->locator = $gui->locator();
112 
113  $this->nav_history = $DIC["ilNavigationHistory"];
114  $this->ctrl = $gui->ctrl();
115 
116  $this->blog_request = $gui->standardRequest();
117 
119  $this->blpg = $req->getBlogPage();
120  $this->old_nr = $req->getOldNr();
121  $this->ppage = $req->getPPage();
122  $this->user_page = $req->getUserPage();
123  $this->new_type = $req->getNewType();
124  $this->prvm = $req->getPreviewMode();
125  $this->ntf = $req->getNotification();
126  $this->apid = $req->getApId();
127  $this->month = $req->getMonth();
128  $this->keyword = $req->getKeyword();
129  $this->author = $req->getAuthor();
130 
131  parent::__construct($a_id, $a_id_type, $a_parent_node_id);
132 
133  $blog_page = $this->blog_request->getBlogPage();
134  if ($blog_page > 0 &&
135  ilBlogPosting::lookupBlogId($blog_page) !== $this->object->getId()) {
136  throw new ilException("Posting ID does not match blog.");
137  }
138 
139  $blog_id = 0;
140  if ($this->object) {
141  // gather postings by month
142  $this->items = $this->buildPostingList($this->object->getId());
143  if ($this->items) {
144  // current month (if none given or empty)
145  if (!$this->month || !$this->items[$this->month]) {
146  $m = array_keys($this->items);
147  $this->month = array_shift($m);
148  $this->month_default = true;
149  }
150  }
151 
152  $this->ctrl->setParameter($this, "bmn", $this->month);
153  $blog_id = $this->object->getId();
154  }
155 
156  $this->lng->loadLanguageModule("blog");
157  $this->ctrl->saveParameter($this, "prvm");
158 
159  $this->content_style_gui = $cs->gui();
160  if (is_object($this->object)) {
161  if ($this->id_type !== self::REPOSITORY_NODE_ID) {
162  $this->content_style_domain = $cs->domain()->styleForObjId($this->object->getId());
163  } else {
164  $this->content_style_domain = $cs->domain()->styleForRefId($this->object->getRefId());
165  }
166  $this->blog_settings =
167  $domain->blogSettings()->getByObjId($this->object->getId());
168  }
169 
170  $this->reading_time_gui = $gui->readingTime()->settingsGUI($blog_id);
171  $this->reading_time_manager = $domain->readingTime();
172  $this->notes = $DIC->notes();
173  $owner = $this->object?->getOwner() ?? 0;
174  $this->perm = $domain->perm(
175  $this->getAccessHandler(),
176  $this->node_id,
177  $this->id_type,
178  $this->user->getId(),
179  $owner
180  );
181  $this->profile = $domain->profile();
182  $this->profile_gui = $gui->profile();
183  }
184 
185  public function getType(): string
186  {
187  return "blog";
188  }
189 
190  public function getItems(): array
191  {
192  return $this->items;
193  }
194 
195  protected function afterSave(ilObject $new_object): void
196  {
197  $ilCtrl = $this->ctrl;
198 
199  $this->tpl->setOnScreenMessage('success', $this->lng->txt("object_added"), true);
200  $ilCtrl->redirect($this, "");
201  }
202 
203  protected function setSettingsSubTabs(string $a_active): void
204  {
205  $tree = $this->tree;
207 
208  // general properties
209  $this->tabs_gui->addSubTab(
210  "properties",
211  $this->lng->txt("general"),
212  $this->ctrl->getLinkTarget($this, 'edit')
213  );
214 
215  $this->tabs_gui->addSubTab(
216  "side_blocks",
217  $this->lng->txt("blog_side_blocks"),
218  $this->ctrl->getLinkTargetByClass(
219  [\ILIAS\Blog\Settings\BlockSettingsGUI::class],
220  ""
221  )
222  );
223 
224  $this->tabs_gui->addSubTab(
225  "style",
226  $this->lng->txt("obj_sty"),
227  $this->ctrl->getLinkTargetByClass("ilobjectcontentstylesettingsgui", "")
228  );
229 
230  // notification settings for blogs in courses and groups
231  if ($this->id_type === self::REPOSITORY_NODE_ID) {
232  $grp_ref_id = $tree->checkForParentType($this->object->getRefId(), 'grp');
233  $crs_ref_id = $tree->checkForParentType($this->object->getRefId(), 'crs');
234 
235  if ($grp_ref_id > 0 || $crs_ref_id > 0) {
236  if ($access->checkAccess('write', '', $this->ref_id)) {
237  $this->tabs_gui->addSubTab(
238  'notifications',
239  $this->lng->txt("notifications"),
240  $this->ctrl->getLinkTargetByClass("ilobjnotificationsettingsgui", '')
241  );
242  }
243  }
244  }
245 
246  $this->tabs_gui->activateSubTab($a_active);
247  }
248 
249  public function edit(): void
250  {
251  $this->ctrl->redirectByClass(SettingsGUI::class, "");
252  }
253 
254  protected function setTabs(): void
255  {
256  $lng = $this->lng;
257  $ilHelp = $this->help;
258 
259  if ($this->id_type === self::WORKSPACE_NODE_ID) {
260  $this->ctrl->setParameter($this, "wsp_id", $this->node_id);
261  }
262 
263  $ilHelp->setScreenIdComponent("blog");
264 
265  if ($this->checkPermissionBool("read")) {
266  $this->ctrl->setParameterByClass(self::class, "bmn", null);
267  $this->tabs_gui->addTab(
268  "content",
269  $lng->txt("content"),
270  $this->ctrl->getLinkTarget($this, "")
271  );
272  }
273  if ($this->checkPermissionBool("read")) {
274  $this->tabs_gui->addTab(
275  "id_info",
276  $lng->txt("info_short"),
277  $this->ctrl->getLinkTargetByClass(array("ilobjbloggui", "ilinfoscreengui"), "showSummary")
278  );
279  }
280 
281  if ($this->checkPermissionBool("write")) {
282  $this->tabs_gui->addTab(
283  "settings",
284  $lng->txt("settings"),
285  $this->ctrl->getLinkTargetByClass(
286  [SettingsGUI::class],
287  ""
288  )
289  );
290 
291  if ($this->id_type === self::REPOSITORY_NODE_ID) {
292  $this->tabs_gui->addTab(
293  "contributors",
294  $lng->txt("blog_contributors"),
295  $this->ctrl->getLinkTarget($this, "contributors")
296  );
297  }
298 
299  if ($this->id_type === self::REPOSITORY_NODE_ID) {
300  $mdgui = new ilObjectMetaDataGUI($this->object, null, null, $this->call_by_reference);
301  $mdtab = $mdgui->getTab();
302  if ($mdtab) {
303  $this->tabs_gui->addTab(
304  "meta_data",
305  $this->lng->txt("meta_data"),
306  $mdtab
307  );
308  }
309  $this->tabs_gui->addTab(
310  "export",
311  $lng->txt("export"),
312  $this->ctrl->getLinkTargetByClass("ilexportgui", "")
313  );
314  }
315  }
316 
317  if ($this->perm->mayContribute()) {
318  $this->tabs_gui->addNonTabbedLink(
319  "preview",
320  $lng->txt("blog_preview"),
321  $this->ctrl->getLinkTarget($this, "preview")
322  );
323  }
324  parent::setTabs();
325  }
326 
327  public function executeCommand(): void
328  {
329  $ilCtrl = $this->ctrl;
330  $tpl = $this->tpl;
331  $ilTabs = $this->tabs;
332  $lng = $this->lng;
333  $ilNavigationHistory = $this->nav_history;
334 
335 
336  $next_class = $ilCtrl->getNextClass($this);
337 
338  if ($next_class !== "ilexportgui") {
339  $this->triggerAssignmentTool();
340  }
341 
342  $cmd = $ilCtrl->getCmd();
343 
344  // add entry to navigation history
345  if (($this->id_type === self::REPOSITORY_NODE_ID) && !$this->getCreationMode() &&
346  $this->getAccessHandler()->checkAccess("read", "", $this->node_id)) {
347  // see #22067
348  $link = $ilCtrl->getLinkTargetByClass(["ilrepositorygui", "ilObjBlogGUI"], "preview");
349  $ilNavigationHistory->addItem($this->node_id, $link, "blog");
350  }
351  switch ($next_class) {
352  case 'ilblogpostinggui':
353  $this->ctrl->saveParameter($this, "user_page");
355 
356  if (!$this->checkPermissionBool("read")) {
357  $this->tpl->setOnScreenMessage('info', $lng->txt("no_permission"));
358  return;
359  }
360 
361  // #9680
362  if ($this->id_type === self::REPOSITORY_NODE_ID) {
363  $this->setLocator();
364  }
365 
366  $style_sheet_id = $this->content_style_domain->getEffectiveStyleId();
367 
368  $bpost_gui = new ilBlogPostingGUI(
369  $this->node_id,
370  $this->getAccessHandler(),
371  $this->blpg,
372  $this->old_nr,
373  ($this->object->getNotesStatus() && !$this->disable_notes),
374  $this->perm->mayEditPosting($this->blpg),
375  $style_sheet_id
376  );
377 
378  // keep preview mode through notes gui (has its own commands)
379  switch ($cmd) {
380  // blog preview
381  case "previewFullscreen":
382  $ilCtrl->setParameter($this, "prvm", "fsc");
383  break;
384 
385  default:
386  $this->setContentStyleSheet();
387 
388 
389  $this->ctrl->setParameterByClass("ilblogpostinggui", "blpg", $this->blpg);
390  $this->tabs_gui->addNonTabbedLink(
391  "preview",
392  $lng->txt("blog_preview"),
393  $this->ctrl->getLinkTargetByClass("ilblogpostinggui", "previewFullscreen")
394  );
395  $this->ctrl->setParameterByClass("ilblogpostinggui", "blpg", "");
396  break;
397  }
398 
399  // keep preview mode through notes gui
400  if ($this->prvm) {
401  $cmd = "previewFullscreen";
402  }
403  if (in_array($cmd, array("previewFullscreen"))) {
404  $this->renderToolbarNavigation($this->items, true);
405  }
406  $ret = $ilCtrl->forwardCommand($bpost_gui);
407  if (!$ilTabs->back_target) {
408  $ilCtrl->setParameter($this, "bmn", "");
409  $ilTabs->setBackTarget(
410  $lng->txt("back"),
411  $ilCtrl->getLinkTarget($this, "")
412  );
413  }
414 
415  if ($ret != "") {
416  // $is_owner = $this->object->getOwner() == $ilUser->getId();
417  $is_owner = $this->perm->mayContribute();
418  $is_active = $bpost_gui->getBlogPosting()->getActive();
419 
420  // do not show inactive postings
421  if (($cmd === "previewFullscreen")
422  && !$is_owner && !$is_active) {
423  $this->ctrl->redirect($this, "preview");
424  }
425 
426  switch ($cmd) {
427  // blog preview
428  case "previewFullscreen":
429  $this->addHeaderActionForCommand($cmd);
430  $this->filterInactivePostings();
431  $nav = $this->renderNavigation("preview", $cmd);
432  $this->renderFullScreen($ret, $nav);
433  break;
434 
435  default:
436  // infos about draft status / snippet
437  $info = array();
438  if (!$is_active) {
439  // single author blog (owner) in personal workspace
440  if ($this->id_type === self::WORKSPACE_NODE_ID) {
441  $info[] = $lng->txt("blog_draft_info");
442  } else {
443  $info[] = $lng->txt("blog_draft_info_contributors");
444  }
445  }
446  $public_action = false;
447  if ($cmd !== "history" && $cmd !== "edit" && $is_active && empty($info)) {
448  $info[] = $lng->txt("blog_new_posting_info");
449  $public_action = true;
450  }
451  if ($this->blog_settings->getApproval() && !$bpost_gui->getBlogPosting()->isApproved()) {
452  // #9737
453  $info[] = $lng->txt("blog_posting_edit_approval_info");
454  }
455  if ($public_action) {
456  $this->tpl->setOnScreenMessage('success', implode("<br />", $info));
457  } else {
458  if (count($info) > 0) {
459  $this->tpl->setOnScreenMessage('info', implode("<br />", $info));
460  }
461  }
462 
463  // revert to edit cmd to avoid confusion
464  $tpl->setContent($ret);
465  if ($cmd !== "edit") {
466  $this->addHeaderActionForCommand("render");
467  $nav = $this->renderNavigation("render", $cmd, "", $is_owner);
468  $tpl->setRightContent($nav);
469  } else {
470  $this->tabs->setBackTarget("", "");
471  }
472  break;
473  }
474  }
475  break;
476 
477  case "ilinfoscreengui":
478  $this->prepareOutput();
479  $this->addHeaderActionForCommand("render");
480  $this->infoScreenForward();
481  break;
482 
483  case "ilnotegui":
484  $this->preview();
485  break;
486 
487  case "ilcommonactiondispatchergui":
489  $gui->enableCommentsSettings(false);
490  $this->prepareOutput();
491  $this->ctrl->forwardCommand($gui);
492  break;
493 
494  case "ilpermissiongui":
495  $this->prepareOutput();
496  $ilTabs->activateTab("id_permissions");
497  $perm_gui = new ilPermissionGUI($this);
498  $this->ctrl->forwardCommand($perm_gui);
499  break;
500 
501  case "ilobjectcopygui":
502  $this->prepareOutput();
503  $cp = new ilObjectCopyGUI($this);
504  $cp->setType("blog");
505  $this->ctrl->forwardCommand($cp);
506  break;
507 
508  case 'ilrepositorysearchgui':
509  $this->prepareOutput();
510  $ilTabs->activateTab("contributors");
511  $rep_search = new ilRepositorySearchGUI();
512  $rep_search->setTitle($this->lng->txt("blog_add_contributor"));
513  $rep_search->setCallback($this, 'addContributor', $this->object->getAllLocalRoles($this->node_id));
514  $this->ctrl->setReturn($this, 'contributors');
515  $this->ctrl->forwardCommand($rep_search);
516  break;
517 
518  case 'ilexportgui':
519  $this->showExportGUI();
520  break;
521 
522  case "ilobjectcontentstylesettingsgui":
523  $this->checkPermission("write");
524  $this->prepareOutput();
525  $this->addHeaderAction();
526  $ilTabs->activateTab("settings");
527  $this->setSettingsSubTabs("style");
528 
529 
530  if ($this->id_type === self::REPOSITORY_NODE_ID) {
531  $settings_gui = $this->content_style_gui
532  ->objectSettingsGUIForRefId(
533  null,
534  $this->object->getRefId()
535  );
536  } else {
537  $settings_gui = $this->content_style_gui
538  ->objectSettingsGUIForObjId(
539  null,
540  $this->object->getId()
541  );
542  }
543  $this->ctrl->forwardCommand($settings_gui);
544  break;
545 
546 
547  case "ilblogexercisegui":
548  $this->ctrl->setReturn($this, "render");
549  $gui = $this->gui->exercise()->ilBlogExerciseGUI($this->node_id);
550  $this->ctrl->forwardCommand($gui);
551  break;
552 
553  case 'ilobjnotificationsettingsgui':
554  $this->prepareOutput();
555  $ilTabs->activateTab("settings");
556  $this->setSettingsSubTabs("notifications");
557  $gui = new ilObjNotificationSettingsGUI($this->object->getRefId());
558  $this->ctrl->forwardCommand($gui);
559  break;
560 
561  case strtolower(ilObjectMetaDataGUI::class):
562  $this->checkPermission("write");
563  $this->prepareOutput();
564  $ilTabs->activateTab("meta_data");
565  $gui = new ilObjectMetaDataGUI($this->object, null, null, $this->call_by_reference);
566  $this->ctrl->forwardCommand($gui);
567  break;
568 
569  case strtolower(SettingsGUI::class):
570  $this->checkPermission("write");
571  $this->prepareOutput();
572  $ilTabs->activateTab("settings");
573  $this->setSettingsSubTabs("properties");
574  $gui = $this->gui->settings()->settingsGUI(
575  $this->obj_id,
576  $this->id_type === self::REPOSITORY_NODE_ID
577  );
578  $this->ctrl->forwardCommand($gui);
579  break;
580 
581  case strtolower(\ILIAS\Blog\Settings\BlockSettingsGUI::class):
582  $this->checkPermission("write");
583  $this->prepareOutput();
584  $ilTabs->activateTab("settings");
585  $this->setSettingsSubTabs("side_blocks");
586  $gui = $this->gui->settings()->blockSettingsGUI(
587  $this->obj_id,
588  $this->id_type === self::REPOSITORY_NODE_ID
589  );
590  $this->ctrl->forwardCommand($gui);
591  break;
592 
593  default:
594  if ($cmd !== "gethtml") {
595  // desktop item handling, must be toggled before header action
596  if ($cmd === "addToDesk" || $cmd === "removeFromDesk") {
597  $this->{$cmd . "Object"}();
598  if ($this->prvm) {
599  $cmd = "preview";
600  } else {
601  $cmd = "render";
602  }
603  // @todo: removed deprecated ilCtrl methods, this needs inspection by a maintainer.
604  // $ilCtrl->setCmd($cmd);
605  }
606  $this->addHeaderActionForCommand($cmd);
607  }
608  parent::executeCommand();
609  }
610  }
611 
612  protected function showExportGUI(): void
613  {
614  $this->prepareOutput();
615  $this->tabs->activateTab("export");
616  $exp_gui = new ilExportGUI($this);
617  $this->ctrl->forwardCommand($exp_gui);
618  }
619 
620  protected function createExportFileWithComments(): void
621  {
622  $this->buildExportFile(true);
623  $this->prepareOutput();
624  $this->tabs->activateTab("export");
625  $this->ctrl->redirectByClass(ilExportGUI::class, ilExportGUI::CMD_LIST_EXPORT_FILES);
626  }
627 
628  protected function createExportFile(): void
629  {
630  $this->buildExportFile();
631  $this->prepareOutput();
632  $this->tabs->activateTab("export");
633  $this->ctrl->redirectByClass(ilExportGUI::class, ilExportGUI::CMD_LIST_EXPORT_FILES);
634  }
635 
636  protected function triggerAssignmentTool(): void
637  {
638  $be = $this->domain->exercise($this->node_id);
639  $be_gui = $this->gui->exercise()->ilBlogExerciseGUI($this->node_id);
640  $assignments = $be->getAssignmentsOfBlog();
641  if (count($assignments) > 0) {
642  $ass_ids = array_map(static function ($i) {
643  return $i["ass_id"];
644  }, $assignments);
645  $this->tool_context->current()->addAdditionalData(ilExerciseGSToolProvider::SHOW_EXC_ASSIGNMENT_INFO, true);
646  $this->tool_context->current()->addAdditionalData(ilExerciseGSToolProvider::EXC_ASS_IDS, $ass_ids);
647  $this->tool_context->current()->addAdditionalData(
649  $be_gui->getActionButtons()
650  );
651  }
652  }
653 
657  public function infoScreen(): void
658  {
659  $this->ctrl->redirectByClass(ilInfoScreenGUI::class, "showSummary");
660  }
661 
662  public function infoScreenForward(): void
663  {
664  $ilTabs = $this->tabs;
665 
666  $ilTabs->activateTab("id_info");
667 
668  $this->checkPermission("visible");
669 
670  $info = new ilInfoScreenGUI($this);
671 
672  if ($this->id_type !== self::WORKSPACE_NODE_ID) {
673  $info->enablePrivateNotes();
674  }
675 
676  if ($this->checkPermissionBool("read")) {
677  $info->enableNews();
678  }
679 
680  // no news editing for files, just notifications
681  $info->enableNewsEditing(false);
682  if ($this->checkPermissionBool("write")) {
683  $news_set = new ilSetting("news");
684  $enable_internal_rss = $news_set->get("enable_rss_for_internal");
685 
686  if ($enable_internal_rss) {
687  $info->setBlockProperty("news", "settings", "1");
688  $info->setBlockProperty("news", "public_notifications_option", "1");
689  }
690  }
691 
692  // standard meta data
693  $info->addMetaDataSections($this->object->getId(), 0, $this->object->getType());
694 
695  $this->ctrl->forwardCommand($info);
696  }
697 
701  public function createPosting(): void
702  {
703  $ilCtrl = $this->ctrl;
704  $ilUser = $this->user;
705 
706  $title = $this->blog_request->getTitle();
707  if ($title) {
708  // create new posting
709  $posting = new ilBlogPosting();
710  $posting->setTitle($title);
711  $posting->setBlogId($this->object->getId());
712  $posting->setActive(false);
713  $posting->setAuthor($ilUser->getId());
714  $posting->create(false);
715 
716  // switch month list to current month (will include new posting)
717  $ilCtrl->setParameter($this, "bmn", date("Y-m"));
718 
719  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $posting->getId());
720  $ilCtrl->redirectByClass("ilblogpostinggui", "edit");
721  } else {
722  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("msg_no_title"), true);
723  $ilCtrl->redirect($this, "render");
724  }
725  }
726 
730  public function render(): void
731  {
732  $tpl = $this->tpl;
733  $ilTabs = $this->tabs;
734  $ilCtrl = $this->ctrl;
735  $lng = $this->lng;
736  $ilToolbar = new ilToolbarGUI();
737 
738  if (!$this->checkPermissionBool("read")) {
739  $this->tpl->setOnScreenMessage('info', $lng->txt("no_permission"));
740  return;
741  }
742 
743  $ilTabs->activateTab("content");
744 
745  // toolbar
746  if ($this->perm->mayContribute()) {
747  $ilToolbar->setFormAction($ilCtrl->getFormAction($this, "createPosting"));
748 
749  $title = new ilTextInputGUI($lng->txt("title"), "title");
750  $title->setSize(30);
751  $ilToolbar->addStickyItem($title, true);
753  document.getElementById('title').setAttribute('data-blog-input', 'posting-title');
754  document.getElementById('title').setAttribute('placeholder', ' ');
755  ");
756 
757  $this->gui->button(
758  $lng->txt("blog_add_posting"),
759  "createPosting"
760  )->submit()->toToolbar(true, $ilToolbar);
761 
762  // #18763
763  $keys = array_keys($this->items);
764  $first = array_shift($keys);
765  if ($first != $this->month) {
766  $ilToolbar->addSeparator();
767 
768  $ilCtrl->setParameter($this, "bmn", $first);
769  $url = $ilCtrl->getLinkTarget($this, "");
770  $ilCtrl->setParameter($this, "bmn", $this->month);
771 
772  $this->gui->link(
773  $lng->txt("blog_show_latest"),
774  $url
775  )->emphasised()->toToolbar(true, $ilToolbar);
776  }
777 
778  // print/pdf
779  $print_view = $this->getPrintView();
780  $modal_elements = $print_view->getModalElements(
781  $this->ctrl->getLinkTarget(
782  $this,
783  "printViewSelection"
784  )
785  );
786  $ilToolbar->addSeparator();
787  $ilToolbar->addComponent($modal_elements->button);
788  $ilToolbar->addComponent($modal_elements->modal);
789  }
790 
791  // $is_owner = ($this->object->getOwner() == $ilUser->getId());
792  $is_owner = $this->perm->mayContribute();
793 
794  $list_items = $this->getListItems($is_owner);
795 
796  $list = $nav = "";
797  if ($list_items) {
798  $list = $this->renderList($list_items, "preview", "", $is_owner);
799  $nav = $this->renderNavigation("render", "edit", "", $is_owner);
800  }
801 
802  $this->setContentStyleSheet();
803 
804  $tpl->setContent($ilToolbar->getHTML() . $list);
805  $tpl->setRightContent($nav);
806  }
807 
808 
812  protected function getListItems(
813  bool $a_show_inactive = false
814  ): array {
815  if ($this->author) {
816  $list_items = array();
817  foreach ($this->items as $month => $items) {
818  foreach ($items as $id => $item) {
819  if ($item["author"] == $this->author ||
820  (isset($item["editors"]) && in_array($this->author, $item["editors"]))) {
821  $list_items[$id] = $item;
822  }
823  }
824  }
825  } elseif ($this->keyword) {
826  $list_items = $this->filterItemsByKeyword($this->items, $this->keyword);
827  } else {
828  $max = $this->blog_settings->getOverviewPostings();
829  if ($this->month_default && $max) {
830  $list_items = array();
831  foreach ($this->items as $month => $postings) {
832  foreach ($postings as $id => $item) {
833  if (!$a_show_inactive &&
835  continue;
836  }
837  $list_items[$id] = $item;
838 
839  if (count($list_items) >= $max) {
840  break(2);
841  }
842  }
843  }
844  } else {
845  $list_items = $this->items[$this->month] ?? [];
846  }
847  }
848  return $list_items;
849  }
850 
854  public function preview(): void
855  {
856  $lng = $this->lng;
858 
859  if (!$this->checkPermissionBool("read")) {
860  $this->tpl->setOnScreenMessage('info', $lng->txt("no_permission"));
861  return;
862  }
863 
864  $this->filterInactivePostings();
865 
866  $list_items = $this->getListItems();
867 
868  $list = $nav = "";
869  if ($list_items) {
870  $list = $this->renderList($list_items, "previewFullscreen");
871  $nav = $this->renderNavigation("preview", "previewFullscreen");
872  $this->renderToolbarNavigation($this->items);
873  }
874 
875  $this->renderFullScreen($list, $nav);
876  }
877 
881  public function export(
882  bool $a_with_comments = false
883  ): void {
884  $zip = $this->buildExportFile($a_with_comments);
885  ilFileDelivery::deliverFileLegacy($zip, $this->object->getTitle() . ".zip", '', false, true);
886  }
887 
888 
889  // --- helper functions
890 
894  public function renderFullScreen(
895  string $a_content,
896  string $a_navigation
897  ): void {
898  $tpl = $this->tpl;
899  $ilUser = $this->user;
900  $ilTabs = $this->tabs;
901  $ilLocator = $this->locator;
902 
903  $owner = $this->object->getOwner();
904 
905  $ilTabs->clearTargets();
906  $tpl->setLocator();
907 
908  $back_caption = "";
909  $back = "";
910 
911  // back (edit)
912  if ($owner === $ilUser->getId()) {
913  // from shared/deeplink
914  if ($this->id_type === self::WORKSPACE_NODE_ID) {
915  $back = "ilias.php?baseClass=ilDashboardGUI&cmd=jumpToWorkspace&wsp_id=" . $this->node_id;
916  }
917  // from editor (#10073)
918  elseif ($this->perm->mayContribute()) {
919  $this->ctrl->setParameter($this, "prvm", "");
920  if ($this->blpg === 0) {
921  $back = $this->ctrl->getLinkTarget($this, "");
922  } else {
923  $this->ctrl->setParameterByClass("ilblogpostinggui", "bmn", $this->month);
924  $this->ctrl->setParameterByClass("ilblogpostinggui", "blpg", $this->blpg);
925  $back = $this->ctrl->getLinkTargetByClass("ilblogpostinggui", "preview");
926  }
927  $this->ctrl->setParameter($this, "prvm", $this->prvm);
928  }
929 
930  $back_caption = $this->lng->txt("blog_back_to_blog_owner");
931  }
932  // back
933  elseif ($ilUser->getId() && $ilUser->getId() !== ANONYMOUS_USER_ID) {
934  // workspace (always shared)
935  if ($this->id_type === self::WORKSPACE_NODE_ID) {
936  $back = "ilias.php?baseClass=ilDashboardGUI&cmd=jumpToWorkspace&dsh=" . $owner;
937  }
938  // contributor
939  elseif ($this->perm->mayContribute()) {
940  $back = $this->ctrl->getLinkTarget($this, "");
941  $back_caption = $this->lng->txt("blog_back_to_blog_owner");
942  }
943  // listgui / parent container
944  else {
945  $tree = $this->tree;
946  $parent_id = $tree->getParentId($this->node_id);
948  }
949  }
950 
951  $this->renderFullscreenHeader($tpl, $owner);
952 
953  // #13564
954  $this->ctrl->setParameter($this, "bmn", "");
955  //$tpl->setTitleUrl($this->ctrl->getLinkTarget($this, "preview"));
956  $this->ctrl->setParameter($this, "bmn", $this->month);
957 
958  $this->setContentStyleSheet();
959 
960  // content
961  $tpl->setContent($a_content);
962  $tpl->setRightContent($a_navigation);
963  }
964 
965  public function renderFullscreenHeader(
967  int $a_user_id,
968  bool $a_export = false
969  ): void {
970  $ilUser = $this->user;
971 
972  if (!$a_export) {
974  $this->object->getType(),
976  $this->object->getId(),
977  $ilUser->getId()
978  );
979  }
980 
981  // repository blogs are multi-author
982  $name = "";
983  if ($this->id_type !== self::REPOSITORY_NODE_ID) {
984  $name = ilObjUser::_lookupName($a_user_id);
985  $name = $name["lastname"] . ", " . $name["firstname"];
986  }
987 
988  $ppic = "";
989  if ($this->blog_settings?->getProfilePicture() && !$a_export) {
990  // repository (multi-user)
991  if ($this->id_type === self::REPOSITORY_NODE_ID) {
992  // #15030
993  if ($this->blpg > 0 && !$a_export) {
994  $post = new ilBlogPosting($this->blpg);
995  $author_id = $post->getAuthor();
996  if ($author_id) {
997  $ppic = $this->profile_gui->getPicturePath($author_id);
998  $name = $this->profile_gui->getNamePresentation($author_id);
999  //$name = $name["lastname"] . ", " . $name["firstname"];
1000  }
1001  }
1002  }
1003  // workspace (author == owner)
1004  else {
1005  $ppic = ilObjUser::_getPersonalPicturePath($a_user_id, "xsmall", true, true);
1006  if ($a_export) {
1007  $ppic = basename($ppic);
1008  }
1009  }
1010  } else {
1011  $ppic = ilUtil::getImagePath("standard/icon_blog.svg");
1012  }
1013  $a_tpl->resetHeaderBlock(false);
1014  $a_tpl->setTitleIcon($ppic);
1015  $a_tpl->setTitle($this->object->getTitle());
1016  if ($this->id_type === self::REPOSITORY_NODE_ID) {
1017  $a_tpl->setDescription($this->object->getDescription());
1018  } else {
1019  $a_tpl->setDescription($name);
1020  }
1021  }
1022 
1026  protected function buildPostingList(
1027  int $a_obj_id
1028  ): array {
1029  $author_found = false;
1030 
1031  $items = array();
1032  foreach (ilBlogPosting::getAllPostings($a_obj_id) as $posting) {
1033  if ($this->author &&
1034  ($posting["author"] == $this->author ||
1035  (is_array($posting["editors"] ?? false) && in_array($this->author, $posting["editors"])))) {
1036  $author_found = true;
1037  }
1038 
1039  $month = substr($posting["created"]->get(IL_CAL_DATE), 0, 7);
1040  $items[$month][$posting["id"]] = $posting;
1041  }
1042 
1043  if ($this->author && !$author_found) {
1044  $this->author = null;
1045  }
1046 
1047  return $items;
1048  }
1049 
1053  public function renderList(
1054  array $items,
1055  string $a_cmd = "preview",
1056  string $a_link_template = "",
1057  bool $a_show_inactive = false,
1058  string $a_export_directory = ""
1059  ): string {
1060  $lng = $this->lng;
1061  $ilCtrl = $this->ctrl;
1062  $ilUser = $this->user;
1063  $ui_factory = $this->ui->factory();
1064  $ui_renderer = $this->ui->renderer();
1065 
1066  $wtpl = new ilTemplate("tpl.blog_list.html", true, true, "components/ILIAS/Blog");
1067 
1068  $is_admin = $this->perm->canManage();
1069 
1070  $last_month = null;
1071  $is_empty = true;
1072  foreach ($items as $item) {
1073  // only published items
1074  $is_active = ilBlogPosting::_lookupActive($item["id"], "blp");
1075  if (!$is_active && !$a_show_inactive) {
1076  continue;
1077  }
1078 
1079  $is_empty = false;
1080 
1081  $month = "";
1082  if (!$this->keyword && !$this->author) {
1083  $month = substr($item["created"]->get(IL_CAL_DATE), 0, 7);
1084  }
1085 
1086  if (!$last_month || $last_month != $month) {
1087  if ($last_month) {
1088  $wtpl->setCurrentBlock("month_bl");
1089  $wtpl->parseCurrentBlock();
1090  }
1091 
1092  // title according to current "filter"/navigation
1093  if ($this->keyword) {
1094  $title = $lng->txt("blog_keyword") . ": " . $this->keyword;
1095  } elseif ($this->author) {
1096  $title = $lng->txt("blog_author") . ": " . $this->profile_gui->getNamePresentation($this->author);
1097  } else {
1098  $title = $this->gui->presentation()->util()->getMonthPresentation($month);
1099  $last_month = $month;
1100  }
1101 
1102  $wtpl->setVariable("TXT_CURRENT_MONTH", $title);
1103  }
1104 
1105  if (!$a_link_template) {
1106  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $this->month);
1107  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $item["id"]);
1108  $preview = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_cmd);
1109  } else {
1110  $preview = $this->buildExportLink($a_link_template, "posting", (string) $item["id"]);
1111  }
1112  $more_link = $preview;
1113 
1114  // actions
1115  $posting_edit = $this->perm->mayEditPosting($item["id"], $item["author"]);
1116  if (($posting_edit || $is_admin) && !$a_link_template && $a_cmd === "preview") {
1117  $actions = [];
1118 
1119  if ($is_active && $this->blog_settings->getApproval() && !$item["approved"]) {
1120  if ($is_admin) {
1121  $ilCtrl->setParameter($this, "apid", $item["id"]);
1122  $actions[] = $ui_factory->link()->standard(
1123  $lng->txt("blog_approve"),
1124  $ilCtrl->getLinkTarget($this, "approve")
1125  );
1126  $ilCtrl->setParameter($this, "apid", "");
1127  }
1128 
1129  $wtpl->setVariable("APPROVAL", $lng->txt("blog_needs_approval"));
1130  }
1131 
1132  if ($posting_edit) {
1133  $actions[] = $ui_factory->link()->standard(
1134  $lng->txt("edit_content"),
1135  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit")
1136  );
1137  $more_link = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit");
1138 
1139  // #11858
1140  if ($is_active) {
1141  $actions[] = $ui_factory->link()->standard(
1142  $lng->txt("blog_toggle_draft"),
1143  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deactivatePageToList")
1144  );
1145  } else {
1146  $actions[] = $ui_factory->link()->standard(
1147  $lng->txt("blog_toggle_final"),
1148  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "activatePageToList")
1149  );
1150  }
1151 
1152  $actions[] = $ui_factory->link()->standard(
1153  $lng->txt("rename"),
1154  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edittitle")
1155  );
1156 
1157  if ($this->blog_settings->getKeywords()) { // #13616
1158  $actions[] = $ui_factory->link()->standard(
1159  $lng->txt("blog_edit_keywords"),
1160  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "editKeywords")
1161  );
1162  }
1163 
1164  $actions[] = $ui_factory->link()->standard(
1165  $lng->txt("blog_edit_date"),
1166  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "editdate")
1167  );
1168 
1169  $actions[] = $ui_factory->link()->standard(
1170  $lng->txt("delete"),
1171  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deleteBlogPostingConfirmationScreen")
1172  );
1173  } elseif ($is_admin) {
1174  // #10513
1175  if ($is_active) {
1176  $ilCtrl->setParameter($this, "apid", $item["id"]);
1177  $actions[] = $ui_factory->link()->standard(
1178  $lng->txt("blog_toggle_draft_admin"),
1179  $ilCtrl->getLinkTarget($this, "deactivateAdmin")
1180  );
1181  $ilCtrl->setParameter($this, "apid", "");
1182  }
1183 
1184  $actions[] = $ui_factory->link()->standard(
1185  $lng->txt("delete"),
1186  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deleteBlogPostingConfirmationScreen")
1187  );
1188  }
1189 
1190  $dd = $ui_factory->dropdown()->standard($actions)->withLabel($this->lng->txt("actions"));
1191 
1192  $wtpl->setCurrentBlock("actions");
1193  $wtpl->setVariable("ACTION_SELECTOR", $ui_renderer->render($dd));
1194  $wtpl->parseCurrentBlock();
1195  }
1196 
1197  // comments
1198  if ($this->object->getNotesStatus() && !$a_link_template && !$this->disable_notes) {
1199  // count (public) notes
1200  $notes_context = $this->notes
1201  ->data()
1202  ->context(
1203  $this->obj_id,
1204  (int) $item["id"],
1205  "blp"
1206  );
1207  $count = $this->notes
1208  ->domain()
1209  ->getNrOfCommentsForContext($notes_context);
1210 
1211  if ($a_cmd !== "preview") {
1212  $wtpl->setCurrentBlock("comments");
1213  $wtpl->setVariable("TEXT_COMMENTS", $lng->txt("blog_comments"));
1214  $wtpl->setVariable("URL_COMMENTS", $preview);
1215  $wtpl->setVariable("COUNT_COMMENTS", $count);
1216  $wtpl->parseCurrentBlock();
1217  }
1218  }
1219 
1220  // permanent link
1221  if ($this->node_id !== null &&
1222  $a_cmd !== "preview") {
1223  if ($this->id_type === self::WORKSPACE_NODE_ID) {
1224  $goto = $this->gui->permanentLink(0, (int) $this->node_id)->getPermanentLink((int) $item["id"]);
1225  } else {
1226  $goto = $this->gui->permanentLink((int) $this->node_id)->getPermanentLink((int) $item["id"]);
1227  }
1228  $wtpl->setCurrentBlock("permalink");
1229  $wtpl->setVariable("URL_PERMALINK", $goto);
1230  $wtpl->setVariable("TEXT_PERMALINK", $lng->txt("blog_link"));
1231  $wtpl->parseCurrentBlock();
1232  }
1233 
1234  $snippet = ilBlogPostingGUI::getSnippet(
1235  $item["id"],
1236  $this->blog_settings->getAbstractShorten(),
1237  $this->blog_settings->getAbstractShortenLength(),
1238  "&hellip;",
1239  $this->blog_settings->getAbstractImage(),
1240  $this->blog_settings->getAbstractImageWidth(),
1241  $this->blog_settings->getAbstractImageHeight(),
1242  $a_export_directory
1243  );
1244 
1245  if ($snippet) {
1246  $wtpl->setCurrentBlock("more");
1247  $wtpl->setVariable("URL_MORE", $more_link);
1248  $wtpl->setVariable("TEXT_MORE", $lng->txt("blog_list_more"));
1249  $wtpl->parseCurrentBlock();
1250  }
1251 
1252 
1253 
1254  if (!$is_active) {
1255  $wtpl->setCurrentBlock("draft_text");
1256  $wtpl->setVariable("DRAFT_TEXT", $lng->txt("blog_draft_text"));
1257  $wtpl->parseCurrentBlock();
1258  $wtpl->setVariable("DRAFT_CLASS", " ilBlogListItemDraft");
1259  }
1260 
1261  // reading time
1262  $reading_time = $this->reading_time_manager->getReadingTime(
1263  $this->object->getId(),
1264  $item["id"]
1265  );
1266  if (!is_null($reading_time)) {
1267  $this->lng->loadLanguageModule("copg");
1268  $wtpl->setCurrentBlock("reading_time");
1269  $wtpl->setVariable(
1270  "READING_TIME",
1271  $this->lng->txt("copg_est_reading_time") . ": " .
1272  sprintf($this->lng->txt("copg_x_minutes"), $reading_time)
1273  );
1274  $wtpl->parseCurrentBlock();
1275  }
1276 
1277  $wtpl->setCurrentBlock("posting");
1278 
1279  $author = "";
1280  if ($this->id_type === self::REPOSITORY_NODE_ID) {
1281  $authors = array();
1282 
1283  $author_id = $item["author"];
1284  if ($author_id) {
1285  $authors[] = $this->profile_gui->getNamePresentation($author_id);
1286  }
1287 
1288  if (isset($item["editors"])) {
1289  foreach ($item["editors"] as $editor_id) {
1290  $authors[] = $this->profile_gui->getNamePresentation($editor_id);
1291  }
1292  }
1293 
1294  if ($authors) {
1295  $author = implode(", ", $authors) . " - ";
1296  }
1297  }
1298 
1299  // title
1300  $wtpl->setVariable("URL_TITLE", $preview);
1301  $wtpl->setVariable("TITLE", $item["title"]);
1302 
1303  $kw = ilBlogPosting::getKeywords($this->obj_id, $item["id"]);
1304  natcasesort($kw);
1305  $keywords = (count($kw) > 0)
1306  ? "<br>" . $this->lng->txt("keywords") . ": " . implode(", ", $kw)
1307  : "";
1308 
1309  $wtpl->setVariable("DATETIME", $author .
1310  ilDatePresentation::formatDate($item["created"]) . $keywords);
1311 
1312  // content
1313  $wtpl->setVariable("CONTENT", $snippet);
1314 
1315  $wtpl->parseCurrentBlock();
1316  }
1317 
1318  // permalink
1319  if ($a_cmd === "previewFullscreen") {
1320  $ref_id = ($this->id_type === self::WORKSPACE_NODE_ID)
1321  ? 0
1322  : $this->node_id;
1323  $wsp_id = ($this->id_type === self::WORKSPACE_NODE_ID)
1324  ? $this->node_id
1325  : 0;
1326  $this->gui->permanentLink($ref_id, $wsp_id)->setPermanentLink();
1327  }
1328 
1329  if (!$is_empty || $a_show_inactive) {
1330  return $wtpl->get();
1331  }
1332  return "";
1333  }
1334 
1338  protected function buildExportLink(
1339  string $a_template,
1340  string $a_type,
1341  string $a_id
1342  ): string {
1343  return BlogHtmlExport::buildExportLink($a_template, $a_type, $a_id, $this->getKeywords(false));
1344  }
1345 
1346 
1350  protected function renderNavigationByDate(
1351  array $a_items,
1352  string $a_list_cmd = "render",
1353  string $a_posting_cmd = "preview",
1354  ?string $a_link_template = null,
1355  bool $a_show_inactive = false,
1356  int $a_blpg = 0
1357  ): string {
1358  $ilCtrl = $this->ctrl;
1359 
1360  $blpg = ($a_blpg > 0)
1361  ? $a_blpg
1362  : $this->blpg;
1363 
1364 
1365  // gather page active status
1366  foreach ($a_items as $month => $postings) {
1367  foreach (array_keys($postings) as $id) {
1368  $active = ilBlogPosting::_lookupActive($id, "blp");
1369  if (!$a_show_inactive && !$active) {
1370  unset($a_items[$month][$id]);
1371  } else {
1372  $a_items[$month][$id]["active"] = $active;
1373  }
1374  }
1375  if (!count($a_items[$month])) {
1376  unset($a_items[$month]);
1377  }
1378  }
1379 
1380  // list month (incl. postings)
1381  if ($this->blog_settings->getNavMode() === ilObjBlog::NAV_MODE_LIST || $a_link_template) {
1382  $max_months = $this->blog_settings->getNavModeListMonths();
1383 
1384  $wtpl = new ilTemplate("tpl.blog_list_navigation_by_date.html", true, true, "components/ILIAS/Blog");
1385 
1386  $ilCtrl->setParameter($this, "blpg", "");
1387 
1388  $counter = $mon_counter = $last_year = 0;
1389  foreach ($a_items as $month => $postings) {
1390  if (!$a_link_template && $max_months && $mon_counter >= $max_months) {
1391  break;
1392  }
1393 
1394  $add_year = false;
1395  $year = substr($month, 0, 4);
1396  if (!$last_year || $year != $last_year) {
1397  // #13562
1398  $add_year = true;
1399  $last_year = $year;
1400  }
1401 
1402  $mon_counter++;
1403 
1404  $month_name = ilCalendarUtil::_numericMonthToString((int) substr($month, 5));
1405  if (!$a_link_template) {
1406  $ilCtrl->setParameter($this, "bmn", $month);
1407  $month_url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1408  } else {
1409  $month_url = $this->buildExportLink($a_link_template, "list", (string) $month);
1410  }
1411 
1412  // list postings for month
1413  //if($counter < $max_detail_postings)
1414  if ($mon_counter <= $this->blog_settings->getNavModeListMonthsWithPostings()) {
1415  if ($add_year) {
1416  $wtpl->setCurrentBlock("navigation_year_details");
1417  $wtpl->setVariable("YEAR", $year);
1418  $wtpl->parseCurrentBlock();
1419  }
1420 
1421  foreach ($postings as $id => $posting) {
1422  //if($max_detail_postings && $counter >= $max_detail_postings)
1423  //{
1424  // break;
1425  //}
1426 
1427  $counter++;
1428 
1429  $caption = /* ilDatePresentation::formatDate($posting["created"], IL_CAL_DATETIME).
1430  ", ".*/ $posting["title"];
1431 
1432  if (!$a_link_template) {
1433  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $month);
1434  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $id);
1435  $url = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_posting_cmd);
1436  } else {
1437  $url = $this->buildExportLink($a_link_template, "posting", (string) $id);
1438  }
1439 
1440  if (!$posting["active"]) {
1441  $wtpl->setVariable("NAV_ITEM_DRAFT", $this->lng->txt("blog_draft"));
1442  } elseif ($this->blog_settings->getApproval() && !$posting["approved"]) {
1443  $wtpl->setVariable("NAV_ITEM_APPROVAL", $this->lng->txt("blog_needs_approval"));
1444  }
1445 
1446  $wtpl->setCurrentBlock("navigation_item");
1447  $wtpl->setVariable("NAV_ITEM_URL", $url);
1448  $wtpl->setVariable("NAV_ITEM_CAPTION", $caption);
1449  $wtpl->parseCurrentBlock();
1450  }
1451 
1452  $wtpl->setCurrentBlock("navigation_month_details");
1453  $wtpl->setVariable("NAV_MONTH", $month_name);
1454  $wtpl->setVariable("URL_MONTH", $month_url);
1455  }
1456  // summarized month
1457  else {
1458  if ($add_year) {
1459  $wtpl->setCurrentBlock("navigation_year");
1460  $wtpl->setVariable("YEAR", $year);
1461  $wtpl->parseCurrentBlock();
1462  }
1463 
1464  $wtpl->setCurrentBlock("navigation_month");
1465  $wtpl->setVariable("MONTH_NAME", $month_name);
1466  $wtpl->setVariable("URL_MONTH", $month_url);
1467  $wtpl->setVariable("MONTH_COUNT", count($postings));
1468  }
1469  $wtpl->parseCurrentBlock();
1470  }
1471  if (!$a_link_template) {
1472  $this->ctrl->setParameterByClass(self::class, "bmn", null);
1473  $url = $this->ctrl->getLinkTargetByClass(self::class, $a_list_cmd);
1474  } else {
1475  $url = "index.html";
1476  }
1477 
1478  $wtpl->setVariable(
1479  "STARTING_PAGE",
1480  $this->ui->renderer()->render(
1481  $this->ui->factory()->link()->standard(
1482  $this->lng->txt("blog_starting_page"),
1483  $url
1484  )
1485  )
1486  );
1487  }
1488  // single month
1489  else {
1490  $wtpl = new ilTemplate("tpl.blog_list_navigation_month.html", true, true, "components/ILIAS/Blog");
1491 
1492  $ilCtrl->setParameter($this, "blpg", "");
1493 
1494  $month_options = array();
1495  foreach ($a_items as $month => $postings) {
1496  $month_name = $this->gui->presentation()->util()->getMonthPresentation($month);
1497 
1498  $month_options[$month] = $month_name;
1499 
1500  if ($month == $this->month) {
1501  if (!$a_link_template) {
1502  $ilCtrl->setParameter($this, "bmn", $month);
1503  $month_url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1504  } else {
1505  $month_url = $this->buildExportLink($a_link_template, "list", (string) $month);
1506  }
1507 
1508  foreach ($postings as $id => $posting) {
1509  $caption = /* ilDatePresentation::formatDate($posting["created"], IL_CAL_DATETIME).
1510  ", ".*/ $posting["title"];
1511 
1512  if (!$a_link_template) {
1513  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $month);
1514  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $id);
1515  $url = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_posting_cmd);
1516  } else {
1517  $url = $this->buildExportLink($a_link_template, "posting", (string) $id);
1518  }
1519 
1520  if (!$posting["active"]) {
1521  $wtpl->setVariable("NAV_ITEM_DRAFT", $this->lng->txt("blog_draft"));
1522  } elseif ($this->blog_settings->getApproval() && !$posting["approved"]) {
1523  $wtpl->setVariable("NAV_ITEM_APPROVAL", $this->lng->txt("blog_needs_approval"));
1524  }
1525 
1526  $wtpl->setCurrentBlock("navigation_item");
1527  $wtpl->setVariable("NAV_ITEM_URL", $url);
1528  $wtpl->setVariable("NAV_ITEM_CAPTION", $caption);
1529  $wtpl->parseCurrentBlock();
1530  }
1531 
1532  $wtpl->setCurrentBlock("navigation_month_details");
1533  if ($blpg > 0) {
1534  $wtpl->setVariable("NAV_MONTH", $month_name);
1535  $wtpl->setVariable("URL_MONTH", $month_url);
1536  }
1537  $wtpl->parseCurrentBlock();
1538  }
1539  }
1540 
1541  if ($blpg === 0) {
1542  $wtpl->setCurrentBlock("option_bl");
1543  foreach ($month_options as $value => $caption) {
1544  $wtpl->setVariable("OPTION_VALUE", $value);
1545  $wtpl->setVariable("OPTION_CAPTION", $caption);
1546  if ($value == $this->month) {
1547  $wtpl->setVariable("OPTION_SEL", ' selected="selected"');
1548  }
1549  $wtpl->parseCurrentBlock();
1550  }
1551 
1552  $wtpl->setVariable("FORM_ACTION", $ilCtrl->getFormAction($this, $a_list_cmd));
1553  }
1554  }
1555  $ilCtrl->setParameter($this, "bmn", $this->month);
1556  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", "");
1557  return $wtpl->get();
1558  }
1559 
1563  protected function renderNavigationByKeywords(
1564  string $a_list_cmd = "render",
1565  bool $a_show_inactive = false,
1566  string $a_link_template = "",
1567  int $a_blpg = 0
1568  ): string {
1569  $ilCtrl = $this->ctrl;
1570 
1571  $blpg = ($a_blpg > 0)
1572  ? $a_blpg
1573  : $this->blpg;
1574 
1575  $keywords = $this->getKeywords($a_show_inactive, $blpg);
1576  if ($keywords) {
1577  $wtpl = new ilTemplate("tpl.blog_list_navigation_keywords.html", true, true, "components/ILIAS/Blog");
1578 
1579  $max = max($keywords);
1580 
1581  $wtpl->setCurrentBlock("keyword");
1582  foreach ($keywords as $keyword => $counter) {
1583  if (!$a_link_template) {
1584  $ilCtrl->setParameter($this, "kwd", urlencode((string) $keyword)); // #15885
1585  $url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1586  $ilCtrl->setParameter($this, "kwd", "");
1587  } else {
1588  $url = $this->buildExportLink($a_link_template, "keyword", (string) $keyword);
1589  }
1590 
1591  $wtpl->setVariable("TXT_KEYWORD", $keyword);
1592  $wtpl->setVariable("CLASS_KEYWORD", ilTagging::getRelevanceClass($counter, $max));
1593  $wtpl->setVariable("URL_KEYWORD", $url);
1594  $wtpl->parseCurrentBlock();
1595  }
1596 
1597  return $wtpl->get();
1598  }
1599  return "";
1600  }
1601 
1602  protected function renderNavigationByAuthors(
1603  array $a_items,
1604  string $a_list_cmd = "render",
1605  bool $a_show_inactive = false
1606  ): string {
1607  $ilCtrl = $this->ctrl;
1608 
1609  $authors = array();
1610  foreach ($a_items as $month => $items) {
1611  foreach ($items as $item) {
1612  if (($a_show_inactive || ilBlogPosting::_lookupActive($item["id"], "blp"))) {
1613  if ($item["author"]) {
1614  $authors[] = $item["author"];
1615  }
1616 
1617  if (isset($item["editors"])) {
1618  foreach ($item["editors"] as $editor_id) {
1619  if ($editor_id != $item["author"]) {
1620  $authors[] = $editor_id;
1621  }
1622  }
1623  }
1624  }
1625  }
1626  }
1627 
1628  $authors = array_unique($authors);
1629 
1630  // filter out deleted users
1631  $authors = array_filter($authors, function ($id) {
1632  return ilObject::_lookupType($id) == "usr";
1633  });
1634 
1635  if (count($authors) > 1) {
1636  $list = array();
1637  foreach ($authors as $user_id) {
1638  if ($user_id) {
1639  $ilCtrl->setParameter($this, "ath", $user_id);
1640  $url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1641  $ilCtrl->setParameter($this, "ath", "");
1642 
1643  $base_name = ilUserUtil::getNamePresentation($user_id);
1644  if (substr($base_name, 0, 1) == "[") {
1645  $name = ilUserUtil::getNamePresentation($user_id, true);
1646  $sort = $name;
1647  } else {
1649  $user_id,
1650  true,
1651  false,
1652  "",
1653  false,
1654  true,
1655  false
1656  );
1657  $name_arr = ilObjUser::_lookupName($user_id);
1658  $sort = $name_arr["lastname"] . " " . $name_arr["firstname"];
1659  }
1660 
1661  $idx = trim(strip_tags($sort)) . "///" . $user_id; // #10934
1662  $list[$idx] = array($name, $url);
1663  }
1664  }
1665  ksort($list);
1666 
1667  $wtpl = new ilTemplate("tpl.blog_list_navigation_authors.html", true, true, "components/ILIAS/Blog");
1668 
1669  $wtpl->setCurrentBlock("author");
1670  foreach ($list as $author) {
1671  $wtpl->setVariable("TXT_AUTHOR", $author[0]);
1672  $wtpl->setVariable("URL_AUTHOR", $author[1]);
1673  $wtpl->parseCurrentBlock();
1674  }
1675 
1676  return $wtpl->get();
1677  }
1678  return "";
1679  }
1680 
1684  public function renderToolbarNavigation(
1685  array $a_items,
1686  bool $single_posting = false
1687  ): void {
1688  $nav_renderer = $this->gui->navigation()->toolbarNavigationRenderer();
1689  $nav_renderer->renderToolbarNavigation(
1690  $this->perm,
1691  $a_items,
1692  $this->blpg,
1693  $single_posting,
1694  $this->month,
1695  $this->user_page
1696  );
1697  }
1698 
1702  public function renderNavigation(
1703  string $a_list_cmd = "render",
1704  string $a_posting_cmd = "preview",
1705  ?string $a_link_template = null,
1706  bool $a_show_inactive = false,
1707  int $a_blpg = 0
1708  ): string {
1710  $a_items = $this->items;
1711  $blpg = ($a_blpg > 0)
1712  ? $a_blpg
1713  : $this->blpg;
1714 
1715  if ($this->blog_settings->getOrder()) {
1716  $order = array_flip($this->blog_settings->getOrder());
1717  } else {
1718  $order = array(
1719  "navigation" => 0
1720  ,"keywords" => 2
1721  ,"authors" => 1
1722  );
1723  }
1724 
1725  $wtpl = new ilTemplate("tpl.blog_list_navigation.html", true, true, "components/ILIAS/Blog");
1726 
1727  $blocks = array();
1728 
1729  // by date
1730  if (count($a_items)) {
1731  $blocks[$order["navigation"]] = array(
1732  $this->lng->txt("blog_navigation"),
1733  $this->renderNavigationByDate($a_items, $a_list_cmd, $a_posting_cmd, $a_link_template, $a_show_inactive, $a_blpg)
1734  );
1735  }
1736 
1737  if ($this->blog_settings->getKeywords()) {
1738  // keywords
1739  $may_edit_keywords = ($blpg > 0 &&
1740  $this->perm->mayEditPosting($blpg) &&
1741  $a_list_cmd !== "preview" &&
1742  $a_list_cmd !== "gethtml" &&
1743  !$a_link_template);
1744  $keywords = $this->renderNavigationByKeywords($a_list_cmd, $a_show_inactive, (string) $a_link_template, $a_blpg);
1745  if ($keywords || $may_edit_keywords) {
1746  if (!$keywords) {
1747  $keywords = $this->lng->txt("blog_no_keywords");
1748  }
1749  $cmd = null;
1750  $blocks[$order["keywords"]] = array(
1751  $this->lng->txt("blog_keywords"),
1752  $keywords,
1753  $cmd
1754  ? array($cmd, $this->lng->txt("blog_edit_keywords"))
1755  : null
1756  );
1757  }
1758  }
1759 
1760  // is not part of (html) export
1761  if (!$a_link_template) {
1762  // authors
1763  if ($this->id_type === self::REPOSITORY_NODE_ID &&
1764  $this->blog_settings->getAuthors()) {
1765  $authors = $this->renderNavigationByAuthors($a_items, $a_list_cmd, $a_show_inactive);
1766  if ($authors) {
1767  $blocks[$order["authors"]] = array($this->lng->txt("blog_authors"), $authors);
1768  }
1769  }
1770 
1771  // rss
1772  if ($this->blog_settings->getRSS() &&
1773  $ilSetting->get('enable_global_profiles') &&
1774  $a_list_cmd === "preview") {
1775  // #10827
1776  $blog_id = $this->node_id;
1777  if ($this->id_type !== self::WORKSPACE_NODE_ID) {
1778  $blog_id .= "_cll";
1779  }
1780  $url = ILIAS_HTTP_PATH . "/feed.php?blog_id=" . $blog_id .
1781  "&client_id=" . rawurlencode(CLIENT_ID);
1782 
1783  $wtpl->setVariable("RSS_BUTTON", ilRSSButtonGUI::get(ilRSSButtonGUI::ICON_RSS, $url));
1784  }
1785  }
1786 
1787  if (count($blocks)) {
1788  global $DIC;
1789 
1790  $ui_factory = $DIC->ui()->factory();
1791  $ui_renderer = $DIC->ui()->renderer();
1792 
1793  ksort($blocks);
1794  foreach ($blocks as $block) {
1795  $title = $block[0];
1796 
1797  $content = $block[1];
1798 
1799  $secondary_panel = $ui_factory->panel()->secondary()->legacy($title, $ui_factory->legacy()->content($content));
1800 
1801  if (isset($block[2]) && is_array($block[2])) {
1802  $link = $ui_factory->button()->shy($block[2][1], $block[2][0]);
1803  $secondary_panel = $secondary_panel->withFooter($link);
1804  }
1805 
1806  $wtpl->setCurrentBlock("block_bl");
1807  $wtpl->setVariable("BLOCK", $ui_renderer->render($secondary_panel));
1808  $wtpl->parseCurrentBlock();
1809  }
1810  }
1811 
1812  return $wtpl->get();
1813  }
1814 
1818  public function getKeywords(
1819  bool $a_show_inactive,
1820  ?int $a_posting_id = null
1821  ): array {
1822  $keywords = array();
1823  if ($a_posting_id) {
1824  foreach (ilBlogPosting::getKeywords($this->obj_id, $a_posting_id) as $keyword) {
1825  if (isset($keywords[$keyword])) {
1826  $keywords[$keyword]++;
1827  } else {
1828  $keywords[$keyword] = 1;
1829  }
1830  }
1831  } else {
1832  foreach ($this->items as $month => $items) {
1833  foreach ($items as $item) {
1834  if ($a_show_inactive || ilBlogPosting::_lookupActive($item["id"], "blp")) {
1835  foreach (ilBlogPosting::getKeywords($this->obj_id, $item["id"]) as $keyword) {
1836  if (isset($keywords[$keyword])) {
1837  $keywords[$keyword]++;
1838  } else {
1839  $keywords[$keyword] = 1;
1840  }
1841  }
1842  }
1843  }
1844  }
1845  }
1846 
1847  // #15881
1848  $tmp = array();
1849  foreach ($keywords as $keyword => $counter) {
1850  $tmp[] = array("keyword" => $keyword, "counter" => $counter);
1851  }
1852  $tmp = ilArrayUtil::sortArray($tmp, "keyword", "ASC");
1853 
1854  $keywords = array();
1855  foreach ($tmp as $item) {
1856  $keywords[(string) $item["keyword"]] = $item["counter"];
1857  }
1858  return $keywords;
1859  }
1860 
1864  public function buildExportFile(
1865  bool $a_include_comments = false,
1866  bool $print_version = false
1867  ): BlogHtmlExport {
1868  $type = "html";
1869  $format = explode("_", $this->blog_request->getFormat());
1870  if (($format[1] ?? "") === "comments" || $a_include_comments) {
1871  $a_include_comments = true;
1872  $type = "html_comments";
1873  }
1874 
1875  // create export file
1876  //ilExport::_createExportDirectory($this->object->getId(), $type, "blog");
1877  //$exp_dir = ilExport::_getExportDirectory($this->object->getId(), $type, "blog");
1878 
1879  $subdir = $this->object->getType() . "_" . $this->object->getId();
1880  if ($print_version) {
1881  $subdir .= "print";
1882  }
1883 
1884  $blog_export = new BlogHtmlExport($this, "", $subdir);
1885  $blog_export->setPrintVersion($print_version);
1886  $blog_export->includeComments($a_include_comments);
1887  $blog_export->exportHTML();
1888  return $blog_export;
1889  }
1890 
1891  public function getNotesSubId(): int
1892  {
1893  return $this->blpg;
1894  }
1895 
1896  public function disableNotes(bool $a_value = false): void
1897  {
1898  $this->disable_notes = $a_value;
1899  }
1900 
1901  protected function addHeaderActionForCommand(
1902  string $a_cmd
1903  ): void {
1904  $ilUser = $this->user;
1905  $ilCtrl = $this->ctrl;
1906  // preview?
1907  if ($a_cmd === "preview" || $a_cmd === "previewFullscreen" || $this->prvm) {
1908  // notification
1909  if ($ilUser->getId() !== ANONYMOUS_USER_ID) {
1910  if (!$this->prvm) {
1911  $ilCtrl->setParameter($this, "prvm", "fsc");
1912  }
1913  $this->insertHeaderAction($this->initHeaderAction(null, null, true));
1914  if (!$this->prvm) {
1915  $ilCtrl->setParameter($this, "prvm", "");
1916  }
1917  }
1918  } else {
1919  $this->addHeaderAction();
1920  }
1921  }
1922 
1923  protected function initHeaderAction(
1924  ?string $sub_type = null,
1925  ?int $sub_id = null,
1926  bool $is_preview = false
1927  ): ?ilObjectListGUI {
1928  $ilUser = $this->user;
1929  $ilCtrl = $this->ctrl;
1930  if (!$this->obj_id) {
1931  return null;
1932  }
1933  $sub_type = $sub_id = null;
1934  if ($this->blpg > 0) {
1935  $sub_type = "blp";
1936  $sub_id = $this->blpg;
1937  }
1938 
1939  $lg = parent::initHeaderAction($sub_type, $sub_id);
1940  if (!$lg) {
1941  return null;
1942  }
1943  $lg->enableComments(false);
1944  $lg->enableNotes(false);
1945 
1946  if ($is_preview) {
1947  if ($this->blpg > 0) {
1948  if (($this->object->getNotesStatus() && !$this->disable_notes)) {
1949  $lg->enableComments(true);
1950  }
1951  $lg->enableNotes(true);
1952  }
1953  $lg->enableTags(false);
1954 
1956  $ilCtrl->setParameter($this, "ntf", 1);
1957  $link = $ilCtrl->getLinkTarget($this, "setNotification");
1958  $ilCtrl->setParameter($this, "ntf", "");
1959  if (ilNotification::hasOptOut($this->obj_id)) {
1960  $lg->addCustomCommand($link, "blog_notification_toggle_off");
1961  }
1962 
1963  $lg->addHeaderIcon(
1964  "not_icon",
1965  ilUtil::getImagePath("object/notification_on.svg"),
1966  $this->lng->txt("blog_notification_activated")
1967  );
1968  } else {
1969  $ilCtrl->setParameter($this, "ntf", 2);
1970  $link = $ilCtrl->getLinkTarget($this, "setNotification");
1971  $ilCtrl->setParameter($this, "ntf", "");
1972  $lg->addCustomCommand($link, "blog_notification_toggle_on");
1973 
1974  $lg->addHeaderIcon(
1975  "not_icon",
1976  ilUtil::getImagePath("object/notification_off.svg"),
1977  $this->lng->txt("blog_notification_deactivated")
1978  );
1979  }
1980 
1981  // #11758
1982  if ($this->perm->mayContribute()) {
1983  $ilCtrl->setParameter($this, "prvm", "");
1984 
1985  $ilCtrl->setParameter($this, "bmn", "");
1986  $ilCtrl->setParameter($this, "blpg", "");
1987  $link = $ilCtrl->getLinkTarget($this, "");
1988  $ilCtrl->setParameter($this, "blpg", $sub_id);
1989  $ilCtrl->setParameter($this, "bmn", $this->month);
1990  $lg->addCustomCommand($link, "blog_edit"); // #11868
1991 
1992  if ($sub_id && $this->perm->mayEditPosting($sub_id)) {
1993  $link = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit");
1994  $lg->addCustomCommand($link, "blog_edit_posting");
1995  }
1996 
1997  $ilCtrl->setParameter($this, "prvm", "fsc");
1998  }
1999 
2000  $ilCtrl->setParameter($this, "ntf", "");
2001  }
2002 
2003  return $lg;
2004  }
2005 
2006  protected function setNotification(): void
2007  {
2008  $ilUser = $this->user;
2009  $ilCtrl = $this->ctrl;
2010 
2011  switch ($this->ntf) {
2012  case 1:
2014  break;
2015 
2016  case 2:
2018  break;
2019  }
2020 
2021  $ilCtrl->redirect($this, "preview");
2022  }
2023 
2027  public static function lookupSubObjectTitle(
2028  int $a_blog_id,
2029  int $a_posting_id
2030  ): string {
2031  // page might be deleted, so setting halt on errors to false
2032  $post = new ilBlogPosting($a_posting_id);
2033  if ($post->getBlogId() === $a_blog_id) {
2034  return $post->getTitle();
2035  }
2036  return "";
2037  }
2038 
2042  protected function filterInactivePostings(): void
2043  {
2044  foreach ($this->items as $month => $postings) {
2045  foreach ($postings as $id => $item) {
2046  if (!ilBlogPosting::_lookupActive($id, "blp")) {
2047  unset($this->items[$month][$id]);
2048  } elseif ($this->blog_settings->getApproval() && !$item["approved"]) {
2049  unset($this->items[$month][$id]);
2050  }
2051  }
2052  if (!count($this->items[$month])) {
2053  unset($this->items[$month]);
2054  }
2055  }
2056 
2057  if ($this->items && !isset($this->items[$this->month])) {
2058  $keys = array_keys($this->items);
2059  $this->month = array_shift($keys);
2060  }
2061  }
2062 
2063  public function filterItemsByKeyword(
2064  array $a_items,
2065  string $a_keyword
2066  ): array {
2067  $res = [];
2068  foreach ($a_items as $month => $items) {
2069  foreach ($items as $item) {
2070  if (in_array(
2071  $a_keyword,
2072  ilBlogPosting::getKeywords($this->obj_id, $item["id"])
2073  )) {
2074  $res[] = $item;
2075  }
2076  }
2077  }
2078  return $res;
2079  }
2080 
2081  protected function addLocatorItems(): void
2082  {
2083  $ilLocator = $this->locator;
2084 
2085  if (is_object($this->object)) {
2086  $ilLocator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, "preview"), "", $this->node_id);
2087  }
2088  }
2089 
2090  public function approve(): void
2091  {
2092  if ($this->perm->canManage() && $this->apid > 0) {
2093  $post = new ilBlogPosting($this->apid);
2094  $post->setApproved(true);
2095  $post->setBlogNodeId($this->node_id, ($this->id_type == self::WORKSPACE_NODE_ID));
2096  $post->update(true, false, true, "new"); // #13434
2097 
2098  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
2099  }
2100 
2101  $this->ctrl->redirect($this, "render");
2102  }
2103 
2104 
2105  //
2106  // contributors
2107  //
2108 
2109  public function contributors(): void
2110  {
2111  $ilTabs = $this->tabs;
2112  $ilToolbar = $this->toolbar;
2113  $ilCtrl = $this->ctrl;
2114  $lng = $this->lng;
2115  $tpl = $this->tpl;
2116 
2117  if (!$this->checkPermissionBool("write")) {
2118  return;
2119  }
2120 
2121  $ilTabs->activateTab("contributors");
2122 
2123  $local_roles = $this->object->getAllLocalRoles($this->node_id);
2124 
2125  // add member
2127  $this,
2128  $ilToolbar,
2129  array(
2130  'auto_complete_name' => $lng->txt('user'),
2131  'submit_name' => $lng->txt('add'),
2132  'add_search' => true,
2133  'add_from_container' => $this->node_id,
2134  'user_type' => $local_roles
2135  ),
2136  true
2137  );
2138 
2139  $other_roles = $this->object->getRolesWithContributeOrRedact($this->node_id);
2140  if ($other_roles) {
2141  $this->tpl->setOnScreenMessage('info', sprintf($lng->txt("blog_contribute_other_roles"), implode(", ", $other_roles)));
2142  }
2143 
2144  $table = $this->gui->contributor()->contributorTableBuilder(
2145  $this->object->getAllLocalRoles($this->node_id),
2146  $this,
2147  "contributors"
2148  )->getTable();
2149 
2150  if ($table->handleCommand()) {
2151  return;
2152  }
2153 
2154  $tpl->setContent($table->render());
2155  }
2156 
2160  public function addUserFromAutoComplete(): void
2161  {
2162  $lng = $this->lng;
2163 
2164  $user_login = $this->blog_request->getUserLogin();
2165  $user_type = $this->blog_request->getUserType();
2166 
2167  if (trim($user_login) === '') {
2168  $this->tpl->setOnScreenMessage('failure', $lng->txt('msg_no_search_string'));
2169  $this->contributors();
2170  return;
2171  }
2172  $users = explode(',', $user_login);
2173 
2174  $user_ids = array();
2175  foreach ($users as $user) {
2176  $user_id = ilObjUser::_lookupId($user);
2177 
2178  if (!$user_id) {
2179  $this->tpl->setOnScreenMessage('failure', $lng->txt('user_not_known'));
2180  $this->contributors();
2181  return;
2182  }
2183 
2184  $user_ids[] = (int) $user_id;
2185  }
2186 
2187  $this->addContributor($user_ids, $user_type);
2188  }
2189 
2193  public function addContributor(
2194  array $a_user_ids = array(),
2195  ?string $a_user_type = null
2196  ): void {
2197  $ilCtrl = $this->ctrl;
2198  $lng = $this->lng;
2199  $rbacreview = $this->rbac_review;
2200  $rbacadmin = $this->rbacadmin;
2201  $a_user_type = (int) $a_user_type;
2202 
2203  if (!$this->checkPermissionBool("write")) {
2204  return;
2205  }
2206 
2207  if (!count($a_user_ids) || !$a_user_type) {
2208  $this->tpl->setOnScreenMessage('failure', $lng->txt("no_checkbox"));
2209  $this->contributors();
2210  return;
2211  }
2212 
2213  // get contributor role
2214  $local_roles = array_keys($this->object->getAllLocalRoles($this->node_id));
2215  if (!in_array($a_user_type, $local_roles)) {
2216  $this->tpl->setOnScreenMessage('failure', $lng->txt("missing_perm"));
2217  $this->contributors();
2218  return;
2219  }
2220 
2221  foreach ($a_user_ids as $user_id) {
2222  $user_id = (int) $user_id;
2223  $a_user_type = (int) $a_user_type;
2224  if (!$rbacreview->isAssigned($user_id, $a_user_type)) {
2225  $rbacadmin->assignUser($a_user_type, $user_id);
2226  }
2227  }
2228 
2229  $this->tpl->setOnScreenMessage('success', $lng->txt("settings_saved"), true);
2230  $ilCtrl->redirect($this, "contributors");
2231  }
2232 
2236  public function confirmRemoveContributor(array $ids = []): void
2237  {
2238  if (empty($ids)) {
2239  $ids = $this->blog_request->getIds();
2240  }
2241  if (count($ids) === 0) {
2242  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
2243  $this->ctrl->redirect($this, "contributors");
2244  }
2245 
2246  $confirm = new ilConfirmationGUI();
2247  $confirm->setHeaderText($this->lng->txt('blog_confirm_delete_contributors'));
2248  $confirm->setFormAction($this->ctrl->getFormAction($this, 'removeContributor'));
2249  $confirm->setConfirm($this->lng->txt('delete'), 'removeContributor');
2250  $confirm->setCancel($this->lng->txt('cancel'), 'contributors');
2251 
2252  foreach ($ids as $user_id) {
2253  $confirm->addItem(
2254  'id[]',
2255  (string) $user_id,
2256  $this->profile_gui->getNamePresentation($user_id, false, "", true)
2257  );
2258  }
2259 
2260  $this->tpl->setContent($confirm->getHTML());
2261  }
2262 
2263  public function removeContributor(): void
2264  {
2265  $ilCtrl = $this->ctrl;
2266  $lng = $this->lng;
2267  $rbacadmin = $this->rbacadmin;
2268 
2269  $ids = $this->blog_request->getIds();
2270 
2271  if (count($ids) === 0) {
2272  $this->tpl->setOnScreenMessage('failure', $lng->txt("select_one"), true);
2273  $ilCtrl->redirect($this, "contributors");
2274  }
2275 
2276  // get contributor role
2277  $local_roles = array_keys($this->object->getAllLocalRoles($this->node_id));
2278  if (!$local_roles) {
2279  $this->tpl->setOnScreenMessage('failure', $lng->txt("missing_perm"));
2280  $this->contributors();
2281  return;
2282  }
2283 
2284  foreach ($ids as $user_id) {
2285  foreach ($local_roles as $role_id) {
2286  $rbacadmin->deassignUser($role_id, $user_id);
2287  }
2288  }
2289 
2290  $this->tpl->setOnScreenMessage('success', $lng->txt("settings_saved"), true);
2291  $this->ctrl->redirect($this, "contributors");
2292  }
2293 
2297  public function addContributorContainerAction(array $ids = []): void
2298  {
2299  if (empty($ids)) {
2300  $ids = $this->blog_request->getIds();
2301  }
2302 
2303  // This would typically add contributors from a container
2304  // For now, redirecting back to contributors as this seems to be a placeholder action
2305  $this->ctrl->redirect($this, "contributors");
2306  }
2307 
2308  public function deactivateAdmin(): void
2309  {
2310  if ($this->checkPermissionBool("write") && $this->apid > 0) {
2311  // ilBlogPostingGUI::deactivatePage()
2312  $post = new ilBlogPosting($this->apid);
2313  $post->setApproved(false);
2314  $post->setActive(false);
2315  $post->update(true, false, false);
2316 
2317  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
2318  }
2319 
2320  $this->ctrl->redirect($this, "render");
2321  }
2322 
2323 
2327 
2328  public function setContentStyleSheet(
2330  ): void {
2331  $tpl = $this->tpl;
2332 
2333  if ($a_tpl) {
2334  $ctpl = $a_tpl;
2335  } else {
2336  $ctpl = $tpl;
2337  }
2338 
2339  $this->content_style_gui->addCss(
2340  $ctpl,
2341  $this->object->getRefId(),
2342  $this->object->getId()
2343  );
2344  }
2345 
2349  protected function exportWithComments(): void
2350  {
2351  $this->export(true);
2352  }
2353 
2357 
2358  public function getPrintView(): \ILIAS\Export\PrintProcessGUI
2359  {
2360  $style_sheet_id = $this->content_style_domain->getEffectiveStyleId();
2361 
2363  $blog = $this->object;
2364  $provider = new \ILIAS\Blog\BlogPrintViewProviderGUI(
2365  $this->lng,
2366  $this->ctrl,
2367  $blog,
2368  $this->node_id,
2369  $this->access_handler,
2370  $style_sheet_id,
2371  $this->blog_request->getObjIds()
2372  );
2373 
2374  return new \ILIAS\Export\PrintProcessGUI(
2375  $provider,
2376  $this->http,
2377  $this->ui,
2378  $this->lng
2379  );
2380  }
2381 
2382  public function printViewSelection(): void
2383  {
2384  $view = $this->getPrintView();
2385  $view->sendForm();
2386  }
2387 
2388  public function printPostings(): void
2389  {
2390  $print_view = $this->getPrintView();
2391  $print_view->sendPrintView();
2392  }
2393 
2394  protected function forwardExport(): void
2395  {
2396  $this->ctrl->redirectByClass(ilExportGUI::class);
2397  }
2398 }
ilNavigationHistory $nav_history
setRightContent(string $a_html)
Sets content of right column.
setLocator()
set Locator
filterInactivePostings()
Filter inactive items from items list.
export(bool $a_with_comments=false)
Build and deliver export file.
ilRbacReview $rbac_review
static _lookupActive(int $a_id, string $a_parent_type, bool $a_check_scheduled_activation=false, string $a_lang="-")
lookup activation status
$res
Definition: ltiservices.php:66
Class ilObjectMetaDataGUI.
addUserFromAutoComplete()
Autocomplete submit.
renderNavigationByKeywords(string $a_list_cmd="render", bool $a_show_inactive=false, string $a_link_template="", int $a_blpg=0)
Build navigation by keywords block.
InternalGUIService $gui
Class ilBlogPosting.
const ANONYMOUS_USER_ID
Definition: constants.php:27
confirmRemoveContributor(array $ids=[])
Used in ContributorTableBuilder.
renderNavigation(string $a_list_cmd="render", string $a_posting_cmd="preview", ?string $a_link_template=null, bool $a_show_inactive=false, int $a_blpg=0)
Build navigation blocks.
preview()
Render fullscreen presentation.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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...
static _numericMonthToString(int $a_month, bool $a_long=true, ?ilLanguage $lng=null)
numeric month to string
static getAllPostings(int $a_blog_id, int $a_limit=1000, int $a_offset=0)
Get all postings of blog.
New implementation of ilObjectGUI.
GUI class for the workflow of copying objects.
addHeaderActionForCommand(string $a_cmd)
buildPostingList(int $a_obj_id)
Gather all blog postings.
insertHeaderAction(?ilObjectListGUI $list_gui=null)
Insert header action into main template.
ReadingTimeManager $reading_time_manager
Interface Observer Contains several chained tasks and infos about them.
renderNavigationByDate(array $a_items, string $a_list_cmd="render", string $a_posting_cmd="preview", ?string $a_link_template=null, bool $a_show_inactive=false, int $a_blpg=0)
Build navigation by date block.
Class ilBlogPosting GUI class.
addOnLoadCode(string $a_code, int $a_batch=2)
Add on load code.
checkAccess(string $a_permission, string $a_cmd, int $a_ref_id, string $a_type="", ?int $a_obj_id=null, ?int $a_tree_id=null)
check access for an object (provide $a_type and $a_obj_id if available for better performance) ...
Help GUI class.
ILIAS DI UIServices $ui
renderNavigationByAuthors(array $a_items, string $a_list_cmd="render", bool $a_show_inactive=false)
perm( $access_handler, ?int $node_id, int $id_type, int $user_id, int $owner)
assignUser(int $a_rol_id, int $a_usr_id)
Assigns an user to a role.
StandardGUIRequest $blog_request
exportWithComments()
Handle export choice.
static _lookupName(int $a_user_id)
lookup user name
static _lookupId($a_user_str)
setContent(string $a_html)
Sets content for standard template.
const NAV_MODE_LIST
setContentStyleSheet(?ilGlobalTemplateInterface $a_tpl=null)
prepareOutput(bool $show_sub_objects=true)
setTitle(string $a_title, bool $hidden=false)
Sets title in standard template.
$url
Definition: shib_logout.php:68
static getRelevanceClass(int $cnt, int $max)
static getSnippet(int $a_id, bool $a_truncate=false, int $a_truncate_length=500, string $a_truncate_sign="...", bool $a_include_picture=false, int $a_picture_width=144, int $a_picture_height=144, ?string $a_export_directory=null)
Get first text paragraph of page.
renderFullScreen(string $a_content, string $a_navigation)
Build fullscreen context.
Settings $blog_settings
setLocator()
Insert locator.
catch(\Exception $e) $req
Definition: xapiproxy.php:91
static deliverFileLegacy(string $a_file, ?string $a_filename=null, ?string $a_mime=null, ?bool $isInline=false, ?bool $removeAfterDelivery=false, ?bool $a_exit_after=true)
ILIAS Style Content GUIService $content_style_gui
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
ilToolbarGUI $toolbar
$provider
Definition: ltitoken.php:80
getListItems(bool $a_show_inactive=false)
Filter blog postings by month, keyword or author.
initHeaderAction(?string $sub_type=null, ?int $sub_id=null, bool $is_preview=false)
checkForParentType(int $a_ref_id, string $a_type, bool $a_exclude_source_check=false)
Check for parent type e.g check if a folder (ref_id 3) is in a parent course obj => checkForParentTyp...
static http()
Fetches the global http state from ILIAS.
UIFactory $ui_factory
addContributorContainerAction(array $ids=[])
Used in ContributorTableBuilder.
checkPermissionBool(string $perm, string $cmd="", string $type="", ?int $node_id=null)
static getNamePresentation( $a_user_id, bool $a_user_image=false, bool $a_profile_link=false, string $a_profile_back_link='', bool $a_force_first_lastname=false, bool $a_omit_login=false, bool $a_sortable=true, bool $a_return_data_array=false, $a_ctrl_path='ilpublicuserprofilegui')
Default behaviour is:
disableNotes(bool $a_value=false)
static setNotification(int $type, int $user_id, int $id, bool $status=true)
Set notification status for object and user.
ilObjBlogGUI: ilBlogPostingGUI, ilWorkspaceAccessGUI ilObjBlogGUI: ilInfoScreenGUI, ilNoteGUI, ilCommonActionDispatcherGUI ilObjBlogGUI: ilPermissionGUI, ilObjectCopyGUI, ilRepositorySearchGUI ilObjBlogGUI: ilExportGUI, ilObjectContentStyleSettingsGUI, ilBlogExerciseGUI, ilObjNotificationSettingsGUI ilObjBlogGUI: ilObjectMetaDataGUI ilObjBlogGUI: ILIAS ilObjBlogGUI: ILIAS
redirect(object $a_gui_obj, ?string $a_cmd=null, ?string $a_anchor=null, bool $is_async=false)
const CLIENT_ID
Definition: constants.php:41
static _recordReadEvent(string $a_type, int $a_ref_id, int $obj_id, int $usr_id, bool $isCatchupWriteEvents=true, $a_ext_rc=null, $a_ext_time=null)
global $DIC
Definition: shib_login.php:26
ProfileGUI $profile_gui
ILIAS Style Content Object ObjectFacade $content_style_domain
ilGlobalTemplateInterface $tpl
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
afterSave(ilObject $new_object)
render()
Render object context.
ContextServices $tool_context
resetHeaderBlock(bool $a_reset_header_action=true)
Reset all header properties: title, icon, description, alerts, action menu.
getParentId(int $a_node_id)
get parent id of given node
buildExportFile(bool $a_include_comments=false, bool $print_version=false)
Build export file.
InternalDomainService $domain
setSettingsSubTabs(string $a_active)
loadStandardTemplate()
This loads the standard template "tpl.adm_content.html" and "tpl.statusline.html" the CONTENT and STA...
getKeywords(bool $a_show_inactive, ?int $a_posting_id=null)
Get keywords for single posting or complete blog.
setTitleIcon(string $a_icon_path, string $a_icon_desc="")
set title icon
renderFullscreenHeader(ilGlobalTemplateInterface $a_tpl, int $a_user_id, bool $a_export=false)
Last visited history for repository items.
static get(string $a_type, string $a_href="")
Get icon html.
checkPermission(string $perm, string $cmd="", string $type="", ?int $ref_id=null)
ProfileAdapter $profile
PermissionManager $perm
createPosting()
Create new posting.
static lookupBlogId(int $a_posting_id)
static _getPersonalPicturePath(int $a_usr_id, string $a_size='small', bool $a_force_pic=false, bool $a_prevent_no_photo_image=false, bool $html_export=false)
ILIAS Blog ReadingTime BlogSettingsGUI $reading_time_gui
activateTab(string $a_id)
const IL_CAL_DATE
setDescription(string $a_descr)
Sets description below title in standard template.
infoScreen()
this one is called from the info button in the repository
addCss(string $a_css_file, string $media="screen")
Add a css file that should be included in the header.
global $ilSetting
Definition: privfeed.php:31
addContributor(array $a_user_ids=array(), ?string $a_user_type=null)
Centralized method to add contributors.
static fillAutoCompleteToolbar(object $parent_object, ?ilToolbarGUI $toolbar=null, array $a_options=[], bool $a_sticky=false)
array( auto_complete_name = $lng->txt(&#39;user&#39;), auto_complete_size = 15, user_type = array(ilCoursePar...
__construct(Container $dic, ilPlugin $plugin)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
static hasNotification(int $type, int $user_id, int $id)
Check notification status for object and user.
static lookupSubObjectTitle(int $a_blog_id, int $a_posting_id)
Get title for blog posting (used in ilNotesGUI)
ilLocatorGUI $locator
static getKeywords(int $a_obj_id, int $a_posting_id)
filterItemsByKeyword(array $a_items, string $a_keyword)
renderToolbarNavigation(array $a_items, bool $single_posting=false)
Toolbar navigation.
$info
Definition: entry_point.php:21
const CMD_LIST_EXPORT_FILES
Class ilRbacAdmin Core functions for role based access control.
setParameter(object $a_gui_obj, string $a_parameter, $a_value)
renderList(array $items, string $a_cmd="preview", string $a_link_template="", bool $a_show_inactive=false, string $a_export_directory="")
Build posting month list.
static _lookupType(int $id, bool $reference=false)
ilRbacAdmin $rbacadmin
$post
Definition: ltitoken.php:46
addHeaderAction()
Add header action menu.
$service
Definition: ltiservices.php:40
UIRenderer $ui_renderer
ilSetting $settings
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
buildExportLink(string $a_template, string $a_type, string $a_id)
Build export link.
__construct(int $a_id=0, int $a_id_type=self::REPOSITORY_NODE_ID, int $a_parent_node_id=0)
deassignUser(int $a_rol_id, int $a_usr_id)
Deassigns a user from a role.
ILIAS Notes Service $notes
ilAccessHandler $access
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
static hasOptOut(int $obj_id)
Is opt out (disable notification) allowed?