ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
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  // @todo: removed deprecated ilCtrl methods, this needs inspection by a maintainer.
599  // $ilCtrl->setCmd($cmd);
600  }
601  $this->addHeaderActionForCommand($cmd);
602  }
603  parent::executeCommand();
604  }
605  }
606 
607  protected function showExportGUI(): void
608  {
609  $this->prepareOutput();
610  $this->tabs->activateTab("export");
611  $exp_gui = new ilExportGUI($this);
612  $this->ctrl->forwardCommand($exp_gui);
613  }
614 
615  protected function createExportFileWithComments(): void
616  {
617  $this->buildExportFile(true);
618  $this->prepareOutput();
619  $this->tabs->activateTab("export");
620  $this->ctrl->redirectByClass(ilExportGUI::class, ilExportGUI::CMD_LIST_EXPORT_FILES);
621  }
622 
623  protected function createExportFile(): void
624  {
625  $this->buildExportFile();
626  $this->prepareOutput();
627  $this->tabs->activateTab("export");
628  $this->ctrl->redirectByClass(ilExportGUI::class, ilExportGUI::CMD_LIST_EXPORT_FILES);
629  }
630 
631  protected function triggerAssignmentTool(): void
632  {
633  $be = $this->domain->exercise($this->node_id);
634  $be_gui = $this->gui->exercise()->ilBlogExerciseGUI($this->node_id);
635  $assignments = $be->getAssignmentsOfBlog();
636  if (count($assignments) > 0) {
637  $ass_ids = array_map(static function ($i) {
638  return $i["ass_id"];
639  }, $assignments);
640  $this->tool_context->current()->addAdditionalData(ilExerciseGSToolProvider::SHOW_EXC_ASSIGNMENT_INFO, true);
641  $this->tool_context->current()->addAdditionalData(ilExerciseGSToolProvider::EXC_ASS_IDS, $ass_ids);
642  $this->tool_context->current()->addAdditionalData(
644  $be_gui->getActionButtons()
645  );
646  }
647  }
648 
652  public function infoScreen(): void
653  {
654  $this->ctrl->redirectByClass(ilInfoScreenGUI::class, "showSummary");
655  }
656 
657  public function infoScreenForward(): void
658  {
659  $ilTabs = $this->tabs;
660 
661  $ilTabs->activateTab("id_info");
662 
663  $this->checkPermission("visible");
664 
665  $info = new ilInfoScreenGUI($this);
666 
667  if ($this->id_type !== self::WORKSPACE_NODE_ID) {
668  $info->enablePrivateNotes();
669  }
670 
671  if ($this->checkPermissionBool("read")) {
672  $info->enableNews();
673  }
674 
675  // no news editing for files, just notifications
676  $info->enableNewsEditing(false);
677  if ($this->checkPermissionBool("write")) {
678  $news_set = new ilSetting("news");
679  $enable_internal_rss = $news_set->get("enable_rss_for_internal");
680 
681  if ($enable_internal_rss) {
682  $info->setBlockProperty("news", "settings", "1");
683  $info->setBlockProperty("news", "public_notifications_option", "1");
684  }
685  }
686 
687  // standard meta data
688  $info->addMetaDataSections($this->object->getId(), 0, $this->object->getType());
689 
690  $this->ctrl->forwardCommand($info);
691  }
692 
696  public function createPosting(): void
697  {
698  $ilCtrl = $this->ctrl;
699  $ilUser = $this->user;
700 
701  $title = $this->blog_request->getTitle();
702  if ($title) {
703  // create new posting
704  $posting = new ilBlogPosting();
705  $posting->setTitle($title);
706  $posting->setBlogId($this->object->getId());
707  $posting->setActive(false);
708  $posting->setAuthor($ilUser->getId());
709  $posting->create(false);
710 
711  // switch month list to current month (will include new posting)
712  $ilCtrl->setParameter($this, "bmn", date("Y-m"));
713 
714  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $posting->getId());
715  $ilCtrl->redirectByClass("ilblogpostinggui", "edit");
716  } else {
717  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("msg_no_title"), true);
718  $ilCtrl->redirect($this, "render");
719  }
720  }
721 
725  public function render(): void
726  {
727  $tpl = $this->tpl;
728  $ilTabs = $this->tabs;
729  $ilCtrl = $this->ctrl;
730  $lng = $this->lng;
731  $ilToolbar = new ilToolbarGUI();
732 
733  if (!$this->checkPermissionBool("read")) {
734  $this->tpl->setOnScreenMessage('info', $lng->txt("no_permission"));
735  return;
736  }
737 
738  $ilTabs->activateTab("content");
739 
740  // toolbar
741  if ($this->blog_access->mayContribute()) {
742  $ilToolbar->setFormAction($ilCtrl->getFormAction($this, "createPosting"));
743 
744  $title = new ilTextInputGUI($lng->txt("title"), "title");
745  $title->setSize(30);
746  $ilToolbar->addStickyItem($title, true);
748  document.getElementById('title').setAttribute('data-blog-input', 'posting-title');
749  document.getElementById('title').setAttribute('placeholder', ' ');
750  ");
751 
752  $this->gui->button(
753  $lng->txt("blog_add_posting"),
754  "createPosting"
755  )->submit()->toToolbar(true, $ilToolbar);
756 
757  // #18763
758  $keys = array_keys($this->items);
759  $first = array_shift($keys);
760  if ($first != $this->month) {
761  $ilToolbar->addSeparator();
762 
763  $ilCtrl->setParameter($this, "bmn", $first);
764  $url = $ilCtrl->getLinkTarget($this, "");
765  $ilCtrl->setParameter($this, "bmn", $this->month);
766 
767  $this->gui->link(
768  $lng->txt("blog_show_latest"),
769  $url
770  )->emphasised()->toToolbar(true, $ilToolbar);
771  }
772 
773  // print/pdf
774  $print_view = $this->getPrintView();
775  $modal_elements = $print_view->getModalElements(
776  $this->ctrl->getLinkTarget(
777  $this,
778  "printViewSelection"
779  )
780  );
781  $ilToolbar->addSeparator();
782  $ilToolbar->addComponent($modal_elements->button);
783  $ilToolbar->addComponent($modal_elements->modal);
784  }
785 
786  // $is_owner = ($this->object->getOwner() == $ilUser->getId());
787  $is_owner = $this->blog_access->mayContribute();
788 
789  $list_items = $this->getListItems($is_owner);
790 
791  $list = $nav = "";
792  if ($list_items) {
793  $list = $this->renderList($list_items, "preview", "", $is_owner);
794  $nav = $this->renderNavigation("render", "edit", "", $is_owner);
795  }
796 
797  $this->setContentStyleSheet();
798 
799  $tpl->setContent($ilToolbar->getHTML() . $list);
800  $tpl->setRightContent($nav);
801  }
802 
803 
807  protected function getListItems(
808  bool $a_show_inactive = false
809  ): array {
810  if ($this->author) {
811  $list_items = array();
812  foreach ($this->items as $month => $items) {
813  foreach ($items as $id => $item) {
814  if ($item["author"] == $this->author ||
815  (isset($item["editors"]) && in_array($this->author, $item["editors"]))) {
816  $list_items[$id] = $item;
817  }
818  }
819  }
820  } elseif ($this->keyword) {
821  $list_items = $this->filterItemsByKeyword($this->items, $this->keyword);
822  } else {
823  $max = $this->blog_settings->getOverviewPostings();
824  if ($this->month_default && $max) {
825  $list_items = array();
826  foreach ($this->items as $month => $postings) {
827  foreach ($postings as $id => $item) {
828  if (!$a_show_inactive &&
830  continue;
831  }
832  $list_items[$id] = $item;
833 
834  if (count($list_items) >= $max) {
835  break(2);
836  }
837  }
838  }
839  } else {
840  $list_items = $this->items[$this->month] ?? [];
841  }
842  }
843  return $list_items;
844  }
845 
849  public function preview(): void
850  {
851  $lng = $this->lng;
853 
854  if (!$this->checkPermissionBool("read")) {
855  $this->tpl->setOnScreenMessage('info', $lng->txt("no_permission"));
856  return;
857  }
858 
859  $this->filterInactivePostings();
860 
861  $list_items = $this->getListItems();
862 
863  $list = $nav = "";
864  if ($list_items) {
865  $list = $this->renderList($list_items, "previewFullscreen");
866  $nav = $this->renderNavigation("preview", "previewFullscreen");
867  $this->renderToolbarNavigation($this->items);
868  }
869 
870  $this->renderFullScreen($list, $nav);
871  }
872 
876  public function export(
877  bool $a_with_comments = false
878  ): void {
879  $zip = $this->buildExportFile($a_with_comments);
880  ilFileDelivery::deliverFileLegacy($zip, $this->object->getTitle() . ".zip", '', false, true);
881  }
882 
883 
884  // --- helper functions
885 
889  public function renderFullScreen(
890  string $a_content,
891  string $a_navigation
892  ): void {
893  $tpl = $this->tpl;
894  $ilUser = $this->user;
895  $ilTabs = $this->tabs;
896  $ilLocator = $this->locator;
897 
898  $owner = $this->object->getOwner();
899 
900  $ilTabs->clearTargets();
901  $tpl->setLocator();
902 
903  $back_caption = "";
904  $back = "";
905 
906  // back (edit)
907  if ($owner === $ilUser->getId()) {
908  // from shared/deeplink
909  if ($this->id_type === self::WORKSPACE_NODE_ID) {
910  $back = "ilias.php?baseClass=ilDashboardGUI&cmd=jumpToWorkspace&wsp_id=" . $this->node_id;
911  }
912  // from editor (#10073)
913  elseif ($this->blog_access->mayContribute()) {
914  $this->ctrl->setParameter($this, "prvm", "");
915  if ($this->blpg === 0) {
916  $back = $this->ctrl->getLinkTarget($this, "");
917  } else {
918  $this->ctrl->setParameterByClass("ilblogpostinggui", "bmn", $this->month);
919  $this->ctrl->setParameterByClass("ilblogpostinggui", "blpg", $this->blpg);
920  $back = $this->ctrl->getLinkTargetByClass("ilblogpostinggui", "preview");
921  }
922  $this->ctrl->setParameter($this, "prvm", $this->prvm);
923  }
924 
925  $back_caption = $this->lng->txt("blog_back_to_blog_owner");
926  }
927  // back
928  elseif ($ilUser->getId() && $ilUser->getId() !== ANONYMOUS_USER_ID) {
929  // workspace (always shared)
930  if ($this->id_type === self::WORKSPACE_NODE_ID) {
931  $back = "ilias.php?baseClass=ilDashboardGUI&cmd=jumpToWorkspace&dsh=" . $owner;
932  }
933  // contributor
934  elseif ($this->blog_access->mayContribute()) {
935  $back = $this->ctrl->getLinkTarget($this, "");
936  $back_caption = $this->lng->txt("blog_back_to_blog_owner");
937  }
938  // listgui / parent container
939  else {
940  $tree = $this->tree;
941  $parent_id = $tree->getParentId($this->node_id);
943  }
944  }
945 
946  $this->renderFullscreenHeader($tpl, $owner);
947 
948  // #13564
949  $this->ctrl->setParameter($this, "bmn", "");
950  //$tpl->setTitleUrl($this->ctrl->getLinkTarget($this, "preview"));
951  $this->ctrl->setParameter($this, "bmn", $this->month);
952 
953  $this->setContentStyleSheet();
954 
955  // content
956  $tpl->setContent($a_content);
957  $tpl->setRightContent($a_navigation);
958  }
959 
960  public function renderFullscreenHeader(
962  int $a_user_id,
963  bool $a_export = false
964  ): void {
965  $ilUser = $this->user;
966 
967  if (!$a_export) {
969  $this->object->getType(),
971  $this->object->getId(),
972  $ilUser->getId()
973  );
974  }
975 
976  // repository blogs are multi-author
977  $name = "";
978  if ($this->id_type !== self::REPOSITORY_NODE_ID) {
979  $name = ilObjUser::_lookupName($a_user_id);
980  $name = $name["lastname"] . ", " . $name["firstname"];
981  }
982 
983  $ppic = "";
984  if ($this->blog_settings?->getProfilePicture()) {
985  // repository (multi-user)
986  if ($this->id_type === self::REPOSITORY_NODE_ID) {
987  // #15030
988  if ($this->blpg > 0 && !$a_export) {
989  $post = new ilBlogPosting($this->blpg);
990  $author_id = $post->getAuthor();
991  if ($author_id) {
992  $ppic = $this->profile_gui->getPicturePath($author_id);
993  $name = $this->profile_gui->getNamePresentation($author_id);
994  //$name = $name["lastname"] . ", " . $name["firstname"];
995  }
996  }
997  }
998  // workspace (author == owner)
999  else {
1000  $ppic = ilObjUser::_getPersonalPicturePath($a_user_id, "xsmall", true, true);
1001  if ($a_export) {
1002  $ppic = basename($ppic);
1003  }
1004  }
1005  }
1006  $a_tpl->resetHeaderBlock(false);
1007  $a_tpl->setTitleIcon($ppic);
1008  $a_tpl->setTitle($this->object->getTitle());
1009  if ($this->id_type === self::REPOSITORY_NODE_ID) {
1010  $a_tpl->setDescription($this->object->getDescription());
1011  } else {
1012  $a_tpl->setDescription($name);
1013  }
1014  }
1015 
1019  protected function buildPostingList(
1020  int $a_obj_id
1021  ): array {
1022  $author_found = false;
1023 
1024  $items = array();
1025  foreach (ilBlogPosting::getAllPostings($a_obj_id) as $posting) {
1026  if ($this->author &&
1027  ($posting["author"] == $this->author ||
1028  (is_array($posting["editors"] ?? false) && in_array($this->author, $posting["editors"])))) {
1029  $author_found = true;
1030  }
1031 
1032  $month = substr($posting["created"]->get(IL_CAL_DATE), 0, 7);
1033  $items[$month][$posting["id"]] = $posting;
1034  }
1035 
1036  if ($this->author && !$author_found) {
1037  $this->author = null;
1038  }
1039 
1040  return $items;
1041  }
1042 
1046  public function renderList(
1047  array $items,
1048  string $a_cmd = "preview",
1049  string $a_link_template = "",
1050  bool $a_show_inactive = false,
1051  string $a_export_directory = ""
1052  ): string {
1053  $lng = $this->lng;
1054  $ilCtrl = $this->ctrl;
1055  $ilUser = $this->user;
1056  $ui_factory = $this->ui->factory();
1057  $ui_renderer = $this->ui->renderer();
1058 
1059  $wtpl = new ilTemplate("tpl.blog_list.html", true, true, "components/ILIAS/Blog");
1060 
1061  $is_admin = $this->isAdmin();
1062 
1063  $last_month = null;
1064  $is_empty = true;
1065  foreach ($items as $item) {
1066  // only published items
1067  $is_active = ilBlogPosting::_lookupActive($item["id"], "blp");
1068  if (!$is_active && !$a_show_inactive) {
1069  continue;
1070  }
1071 
1072  $is_empty = false;
1073 
1074  $month = "";
1075  if (!$this->keyword && !$this->author) {
1076  $month = substr($item["created"]->get(IL_CAL_DATE), 0, 7);
1077  }
1078 
1079  if (!$last_month || $last_month != $month) {
1080  if ($last_month) {
1081  $wtpl->setCurrentBlock("month_bl");
1082  $wtpl->parseCurrentBlock();
1083  }
1084 
1085  // title according to current "filter"/navigation
1086  if ($this->keyword) {
1087  $title = $lng->txt("blog_keyword") . ": " . $this->keyword;
1088  } elseif ($this->author) {
1089  $title = $lng->txt("blog_author") . ": " . $this->profile_gui->getNamePresentation($this->author);
1090  } else {
1091  $title = $this->gui->presentation()->util()->getMonthPresentation($month);
1092  $last_month = $month;
1093  }
1094 
1095  $wtpl->setVariable("TXT_CURRENT_MONTH", $title);
1096  }
1097 
1098  if (!$a_link_template) {
1099  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $this->month);
1100  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $item["id"]);
1101  $preview = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_cmd);
1102  } else {
1103  $preview = $this->buildExportLink($a_link_template, "posting", (string) $item["id"]);
1104  }
1105  $more_link = $preview;
1106 
1107  // actions
1108  $posting_edit = $this->blog_access->mayEditPosting($item["id"], $item["author"]);
1109  if (($posting_edit || $is_admin) && !$a_link_template && $a_cmd === "preview") {
1110  $actions = [];
1111 
1112  if ($is_active && $this->blog_settings->getApproval() && !$item["approved"]) {
1113  if ($is_admin) {
1114  $ilCtrl->setParameter($this, "apid", $item["id"]);
1115  $actions[] = $ui_factory->link()->standard(
1116  $lng->txt("blog_approve"),
1117  $ilCtrl->getLinkTarget($this, "approve")
1118  );
1119  $ilCtrl->setParameter($this, "apid", "");
1120  }
1121 
1122  $wtpl->setVariable("APPROVAL", $lng->txt("blog_needs_approval"));
1123  }
1124 
1125  if ($posting_edit) {
1126  $actions[] = $ui_factory->link()->standard(
1127  $lng->txt("edit_content"),
1128  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit")
1129  );
1130  $more_link = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit");
1131 
1132  // #11858
1133  if ($is_active) {
1134  $actions[] = $ui_factory->link()->standard(
1135  $lng->txt("blog_toggle_draft"),
1136  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deactivatePageToList")
1137  );
1138  } else {
1139  $actions[] = $ui_factory->link()->standard(
1140  $lng->txt("blog_toggle_final"),
1141  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "activatePageToList")
1142  );
1143  }
1144 
1145  $actions[] = $ui_factory->link()->standard(
1146  $lng->txt("rename"),
1147  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edittitle")
1148  );
1149 
1150  if ($this->blog_settings->getKeywords()) { // #13616
1151  $actions[] = $ui_factory->link()->standard(
1152  $lng->txt("blog_edit_keywords"),
1153  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "editKeywords")
1154  );
1155  }
1156 
1157  $actions[] = $ui_factory->link()->standard(
1158  $lng->txt("blog_edit_date"),
1159  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "editdate")
1160  );
1161 
1162  $actions[] = $ui_factory->link()->standard(
1163  $lng->txt("delete"),
1164  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deleteBlogPostingConfirmationScreen")
1165  );
1166  } elseif ($is_admin) {
1167  // #10513
1168  if ($is_active) {
1169  $ilCtrl->setParameter($this, "apid", $item["id"]);
1170  $actions[] = $ui_factory->link()->standard(
1171  $lng->txt("blog_toggle_draft_admin"),
1172  $ilCtrl->getLinkTarget($this, "deactivateAdmin")
1173  );
1174  $ilCtrl->setParameter($this, "apid", "");
1175  }
1176 
1177  $actions[] = $ui_factory->link()->standard(
1178  $lng->txt("delete"),
1179  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deleteBlogPostingConfirmationScreen")
1180  );
1181  }
1182 
1183  $dd = $ui_factory->dropdown()->standard($actions)->withLabel($this->lng->txt("actions"));
1184 
1185  $wtpl->setCurrentBlock("actions");
1186  $wtpl->setVariable("ACTION_SELECTOR", $ui_renderer->render($dd));
1187  $wtpl->parseCurrentBlock();
1188  }
1189 
1190  // comments
1191  if ($this->object->getNotesStatus() && !$a_link_template && !$this->disable_notes) {
1192  // count (public) notes
1193  $notes_context = $this->notes
1194  ->data()
1195  ->context(
1196  $this->obj_id,
1197  (int) $item["id"],
1198  "blp"
1199  );
1200  $count = $this->notes
1201  ->domain()
1202  ->getNrOfCommentsForContext($notes_context);
1203 
1204  if ($a_cmd !== "preview") {
1205  $wtpl->setCurrentBlock("comments");
1206  $wtpl->setVariable("TEXT_COMMENTS", $lng->txt("blog_comments"));
1207  $wtpl->setVariable("URL_COMMENTS", $preview);
1208  $wtpl->setVariable("COUNT_COMMENTS", $count);
1209  $wtpl->parseCurrentBlock();
1210  }
1211  }
1212 
1213  // permanent link
1214  if ($a_cmd !== "preview") {
1215  if ($this->id_type === self::WORKSPACE_NODE_ID) {
1216  $goto = $this->gui->permanentLink(0, $this->node_id)->getPermanentLink((int) $item["id"]);
1217  } else {
1218  $goto = $this->gui->permanentLink($this->node_id)->getPermanentLink((int) $item["id"]);
1219  }
1220  $wtpl->setCurrentBlock("permalink");
1221  $wtpl->setVariable("URL_PERMALINK", $goto);
1222  $wtpl->setVariable("TEXT_PERMALINK", $lng->txt("blog_link"));
1223  $wtpl->parseCurrentBlock();
1224  }
1225 
1226  $snippet = ilBlogPostingGUI::getSnippet(
1227  $item["id"],
1228  $this->blog_settings->getAbstractShorten(),
1229  $this->blog_settings->getAbstractShortenLength(),
1230  "&hellip;",
1231  $this->blog_settings->getAbstractImage(),
1232  $this->blog_settings->getAbstractImageWidth(),
1233  $this->blog_settings->getAbstractImageHeight(),
1234  $a_export_directory
1235  );
1236 
1237  if ($snippet) {
1238  $wtpl->setCurrentBlock("more");
1239  $wtpl->setVariable("URL_MORE", $more_link);
1240  $wtpl->setVariable("TEXT_MORE", $lng->txt("blog_list_more"));
1241  $wtpl->parseCurrentBlock();
1242  }
1243 
1244 
1245 
1246  if (!$is_active) {
1247  $wtpl->setCurrentBlock("draft_text");
1248  $wtpl->setVariable("DRAFT_TEXT", $lng->txt("blog_draft_text"));
1249  $wtpl->parseCurrentBlock();
1250  $wtpl->setVariable("DRAFT_CLASS", " ilBlogListItemDraft");
1251  }
1252 
1253  // reading time
1254  $reading_time = $this->reading_time_manager->getReadingTime(
1255  $this->object->getId(),
1256  $item["id"]
1257  );
1258  if (!is_null($reading_time)) {
1259  $this->lng->loadLanguageModule("copg");
1260  $wtpl->setCurrentBlock("reading_time");
1261  $wtpl->setVariable(
1262  "READING_TIME",
1263  $this->lng->txt("copg_est_reading_time") . ": " .
1264  sprintf($this->lng->txt("copg_x_minutes"), $reading_time)
1265  );
1266  $wtpl->parseCurrentBlock();
1267  }
1268 
1269  $wtpl->setCurrentBlock("posting");
1270 
1271  $author = "";
1272  if ($this->id_type === self::REPOSITORY_NODE_ID) {
1273  $authors = array();
1274 
1275  $author_id = $item["author"];
1276  if ($author_id) {
1277  $authors[] = $this->profile_gui->getNamePresentation($author_id);
1278  }
1279 
1280  if (isset($item["editors"])) {
1281  foreach ($item["editors"] as $editor_id) {
1282  $authors[] = $this->profile_gui->getNamePresentation($editor_id);
1283  }
1284  }
1285 
1286  if ($authors) {
1287  $author = implode(", ", $authors) . " - ";
1288  }
1289  }
1290 
1291  // title
1292  $wtpl->setVariable("URL_TITLE", $preview);
1293  $wtpl->setVariable("TITLE", $item["title"]);
1294 
1295  $kw = ilBlogPosting::getKeywords($this->obj_id, $item["id"]);
1296  natcasesort($kw);
1297  $keywords = (count($kw) > 0)
1298  ? "<br>" . $this->lng->txt("keywords") . ": " . implode(", ", $kw)
1299  : "";
1300 
1301  $wtpl->setVariable("DATETIME", $author .
1302  ilDatePresentation::formatDate($item["created"]) . $keywords);
1303 
1304  // content
1305  $wtpl->setVariable("CONTENT", $snippet);
1306 
1307  $wtpl->parseCurrentBlock();
1308  }
1309 
1310  // permalink
1311  if ($a_cmd === "previewFullscreen") {
1312  $ref_id = ($this->id_type === self::WORKSPACE_NODE_ID)
1313  ? 0
1314  : $this->node_id;
1315  $wsp_id = ($this->id_type === self::WORKSPACE_NODE_ID)
1316  ? $this->node_id
1317  : 0;
1318  $this->gui->permanentLink($ref_id, $wsp_id)->setPermanentLink();
1319  }
1320 
1321  if (!$is_empty || $a_show_inactive) {
1322  return $wtpl->get();
1323  }
1324  return "";
1325  }
1326 
1330  protected function buildExportLink(
1331  string $a_template,
1332  string $a_type,
1333  string $a_id
1334  ): string {
1335  return BlogHtmlExport::buildExportLink($a_template, $a_type, $a_id, $this->getKeywords(false));
1336  }
1337 
1338 
1342  protected function renderNavigationByDate(
1343  array $a_items,
1344  string $a_list_cmd = "render",
1345  string $a_posting_cmd = "preview",
1346  ?string $a_link_template = null,
1347  bool $a_show_inactive = false,
1348  int $a_blpg = 0
1349  ): string {
1350  $ilCtrl = $this->ctrl;
1351 
1352  $blpg = ($a_blpg > 0)
1353  ? $a_blpg
1354  : $this->blpg;
1355 
1356 
1357  // gather page active status
1358  foreach ($a_items as $month => $postings) {
1359  foreach (array_keys($postings) as $id) {
1360  $active = ilBlogPosting::_lookupActive($id, "blp");
1361  if (!$a_show_inactive && !$active) {
1362  unset($a_items[$month][$id]);
1363  } else {
1364  $a_items[$month][$id]["active"] = $active;
1365  }
1366  }
1367  if (!count($a_items[$month])) {
1368  unset($a_items[$month]);
1369  }
1370  }
1371 
1372  // list month (incl. postings)
1373  if ($this->blog_settings->getNavMode() === ilObjBlog::NAV_MODE_LIST || $a_link_template) {
1374  $max_months = $this->blog_settings->getNavModeListMonths();
1375 
1376  $wtpl = new ilTemplate("tpl.blog_list_navigation_by_date.html", true, true, "components/ILIAS/Blog");
1377 
1378  $ilCtrl->setParameter($this, "blpg", "");
1379 
1380  $counter = $mon_counter = $last_year = 0;
1381  foreach ($a_items as $month => $postings) {
1382  if (!$a_link_template && $max_months && $mon_counter >= $max_months) {
1383  break;
1384  }
1385 
1386  $add_year = false;
1387  $year = substr($month, 0, 4);
1388  if (!$last_year || $year != $last_year) {
1389  // #13562
1390  $add_year = true;
1391  $last_year = $year;
1392  }
1393 
1394  $mon_counter++;
1395 
1396  $month_name = ilCalendarUtil::_numericMonthToString((int) substr($month, 5));
1397  if (!$a_link_template) {
1398  $ilCtrl->setParameter($this, "bmn", $month);
1399  $month_url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1400  } else {
1401  $month_url = $this->buildExportLink($a_link_template, "list", (string) $month);
1402  }
1403 
1404  // list postings for month
1405  //if($counter < $max_detail_postings)
1406  if ($mon_counter <= $this->blog_settings->getNavModeListMonthsWithPostings()) {
1407  if ($add_year) {
1408  $wtpl->setCurrentBlock("navigation_year_details");
1409  $wtpl->setVariable("YEAR", $year);
1410  $wtpl->parseCurrentBlock();
1411  }
1412 
1413  foreach ($postings as $id => $posting) {
1414  //if($max_detail_postings && $counter >= $max_detail_postings)
1415  //{
1416  // break;
1417  //}
1418 
1419  $counter++;
1420 
1421  $caption = /* ilDatePresentation::formatDate($posting["created"], IL_CAL_DATETIME).
1422  ", ".*/ $posting["title"];
1423 
1424  if (!$a_link_template) {
1425  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $month);
1426  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $id);
1427  $url = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_posting_cmd);
1428  } else {
1429  $url = $this->buildExportLink($a_link_template, "posting", (string) $id);
1430  }
1431 
1432  if (!$posting["active"]) {
1433  $wtpl->setVariable("NAV_ITEM_DRAFT", $this->lng->txt("blog_draft"));
1434  } elseif ($this->blog_settings->getApproval() && !$posting["approved"]) {
1435  $wtpl->setVariable("NAV_ITEM_APPROVAL", $this->lng->txt("blog_needs_approval"));
1436  }
1437 
1438  $wtpl->setCurrentBlock("navigation_item");
1439  $wtpl->setVariable("NAV_ITEM_URL", $url);
1440  $wtpl->setVariable("NAV_ITEM_CAPTION", $caption);
1441  $wtpl->parseCurrentBlock();
1442  }
1443 
1444  $wtpl->setCurrentBlock("navigation_month_details");
1445  $wtpl->setVariable("NAV_MONTH", $month_name);
1446  $wtpl->setVariable("URL_MONTH", $month_url);
1447  }
1448  // summarized month
1449  else {
1450  if ($add_year) {
1451  $wtpl->setCurrentBlock("navigation_year");
1452  $wtpl->setVariable("YEAR", $year);
1453  $wtpl->parseCurrentBlock();
1454  }
1455 
1456  $wtpl->setCurrentBlock("navigation_month");
1457  $wtpl->setVariable("MONTH_NAME", $month_name);
1458  $wtpl->setVariable("URL_MONTH", $month_url);
1459  $wtpl->setVariable("MONTH_COUNT", count($postings));
1460  }
1461  $wtpl->parseCurrentBlock();
1462  }
1463  if (!$a_link_template) {
1464  $this->ctrl->setParameterByClass(self::class, "bmn", null);
1465  $url = $this->ctrl->getLinkTargetByClass(self::class, $a_list_cmd);
1466  } else {
1467  $url = "index.html";
1468  }
1469 
1470  $wtpl->setVariable(
1471  "STARTING_PAGE",
1472  $this->ui->renderer()->render(
1473  $this->ui->factory()->link()->standard(
1474  $this->lng->txt("blog_starting_page"),
1475  $url
1476  )
1477  )
1478  );
1479  }
1480  // single month
1481  else {
1482  $wtpl = new ilTemplate("tpl.blog_list_navigation_month.html", true, true, "components/ILIAS/Blog");
1483 
1484  $ilCtrl->setParameter($this, "blpg", "");
1485 
1486  $month_options = array();
1487  foreach ($a_items as $month => $postings) {
1488  $month_name = $this->gui->presentation()->util()->getMonthPresentation($month);
1489 
1490  $month_options[$month] = $month_name;
1491 
1492  if ($month == $this->month) {
1493  if (!$a_link_template) {
1494  $ilCtrl->setParameter($this, "bmn", $month);
1495  $month_url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1496  } else {
1497  $month_url = $this->buildExportLink($a_link_template, "list", (string) $month);
1498  }
1499 
1500  foreach ($postings as $id => $posting) {
1501  $caption = /* ilDatePresentation::formatDate($posting["created"], IL_CAL_DATETIME).
1502  ", ".*/ $posting["title"];
1503 
1504  if (!$a_link_template) {
1505  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $month);
1506  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $id);
1507  $url = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_posting_cmd);
1508  } else {
1509  $url = $this->buildExportLink($a_link_template, "posting", (string) $id);
1510  }
1511 
1512  if (!$posting["active"]) {
1513  $wtpl->setVariable("NAV_ITEM_DRAFT", $this->lng->txt("blog_draft"));
1514  } elseif ($this->blog_settings->getApproval() && !$posting["approved"]) {
1515  $wtpl->setVariable("NAV_ITEM_APPROVAL", $this->lng->txt("blog_needs_approval"));
1516  }
1517 
1518  $wtpl->setCurrentBlock("navigation_item");
1519  $wtpl->setVariable("NAV_ITEM_URL", $url);
1520  $wtpl->setVariable("NAV_ITEM_CAPTION", $caption);
1521  $wtpl->parseCurrentBlock();
1522  }
1523 
1524  $wtpl->setCurrentBlock("navigation_month_details");
1525  if ($blpg > 0) {
1526  $wtpl->setVariable("NAV_MONTH", $month_name);
1527  $wtpl->setVariable("URL_MONTH", $month_url);
1528  }
1529  $wtpl->parseCurrentBlock();
1530  }
1531  }
1532 
1533  if ($blpg === 0) {
1534  $wtpl->setCurrentBlock("option_bl");
1535  foreach ($month_options as $value => $caption) {
1536  $wtpl->setVariable("OPTION_VALUE", $value);
1537  $wtpl->setVariable("OPTION_CAPTION", $caption);
1538  if ($value == $this->month) {
1539  $wtpl->setVariable("OPTION_SEL", ' selected="selected"');
1540  }
1541  $wtpl->parseCurrentBlock();
1542  }
1543 
1544  $wtpl->setVariable("FORM_ACTION", $ilCtrl->getFormAction($this, $a_list_cmd));
1545  }
1546  }
1547  $ilCtrl->setParameter($this, "bmn", $this->month);
1548  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", "");
1549  return $wtpl->get();
1550  }
1551 
1555  protected function renderNavigationByKeywords(
1556  string $a_list_cmd = "render",
1557  bool $a_show_inactive = false,
1558  string $a_link_template = "",
1559  int $a_blpg = 0
1560  ): string {
1561  $ilCtrl = $this->ctrl;
1562 
1563  $blpg = ($a_blpg > 0)
1564  ? $a_blpg
1565  : $this->blpg;
1566 
1567  $keywords = $this->getKeywords($a_show_inactive, $blpg);
1568  if ($keywords) {
1569  $wtpl = new ilTemplate("tpl.blog_list_navigation_keywords.html", true, true, "components/ILIAS/Blog");
1570 
1571  $max = max($keywords);
1572 
1573  $wtpl->setCurrentBlock("keyword");
1574  foreach ($keywords as $keyword => $counter) {
1575  if (!$a_link_template) {
1576  $ilCtrl->setParameter($this, "kwd", urlencode((string) $keyword)); // #15885
1577  $url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1578  $ilCtrl->setParameter($this, "kwd", "");
1579  } else {
1580  $url = $this->buildExportLink($a_link_template, "keyword", (string) $keyword);
1581  }
1582 
1583  $wtpl->setVariable("TXT_KEYWORD", $keyword);
1584  $wtpl->setVariable("CLASS_KEYWORD", ilTagging::getRelevanceClass($counter, $max));
1585  $wtpl->setVariable("URL_KEYWORD", $url);
1586  $wtpl->parseCurrentBlock();
1587  }
1588 
1589  return $wtpl->get();
1590  }
1591  return "";
1592  }
1593 
1594  protected function renderNavigationByAuthors(
1595  array $a_items,
1596  string $a_list_cmd = "render",
1597  bool $a_show_inactive = false
1598  ): string {
1599  $ilCtrl = $this->ctrl;
1600 
1601  $authors = array();
1602  foreach ($a_items as $month => $items) {
1603  foreach ($items as $item) {
1604  if (($a_show_inactive || ilBlogPosting::_lookupActive($item["id"], "blp"))) {
1605  if ($item["author"]) {
1606  $authors[] = $item["author"];
1607  }
1608 
1609  if (isset($item["editors"])) {
1610  foreach ($item["editors"] as $editor_id) {
1611  if ($editor_id != $item["author"]) {
1612  $authors[] = $editor_id;
1613  }
1614  }
1615  }
1616  }
1617  }
1618  }
1619 
1620  $authors = array_unique($authors);
1621 
1622  // filter out deleted users
1623  $authors = array_filter($authors, function ($id) {
1624  return ilObject::_lookupType($id) == "usr";
1625  });
1626 
1627  if (count($authors) > 1) {
1628  $list = array();
1629  foreach ($authors as $user_id) {
1630  if ($user_id) {
1631  $ilCtrl->setParameter($this, "ath", $user_id);
1632  $url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1633  $ilCtrl->setParameter($this, "ath", "");
1634 
1635  $base_name = ilUserUtil::getNamePresentation($user_id);
1636  if (substr($base_name, 0, 1) == "[") {
1637  $name = ilUserUtil::getNamePresentation($user_id, true);
1638  $sort = $name;
1639  } else {
1641  $user_id,
1642  true,
1643  false,
1644  "",
1645  false,
1646  true,
1647  false
1648  );
1649  $name_arr = ilObjUser::_lookupName($user_id);
1650  $sort = $name_arr["lastname"] . " " . $name_arr["firstname"];
1651  }
1652 
1653  $idx = trim(strip_tags($sort)) . "///" . $user_id; // #10934
1654  $list[$idx] = array($name, $url);
1655  }
1656  }
1657  ksort($list);
1658 
1659  $wtpl = new ilTemplate("tpl.blog_list_navigation_authors.html", true, true, "components/ILIAS/Blog");
1660 
1661  $wtpl->setCurrentBlock("author");
1662  foreach ($list as $author) {
1663  $wtpl->setVariable("TXT_AUTHOR", $author[0]);
1664  $wtpl->setVariable("URL_AUTHOR", $author[1]);
1665  $wtpl->parseCurrentBlock();
1666  }
1667 
1668  return $wtpl->get();
1669  }
1670  return "";
1671  }
1672 
1676  public function renderToolbarNavigation(
1677  array $a_items,
1678  bool $single_posting = false
1679  ): void {
1680  $nav_renderer = $this->gui->navigation()->toolbarNavigationRenderer();
1681  $nav_renderer->renderToolbarNavigation(
1682  $this->blog_access,
1683  $a_items,
1684  $this->blpg,
1685  $single_posting,
1686  $this->month,
1687  $this->user_page
1688  );
1689  }
1690 
1694  public function renderNavigation(
1695  string $a_list_cmd = "render",
1696  string $a_posting_cmd = "preview",
1697  ?string $a_link_template = null,
1698  bool $a_show_inactive = false,
1699  int $a_blpg = 0
1700  ): string {
1702  $a_items = $this->items;
1703  $blpg = ($a_blpg > 0)
1704  ? $a_blpg
1705  : $this->blpg;
1706 
1707  if ($this->blog_settings->getOrder()) {
1708  $order = array_flip($this->blog_settings->getOrder());
1709  } else {
1710  $order = array(
1711  "navigation" => 0
1712  ,"keywords" => 2
1713  ,"authors" => 1
1714  );
1715  }
1716 
1717  $wtpl = new ilTemplate("tpl.blog_list_navigation.html", true, true, "components/ILIAS/Blog");
1718 
1719  $blocks = array();
1720 
1721  // by date
1722  if (count($a_items)) {
1723  $blocks[$order["navigation"]] = array(
1724  $this->lng->txt("blog_navigation"),
1725  $this->renderNavigationByDate($a_items, $a_list_cmd, $a_posting_cmd, $a_link_template, $a_show_inactive, $a_blpg)
1726  );
1727  }
1728 
1729  if ($this->blog_settings->getKeywords()) {
1730  // keywords
1731  $may_edit_keywords = ($blpg > 0 &&
1732  $this->blog_access->mayEditPosting($blpg) &&
1733  $a_list_cmd !== "preview" &&
1734  $a_list_cmd !== "gethtml" &&
1735  !$a_link_template);
1736  $keywords = $this->renderNavigationByKeywords($a_list_cmd, $a_show_inactive, (string) $a_link_template, $a_blpg);
1737  if ($keywords || $may_edit_keywords) {
1738  if (!$keywords) {
1739  $keywords = $this->lng->txt("blog_no_keywords");
1740  }
1741  $cmd = null;
1742  $blocks[$order["keywords"]] = array(
1743  $this->lng->txt("blog_keywords"),
1744  $keywords,
1745  $cmd
1746  ? array($cmd, $this->lng->txt("blog_edit_keywords"))
1747  : null
1748  );
1749  }
1750  }
1751 
1752  // is not part of (html) export
1753  if (!$a_link_template) {
1754  // authors
1755  if ($this->id_type === self::REPOSITORY_NODE_ID &&
1756  $this->blog_settings->getAuthors()) {
1757  $authors = $this->renderNavigationByAuthors($a_items, $a_list_cmd, $a_show_inactive);
1758  if ($authors) {
1759  $blocks[$order["authors"]] = array($this->lng->txt("blog_authors"), $authors);
1760  }
1761  }
1762 
1763  // rss
1764  if ($this->blog_settings->getRSS() &&
1765  $ilSetting->get('enable_global_profiles') &&
1766  $a_list_cmd === "preview") {
1767  // #10827
1768  $blog_id = $this->node_id;
1769  if ($this->id_type !== self::WORKSPACE_NODE_ID) {
1770  $blog_id .= "_cll";
1771  }
1772  $url = ILIAS_HTTP_PATH . "/feed.php?blog_id=" . $blog_id .
1773  "&client_id=" . rawurlencode(CLIENT_ID);
1774 
1775  $wtpl->setVariable("RSS_BUTTON", ilRSSButtonGUI::get(ilRSSButtonGUI::ICON_RSS, $url));
1776  }
1777  }
1778 
1779  if (count($blocks)) {
1780  global $DIC;
1781 
1782  $ui_factory = $DIC->ui()->factory();
1783  $ui_renderer = $DIC->ui()->renderer();
1784 
1785  ksort($blocks);
1786  foreach ($blocks as $block) {
1787  $title = $block[0];
1788 
1789  $content = $block[1];
1790 
1791  $secondary_panel = $ui_factory->panel()->secondary()->legacy($title, $ui_factory->legacy()->content($content));
1792 
1793  if (isset($block[2]) && is_array($block[2])) {
1794  $link = $ui_factory->button()->shy($block[2][1], $block[2][0]);
1795  $secondary_panel = $secondary_panel->withFooter($link);
1796  }
1797 
1798  $wtpl->setCurrentBlock("block_bl");
1799  $wtpl->setVariable("BLOCK", $ui_renderer->render($secondary_panel));
1800  $wtpl->parseCurrentBlock();
1801  }
1802  }
1803 
1804  return $wtpl->get();
1805  }
1806 
1810  public function getKeywords(
1811  bool $a_show_inactive,
1812  ?int $a_posting_id = null
1813  ): array {
1814  $keywords = array();
1815  if ($a_posting_id) {
1816  foreach (ilBlogPosting::getKeywords($this->obj_id, $a_posting_id) as $keyword) {
1817  if (isset($keywords[$keyword])) {
1818  $keywords[$keyword]++;
1819  } else {
1820  $keywords[$keyword] = 1;
1821  }
1822  }
1823  } else {
1824  foreach ($this->items as $month => $items) {
1825  foreach ($items as $item) {
1826  if ($a_show_inactive || ilBlogPosting::_lookupActive($item["id"], "blp")) {
1827  foreach (ilBlogPosting::getKeywords($this->obj_id, $item["id"]) as $keyword) {
1828  if (isset($keywords[$keyword])) {
1829  $keywords[$keyword]++;
1830  } else {
1831  $keywords[$keyword] = 1;
1832  }
1833  }
1834  }
1835  }
1836  }
1837  }
1838 
1839  // #15881
1840  $tmp = array();
1841  foreach ($keywords as $keyword => $counter) {
1842  $tmp[] = array("keyword" => $keyword, "counter" => $counter);
1843  }
1844  $tmp = ilArrayUtil::sortArray($tmp, "keyword", "ASC");
1845 
1846  $keywords = array();
1847  foreach ($tmp as $item) {
1848  $keywords[(string) $item["keyword"]] = $item["counter"];
1849  }
1850  return $keywords;
1851  }
1852 
1856  public function buildExportFile(
1857  bool $a_include_comments = false,
1858  bool $print_version = false
1859  ): BlogHtmlExport {
1860  $type = "html";
1861  $format = explode("_", $this->blog_request->getFormat());
1862  if (($format[1] ?? "") === "comments" || $a_include_comments) {
1863  $a_include_comments = true;
1864  $type = "html_comments";
1865  }
1866 
1867  // create export file
1868  ilExport::_createExportDirectory($this->object->getId(), $type, "blog");
1869  $exp_dir = ilExport::_getExportDirectory($this->object->getId(), $type, "blog");
1870 
1871  $subdir = $this->object->getType() . "_" . $this->object->getId();
1872  if ($print_version) {
1873  $subdir .= "print";
1874  }
1875 
1876  $blog_export = new BlogHtmlExport($this, $exp_dir, $subdir);
1877  $blog_export->setPrintVersion($print_version);
1878  $blog_export->includeComments($a_include_comments);
1879  $blog_export->exportHTML();
1880  return $blog_export;
1881  }
1882 
1883  public function getNotesSubId(): int
1884  {
1885  return $this->blpg;
1886  }
1887 
1888  public function disableNotes(bool $a_value = false): void
1889  {
1890  $this->disable_notes = $a_value;
1891  }
1892 
1893  protected function addHeaderActionForCommand(
1894  string $a_cmd
1895  ): void {
1896  $ilUser = $this->user;
1897  $ilCtrl = $this->ctrl;
1898  // preview?
1899  if ($a_cmd === "preview" || $a_cmd === "previewFullscreen" || $this->prvm) {
1900  // notification
1901  if ($ilUser->getId() !== ANONYMOUS_USER_ID) {
1902  if (!$this->prvm) {
1903  $ilCtrl->setParameter($this, "prvm", "fsc");
1904  }
1905  $this->insertHeaderAction($this->initHeaderAction(null, null, true));
1906  if (!$this->prvm) {
1907  $ilCtrl->setParameter($this, "prvm", "");
1908  }
1909  }
1910  } else {
1911  $this->addHeaderAction();
1912  }
1913  }
1914 
1915  protected function initHeaderAction(
1916  ?string $sub_type = null,
1917  ?int $sub_id = null,
1918  bool $is_preview = false
1919  ): ?ilObjectListGUI {
1920  $ilUser = $this->user;
1921  $ilCtrl = $this->ctrl;
1922  if (!$this->obj_id) {
1923  return null;
1924  }
1925  $sub_type = $sub_id = null;
1926  if ($this->blpg > 0) {
1927  $sub_type = "blp";
1928  $sub_id = $this->blpg;
1929  }
1930 
1931  $lg = parent::initHeaderAction($sub_type, $sub_id);
1932  if (!$lg) {
1933  return null;
1934  }
1935  $lg->enableComments(false);
1936  $lg->enableNotes(false);
1937 
1938  if ($is_preview) {
1939  if ($this->blpg > 0) {
1940  if (($this->object->getNotesStatus() && !$this->disable_notes)) {
1941  $lg->enableComments(true);
1942  }
1943  $lg->enableNotes(true);
1944  }
1945  $lg->enableTags(false);
1946 
1948  $ilCtrl->setParameter($this, "ntf", 1);
1949  $link = $ilCtrl->getLinkTarget($this, "setNotification");
1950  $ilCtrl->setParameter($this, "ntf", "");
1951  if (ilNotification::hasOptOut($this->obj_id)) {
1952  $lg->addCustomCommand($link, "blog_notification_toggle_off");
1953  }
1954 
1955  $lg->addHeaderIcon(
1956  "not_icon",
1957  ilUtil::getImagePath("object/notification_on.svg"),
1958  $this->lng->txt("blog_notification_activated")
1959  );
1960  } else {
1961  $ilCtrl->setParameter($this, "ntf", 2);
1962  $link = $ilCtrl->getLinkTarget($this, "setNotification");
1963  $ilCtrl->setParameter($this, "ntf", "");
1964  $lg->addCustomCommand($link, "blog_notification_toggle_on");
1965 
1966  $lg->addHeaderIcon(
1967  "not_icon",
1968  ilUtil::getImagePath("object/notification_off.svg"),
1969  $this->lng->txt("blog_notification_deactivated")
1970  );
1971  }
1972 
1973  // #11758
1974  if ($this->blog_access->mayContribute()) {
1975  $ilCtrl->setParameter($this, "prvm", "");
1976 
1977  $ilCtrl->setParameter($this, "bmn", "");
1978  $ilCtrl->setParameter($this, "blpg", "");
1979  $link = $ilCtrl->getLinkTarget($this, "");
1980  $ilCtrl->setParameter($this, "blpg", $sub_id);
1981  $ilCtrl->setParameter($this, "bmn", $this->month);
1982  $lg->addCustomCommand($link, "blog_edit"); // #11868
1983 
1984  if ($sub_id && $this->blog_access->mayEditPosting($sub_id)) {
1985  $link = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit");
1986  $lg->addCustomCommand($link, "blog_edit_posting");
1987  }
1988 
1989  $ilCtrl->setParameter($this, "prvm", "fsc");
1990  }
1991 
1992  $ilCtrl->setParameter($this, "ntf", "");
1993  }
1994 
1995  return $lg;
1996  }
1997 
1998  protected function setNotification(): void
1999  {
2000  $ilUser = $this->user;
2001  $ilCtrl = $this->ctrl;
2002 
2003  switch ($this->ntf) {
2004  case 1:
2006  break;
2007 
2008  case 2:
2010  break;
2011  }
2012 
2013  $ilCtrl->redirect($this, "preview");
2014  }
2015 
2019  public static function lookupSubObjectTitle(
2020  int $a_blog_id,
2021  int $a_posting_id
2022  ): string {
2023  // page might be deleted, so setting halt on errors to false
2024  $post = new ilBlogPosting($a_posting_id);
2025  if ($post->getBlogId() === $a_blog_id) {
2026  return $post->getTitle();
2027  }
2028  return "";
2029  }
2030 
2034  protected function filterInactivePostings(): void
2035  {
2036  foreach ($this->items as $month => $postings) {
2037  foreach ($postings as $id => $item) {
2038  if (!ilBlogPosting::_lookupActive($id, "blp")) {
2039  unset($this->items[$month][$id]);
2040  } elseif ($this->blog_settings->getApproval() && !$item["approved"]) {
2041  unset($this->items[$month][$id]);
2042  }
2043  }
2044  if (!count($this->items[$month])) {
2045  unset($this->items[$month]);
2046  }
2047  }
2048 
2049  if ($this->items && !isset($this->items[$this->month])) {
2050  $keys = array_keys($this->items);
2051  $this->month = array_shift($keys);
2052  }
2053  }
2054 
2055  public function filterItemsByKeyword(
2056  array $a_items,
2057  string $a_keyword
2058  ): array {
2059  $res = [];
2060  foreach ($a_items as $month => $items) {
2061  foreach ($items as $item) {
2062  if (in_array(
2063  $a_keyword,
2064  ilBlogPosting::getKeywords($this->obj_id, $item["id"])
2065  )) {
2066  $res[] = $item;
2067  }
2068  }
2069  }
2070  return $res;
2071  }
2072 
2076  protected function isAdmin(): bool
2077  {
2078  return ($this->checkPermissionBool("redact") ||
2079  $this->checkPermissionBool("write"));
2080  }
2081 
2082  protected function addLocatorItems(): void
2083  {
2084  $ilLocator = $this->locator;
2085 
2086  if (is_object($this->object)) {
2087  $ilLocator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, "preview"), "", $this->node_id);
2088  }
2089  }
2090 
2091  public function approve(): void
2092  {
2093  if ($this->isAdmin() && $this->apid > 0) {
2094  $post = new ilBlogPosting($this->apid);
2095  $post->setApproved(true);
2096  $post->setBlogNodeId($this->node_id, ($this->id_type == self::WORKSPACE_NODE_ID));
2097  $post->update(true, false, true, "new"); // #13434
2098 
2099  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
2100  }
2101 
2102  $this->ctrl->redirect($this, "render");
2103  }
2104 
2105 
2106  //
2107  // contributors
2108  //
2109 
2110  public function contributors(): void
2111  {
2112  $ilTabs = $this->tabs;
2113  $ilToolbar = $this->toolbar;
2114  $ilCtrl = $this->ctrl;
2115  $lng = $this->lng;
2116  $tpl = $this->tpl;
2117 
2118  if (!$this->checkPermissionBool("write")) {
2119  return;
2120  }
2121 
2122  $ilTabs->activateTab("contributors");
2123 
2124  $local_roles = $this->object->getAllLocalRoles($this->node_id);
2125 
2126  // add member
2128  $this,
2129  $ilToolbar,
2130  array(
2131  'auto_complete_name' => $lng->txt('user'),
2132  'submit_name' => $lng->txt('add'),
2133  'add_search' => true,
2134  'add_from_container' => $this->node_id,
2135  'user_type' => $local_roles
2136  ),
2137  true
2138  );
2139 
2140  $other_roles = $this->object->getRolesWithContributeOrRedact($this->node_id);
2141  if ($other_roles) {
2142  $this->tpl->setOnScreenMessage('info', sprintf($lng->txt("blog_contribute_other_roles"), implode(", ", $other_roles)));
2143  }
2144 
2145  $tbl = $this->gui->contributor()->ilContributorTableGUI(
2146  $this,
2147  "contributors",
2148  $this->object->getAllLocalRoles($this->node_id)
2149  );
2150 
2151  $tpl->setContent($tbl->getHTML());
2152  }
2153 
2157  public function addUserFromAutoComplete(): void
2158  {
2159  $lng = $this->lng;
2160 
2161  $user_login = $this->blog_request->getUserLogin();
2162  $user_type = $this->blog_request->getUserType();
2163 
2164  if (trim($user_login) === '') {
2165  $this->tpl->setOnScreenMessage('failure', $lng->txt('msg_no_search_string'));
2166  $this->contributors();
2167  return;
2168  }
2169  $users = explode(',', $user_login);
2170 
2171  $user_ids = array();
2172  foreach ($users as $user) {
2173  $user_id = ilObjUser::_lookupId($user);
2174 
2175  if (!$user_id) {
2176  $this->tpl->setOnScreenMessage('failure', $lng->txt('user_not_known'));
2177  $this->contributors();
2178  return;
2179  }
2180 
2181  $user_ids[] = (int) $user_id;
2182  }
2183 
2184  $this->addContributor($user_ids, $user_type);
2185  }
2186 
2190  public function addContributor(
2191  array $a_user_ids = array(),
2192  ?string $a_user_type = null
2193  ): void {
2194  $ilCtrl = $this->ctrl;
2195  $lng = $this->lng;
2196  $rbacreview = $this->rbac_review;
2197  $rbacadmin = $this->rbacadmin;
2198  $a_user_type = (int) $a_user_type;
2199 
2200  if (!$this->checkPermissionBool("write")) {
2201  return;
2202  }
2203 
2204  if (!count($a_user_ids) || !$a_user_type) {
2205  $this->tpl->setOnScreenMessage('failure', $lng->txt("no_checkbox"));
2206  $this->contributors();
2207  return;
2208  }
2209 
2210  // get contributor role
2211  $local_roles = array_keys($this->object->getAllLocalRoles($this->node_id));
2212  if (!in_array($a_user_type, $local_roles)) {
2213  $this->tpl->setOnScreenMessage('failure', $lng->txt("missing_perm"));
2214  $this->contributors();
2215  return;
2216  }
2217 
2218  foreach ($a_user_ids as $user_id) {
2219  $user_id = (int) $user_id;
2220  $a_user_type = (int) $a_user_type;
2221  if (!$rbacreview->isAssigned($user_id, $a_user_type)) {
2222  $rbacadmin->assignUser($a_user_type, $user_id);
2223  }
2224  }
2225 
2226  $this->tpl->setOnScreenMessage('success', $lng->txt("settings_saved"), true);
2227  $ilCtrl->redirect($this, "contributors");
2228  }
2229 
2233  public function confirmRemoveContributor(): void
2234  {
2235  $ids = $this->blog_request->getIds();
2236 
2237  if (count($ids) === 0) {
2238  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
2239  $this->ctrl->redirect($this, "contributors");
2240  }
2241 
2242  $confirm = new ilConfirmationGUI();
2243  $confirm->setHeaderText($this->lng->txt('blog_confirm_delete_contributors'));
2244  $confirm->setFormAction($this->ctrl->getFormAction($this, 'removeContributor'));
2245  $confirm->setConfirm($this->lng->txt('delete'), 'removeContributor');
2246  $confirm->setCancel($this->lng->txt('cancel'), 'contributors');
2247 
2248  foreach ($ids as $user_id) {
2249  $confirm->addItem(
2250  'id[]',
2251  (string) $user_id,
2252  $this->profile_gui->getNamePresentation($user_id, false, "", true)
2253  );
2254  }
2255 
2256  $this->tpl->setContent($confirm->getHTML());
2257  }
2258 
2259  public function removeContributor(): void
2260  {
2261  $ilCtrl = $this->ctrl;
2262  $lng = $this->lng;
2263  $rbacadmin = $this->rbacadmin;
2264 
2265  $ids = $this->blog_request->getIds();
2266 
2267  if (count($ids) === 0) {
2268  $this->tpl->setOnScreenMessage('failure', $lng->txt("select_one"), true);
2269  $ilCtrl->redirect($this, "contributors");
2270  }
2271 
2272  // get contributor role
2273  $local_roles = array_keys($this->object->getAllLocalRoles($this->node_id));
2274  if (!$local_roles) {
2275  $this->tpl->setOnScreenMessage('failure', $lng->txt("missing_perm"));
2276  $this->contributors();
2277  return;
2278  }
2279 
2280  foreach ($ids as $user_id) {
2281  foreach ($local_roles as $role_id) {
2282  $rbacadmin->deassignUser($role_id, $user_id);
2283  }
2284  }
2285 
2286  $this->tpl->setOnScreenMessage('success', $lng->txt("settings_saved"), true);
2287  $this->ctrl->redirect($this, "contributors");
2288  }
2289 
2290  public function deactivateAdmin(): void
2291  {
2292  if ($this->checkPermissionBool("write") && $this->apid > 0) {
2293  // ilBlogPostingGUI::deactivatePage()
2294  $post = new ilBlogPosting($this->apid);
2295  $post->setApproved(false);
2296  $post->setActive(false);
2297  $post->update(true, false, false);
2298 
2299  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
2300  }
2301 
2302  $this->ctrl->redirect($this, "render");
2303  }
2304 
2305 
2309 
2310  public function setContentStyleSheet(
2312  ): void {
2313  $tpl = $this->tpl;
2314 
2315  if ($a_tpl) {
2316  $ctpl = $a_tpl;
2317  } else {
2318  $ctpl = $tpl;
2319  }
2320 
2321  $this->content_style_gui->addCss(
2322  $ctpl,
2323  $this->object->getRefId(),
2324  $this->object->getId()
2325  );
2326  }
2327 
2331  protected function exportWithComments(): void
2332  {
2333  $this->export(true);
2334  }
2335 
2339 
2340  public function getPrintView(): \ILIAS\Export\PrintProcessGUI
2341  {
2342  $style_sheet_id = $this->content_style_domain->getEffectiveStyleId();
2343 
2345  $blog = $this->object;
2346  $provider = new \ILIAS\Blog\BlogPrintViewProviderGUI(
2347  $this->lng,
2348  $this->ctrl,
2349  $blog,
2350  $this->node_id,
2351  $this->access_handler,
2352  $style_sheet_id,
2353  $this->blog_request->getObjIds()
2354  );
2355 
2356  return new \ILIAS\Export\PrintProcessGUI(
2357  $provider,
2358  $this->http,
2359  $this->ui,
2360  $this->lng
2361  );
2362  }
2363 
2364  public function printViewSelection(): void
2365  {
2366  $view = $this->getPrintView();
2367  $view->sendForm();
2368  }
2369 
2370  public function printPostings(): void
2371  {
2372  $print_view = $this->getPrintView();
2373  $print_view->sendPrintView();
2374  }
2375 
2376  protected function forwardExport(): void
2377  {
2378  $this->ctrl->redirectByClass(ilExportGUI::class);
2379  }
2380 }
ilNavigationHistory $nav_history
setRightContent(string $a_html)
Sets content of right column.
setLocator()
set Locator
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: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.
Class ilBlogPosting.
const ANONYMOUS_USER_ID
Definition: constants.php:27
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
ILIAS Blog Settings Settings $blog_settings
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.
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)
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:66
ILIAS Blog InternalGUIService $gui
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.
setLocator()
Insert locator.
static _getExportDirectory(int $a_obj_id, string $a_type="xml", string $a_obj_type="", string $a_entity="")
Get export directory for an repository object
ILIAS Blog Access BlogAccess $blog_access
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...
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)
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)
confirmRemoveContributor()
Used in ilContributorTableGUI.
static _createExportDirectory(int $a_obj_id, string $a_export_type="xml", string $a_obj_type="")
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:22
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.
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)
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
isAdmin()
Check if user has admin access (approve, may edit & deactivate all postings)
ILIAS HTTP Services $http
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.
ILIAS Repository Profile ProfileGUI $profile_gui
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.
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?