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