ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilObjBlogGUI.php
Go to the documentation of this file.
1 <?php
2 
21 
31 {
32  protected string $rendered_content = "";
33  protected \ILIAS\Notes\Service $notes;
34  protected \ILIAS\Blog\ReadingTime\BlogSettingsGUI $reading_time_gui;
35  protected \ILIAS\Blog\ReadingTime\ReadingTimeManager $reading_time_manager;
36 
38  protected ilHelpGUI $help;
39  protected ilTabsGUI $tabs;
42 
43  protected string $month = "";
44  protected array $items = [];
45  protected string $keyword = "";
46  protected ?int $author = null;
47  protected bool $month_default = false;
48  protected int $gtp = 0;
49  protected string $edt;
50  protected int $blpg = 0;
51  protected int $old_nr = 0;
52  protected int $ppage = 0;
53  protected int $user_page = 0;
54  public bool $prtf_embed = false; // note: this is currently set in ilPortfolioPageGUI, should use getter/setter
55  protected string $prvm; //preview mode (fsc|emb)
56  protected int $ntf = 0;
57  protected int $apid = 0;
58  protected string $new_type = "";
59  protected int $prt_id = 0;
60  protected bool $disable_notes = false;
62  protected \ILIAS\HTTP\Services $http;
63  protected \ILIAS\DI\UIServices $ui;
64  protected \ILIAS\Style\Content\GUIService $content_style_gui;
65  protected \ILIAS\Style\Content\Object\ObjectFacade $content_style_domain;
66 
67  public function __construct(
68  int $a_id = 0,
69  int $a_id_type = self::REPOSITORY_NODE_ID,
70  int $a_parent_node_id = 0
71  ) {
72  global $DIC;
73 
74  $this->settings = $DIC->settings();
75  $this->help = $DIC["ilHelp"];
76  $this->tabs = $DIC->tabs();
77  $this->nav_history = $DIC["ilNavigationHistory"];
78  $this->user = $DIC->user();
79  $this->toolbar = $DIC->toolbar();
80  $this->tree = $DIC->repositoryTree();
81  $this->locator = $DIC["ilLocator"];
82  $this->rbac_review = $DIC->rbac()->review();
83  $this->rbacadmin = $DIC->rbac()->admin();
84  $this->http = $DIC->http();
85  $this->ui = $DIC->ui();
86 
87  $lng = $DIC->language();
88  $ilCtrl = $DIC->ctrl();
89 
90  $this->blog_request = $DIC->blog()
91  ->internal()
92  ->gui()
93  ->standardRequest();
94 
96 
97  $this->gtp = $req->getGotoPage();
98  $this->edt = $req->getEditing();
99  $this->blpg = $req->getBlogPage();
100  $this->old_nr = $req->getOldNr();
101  $this->ppage = $req->getPPage();
102  $this->user_page = $req->getUserPage();
103  $this->new_type = $req->getNewType();
104  $this->prvm = $req->getPreviewMode();
105  $this->ntf = $req->getNotification();
106  $this->apid = $req->getApId();
107  $this->month = $req->getMonth();
108  $this->keyword = $req->getKeyword();
109  $this->author = $req->getAuthor();
110  $this->prt_id = $req->getPrtId();
111 
112  $this->tool_context = $DIC->globalScreen()->tool()->context();
113 
114  parent::__construct($a_id, $a_id_type, $a_parent_node_id);
115 
116  $blog_page = $this->blog_request->getBlogPage();
117  if ($blog_page > 0 &&
118  ilBlogPosting::lookupBlogId($blog_page) !== $this->object->getId()) {
119  throw new ilException("Posting ID does not match blog.");
120  }
121 
122  $blog_id = 0;
123  if ($this->object) {
124  // gather postings by month
125  $this->items = $this->buildPostingList($this->object->getId());
126  if ($this->items) {
127  // current month (if none given or empty)
128  if (!$this->month || !$this->items[$this->month]) {
129  $m = array_keys($this->items);
130  $this->month = array_shift($m);
131  $this->month_default = true;
132  }
133  }
134 
135  $ilCtrl->setParameter($this, "bmn", $this->month);
136  $blog_id = $this->object->getId();
137  }
138 
139  $lng->loadLanguageModule("blog");
140  $ilCtrl->saveParameter($this, "prvm");
141 
142  $cs = $DIC->contentStyle();
143  $this->content_style_gui = $cs->gui();
144  if (is_object($this->object)) {
145  if ($this->id_type !== self::REPOSITORY_NODE_ID) {
146  $this->content_style_domain = $cs->domain()->styleForObjId($this->object->getId());
147  } else {
148  $this->content_style_domain = $cs->domain()->styleForRefId($this->object->getRefId());
149  }
150  }
151 
152  $this->reading_time_gui = new \ILIAS\Blog\ReadingTime\BlogSettingsGUI($blog_id);
153  $this->reading_time_manager = new \ILIAS\Blog\ReadingTime\ReadingTimeManager();
154  $this->notes = $DIC->notes();
155  }
156 
157  public function getType(): string
158  {
159  return "blog";
160  }
161 
162  public function getItems(): array
163  {
164  return $this->items;
165  }
166 
167 
168  protected function initCreationForms(string $new_type): array
169  {
170  $forms = parent::initCreationForms($new_type);
171 
172  if ($this->id_type === self::WORKSPACE_NODE_ID) {
173  unset($forms[self::CFORM_IMPORT], $forms[self::CFORM_CLONE]);
174  }
175 
176  return $forms;
177  }
178 
179  protected function afterSave(ilObject $new_object): void
180  {
181  $ilCtrl = $this->ctrl;
182 
183  $this->tpl->setOnScreenMessage('success', $this->lng->txt("object_added"), true);
184  $ilCtrl->redirect($this, "");
185  }
186 
187  protected function setSettingsSubTabs(string $a_active): void
188  {
189  global $DIC;
190 
191  $tree = $DIC->repositoryTree();
192  $access = $DIC->access();
193 
194  // general properties
195  $this->tabs_gui->addSubTab(
196  "properties",
197  $this->lng->txt("blog_properties"),
198  $this->ctrl->getLinkTarget($this, 'edit')
199  );
200 
201  $this->tabs_gui->addSubTab(
202  "style",
203  $this->lng->txt("obj_sty"),
204  $this->ctrl->getLinkTargetByClass("ilobjectcontentstylesettingsgui", "")
205  );
206 
207  // notification settings for blogs in courses and groups
208  if ($this->id_type === self::REPOSITORY_NODE_ID) {
209  $grp_ref_id = $tree->checkForParentType($this->object->getRefId(), 'grp');
210  $crs_ref_id = $tree->checkForParentType($this->object->getRefId(), 'crs');
211 
212  if ($grp_ref_id > 0 || $crs_ref_id > 0) {
213  if ($access->checkAccess('write', '', $this->ref_id)) {
214  $this->tabs_gui->addSubTab(
215  'notifications',
216  $this->lng->txt("notifications"),
217  $this->ctrl->getLinkTargetByClass("ilobjnotificationsettingsgui", '')
218  );
219  }
220  }
221  }
222 
223  $this->tabs_gui->activateSubTab($a_active);
224  }
225 
226  protected function initEditCustomForm(
227  ilPropertyFormGUI $a_form
228  ): void {
229  $lng = $this->lng;
231  $obj_service = $this->getObjectService();
232 
233  $this->setSettingsSubTabs("properties");
234 
235  if ($this->id_type === self::REPOSITORY_NODE_ID) {
236  $appr = new ilCheckboxInputGUI($lng->txt("blog_enable_approval"), "approval");
237  $appr->setInfo($lng->txt("blog_enable_approval_info"));
238  $a_form->addItem($appr);
239  }
240 
241  $notes = new ilCheckboxInputGUI($lng->txt("blog_enable_notes"), "notes");
242  $a_form->addItem($notes);
243 
244  if ($ilSetting->get('enable_global_profiles')) {
245  $rss = new ilCheckboxInputGUI($lng->txt("blog_enable_rss"), "rss");
246  $rss->setInfo($lng->txt("blog_enable_rss_info"));
247  $a_form->addItem($rss);
248  }
249 
250 
251  // navigation
252 
253  $nav = new ilFormSectionHeaderGUI();
254  $nav->setTitle($lng->txt("blog_settings_navigation"));
255  $a_form->addItem($nav);
256 
257  $nav_mode = new ilRadioGroupInputGUI($lng->txt("blog_nav_mode"), "nav");
258  $nav_mode->setRequired(true);
259  $a_form->addItem($nav_mode);
260 
261  $opt = new ilRadioOption($lng->txt("blog_nav_mode_month_list"), ilObjBlog::NAV_MODE_LIST);
262  $opt->setInfo($lng->txt("blog_nav_mode_month_list_info"));
263  $nav_mode->addOption($opt);
264 
265 
266  $mon_num = new ilNumberInputGUI($lng->txt("blog_nav_mode_month_list_num_month"), "nav_list_mon");
267  $mon_num->setInfo($lng->txt("blog_nav_mode_month_list_num_month_info"));
268  $mon_num->setSize(3);
269  $mon_num->setMinValue(1);
270  $opt->addSubItem($mon_num);
271 
272  $detail_num = new ilNumberInputGUI($lng->txt("blog_nav_mode_month_list_num_month_with_post"), "nav_list_mon_with_post");
273  $detail_num->setInfo($lng->txt("blog_nav_mode_month_list_num_month_with_post_info"));
274  //$detail_num->setRequired(true);
275  $detail_num->setSize(3);
276  //$detail_num->setMinValue(0);
277  $opt->addSubItem($detail_num);
278 
279  $opt = new ilRadioOption($lng->txt("blog_nav_mode_month_single"), ilObjBlog::NAV_MODE_MONTH);
280  $opt->setInfo($lng->txt("blog_nav_mode_month_single_info"));
281  $nav_mode->addOption($opt);
282 
283  $order_options = array();
284  if ($this->object->getOrder()) {
285  foreach ($this->object->getOrder() as $item) {
286  $order_options[] = $lng->txt("blog_" . $item);
287  }
288  }
289 
290  if (!in_array($lng->txt("blog_navigation"), $order_options)) {
291  $order_options[] = $lng->txt("blog_navigation");
292  }
293 
294  if ($this->id_type === self::REPOSITORY_NODE_ID) {
295  if (!in_array($lng->txt("blog_authors"), $order_options)) {
296  $order_options[] = $lng->txt("blog_authors");
297  }
298 
299  $auth = new ilCheckboxInputGUI($lng->txt("blog_enable_nav_authors"), "nav_authors");
300  $auth->setInfo($lng->txt("blog_enable_nav_authors_info"));
301  $a_form->addItem($auth);
302  }
303 
304  $keyw = new ilCheckboxInputGUI($lng->txt("blog_enable_keywords"), "keywords");
305  $keyw->setInfo($lng->txt("blog_enable_keywords_info"));
306  $a_form->addItem($keyw);
307 
308  if (!in_array($lng->txt("blog_keywords"), $order_options)) {
309  $order_options[] = $lng->txt("blog_keywords");
310  }
311 
312  $order = new ilNonEditableValueGUI($lng->txt("blog_nav_sortorder"), "order");
313  $order->setMultiValues($order_options);
314  $order->setValue(array_shift($order_options));
315  $order->setMulti(true, true, false);
316  $a_form->addItem($order);
317 
318 
319  // presentation (frame)
320 
321  $pres = new ilFormSectionHeaderGUI();
322  $pres->setTitle($lng->txt("blog_presentation_frame"));
323  $a_form->addItem($pres);
324 
325  if ($this->id_type === self::REPOSITORY_NODE_ID) {
326  $obj_service->commonSettings()->legacyForm($a_form, $this->object)->addTileImage();
327  }
328 
329  $ppic = new ilCheckboxInputGUI($lng->txt("blog_profile_picture"), "ppic");
330  $a_form->addItem($ppic);
331 
332  if ($this->id_type === self::REPOSITORY_NODE_ID) {
333  $ppic->setInfo($lng->txt("blog_profile_picture_repository_info"));
334  }
335 
336  $blga_set = new ilSetting("blga");
337  if ($blga_set->get("banner")) {
338  $dimensions = " (" . $blga_set->get("banner_width") . "x" .
339  $blga_set->get("banner_height") . ")";
340 
341  $img = new ilImageFileInputGUI($lng->txt("blog_banner") . $dimensions, "banner");
342  $a_form->addItem($img);
343 
344  // show existing file
345  $file = $this->object->getImageFullPath(true);
346  if ($file) {
347  $img->setImage(ilWACSignedPath::signFile($file));
348  }
349  }
350 
351  $this->reading_time_gui->addSettingToForm($a_form);
352 
353  /* #15000
354  $bg_color = new ilColorPickerInputGUI($lng->txt("blog_background_color"), "bg_color");
355  $a_form->addItem($bg_color);
356 
357  $font_color = new ilColorPickerInputGUI($lng->txt("blog_font_color"), "font_color");
358  $a_form->addItem($font_color);
359  */
360 
361  // presentation (overview)
362 
363  $list = new ilFormSectionHeaderGUI();
364  $list->setTitle($lng->txt("blog_presentation_overview"));
365  $a_form->addItem($list);
366 
367 
368  $post_num = new ilNumberInputGUI($lng->txt("blog_list_num_postings"), "ov_list_post_num");
369  $post_num->setInfo($lng->txt("blog_list_num_postings_info"));
370  $post_num->setSize(3);
371  $post_num->setMinValue(1);
372  $post_num->setRequired(true);
373  $a_form->addItem($post_num);
374 
375  $abs_shorten = new ilCheckboxInputGUI($lng->txt("blog_abstract_shorten"), "abss");
376  $a_form->addItem($abs_shorten);
377 
378  $abs_shorten_len = new ilNumberInputGUI($lng->txt("blog_abstract_shorten_length"), "abssl");
379  $abs_shorten_len->setSize(5);
380  $abs_shorten_len->setRequired(true);
381  $abs_shorten_len->setSuffix($lng->txt("blog_abstract_shorten_characters"));
382  $abs_shorten_len->setMinValue(50, true);
383  $abs_shorten->addSubItem($abs_shorten_len);
384 
385  $abs_img = new ilCheckboxInputGUI($lng->txt("blog_abstract_image"), "absi");
386  $abs_img->setInfo($lng->txt("blog_abstract_image_info"));
387  $a_form->addItem($abs_img);
388 
389  $abs_img_width = new ilNumberInputGUI($lng->txt("blog_abstract_image_width"), "absiw");
390  $abs_img_width->setSize(5);
391  $abs_img_width->setRequired(true);
392  $abs_img_width->setSuffix($lng->txt("blog_abstract_image_pixels"));
393  $abs_img_width->setMinValue(32, true);
394  $abs_img->addSubItem($abs_img_width);
395 
396  $abs_img_height = new ilNumberInputGUI($lng->txt("blog_abstract_image_height"), "absih");
397  $abs_img_height->setSize(5);
398  $abs_img_height->setRequired(true);
399  $abs_img_height->setSuffix($lng->txt("blog_abstract_image_pixels"));
400  $abs_img_height->setMinValue(32, true);
401  $abs_img->addSubItem($abs_img_height);
402  }
403 
404  protected function getEditFormCustomValues(array &$a_values): void
405  {
406  if ($this->id_type === self::REPOSITORY_NODE_ID) {
407  $a_values["approval"] = $this->object->hasApproval();
408  $a_values["nav_authors"] = $this->object->hasAuthors();
409  }
410  $a_values["keywords"] = $this->object->hasKeywords();
411  $a_values["notes"] = $this->object->getNotesStatus();
412  $a_values["ppic"] = $this->object->hasProfilePicture();
413  /*
414  $a_values["bg_color"] = $this->object->getBackgroundColor();
415  $a_values["font_color"] = $this->object->getFontColor();
416  */
417  $a_values["banner"] = $this->object->getImage();
418  $a_values["rss"] = $this->object->hasRSS();
419  $a_values["abss"] = $this->object->hasAbstractShorten();
420  $a_values["absi"] = $this->object->hasAbstractImage();
421  $a_values["nav"] = $this->object->getNavMode();
422  $a_values["nav_list_mon_with_post"] = $this->object->getNavModeListMonthsWithPostings();
423  $a_values["nav_list_mon"] = $this->object->getNavModeListMonths();
424  $a_values["ov_list_post_num"] = $this->object->getOverviewPostings();
425 
426  // #13420
427  $a_values["abssl"] = $this->object->getAbstractShortenLength() ?: ilObjBlog::ABSTRACT_DEFAULT_SHORTEN_LENGTH;
428  $a_values["absiw"] = $this->object->getAbstractImageWidth() ?: ilObjBlog::ABSTRACT_DEFAULT_IMAGE_WIDTH;
429  $a_values["absih"] = $this->object->getAbstractImageHeight() ?: ilObjBlog::ABSTRACT_DEFAULT_IMAGE_HEIGHT;
430  $a_values = $this->reading_time_gui->addValueToArray($a_values);
431  }
432 
433  protected function updateCustom(ilPropertyFormGUI $form): void
434  {
435  $lng = $this->lng;
436  $obj_service = $this->getObjectService();
437 
438  if ($this->id_type === self::REPOSITORY_NODE_ID) {
439  $this->object->setApproval($form->getInput("approval"));
440  $this->object->setAuthors($form->getInput("nav_authors"));
441  $obj_service->commonSettings()->legacyForm($form, $this->object)->saveTileImage();
442  }
443  $this->object->setKeywords($form->getInput("keywords"));
444  $this->object->setNotesStatus($form->getInput("notes"));
445  $this->object->setProfilePicture($form->getInput("ppic"));
446  $this->object->setRSS($form->getInput("rss"));
447  $this->object->setAbstractShorten($form->getInput("abss"));
448  $this->object->setAbstractShortenLength($form->getInput("abssl"));
449  $this->object->setAbstractImage($form->getInput("absi"));
450  $this->object->setAbstractImageWidth($form->getInput("absiw"));
451  $this->object->setAbstractImageHeight($form->getInput("absih"));
452  $this->object->setNavMode($form->getInput("nav"));
453  $this->object->setNavModeListMonthsWithPostings($form->getInput("nav_list_mon_with_post"));
454  $this->object->setNavModeListMonths($form->getInput("nav_list_mon"));
455  $this->object->setOverviewPostings($form->getInput("ov_list_post_num"));
456  $this->reading_time_gui->saveSettingFromForm($form);
457 
458  $order = (array) $form->getInput("order");
459 
460  foreach ($order as $idx => $value) {
461  if ($value == $lng->txt("blog_navigation")) {
462  $order[$idx] = "navigation";
463  } elseif ($value == $lng->txt("blog_keywords")) {
464  $order[$idx] = "keywords";
465  } else {
466  $order[$idx] = "authors";
467  }
468  }
469  $this->object->setOrder($order);
470  // banner field is optional
471  $banner = $form->getItemByPostVar("banner");
472  if ($banner) {
473  if ($_FILES["banner"]["tmp_name"]) {
474  $this->object->uploadImage($_FILES["banner"]);
475  } elseif ($banner->getDeletionFlag()) {
476  $this->object->deleteImage();
477  }
478  }
479  }
480 
481  protected function setTabs(): void
482  {
483  $lng = $this->lng;
484  $ilHelp = $this->help;
485 
486  if ($this->id_type === self::WORKSPACE_NODE_ID) {
487  $this->ctrl->setParameter($this, "wsp_id", $this->node_id);
488  }
489 
490  $ilHelp->setScreenIdComponent("blog");
491 
492  if ($this->checkPermissionBool("read")) {
493  $this->ctrl->setParameterByClass(self::class, "bmn", null);
494  $this->tabs_gui->addTab(
495  "content",
496  $lng->txt("content"),
497  $this->ctrl->getLinkTarget($this, "")
498  );
499  }
500  if ($this->checkPermissionBool("read") && !$this->prtf_embed) {
501  $this->tabs_gui->addTab(
502  "id_info",
503  $lng->txt("info_short"),
504  $this->ctrl->getLinkTargetByClass(array("ilobjbloggui", "ilinfoscreengui"), "showSummary")
505  );
506  }
507 
508  if ($this->checkPermissionBool("write")) {
509  $this->tabs_gui->addTab(
510  "settings",
511  $lng->txt("settings"),
512  $this->ctrl->getLinkTarget($this, "edit")
513  );
514 
515  if (!$this->prtf_embed) {
516  if ($this->id_type === self::REPOSITORY_NODE_ID) {
517  $this->tabs_gui->addTab(
518  "contributors",
519  $lng->txt("blog_contributors"),
520  $this->ctrl->getLinkTarget($this, "contributors")
521  );
522  }
523 
524  if ($this->id_type === self::REPOSITORY_NODE_ID) {
525  $this->tabs_gui->addTab(
526  "export",
527  $lng->txt("export"),
528  $this->ctrl->getLinkTargetByClass("ilexportgui", "")
529  );
530  }
531  }
532  }
533 
534  if (!$this->prtf_embed) {
535  if ($this->mayContribute()) {
536  $this->tabs_gui->addNonTabbedLink(
537  "preview",
538  $lng->txt("blog_preview"),
539  $this->ctrl->getLinkTarget($this, "preview")
540  );
541  }
542  parent::setTabs();
543  }
544  }
545 
546  public function executeCommand(): void
547  {
548  $ilCtrl = $this->ctrl;
549  $tpl = $this->tpl;
550  $ilTabs = $this->tabs;
551  $lng = $this->lng;
552  $ilNavigationHistory = $this->nav_history;
553 
554 
555  $next_class = $ilCtrl->getNextClass($this);
556 
557  if ($next_class !== "ilexportgui") {
558  $this->triggerAssignmentTool();
559  }
560 
561  // goto link to blog posting
562  if ($this->gtp > 0) {
563  $page_id = $this->gtp;
564  if (ilBlogPosting::exists($this->object_id, $page_id)) {
565  // #12312
566  $ilCtrl->setCmdClass("ilblogpostinggui");
567  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $page_id);
568  if ($this->edt === "edit") {
569  $ilCtrl->redirectByClass("ilblogpostinggui", "edit");
570  } else {
571  $ilCtrl->redirectByClass("ilblogpostinggui", "previewFullscreen");
572  }
573  } else {
574  $this->tpl->setOnScreenMessage('failure', $lng->txt("blog_posting_not_found"));
575  }
576  }
577 
578 
579  $cmd = $ilCtrl->getCmd();
580 
581  // add entry to navigation history
582  if (($this->id_type === self::REPOSITORY_NODE_ID) && !$this->getCreationMode() &&
583  $this->getAccessHandler()->checkAccess("read", "", $this->node_id)) {
584  // see #22067
585  $link = $ilCtrl->getLinkTargetByClass(["ilrepositorygui", "ilObjBlogGUI"], "preview");
586  $ilNavigationHistory->addItem($this->node_id, $link, "blog");
587  }
588  switch ($next_class) {
589  case 'ilblogpostinggui':
590  $this->ctrl->saveParameter($this, "user_page");
591  if (!$this->prtf_embed) {
593  }
594 
595  if (!$this->checkPermissionBool("read") && !$this->prtf_embed) {
596  $this->tpl->setOnScreenMessage('info', $lng->txt("no_permission"));
597  return;
598  }
599 
600  // #9680
601  if ($this->id_type === self::REPOSITORY_NODE_ID) {
602  $this->setLocator();
603  }
604 
605  $style_sheet_id = $this->content_style_domain->getEffectiveStyleId();
606 
607  $bpost_gui = new ilBlogPostingGUI(
608  $this->node_id,
609  $this->getAccessHandler(),
610  $this->blpg,
611  $this->old_nr,
612  ($this->object->getNotesStatus() && !$this->disable_notes),
613  $this->mayEditPosting($this->blpg),
614  $style_sheet_id
615  );
616 
617  // keep preview mode through notes gui (has its own commands)
618  switch ($cmd) {
619  // blog preview
620  case "previewFullscreen":
621  $ilCtrl->setParameter($this, "prvm", "fsc");
622  break;
623 
624  // blog in portfolio
625  case "previewEmbedded":
626  $ilCtrl->setParameter($this, "prvm", "emb");
627  break;
628 
629  // edit
630  default:
631  $this->setContentStyleSheet();
632 
633 
634  if (!$this->prtf_embed) {
635  $this->ctrl->setParameterByClass("ilblogpostinggui", "blpg", $this->blpg);
636  $this->tabs_gui->addNonTabbedLink(
637  "preview",
638  $lng->txt("blog_preview"),
639  $this->ctrl->getLinkTargetByClass("ilblogpostinggui", "previewFullscreen")
640  );
641  $this->ctrl->setParameterByClass("ilblogpostinggui", "blpg", "");
642  } else {
643  $this->ctrl->setParameterByClass("ilobjportfoliogui", "user_page", $this->ppage);
644  $this->tabs_gui->addNonTabbedLink(
645  "preview",
646  $lng->txt("blog_preview"),
647  $this->ctrl->getLinkTargetByClass("ilobjportfoliogui", "preview")
648  );
649  $this->ctrl->setParameterByClass("ilobjportfoliogui", "user_page", "");
650  }
651  break;
652  }
653 
654  // keep preview mode through notes gui
655  if ($this->prvm) {
656  $cmd = "preview" . (($this->prvm === "fsc") ? "Fullscreen" : "Embedded");
657  }
658  if (in_array($cmd, array("previewFullscreen", "previewEmbedded"))) {
659  $this->renderToolbarNavigation($this->items, true);
660  }
661  $ret = $ilCtrl->forwardCommand($bpost_gui);
662  if (!$ilTabs->back_target) {
663  $ilCtrl->setParameter($this, "bmn", "");
664  $ilTabs->setBackTarget(
665  $lng->txt("back"),
666  $ilCtrl->getLinkTarget($this, "")
667  );
668  }
669 
670  if ($ret != "") {
671 
672  // $is_owner = $this->object->getOwner() == $ilUser->getId();
673  $is_owner = $this->mayContribute();
674  $is_active = $bpost_gui->getBlogPosting()->getActive();
675 
676  // do not show inactive postings
677  if (($cmd === "previewFullscreen" || $cmd === "previewEmbedded")
678  && !$is_owner && !$is_active) {
679  $this->ctrl->redirect($this, "preview");
680  }
681 
682  switch ($cmd) {
683  // blog preview
684  case "previewFullscreen":
685  $this->addHeaderActionForCommand($cmd);
686  $this->filterInactivePostings();
687  $nav = $this->renderNavigation("preview", $cmd);
688  $this->renderFullScreen($ret, $nav);
689  break;
690 
691  // blog in portfolio
692  case "previewEmbedded":
693  $this->addHeaderActionForCommand($cmd);
694  $this->filterInactivePostings();
695  $nav = $this->renderNavigation("gethtml", $cmd);
696  // this is important for embedded blog pages!
697  $this->rendered_content = $this->buildEmbedded($ret, $nav);
698  return;
699 
700  // ilias/editor
701  default:
702  // infos about draft status / snippet
703  $info = array();
704  if (!$is_active) {
705  // single author blog (owner) in personal workspace
706  if ($this->id_type === self::WORKSPACE_NODE_ID) {
707  $info[] = $lng->txt("blog_draft_info");
708  } else {
709  $info[] = $lng->txt("blog_draft_info_contributors");
710  }
711  }
712  $public_action = false;
713  if ($cmd !== "history" && $cmd !== "edit" && $is_active && empty($info)) {
714  $info[] = $lng->txt("blog_new_posting_info");
715  $public_action = true;
716  }
717  if ($this->object->hasApproval() && !$bpost_gui->getBlogPosting()->isApproved()) {
718  // #9737
719  $info[] = $lng->txt("blog_posting_edit_approval_info");
720  }
721  if ($public_action) {
722  $this->tpl->setOnScreenMessage('success', implode("<br />", $info));
723  } else {
724  if (count($info) > 0) {
725  $this->tpl->setOnScreenMessage('info', implode("<br />", $info));
726  }
727  }
728 
729  // revert to edit cmd to avoid confusion
730  $tpl->setContent($ret);
731  if ($cmd !== "edit") {
732  $this->addHeaderActionForCommand("render");
733  $nav = $this->renderNavigation("render", $cmd, "", $is_owner);
734  $tpl->setRightContent($nav);
735  } else {
736  $this->tabs->setBackTarget("", "");
737  }
738  break;
739  }
740  }
741  break;
742 
743  case "ilinfoscreengui":
744  $this->prepareOutput();
745  $this->addHeaderActionForCommand("render");
746  $this->infoScreenForward();
747  break;
748 
749  case "ilnotegui":
750  $this->preview();
751  break;
752 
753  case "ilcommonactiondispatchergui":
755  $gui->enableCommentsSettings(false);
756  $this->prepareOutput();
757  $this->ctrl->forwardCommand($gui);
758  break;
759 
760  case "ilpermissiongui":
761  $this->prepareOutput();
762  $ilTabs->activateTab("id_permissions");
763  $perm_gui = new ilPermissionGUI($this);
764  $this->ctrl->forwardCommand($perm_gui);
765  break;
766 
767  case "ilobjectcopygui":
768  $this->prepareOutput();
769  $cp = new ilObjectCopyGUI($this);
770  $cp->setType("blog");
771  $this->ctrl->forwardCommand($cp);
772  break;
773 
774  case 'ilrepositorysearchgui':
775  $this->prepareOutput();
776  $ilTabs->activateTab("contributors");
777  $rep_search = new ilRepositorySearchGUI();
778  $rep_search->setTitle($this->lng->txt("blog_add_contributor"));
779  $rep_search->setCallback($this, 'addContributor', $this->object->getAllLocalRoles($this->node_id));
780  $this->ctrl->setReturn($this, 'contributors');
781  $this->ctrl->forwardCommand($rep_search);
782  break;
783 
784  case 'ilexportgui':
785  $this->prepareOutput();
786  $ilTabs->activateTab("export");
787  $exp_gui = new ilExportGUI($this);
788  $exp_gui->addFormat("xml");
789  $exp_gui->addFormat("html", "", $this, "buildExportFile"); // #13419
790  if (ilObjBlogAccess::isCommentsExportPossible($this->object->getId())) {
791  $exp_gui->addFormat("html_comments", "HTML (" . $this->lng->txt("blog_incl_comments") . ")", $this, "buildExportFile");
792  }
793  $ilCtrl->forwardCommand($exp_gui);
794  break;
795 
796  case "ilobjectcontentstylesettingsgui":
797  $this->checkPermission("write");
798  $this->prepareOutput();
799  $this->addHeaderAction();
800  $ilTabs->activateTab("settings");
801  $this->setSettingsSubTabs("style");
802 
803 
804  if ($this->id_type === self::REPOSITORY_NODE_ID) {
805  $settings_gui = $this->content_style_gui
806  ->objectSettingsGUIForRefId(
807  null,
808  $this->object->getRefId()
809  );
810  } else {
811  $settings_gui = $this->content_style_gui
812  ->objectSettingsGUIForObjId(
813  null,
814  $this->object->getId()
815  );
816  }
817  $this->ctrl->forwardCommand($settings_gui);
818  break;
819 
820 
821  case "ilblogexercisegui":
822  $this->ctrl->setReturn($this, "render");
823  $gui = new ilBlogExerciseGUI($this->node_id);
824  $this->ctrl->forwardCommand($gui);
825  break;
826 
827  case 'ilobjnotificationsettingsgui':
828  $this->prepareOutput();
829  $ilTabs->activateTab("settings");
830  $this->setSettingsSubTabs("notifications");
831  $gui = new ilObjNotificationSettingsGUI($this->object->getRefId());
832  $this->ctrl->forwardCommand($gui);
833  break;
834 
835  default:
836  if ($cmd !== "gethtml") {
837  // desktop item handling, must be toggled before header action
838  if ($cmd === "addToDesk" || $cmd === "removeFromDesk") {
839  $this->{$cmd . "Object"}();
840  if ($this->prvm) {
841  $cmd = "preview";
842  } else {
843  $cmd = "render";
844  }
845  $ilCtrl->setCmd($cmd);
846  }
847  $this->addHeaderActionForCommand($cmd);
848  }
849  if (!$this->prtf_embed) {
850  parent::executeCommand();
851  return;
852  }
853 
854  $this->setTabs();
855 
856  if (!$cmd) {
857  $cmd = "render";
858  }
859  $this->rendered_content = (string) $this->$cmd();
860  }
861  }
862 
863  public function getRenderedContent(): string
864  {
866  }
867 
868  protected function triggerAssignmentTool(): void
869  {
870  $be = new ilBlogExercise($this->node_id);
871  $be_gui = new ilBlogExerciseGUI($this->node_id);
872  $assignments = $be->getAssignmentsOfBlog();
873  if (count($assignments) > 0) {
874  $ass_ids = array_map(static function ($i) {
875  return $i["ass_id"];
876  }, $assignments);
877  $this->tool_context->current()->addAdditionalData(ilExerciseGSToolProvider::SHOW_EXC_ASSIGNMENT_INFO, true);
878  $this->tool_context->current()->addAdditionalData(ilExerciseGSToolProvider::EXC_ASS_IDS, $ass_ids);
879  $this->tool_context->current()->addAdditionalData(
881  $be_gui->getActionButtons()
882  );
883  }
884  }
885 
889  public function infoScreen(): void
890  {
891  $this->ctrl->setCmd("showSummary");
892  $this->ctrl->setCmdClass("ilinfoscreengui");
893  $this->infoScreenForward();
894  }
895 
896  public function infoScreenForward(): void
897  {
898  $ilTabs = $this->tabs;
899 
900  $ilTabs->activateTab("id_info");
901 
902  $this->checkPermission("visible");
903 
904  $info = new ilInfoScreenGUI($this);
905 
906  if ($this->id_type !== self::WORKSPACE_NODE_ID) {
907  $info->enablePrivateNotes();
908  }
909 
910  if ($this->checkPermissionBool("read")) {
911  $info->enableNews();
912  }
913 
914  // no news editing for files, just notifications
915  $info->enableNewsEditing(false);
916  if ($this->checkPermissionBool("write")) {
917  $news_set = new ilSetting("news");
918  $enable_internal_rss = $news_set->get("enable_rss_for_internal");
919 
920  if ($enable_internal_rss) {
921  $info->setBlockProperty("news", "settings", true);
922  $info->setBlockProperty("news", "public_notifications_option", true);
923  }
924  }
925 
926  // standard meta data
927  $info->addMetaDataSections($this->object->getId(), 0, $this->object->getType());
928 
929  if ($this->id_type === self::WORKSPACE_NODE_ID) {
930  $info->addProperty($this->lng->txt("perma_link"), $this->getPermanentLinkWidget());
931  }
932 
933  $this->ctrl->forwardCommand($info);
934  }
935 
939  public function createPosting(): void
940  {
941  $ilCtrl = $this->ctrl;
943 
944  $title = $this->blog_request->getTitle();
945  if ($title) {
946  // create new posting
947  $posting = new ilBlogPosting();
948  $posting->setTitle($title);
949  $posting->setBlogId($this->object->getId());
950  $posting->setActive(false);
951  $posting->setAuthor($ilUser->getId());
952  $posting->create(false);
953 
954  // switch month list to current month (will include new posting)
955  $ilCtrl->setParameter($this, "bmn", date("Y-m"));
956 
957  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $posting->getId());
958  $ilCtrl->redirectByClass("ilblogpostinggui", "edit");
959  } else {
960  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("msg_no_title"), true);
961  $ilCtrl->redirect($this, "render");
962  }
963  }
964 
968  public function render(): void
969  {
970  $tpl = $this->tpl;
971  $ilTabs = $this->tabs;
972  $ilCtrl = $this->ctrl;
973  $lng = $this->lng;
974  $ilToolbar = new ilToolbarGUI();
975 
976  if (!$this->checkPermissionBool("read")) {
977  $this->tpl->setOnScreenMessage('info', $lng->txt("no_permission"));
978  return;
979  }
980 
981  $ilTabs->activateTab("content");
982 
983  // toolbar
984  if ($this->mayContribute()) {
985  $ilToolbar->setFormAction($ilCtrl->getFormAction($this, "createPosting"));
986 
987  $title = new ilTextInputGUI($lng->txt("title"), "title");
988  $title->setSize(30);
989  $ilToolbar->addStickyItem($title, $lng->txt("title"));
991  document.getElementById('title').setAttribute('data-blog-input', 'posting-title');
992  document.getElementById('title').setAttribute('placeholder', ' ');
993  ");
994 
995  $button = ilSubmitButton::getInstance();
996  $button->setCaption("blog_add_posting");
997  $button->setCommand("createPosting");
998  $ilToolbar->addStickyItem($button);
999 
1000  // #18763
1001  $keys = array_keys($this->items);
1002  $first = array_shift($keys);
1003  if ($first != $this->month) {
1004  $ilToolbar->addSeparator();
1005 
1006  $ilCtrl->setParameter($this, "bmn", $first);
1007  $url = $ilCtrl->getLinkTarget($this, "");
1008  $ilCtrl->setParameter($this, "bmn", $this->month);
1009 
1010  $button = ilLinkButton::getInstance();
1011  $button->setCaption("blog_show_latest");
1012  $button->setUrl($url);
1013  $ilToolbar->addButtonInstance($button);
1014  }
1015 
1016  // print/pdf
1017  $print_view = $this->getPrintView();
1018  $modal_elements = $print_view->getModalElements(
1019  $this->ctrl->getLinkTarget(
1020  $this,
1021  "printViewSelection"
1022  )
1023  );
1024  $ilToolbar->addSeparator();
1025  $ilToolbar->addComponent($modal_elements->button);
1026  $ilToolbar->addComponent($modal_elements->modal);
1027  }
1028 
1029  // $is_owner = ($this->object->getOwner() == $ilUser->getId());
1030  $is_owner = $this->mayContribute();
1031 
1032  $list_items = $this->getListItems($is_owner);
1033 
1034  $list = $nav = "";
1035  if ($list_items) {
1036  $list = $this->renderList($list_items, "preview", "", $is_owner);
1037  $nav = $this->renderNavigation("render", "edit", "", $is_owner);
1038  }
1039 
1040  $this->setContentStyleSheet();
1041 
1042  $tpl->setContent($ilToolbar->getHTML() . $list);
1043  $tpl->setRightContent($nav);
1044  }
1045 
1049  public function getHTML(): string
1050  {
1051  $ilUser = $this->user;
1052  $ilCtrl = $this->ctrl;
1053  $lng = $this->lng;
1054 
1055  // getHTML() is called by ilRepositoryGUI::show()
1056  if ($this->id_type === self::REPOSITORY_NODE_ID) {
1057  return "";
1058  }
1059 
1060  // there is no way to do a permissions check here, we have no wsp
1061 
1062  $this->filterInactivePostings();
1063 
1064  $list_items = $this->getListItems();
1065 
1066  $list = $nav = "";
1067  if ($list_items) {
1068  $list = $this->renderList($list_items, "previewEmbedded");
1069  $nav = $this->renderNavigation("gethtml", "previewEmbedded");
1070  }
1071  // quick editing in portfolio
1072  elseif ($this->prt_id) {
1073  // see renderList()
1074  if (ilObject::_lookupOwner($this->prt_id) === $ilUser->getId()) {
1075  // see ilPortfolioPageTableGUI::fillRow()
1076  $ilCtrl->setParameterByClass("ilportfoliopagegui", "ppage", $this->user_page);
1077  $link = $ilCtrl->getLinkTargetByClass(array("ilportfoliopagegui", "ilobjbloggui"), "render");
1078  $ilCtrl->setParameterByClass("ilportfoliopagegui", "ppage", "");
1079 
1080  $this->toolbar->addComponent($this->ui->factory()->button()->standard(
1081  $this->lng->txt("blog_edit"),
1082  $link
1083  ));
1084  }
1085  }
1086 
1087  return $this->buildEmbedded($list, $nav);
1088  }
1089 
1093  protected function getListItems(
1094  bool $a_show_inactive = false
1095  ): array {
1096  if ($this->author) {
1097  $list_items = array();
1098  foreach ($this->items as $month => $items) {
1099  foreach ($items as $id => $item) {
1100  if ($item["author"] == $this->author ||
1101  (isset($item["editors"]) && in_array($this->author, $item["editors"]))) {
1102  $list_items[$id] = $item;
1103  }
1104  }
1105  }
1106  } elseif ($this->keyword) {
1107  $list_items = $this->filterItemsByKeyword($this->items, $this->keyword);
1108  } else {
1109  $max = $this->object->getOverviewPostings();
1110  if ($this->month_default && $max) {
1111  $list_items = array();
1112  foreach ($this->items as $month => $postings) {
1113  foreach ($postings as $id => $item) {
1114  if (!$a_show_inactive &&
1115  !ilBlogPosting::_lookupActive($id, "blp")) {
1116  continue;
1117  }
1118  $list_items[$id] = $item;
1119 
1120  if (count($list_items) >= $max) {
1121  break(2);
1122  }
1123  }
1124  }
1125  } else {
1126  $list_items = $this->items[$this->month] ?? [];
1127  }
1128  }
1129  return $list_items;
1130  }
1131 
1135  public function preview(): void
1136  {
1137  global $DIC;
1138 
1139  $lng = $DIC->language();
1140  $toolbar = $DIC->toolbar();
1141 
1142  if (!$this->checkPermissionBool("read")) {
1143  $this->tpl->setOnScreenMessage('info', $lng->txt("no_permission"));
1144  return;
1145  }
1146 
1147  $this->filterInactivePostings();
1148 
1149  $list_items = $this->getListItems();
1150 
1151  $list = $nav = "";
1152  if ($list_items) {
1153  $list = $this->renderList($list_items, "previewFullscreen");
1154  $nav = $this->renderNavigation("preview", "previewFullscreen");
1155  $this->renderToolbarNavigation($this->items);
1156  $list .= $toolbar->getHTML();
1157  }
1158 
1159  $this->renderFullScreen($list, $nav);
1160  }
1161 
1165  public function export(
1166  bool $a_with_comments = false
1167  ): void {
1168  $zip = $this->buildExportFile($a_with_comments);
1169  ilFileDelivery::deliverFileLegacy($zip, $this->object->getTitle() . ".zip", '', false, true);
1170  }
1171 
1172 
1173  // --- helper functions
1174 
1178  protected function buildEmbedded(
1179  string $a_content,
1180  string $a_nav
1181  ): string {
1182  $wtpl = new ilTemplate("tpl.blog_embedded.html", true, true, "Modules/Blog");
1183  $wtpl->setVariable("VAL_LIST", $a_content);
1184  $wtpl->setVariable("VAL_NAVIGATION", $a_nav);
1185  return $wtpl->get();
1186  }
1187 
1191  public function renderFullScreen(
1192  string $a_content,
1193  string $a_navigation
1194  ): void {
1195  $tpl = $this->tpl;
1196  $ilUser = $this->user;
1197  $ilTabs = $this->tabs;
1198  $ilLocator = $this->locator;
1199 
1200  $owner = $this->object->getOwner();
1201 
1202  $ilTabs->clearTargets();
1203  $tpl->setLocator();
1204 
1205  $back_caption = "";
1206  $back = "";
1207 
1208  // back (edit)
1209  if ($owner === $ilUser->getId()) {
1210  // from shared/deeplink
1211  if ($this->id_type === self::WORKSPACE_NODE_ID) {
1212  $back = "ilias.php?baseClass=ilDashboardGUI&cmd=jumpToWorkspace&wsp_id=" . $this->node_id;
1213  }
1214  // from editor (#10073)
1215  elseif ($this->mayContribute()) {
1216  $this->ctrl->setParameter($this, "prvm", "");
1217  if ($this->blpg === 0) {
1218  $back = $this->ctrl->getLinkTarget($this, "");
1219  } else {
1220  $this->ctrl->setParameterByClass("ilblogpostinggui", "bmn", $this->month);
1221  $this->ctrl->setParameterByClass("ilblogpostinggui", "blpg", $this->blpg);
1222  $back = $this->ctrl->getLinkTargetByClass("ilblogpostinggui", "preview");
1223  }
1224  $this->ctrl->setParameter($this, "prvm", $this->prvm);
1225  }
1226 
1227  $back_caption = $this->lng->txt("blog_back_to_blog_owner");
1228  }
1229  // back
1230  elseif ($ilUser->getId() && $ilUser->getId() !== ANONYMOUS_USER_ID) {
1231  // workspace (always shared)
1232  if ($this->id_type === self::WORKSPACE_NODE_ID) {
1233  $back = "ilias.php?baseClass=ilDashboardGUI&cmd=jumpToWorkspace&dsh=" . $owner;
1234  }
1235  // contributor
1236  elseif ($this->mayContribute()) {
1237  $back = $this->ctrl->getLinkTarget($this, "");
1238  $back_caption = $this->lng->txt("blog_back_to_blog_owner");
1239  }
1240  // listgui / parent container
1241  else {
1242  $tree = $this->tree;
1243  $parent_id = $tree->getParentId($this->node_id);
1245  }
1246  }
1247 
1248  $this->renderFullscreenHeader($tpl, $owner);
1249 
1250  // #13564
1251  $this->ctrl->setParameter($this, "bmn", "");
1252  //$tpl->setTitleUrl($this->ctrl->getLinkTarget($this, "preview"));
1253  $this->ctrl->setParameter($this, "bmn", $this->month);
1254 
1255  $this->setContentStyleSheet();
1256 
1257  // content
1258  $tpl->setContent($a_content);
1259  $tpl->setRightContent($a_navigation);
1260  }
1261 
1265  public function renderFullscreenHeader(
1267  int $a_user_id,
1268  bool $a_export = false
1269  ): void {
1270  $ilUser = $this->user;
1271 
1272  if (!$a_export) {
1274  $this->object->getType(),
1276  $this->object->getId(),
1277  $ilUser->getId()
1278  );
1279  }
1280 
1281  // repository blogs are multi-author
1282  $name = "";
1283  if ($this->id_type !== self::REPOSITORY_NODE_ID) {
1284  $name = ilObjUser::_lookupName($a_user_id);
1285  $name = $name["lastname"] . ", " . $name["firstname"];
1286  }
1287 
1288  // show banner?
1289  $banner = false;
1290  $blga_set = new ilSetting("blga");
1291  $banner_width = "";
1292  $banner_height = "";
1293  if ($blga_set->get("banner")) {
1294  $banner = ilWACSignedPath::signFile($this->object->getImageFullPath());
1295  $banner_width = $blga_set->get("banner_width");
1296  $banner_height = $blga_set->get("banner_height");
1297  if ($a_export) {
1298  $banner = basename($banner);
1299  }
1300  }
1301 
1302  $ppic = "";
1303  if ($this->object->hasProfilePicture()) {
1304  // repository (multi-user)
1305  if ($this->id_type === self::REPOSITORY_NODE_ID) {
1306  // #15030
1307  if ($this->blpg > 0 && !$a_export) {
1308  $post = new ilBlogPosting($this->blpg);
1309  $author_id = $post->getAuthor();
1310  if ($author_id) {
1311  $ppic = ilObjUser::_getPersonalPicturePath($author_id, "xsmall", true, true);
1312 
1313  $name = ilObjUser::_lookupName($author_id);
1314  $name = $name["lastname"] . ", " . $name["firstname"];
1315  }
1316  }
1317  }
1318  // workspace (author == owner)
1319  else {
1320  $ppic = ilObjUser::_getPersonalPicturePath($a_user_id, "xsmall", true, true);
1321  if ($a_export) {
1322  $ppic = basename($ppic);
1323  }
1324  }
1325  }
1326 
1327  $a_tpl->resetHeaderBlock(false);
1328  $a_tpl->setBanner($banner);
1329  $a_tpl->setTitleIcon($ppic);
1330  $a_tpl->setTitle($this->object->getTitle());
1331  if ($this->id_type === self::REPOSITORY_NODE_ID) {
1332  $a_tpl->setDescription($this->object->getDescription());
1333  } else {
1334  $a_tpl->setDescription($name);
1335  }
1336  }
1337 
1341  protected function buildPostingList(
1342  int $a_obj_id
1343  ): array {
1344  $author_found = false;
1345 
1346  $items = array();
1347  foreach (ilBlogPosting::getAllPostings($a_obj_id) as $posting) {
1348  if ($this->author &&
1349  ($posting["author"] == $this->author ||
1350  (is_array($posting["editors"] ?? false) && in_array($this->author, $posting["editors"])))) {
1351  $author_found = true;
1352  }
1353 
1354  $month = substr($posting["created"]->get(IL_CAL_DATE), 0, 7);
1355  $items[$month][$posting["id"]] = $posting;
1356  }
1357 
1358  if ($this->author && !$author_found) {
1359  $this->author = null;
1360  }
1361 
1362  return $items;
1363  }
1364 
1368  public function renderList(
1369  array $items,
1370  string $a_cmd = "preview",
1371  string $a_link_template = "",
1372  bool $a_show_inactive = false,
1373  string $a_export_directory = ""
1374  ): string {
1375  $lng = $this->lng;
1376  $ilCtrl = $this->ctrl;
1377  $ilUser = $this->user;
1378 
1379  $wtpl = new ilTemplate("tpl.blog_list.html", true, true, "Modules/Blog");
1380 
1381  // quick editing in portfolio
1382  if ($this->prt_id > 0 &&
1383  stripos($a_cmd, "embedded") !== false && ilObject::_lookupOwner($this->prt_id) === $ilUser->getId()) {
1384  // see ilPortfolioPageTableGUI::fillRow()
1385  $ilCtrl->setParameterByClass("ilportfoliopagegui", "ppage", $this->user_page);
1386  $link = $ilCtrl->getLinkTargetByClass(array("ilportfoliopagegui", "ilobjbloggui"), "render");
1387  $ilCtrl->setParameterByClass("ilportfoliopagegui", "ppage", "");
1388  $b = $this->ui->factory()->button()->standard(
1389  $this->lng->txt("blog_edit"),
1390  $link
1391  );
1392  $this->toolbar->addComponent($b);
1393  }
1394 
1395  $is_admin = $this->isAdmin();
1396 
1397  $last_month = null;
1398  $is_empty = true;
1399  foreach ($items as $item) {
1400  // only published items
1401  $is_active = ilBlogPosting::_lookupActive($item["id"], "blp");
1402  if (!$is_active && !$a_show_inactive) {
1403  continue;
1404  }
1405 
1406  $is_empty = false;
1407 
1408  $month = "";
1409  if (!$this->keyword && !$this->author) {
1410  $month = substr($item["created"]->get(IL_CAL_DATE), 0, 7);
1411  }
1412 
1413  if (!$last_month || $last_month != $month) {
1414  if ($last_month) {
1415  $wtpl->setCurrentBlock("month_bl");
1416  $wtpl->parseCurrentBlock();
1417  }
1418 
1419  // title according to current "filter"/navigation
1420  if ($this->keyword) {
1421  $title = $lng->txt("blog_keyword") . ": " . $this->keyword;
1422  } elseif ($this->author) {
1423  $title = $lng->txt("blog_author") . ": " . ilUserUtil::getNamePresentation($this->author);
1424  } else {
1425  $title = ilCalendarUtil::_numericMonthToString((int) substr($month, 5)) .
1426  " " . substr($month, 0, 4);
1427 
1428  $last_month = $month;
1429  }
1430 
1431  $wtpl->setVariable("TXT_CURRENT_MONTH", $title);
1432  }
1433 
1434  if (!$a_link_template) {
1435  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $this->month);
1436  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $item["id"]);
1437  $preview = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_cmd);
1438  } else {
1439  $preview = $this->buildExportLink($a_link_template, "posting", $item["id"]);
1440  }
1441  $more_link = $preview;
1442 
1443  // actions
1444  $posting_edit = $this->mayEditPosting($item["id"], $item["author"]);
1445  if (($posting_edit || $is_admin) && !$a_link_template && $a_cmd === "preview") {
1446  $alist = new ilAdvancedSelectionListGUI();
1447  $alist->setId($item["id"]);
1448  $alist->setListTitle($lng->txt("actions"));
1449 
1450  if ($is_active && $this->object->hasApproval() && !$item["approved"]) {
1451  if ($is_admin) {
1452  $ilCtrl->setParameter($this, "apid", $item["id"]);
1453  $alist->addItem(
1454  $lng->txt("blog_approve"),
1455  "approve",
1456  $ilCtrl->getLinkTarget($this, "approve")
1457  );
1458  $ilCtrl->setParameter($this, "apid", "");
1459  }
1460 
1461  $wtpl->setVariable("APPROVAL", $lng->txt("blog_needs_approval"));
1462  }
1463 
1464  if ($posting_edit) {
1465  $alist->addItem(
1466  $lng->txt("edit_content"),
1467  "edit",
1468  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit")
1469  );
1470  $more_link = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit");
1471 
1472  // #11858
1473  if ($is_active) {
1474  $alist->addItem(
1475  $lng->txt("blog_toggle_draft"),
1476  "deactivate",
1477  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deactivatePageToList")
1478  );
1479  } else {
1480  $alist->addItem(
1481  $lng->txt("blog_toggle_final"),
1482  "activate",
1483  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "activatePageToList")
1484  );
1485  }
1486 
1487  $alist->addItem(
1488  $lng->txt("rename"),
1489  "rename",
1490  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edittitle")
1491  );
1492 
1493  if ($this->object->hasKeywords()) { // #13616
1494  $alist->addItem(
1495  $lng->txt("blog_edit_keywords"),
1496  "keywords",
1497  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "editKeywords")
1498  );
1499  }
1500 
1501  $alist->addItem(
1502  $lng->txt("blog_edit_date"),
1503  "editdate",
1504  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "editdate")
1505  );
1506  $alist->addItem(
1507  $lng->txt("delete"),
1508  "delete",
1509  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deleteBlogPostingConfirmationScreen")
1510  );
1511  } elseif ($is_admin) {
1512  // #10513
1513  if ($is_active) {
1514  $ilCtrl->setParameter($this, "apid", $item["id"]);
1515  $alist->addItem(
1516  $lng->txt("blog_toggle_draft_admin"),
1517  "deactivate",
1518  $ilCtrl->getLinkTarget($this, "deactivateAdmin")
1519  );
1520  $ilCtrl->setParameter($this, "apid", "");
1521  }
1522 
1523  $alist->addItem(
1524  $lng->txt("delete"),
1525  "delete",
1526  $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "deleteBlogPostingConfirmationScreen")
1527  );
1528  }
1529 
1530  $wtpl->setCurrentBlock("actions");
1531  $wtpl->setVariable("ACTION_SELECTOR", $alist->getHTML());
1532  $wtpl->parseCurrentBlock();
1533  }
1534 
1535  // comments
1536  if ($this->object->getNotesStatus() && !$a_link_template && !$this->disable_notes) {
1537  // count (public) notes
1538  $notes_context = $this->notes
1539  ->data()
1540  ->context(
1541  $this->obj_id,
1542  (int) $item["id"],
1543  "blp"
1544  );
1545  $count = $this->notes
1546  ->domain()
1547  ->getNrOfCommentsForContext($notes_context);
1548 
1549  if ($a_cmd !== "preview") {
1550  $wtpl->setCurrentBlock("comments");
1551  $wtpl->setVariable("TEXT_COMMENTS", $lng->txt("blog_comments"));
1552  $wtpl->setVariable("URL_COMMENTS", $preview);
1553  $wtpl->setVariable("COUNT_COMMENTS", $count);
1554  $wtpl->parseCurrentBlock();
1555  }
1556  }
1557 
1558  // permanent link
1559  if ($a_cmd !== "preview" && $a_cmd !== "previewEmbedded") {
1560  if ($this->id_type === self::WORKSPACE_NODE_ID) {
1561  $goto = $this->getAccessHandler()->getGotoLink($this->node_id, $this->obj_id, "_" . $item["id"]);
1562  } else {
1563  $goto = ilLink::_getStaticLink($this->node_id, $this->getType(), true, "_" . $item["id"]);
1564  }
1565  $wtpl->setCurrentBlock("permalink");
1566  $wtpl->setVariable("URL_PERMALINK", $goto);
1567  $wtpl->setVariable("TEXT_PERMALINK", $lng->txt("blog_link"));
1568  $wtpl->parseCurrentBlock();
1569  }
1570 
1571  $snippet = ilBlogPostingGUI::getSnippet(
1572  $item["id"],
1573  $this->object->hasAbstractShorten(),
1574  $this->object->getAbstractShortenLength(),
1575  "&hellip;",
1576  $this->object->hasAbstractImage(),
1577  $this->object->getAbstractImageWidth(),
1578  $this->object->getAbstractImageHeight(),
1579  $a_export_directory
1580  );
1581 
1582  if ($snippet) {
1583  $wtpl->setCurrentBlock("more");
1584  $wtpl->setVariable("URL_MORE", $more_link);
1585  $wtpl->setVariable("TEXT_MORE", $lng->txt("blog_list_more"));
1586  $wtpl->parseCurrentBlock();
1587  }
1588 
1589 
1590 
1591  if (!$is_active) {
1592  $wtpl->setCurrentBlock("draft_text");
1593  $wtpl->setVariable("DRAFT_TEXT", $lng->txt("blog_draft_text"));
1594  $wtpl->parseCurrentBlock();
1595  $wtpl->setVariable("DRAFT_CLASS", " ilBlogListItemDraft");
1596  }
1597 
1598  // reading time
1599  $reading_time = $this->reading_time_manager->getReadingTime(
1600  $this->object->getId(),
1601  $item["id"]
1602  );
1603  if (!is_null($reading_time)) {
1604  $this->lng->loadLanguageModule("copg");
1605  $wtpl->setCurrentBlock("reading_time");
1606  $wtpl->setVariable(
1607  "READING_TIME",
1608  $this->lng->txt("copg_est_reading_time") . ": " .
1609  sprintf($this->lng->txt("copg_x_minutes"), $reading_time)
1610  );
1611  $wtpl->parseCurrentBlock();
1612  }
1613 
1614  $wtpl->setCurrentBlock("posting");
1615 
1616  $author = "";
1617  if ($this->id_type === self::REPOSITORY_NODE_ID) {
1618  $authors = array();
1619 
1620  $author_id = $item["author"];
1621  if ($author_id) {
1622  $authors[] = ilUserUtil::getNamePresentation($author_id);
1623  }
1624 
1625  if (isset($item["editors"])) {
1626  foreach ($item["editors"] as $editor_id) {
1627  $authors[] = ilUserUtil::getNamePresentation($editor_id);
1628  }
1629  }
1630 
1631  if ($authors) {
1632  $author = implode(", ", $authors) . " - ";
1633  }
1634  }
1635 
1636  // title
1637  $wtpl->setVariable("URL_TITLE", $preview);
1638  $wtpl->setVariable("TITLE", $item["title"]);
1639 
1640  $kw = ilBlogPosting::getKeywords($this->obj_id, $item["id"]);
1641  natcasesort($kw);
1642  $keywords = (count($kw) > 0)
1643  ? "<br>" . $this->lng->txt("keywords") . ": " . implode(", ", $kw)
1644  : "";
1645 
1646  $wtpl->setVariable("DATETIME", $author .
1647  ilDatePresentation::formatDate($item["created"]) . $keywords);
1648 
1649  // content
1650  $wtpl->setVariable("CONTENT", $snippet);
1651 
1652  $wtpl->parseCurrentBlock();
1653  }
1654 
1655  // permalink
1656  if ($a_cmd === "previewFullscreen") {
1657  $this->tpl->setPermanentLink(
1658  "blog",
1659  $this->node_id,
1660  ($this->id_type === self::WORKSPACE_NODE_ID)
1661  ? "_wsp"
1662  : ""
1663  );
1664  }
1665 
1666  if (!$is_empty || $a_show_inactive) {
1667  return $wtpl->get();
1668  }
1669  return "";
1670  }
1671 
1675  protected function buildExportLink(
1676  string $a_template,
1677  string $a_type,
1678  string $a_id
1679  ): string {
1680  return \ILIAS\Blog\Export\BlogHtmlExport::buildExportLink($a_template, $a_type, $a_id, $this->getKeywords(false));
1681  }
1682 
1683 
1687  protected function renderNavigationByDate(
1688  array $a_items,
1689  string $a_list_cmd = "render",
1690  string $a_posting_cmd = "preview",
1691  ?string $a_link_template = null,
1692  bool $a_show_inactive = false,
1693  int $a_blpg = 0
1694  ): string {
1695  $ilCtrl = $this->ctrl;
1696 
1697  $blpg = ($a_blpg > 0)
1698  ? $a_blpg
1699  : $this->blpg;
1700 
1701 
1702  // gather page active status
1703  foreach ($a_items as $month => $postings) {
1704  foreach (array_keys($postings) as $id) {
1705  $active = ilBlogPosting::_lookupActive($id, "blp");
1706  if (!$a_show_inactive && !$active) {
1707  unset($a_items[$month][$id]);
1708  } else {
1709  $a_items[$month][$id]["active"] = $active;
1710  }
1711  }
1712  if (!count($a_items[$month])) {
1713  unset($a_items[$month]);
1714  }
1715  }
1716 
1717  // list month (incl. postings)
1718  if ($this->object->getNavMode() === ilObjBlog::NAV_MODE_LIST || $a_link_template) {
1719  //$max_detail_postings = $this->object->getNavModeListPostings();
1720  $max_months = $this->object->getNavModeListMonths();
1721 
1722  $wtpl = new ilTemplate("tpl.blog_list_navigation_by_date.html", true, true, "Modules/Blog");
1723 
1724  $ilCtrl->setParameter($this, "blpg", "");
1725 
1726  $counter = $mon_counter = $last_year = 0;
1727  foreach ($a_items as $month => $postings) {
1728  if (!$a_link_template && $max_months && $mon_counter >= $max_months) {
1729  break;
1730  }
1731 
1732  $add_year = false;
1733  $year = substr($month, 0, 4);
1734  if (!$last_year || $year != $last_year) {
1735  // #13562
1736  $add_year = true;
1737  $last_year = $year;
1738  }
1739 
1740  $mon_counter++;
1741 
1742  $month_name = ilCalendarUtil::_numericMonthToString((int) substr($month, 5));
1743 
1744  if (!$a_link_template) {
1745  $ilCtrl->setParameter($this, "bmn", $month);
1746  $month_url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1747  } else {
1748  $month_url = $this->buildExportLink($a_link_template, "list", $month);
1749  }
1750 
1751  // list postings for month
1752  //if($counter < $max_detail_postings)
1753  if ($mon_counter <= $this->object->getNavModeListMonthsWithPostings()) {
1754  if ($add_year) {
1755  $wtpl->setCurrentBlock("navigation_year_details");
1756  $wtpl->setVariable("YEAR", $year);
1757  $wtpl->parseCurrentBlock();
1758  }
1759 
1760  foreach ($postings as $id => $posting) {
1761  //if($max_detail_postings && $counter >= $max_detail_postings)
1762  //{
1763  // break;
1764  //}
1765 
1766  $counter++;
1767 
1768  $caption = /* ilDatePresentation::formatDate($posting["created"], IL_CAL_DATETIME).
1769  ", ".*/ $posting["title"];
1770 
1771  if (!$a_link_template) {
1772  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $month);
1773  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $id);
1774  $url = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_posting_cmd);
1775  } else {
1776  $url = $this->buildExportLink($a_link_template, "posting", $id);
1777  }
1778 
1779  if (!$posting["active"]) {
1780  $wtpl->setVariable("NAV_ITEM_DRAFT", $this->lng->txt("blog_draft"));
1781  } elseif ($this->object->hasApproval() && !$posting["approved"]) {
1782  $wtpl->setVariable("NAV_ITEM_APPROVAL", $this->lng->txt("blog_needs_approval"));
1783  }
1784 
1785  $wtpl->setCurrentBlock("navigation_item");
1786  $wtpl->setVariable("NAV_ITEM_URL", $url);
1787  $wtpl->setVariable("NAV_ITEM_CAPTION", $caption);
1788  $wtpl->parseCurrentBlock();
1789  }
1790 
1791  $wtpl->setCurrentBlock("navigation_month_details");
1792  $wtpl->setVariable("NAV_MONTH", $month_name);
1793  $wtpl->setVariable("URL_MONTH", $month_url);
1794  }
1795  // summarized month
1796  else {
1797  if ($add_year) {
1798  $wtpl->setCurrentBlock("navigation_year");
1799  $wtpl->setVariable("YEAR", $year);
1800  $wtpl->parseCurrentBlock();
1801  }
1802 
1803  $wtpl->setCurrentBlock("navigation_month");
1804  $wtpl->setVariable("MONTH_NAME", $month_name);
1805  $wtpl->setVariable("URL_MONTH", $month_url);
1806  $wtpl->setVariable("MONTH_COUNT", count($postings));
1807  }
1808  $wtpl->parseCurrentBlock();
1809  }
1810 
1811  if (!$a_link_template) {
1812  $this->ctrl->setParameterByClass(self::class, "bmn", null);
1813  $url = $this->ctrl->getLinkTargetByClass(self::class, $a_list_cmd);
1814  } else {
1815  $url = "index.html";
1816  }
1817  $wtpl->setVariable(
1818  "STARTING_PAGE",
1819  $this->ui->renderer()->render(
1820  $this->ui->factory()->link()->standard(
1821  $this->lng->txt("blog_starting_page"),
1822  $url
1823  )
1824  )
1825  );
1826  }
1827  // single month
1828  else {
1829  $wtpl = new ilTemplate("tpl.blog_list_navigation_month.html", true, true, "Modules/Blog");
1830 
1831  $ilCtrl->setParameter($this, "blpg", "");
1832 
1833  $month_options = array();
1834  foreach ($a_items as $month => $postings) {
1835  $month_name = ilCalendarUtil::_numericMonthToString((int) substr($month, 5)) .
1836  " " . substr($month, 0, 4);
1837 
1838  $month_options[$month] = $month_name;
1839 
1840  if ($month == $this->month) {
1841  if (!$a_link_template) {
1842  $ilCtrl->setParameter($this, "bmn", $month);
1843  $month_url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1844  } else {
1845  $month_url = $this->buildExportLink($a_link_template, "list", $month);
1846  }
1847 
1848  foreach ($postings as $id => $posting) {
1849  $caption = /* ilDatePresentation::formatDate($posting["created"], IL_CAL_DATETIME).
1850  ", ".*/ $posting["title"];
1851 
1852  if (!$a_link_template) {
1853  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", $month);
1854  $ilCtrl->setParameterByClass("ilblogpostinggui", "blpg", $id);
1855  $url = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", $a_posting_cmd);
1856  } else {
1857  $url = $this->buildExportLink($a_link_template, "posting", $id);
1858  }
1859 
1860  if (!$posting["active"]) {
1861  $wtpl->setVariable("NAV_ITEM_DRAFT", $this->lng->txt("blog_draft"));
1862  } elseif ($this->object->hasApproval() && !$posting["approved"]) {
1863  $wtpl->setVariable("NAV_ITEM_APPROVAL", $this->lng->txt("blog_needs_approval"));
1864  }
1865 
1866  $wtpl->setCurrentBlock("navigation_item");
1867  $wtpl->setVariable("NAV_ITEM_URL", $url);
1868  $wtpl->setVariable("NAV_ITEM_CAPTION", $caption);
1869  $wtpl->parseCurrentBlock();
1870  }
1871 
1872  $wtpl->setCurrentBlock("navigation_month_details");
1873  if ($blpg > 0) {
1874  $wtpl->setVariable("NAV_MONTH", $month_name);
1875  $wtpl->setVariable("URL_MONTH", $month_url);
1876  }
1877  $wtpl->parseCurrentBlock();
1878  }
1879  }
1880 
1881  if ($blpg === 0) {
1882  $wtpl->setCurrentBlock("option_bl");
1883  foreach ($month_options as $value => $caption) {
1884  $wtpl->setVariable("OPTION_VALUE", $value);
1885  $wtpl->setVariable("OPTION_CAPTION", $caption);
1886  if ($value == $this->month) {
1887  $wtpl->setVariable("OPTION_SEL", ' selected="selected"');
1888  }
1889  $wtpl->parseCurrentBlock();
1890  }
1891 
1892  $wtpl->setVariable("FORM_ACTION", $ilCtrl->getFormAction($this, $a_list_cmd));
1893  }
1894  }
1895  $ilCtrl->setParameter($this, "bmn", $this->month);
1896  $ilCtrl->setParameterByClass("ilblogpostinggui", "bmn", "");
1897  return $wtpl->get();
1898  }
1899 
1903  protected function renderNavigationByKeywords(
1904  string $a_list_cmd = "render",
1905  bool $a_show_inactive = false,
1906  string $a_link_template = "",
1907  int $a_blpg = 0
1908  ): string {
1909  $ilCtrl = $this->ctrl;
1910 
1911  $blpg = ($a_blpg > 0)
1912  ? $a_blpg
1913  : $this->blpg;
1914 
1915  $keywords = $this->getKeywords($a_show_inactive, $blpg);
1916  if ($keywords) {
1917  $wtpl = new ilTemplate("tpl.blog_list_navigation_keywords.html", true, true, "Modules/Blog");
1918 
1919  $max = max($keywords);
1920 
1921  $wtpl->setCurrentBlock("keyword");
1922  foreach ($keywords as $keyword => $counter) {
1923  if (!$a_link_template) {
1924  $ilCtrl->setParameter($this, "kwd", urlencode((string) $keyword)); // #15885
1925  $url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1926  $ilCtrl->setParameter($this, "kwd", "");
1927  } else {
1928  $url = $this->buildExportLink($a_link_template, "keyword", $keyword);
1929  }
1930 
1931  $wtpl->setVariable("TXT_KEYWORD", $keyword);
1932  $wtpl->setVariable("CLASS_KEYWORD", ilTagging::getRelevanceClass($counter, $max));
1933  $wtpl->setVariable("URL_KEYWORD", $url);
1934  $wtpl->parseCurrentBlock();
1935  }
1936 
1937  return $wtpl->get();
1938  }
1939  return "";
1940  }
1941 
1942  protected function renderNavigationByAuthors(
1943  array $a_items,
1944  string $a_list_cmd = "render",
1945  bool $a_show_inactive = false
1946  ): string {
1947  $ilCtrl = $this->ctrl;
1948 
1949  $authors = array();
1950  foreach ($a_items as $month => $items) {
1951  foreach ($items as $item) {
1952  if (($a_show_inactive || ilBlogPosting::_lookupActive($item["id"], "blp"))) {
1953  if ($item["author"]) {
1954  $authors[] = $item["author"];
1955  }
1956 
1957  if (isset($item["editors"])) {
1958  foreach ($item["editors"] as $editor_id) {
1959  if ($editor_id != $item["author"]) {
1960  $authors[] = $editor_id;
1961  }
1962  }
1963  }
1964  }
1965  }
1966  }
1967 
1968  $authors = array_unique($authors);
1969 
1970  // filter out deleted users
1971  $authors = array_filter($authors, function ($id) {
1972  return ilObject::_lookupType($id) == "usr";
1973  });
1974 
1975  if (count($authors) > 1) {
1976  $list = array();
1977  foreach ($authors as $user_id) {
1978  if ($user_id) {
1979  $ilCtrl->setParameter($this, "ath", $user_id);
1980  $url = $ilCtrl->getLinkTarget($this, $a_list_cmd);
1981  $ilCtrl->setParameter($this, "ath", "");
1982 
1983  $base_name = ilUserUtil::getNamePresentation($user_id);
1984  if (substr($base_name, 0, 1) == "[") {
1985  $name = ilUserUtil::getNamePresentation($user_id, true);
1986  $sort = $name;
1987  } else {
1989  $user_id,
1990  true,
1991  false,
1992  "",
1993  false,
1994  true,
1995  false
1996  );
1997  $name_arr = ilObjUser::_lookupName($user_id);
1998  $sort = $name_arr["lastname"] . " " . $name_arr["firstname"];
1999  }
2000 
2001  $idx = trim(strip_tags($sort)) . "///" . $user_id; // #10934
2002  $list[$idx] = array($name, $url);
2003  }
2004  }
2005  ksort($list);
2006 
2007  $wtpl = new ilTemplate("tpl.blog_list_navigation_authors.html", true, true, "Modules/Blog");
2008 
2009  $wtpl->setCurrentBlock("author");
2010  foreach ($list as $author) {
2011  $wtpl->setVariable("TXT_AUTHOR", $author[0]);
2012  $wtpl->setVariable("URL_AUTHOR", $author[1]);
2013  $wtpl->parseCurrentBlock();
2014  }
2015 
2016  return $wtpl->get();
2017  }
2018  return "";
2019  }
2020 
2024  public function renderToolbarNavigation(
2025  array $a_items,
2026  bool $single_posting = false
2027  ): void {
2028  global $DIC;
2029 
2030  $toolbar = $DIC->toolbar();
2031  $lng = $DIC->language();
2032  $ctrl = $DIC->ctrl();
2033 
2034  $f = $DIC->ui()->factory();
2035 
2036  $cmd = ($this->prtf_embed)
2037  ? "previewEmbedded"
2038  : "previewFullscreen";
2039 
2040  if ($single_posting) { // single posting view
2041  $latest_posting = $this->getLatestPosting($a_items);
2042  if ($latest_posting > 0 && $this->blpg !== $latest_posting) {
2043  $ctrl->setParameterByClass("ilblogpostinggui", "blpg", $latest_posting);
2044  $mb = $f->button()->standard(
2045  $lng->txt("blog_latest_posting"),
2046  $ctrl->getLinkTargetByClass("ilblogpostinggui", $cmd)
2047  );
2048  } else {
2049  $mb = $f->button()->standard($lng->txt("blog_latest_posting"), "#")->withUnavailableAction();
2050  }
2051 
2052  $prev_posting = $this->getPreviousPosting($a_items);
2053  if ($prev_posting > 0) {
2054  $ctrl->setParameterByClass("ilblogpostinggui", "blpg", $prev_posting);
2055  $pb = $f->button()->standard(
2056  $lng->txt("previous"),
2057  $ctrl->getLinkTargetByClass("ilblogpostinggui", $cmd)
2058  );
2059  } else {
2060  $pb = $f->button()->standard($lng->txt("previous"), "#")->withUnavailableAction();
2061  }
2062 
2063  $next_posting = $this->getNextPosting($a_items);
2064  if ($next_posting > 0) {
2065  $ctrl->setParameterByClass("ilblogpostinggui", "blpg", $next_posting);
2066  $nb = $f->button()->standard(
2067  $lng->txt("next"),
2068  $ctrl->getLinkTargetByClass("ilblogpostinggui", $cmd)
2069  );
2070  } else {
2071  $nb = $f->button()->standard($lng->txt("next"), "#")->withUnavailableAction();
2072  }
2073  $ctrl->setParameter($this, "blpg", $this->blpg);
2074  $vc = $f->viewControl()->section($pb, $mb, $nb);
2075  $toolbar->addComponent($vc);
2076  if ($this->mayContribute() && $this->mayEditPosting($this->blpg)) {
2077  $ctrl->setParameter($this, "prvm", "");
2078 
2079 
2080  $ctrl->setParameter($this, "bmn", "");
2081  $ctrl->setParameter($this, "blpg", "");
2082  $link = $ctrl->getLinkTarget($this, "");
2083  $ctrl->setParameter($this, "blpg", $this->blpg);
2084  $ctrl->setParameter($this, "bmn", $this->month);
2086  $toolbar->addComponent($f->button()->standard($lng->txt("blog_edit"), $link));
2087 
2088 
2089  $ctrl->setParameterByClass("ilblogpostinggui", "blpg", $this->blpg);
2090  /*if ($this->prtf_embed) {
2091  $this->ctrl->setParameterByClass("ilobjportfoliogui", "ppage", $this->user_page);
2092  }*/
2093  $link = $ctrl->getLinkTargetByClass("ilblogpostinggui", "edit");
2094  $toolbar->addComponent($f->button()->standard($lng->txt("blog_edit_posting"), $link));
2095  }
2096  } else { // month view
2097  $latest_month = $this->getLatestMonth($a_items);
2098  if ($latest_month !== "" && $this->month !== $latest_month) {
2099  $ctrl->setParameter($this, "bmn", $latest_month);
2100  $mb = $f->button()->standard(
2101  $lng->txt("blog_latest_posting"),
2102  $ctrl->getLinkTarget($this, "preview")
2103  );
2104  } else {
2105  $mb = $f->button()->standard($lng->txt("blog_latest_posting"), "#")->withUnavailableAction();
2106  }
2107 
2108  $prev_month = $this->getPreviousMonth($a_items);
2109  if ($prev_month !== "") {
2110  $ctrl->setParameter($this, "bmn", $prev_month);
2111  $pb = $f->button()->standard($lng->txt("previous"), $ctrl->getLinkTarget($this, "preview"));
2112  } else {
2113  $pb = $f->button()->standard($lng->txt("previous"), "#")->withUnavailableAction();
2114  }
2115 
2116  $next_month = $this->getNextMonth($a_items);
2117  if ($next_month !== "") {
2118  $ctrl->setParameter($this, "bmn", $next_month);
2119  $nb = $f->button()->standard($lng->txt("next"), $ctrl->getLinkTarget($this, "preview"));
2120  } else {
2121  $nb = $f->button()->standard($lng->txt("next"), "#")->withUnavailableAction();
2122  }
2123  $ctrl->setParameter($this, "bmn", $this->month);
2124  $vc = $f->viewControl()->section($pb, $mb, $nb);
2125  $toolbar->addComponent($vc);
2126 
2127  if ($this->mayContribute()) {
2128  $ctrl->setParameter($this, "prvm", "");
2129 
2130  $ctrl->setParameter($this, "bmn", "");
2131  $ctrl->setParameter($this, "blpg", "");
2132  $link = $ctrl->getLinkTarget($this, "");
2133  $ctrl->setParameter($this, "blpg", $this->blpg);
2134  $ctrl->setParameter($this, "bmn", $this->month);
2136  $toolbar->addComponent($f->button()->standard($lng->txt("blog_edit"), $link));
2137  }
2138  }
2139  }
2140 
2144  public function getNextMonth(
2145  array $a_items
2146  ): string {
2147  reset($a_items);
2148  $found = "";
2149  foreach ($a_items as $month => $items) {
2150  if ($month > $this->month) {
2151  $found = $month;
2152  }
2153  }
2154  return $found;
2155  }
2156 
2157  public function getPreviousMonth(
2158  array $a_items
2159  ): string {
2160  reset($a_items);
2161  $found = "";
2162  foreach ($a_items as $month => $items) {
2163  if ($month < $this->month && $found === "") {
2164  $found = $month;
2165  }
2166  }
2167  return $found;
2168  }
2169 
2173  public function getLatestMonth(
2174  array $a_items
2175  ): string {
2176  reset($a_items);
2177  return key($a_items);
2178  }
2179 
2185  public function getNextPosting(
2186  array $a_items
2187  ): int {
2188  reset($a_items);
2189  $found = "";
2190  $next_blpg = 0;
2191  foreach ($a_items as $month => $items) {
2192  foreach ($items as $item) {
2193  if ($item["id"] == $this->blpg) {
2194  $found = true;
2195  }
2196  if (!$found) {
2197  $next_blpg = (int) $item["id"];
2198  }
2199  }
2200  }
2201  return $next_blpg;
2202  }
2203 
2209  public function getPreviousPosting(
2210  array $a_items
2211  ): int {
2212  reset($a_items);
2213  $found = "";
2214  $prev_blpg = 0;
2215  foreach ($a_items as $month => $items) {
2216  foreach ($items as $item) {
2217  if ($found && $prev_blpg === 0) {
2218  $prev_blpg = (int) $item["id"];
2219  }
2220  if ((int) $item["id"] === $this->blpg) {
2221  $found = true;
2222  }
2223  }
2224  }
2225  return $prev_blpg;
2226  }
2227 
2233  public function getLatestPosting(
2234  array $a_items
2235  ): int {
2236  reset($a_items);
2237  $month = current($a_items);
2238  if (is_array($month)) {
2239  return (int) current($month)["id"];
2240  }
2241  return 0;
2242  }
2243 
2247  public function renderNavigation(
2248  string $a_list_cmd = "render",
2249  string $a_posting_cmd = "preview",
2250  string $a_link_template = null,
2251  bool $a_show_inactive = false,
2252  int $a_blpg = 0
2253  ): string {
2255  $a_items = $this->items;
2256 
2257  $blpg = ($a_blpg > 0)
2258  ? $a_blpg
2259  : $this->blpg;
2260 
2261  if ($this->object->getOrder()) {
2262  $order = array_flip($this->object->getOrder());
2263  } else {
2264  $order = array(
2265  "navigation" => 0
2266  ,"keywords" => 2
2267  ,"authors" => 1
2268  );
2269  }
2270 
2271  $wtpl = new ilTemplate("tpl.blog_list_navigation.html", true, true, "Modules/Blog");
2272 
2273  $blocks = array();
2274 
2275  // by date
2276  if (count($a_items)) {
2277  $blocks[$order["navigation"]] = array(
2278  $this->lng->txt("blog_navigation"),
2279  $this->renderNavigationByDate($a_items, $a_list_cmd, $a_posting_cmd, $a_link_template, $a_show_inactive, $a_blpg)
2280  );
2281  }
2282 
2283  if ($this->object->hasKeywords()) {
2284  // keywords
2285  $may_edit_keywords = ($blpg > 0 &&
2286  $this->mayEditPosting($blpg) &&
2287  $a_list_cmd !== "preview" &&
2288  $a_list_cmd !== "gethtml" &&
2289  !$a_link_template);
2290  $keywords = $this->renderNavigationByKeywords($a_list_cmd, $a_show_inactive, (bool) $a_link_template, $a_blpg);
2291  if ($keywords || $may_edit_keywords) {
2292  if (!$keywords) {
2293  $keywords = $this->lng->txt("blog_no_keywords");
2294  }
2295  $cmd = null;
2296  $blocks[$order["keywords"]] = array(
2297  $this->lng->txt("blog_keywords"),
2298  $keywords,
2299  $cmd
2300  ? array($cmd, $this->lng->txt("blog_edit_keywords"))
2301  : null
2302  );
2303  }
2304  }
2305 
2306  // is not part of (html) export
2307  if (!$a_link_template) {
2308  // authors
2309  if ($this->id_type === self::REPOSITORY_NODE_ID &&
2310  $this->object->hasAuthors()) {
2311  $authors = $this->renderNavigationByAuthors($a_items, $a_list_cmd, $a_show_inactive);
2312  if ($authors) {
2313  $blocks[$order["authors"]] = array($this->lng->txt("blog_authors"), $authors);
2314  }
2315  }
2316 
2317  // rss
2318  if ($this->object->hasRSS() &&
2319  $ilSetting->get('enable_global_profiles') &&
2320  $a_list_cmd === "preview") {
2321  // #10827
2322  $blog_id = $this->node_id;
2323  if ($this->id_type !== self::WORKSPACE_NODE_ID) {
2324  $blog_id .= "_cll";
2325  }
2326  $url = ILIAS_HTTP_PATH . "/feed.php?blog_id=" . $blog_id .
2327  "&client_id=" . rawurlencode(CLIENT_ID);
2328 
2329  $wtpl->setVariable("RSS_BUTTON", ilRSSButtonGUI::get(ilRSSButtonGUI::ICON_RSS, $url));
2330  }
2331  }
2332 
2333  if (count($blocks)) {
2334  global $DIC;
2335 
2336  $ui_factory = $DIC->ui()->factory();
2337  $ui_renderer = $DIC->ui()->renderer();
2338 
2339  ksort($blocks);
2340  foreach ($blocks as $block) {
2341  $title = $block[0];
2342 
2343  $content = $block[1];
2344 
2345  $secondary_panel = $ui_factory->panel()->secondary()->legacy($title, $ui_factory->legacy($content));
2346 
2347  if (isset($block[2]) && is_array($block[2])) {
2348  $link = $ui_factory->button()->shy($block[2][1], $block[2][0]);
2349  $secondary_panel = $secondary_panel->withFooter($link);
2350  }
2351 
2352  $wtpl->setCurrentBlock("block_bl");
2353  $wtpl->setVariable("BLOCK", $ui_renderer->render($secondary_panel));
2354  $wtpl->parseCurrentBlock();
2355  }
2356  }
2357 
2358  return $wtpl->get();
2359  }
2360 
2364  public function getKeywords(
2365  bool $a_show_inactive,
2366  ?int $a_posting_id = null
2367  ): array {
2368  $keywords = array();
2369  if ($a_posting_id) {
2370  foreach (ilBlogPosting::getKeywords($this->obj_id, $a_posting_id) as $keyword) {
2371  if (isset($keywords[$keyword])) {
2372  $keywords[$keyword]++;
2373  } else {
2374  $keywords[$keyword] = 1;
2375  }
2376  }
2377  } else {
2378  foreach ($this->items as $month => $items) {
2379  foreach ($items as $item) {
2380  if ($a_show_inactive || ilBlogPosting::_lookupActive($item["id"], "blp")) {
2381  foreach (ilBlogPosting::getKeywords($this->obj_id, $item["id"]) as $keyword) {
2382  if (isset($keywords[$keyword])) {
2383  $keywords[$keyword]++;
2384  } else {
2385  $keywords[$keyword] = 1;
2386  }
2387  }
2388  }
2389  }
2390  }
2391  }
2392 
2393  // #15881
2394  $tmp = array();
2395  foreach ($keywords as $keyword => $counter) {
2396  $tmp[] = array("keyword" => $keyword, "counter" => $counter);
2397  }
2398  $tmp = ilArrayUtil::sortArray($tmp, "keyword", "ASC");
2399 
2400  $keywords = array();
2401  foreach ($tmp as $item) {
2402  $keywords[(string) $item["keyword"]] = $item["counter"];
2403  }
2404  return $keywords;
2405  }
2406 
2410  public function buildExportFile(
2411  bool $a_include_comments = false,
2412  bool $print_version = false
2413  ): string {
2414  $type = "html";
2415  $format = explode("_", $this->blog_request->getFormat());
2416  if (($format[1] ?? "") === "comments" || $a_include_comments) {
2417  $a_include_comments = true;
2418  $type = "html_comments";
2419  }
2420 
2421  // create export file
2422  ilExport::_createExportDirectory($this->object->getId(), $type, "blog");
2423  $exp_dir = ilExport::_getExportDirectory($this->object->getId(), $type, "blog");
2424 
2425  $subdir = $this->object->getType() . "_" . $this->object->getId();
2426  if ($print_version) {
2427  $subdir .= "print";
2428  }
2429 
2430  $blog_export = new \ILIAS\Blog\Export\BlogHtmlExport($this, $exp_dir, $subdir);
2431  $blog_export->setPrintVersion($print_version);
2432  $blog_export->includeComments($a_include_comments);
2433  return $blog_export->exportHTML();
2434  }
2435 
2436  public function getNotesSubId(): int
2437  {
2438  return $this->blpg;
2439  }
2440 
2441  public function disableNotes(bool $a_value = false): void
2442  {
2443  $this->disable_notes = $a_value;
2444  }
2445 
2446  protected function addHeaderActionForCommand(
2447  string $a_cmd
2448  ): void {
2449  $ilUser = $this->user;
2450  $ilCtrl = $this->ctrl;
2451  // preview?
2452  if ($a_cmd === "preview" || $a_cmd === "previewEmbedded" || $a_cmd === "previewFullscreen" || $this->prvm) {
2453  // notification
2454  if ($ilUser->getId() !== ANONYMOUS_USER_ID) {
2455  if (!$this->prvm) {
2456  $ilCtrl->setParameter($this, "prvm", "fsc");
2457  }
2458  $this->insertHeaderAction($this->initHeaderAction(null, null, true));
2459  if (!$this->prvm) {
2460  $ilCtrl->setParameter($this, "prvm", "");
2461  }
2462  }
2463  } else {
2464  $this->addHeaderAction();
2465  }
2466  }
2467 
2468  protected function initHeaderAction(
2469  ?string $sub_type = null,
2470  ?int $sub_id = null,
2471  bool $is_preview = false
2472  ): ?ilObjectListGUI {
2473  $ilUser = $this->user;
2474  $ilCtrl = $this->ctrl;
2475  if (!$this->obj_id) {
2476  return null;
2477  }
2478  $sub_type = $sub_id = null;
2479  if ($this->blpg > 0) {
2480  $sub_type = "blp";
2481  $sub_id = $this->blpg;
2482  }
2483 
2484  $lg = parent::initHeaderAction($sub_type, $sub_id);
2485  if (!$lg) {
2486  return null;
2487  }
2488  $lg->enableComments(false);
2489  $lg->enableNotes(false);
2490 
2491  if ($is_preview) {
2492  if ($this->blpg > 0) {
2493  if (($this->object->getNotesStatus() && !$this->disable_notes)) {
2494  $lg->enableComments(true);
2495  }
2496  $lg->enableNotes(true);
2497  }
2498  $lg->enableTags(false);
2499 
2500  if (!$this->prtf_embed) {
2502  $ilCtrl->setParameter($this, "ntf", 1);
2503  $link = $ilCtrl->getLinkTarget($this, "setNotification");
2504  $ilCtrl->setParameter($this, "ntf", "");
2505  if (ilNotification::hasOptOut($this->obj_id)) {
2506  $lg->addCustomCommand($link, "blog_notification_toggle_off");
2507  }
2508 
2509  $lg->addHeaderIcon(
2510  "not_icon",
2511  ilUtil::getImagePath("notification_on.svg"),
2512  $this->lng->txt("blog_notification_activated")
2513  );
2514  } else {
2515  $ilCtrl->setParameter($this, "ntf", 2);
2516  $link = $ilCtrl->getLinkTarget($this, "setNotification");
2517  $ilCtrl->setParameter($this, "ntf", "");
2518  $lg->addCustomCommand($link, "blog_notification_toggle_on");
2519 
2520  $lg->addHeaderIcon(
2521  "not_icon",
2522  ilUtil::getImagePath("notification_off.svg"),
2523  $this->lng->txt("blog_notification_deactivated")
2524  );
2525  }
2526  }
2527 
2528  // #11758
2529  if ($this->mayContribute()) {
2530  $ilCtrl->setParameter($this, "prvm", "");
2531 
2532  $ilCtrl->setParameter($this, "bmn", "");
2533  $ilCtrl->setParameter($this, "blpg", "");
2534  $link = $ilCtrl->getLinkTarget($this, "");
2535  $ilCtrl->setParameter($this, "blpg", $sub_id);
2536  $ilCtrl->setParameter($this, "bmn", $this->month);
2537  $lg->addCustomCommand($link, "blog_edit"); // #11868
2538 
2539  if ($sub_id && $this->mayEditPosting($sub_id)) {
2540  $link = $ilCtrl->getLinkTargetByClass("ilblogpostinggui", "edit");
2541  $lg->addCustomCommand($link, "blog_edit_posting");
2542  }
2543 
2544  $ilCtrl->setParameter($this, "prvm", "fsc");
2545  }
2546 
2547  $ilCtrl->setParameter($this, "ntf", "");
2548  }
2549 
2550  return $lg;
2551  }
2552 
2553  protected function setNotification(): void
2554  {
2555  $ilUser = $this->user;
2556  $ilCtrl = $this->ctrl;
2557 
2558  switch ($this->ntf) {
2559  case 1:
2561  break;
2562 
2563  case 2:
2565  break;
2566  }
2567 
2568  $ilCtrl->redirect($this, "preview");
2569  }
2570 
2574  public static function lookupSubObjectTitle(
2575  int $a_blog_id,
2576  int $a_posting_id
2577  ): string {
2578  // page might be deleted, so setting halt on errors to false
2579  $post = new ilBlogPosting($a_posting_id);
2580  if ($post->getBlogId() === $a_blog_id) {
2581  return $post->getTitle();
2582  }
2583  return "";
2584  }
2585 
2589  protected function filterInactivePostings(): void
2590  {
2591  foreach ($this->items as $month => $postings) {
2592  foreach ($postings as $id => $item) {
2593  if (!ilBlogPosting::_lookupActive($id, "blp")) {
2594  unset($this->items[$month][$id]);
2595  } elseif ($this->object->hasApproval() && !$item["approved"]) {
2596  unset($this->items[$month][$id]);
2597  }
2598  }
2599  if (!count($this->items[$month])) {
2600  unset($this->items[$month]);
2601  }
2602  }
2603 
2604  if ($this->items && !isset($this->items[$this->month])) {
2605  $keys = array_keys($this->items);
2606  $this->month = array_shift($keys);
2607  }
2608  }
2609 
2610  public function filterItemsByKeyword(
2611  array $a_items,
2612  string $a_keyword
2613  ): array {
2614  $res = [];
2615  foreach ($a_items as $month => $items) {
2616  foreach ($items as $item) {
2617  if (in_array(
2618  $a_keyword,
2619  ilBlogPosting::getKeywords($this->obj_id, $item["id"])
2620  )) {
2621  $res[] = $item;
2622  }
2623  }
2624  }
2625  return $res;
2626  }
2627 
2631  protected function isAdmin(): bool
2632  {
2633  return ($this->checkPermissionBool("redact") ||
2634  $this->checkPermissionBool("write"));
2635  }
2636 
2640  protected function mayEditPosting(
2641  int $a_posting_id,
2642  int $a_author_id = null
2643  ): bool {
2644  $ilUser = $this->user;
2645 
2646  // single author blog (owner) in personal workspace
2647  if ($this->id_type === self::WORKSPACE_NODE_ID) {
2648  return $this->checkPermissionBool("write");
2649  }
2650 
2651  // repository blogs
2652 
2653  // redact allows to edit all postings
2654  if ($this->checkPermissionBool("redact")) {
2655  return true;
2656  }
2657 
2658  // contribute gives access to own postings
2659  if ($this->checkPermissionBool("contribute")) {
2660  // check owner of posting
2661  if (!$a_author_id) {
2662  $post = new ilBlogPosting($a_posting_id);
2663  $a_author_id = $post->getAuthor();
2664  }
2665  return $ilUser->getId() === $a_author_id;
2666  }
2667  return false;
2668  }
2669 
2673  protected function mayContribute(): bool
2674  {
2675  // single author blog (owner) in personal workspace
2676  if ($this->id_type == self::WORKSPACE_NODE_ID) {
2677  return $this->checkPermissionBool("write");
2678  }
2679 
2680  return ($this->checkPermissionBool("redact") ||
2681  $this->checkPermissionBool("contribute"));
2682  }
2683 
2684  protected function addLocatorItems(): void
2685  {
2686  $ilLocator = $this->locator;
2687 
2688  if (is_object($this->object)) {
2689  $ilLocator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, "preview"), "", $this->node_id);
2690  }
2691  }
2692 
2693  public function approve(): void
2694  {
2695  if ($this->isAdmin() && $this->apid > 0) {
2696  $post = new ilBlogPosting($this->apid);
2697  $post->setApproved(true);
2698  $post->setBlogNodeId($this->node_id, ($this->id_type == self::WORKSPACE_NODE_ID));
2699  $post->update(true, false, true, "new"); // #13434
2700 
2701  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
2702  }
2703 
2704  $this->ctrl->redirect($this, "render");
2705  }
2706 
2707 
2708  //
2709  // contributors
2710  //
2711 
2712  public function contributors(): void
2713  {
2714  $ilTabs = $this->tabs;
2715  $ilToolbar = $this->toolbar;
2716  $ilCtrl = $this->ctrl;
2717  $lng = $this->lng;
2718  $tpl = $this->tpl;
2719 
2720  if (!$this->checkPermissionBool("write")) {
2721  return;
2722  }
2723 
2724  $ilTabs->activateTab("contributors");
2725 
2726  $local_roles = $this->object->getAllLocalRoles($this->node_id);
2727 
2728  // add member
2730  $this,
2731  $ilToolbar,
2732  array(
2733  'auto_complete_name' => $lng->txt('user'),
2734  'submit_name' => $lng->txt('add'),
2735  'add_search' => true,
2736  'add_from_container' => $this->node_id,
2737  'user_type' => $local_roles
2738  ),
2739  true
2740  );
2741 
2742  $other_roles = $this->object->getRolesWithContributeOrRedact($this->node_id);
2743  if ($other_roles) {
2744  $this->tpl->setOnScreenMessage('info', sprintf($lng->txt("blog_contribute_other_roles"), implode(", ", $other_roles)));
2745  }
2746 
2747  $tbl = new ilContributorTableGUI($this, "contributors", $this->object->getAllLocalRoles($this->node_id));
2748 
2749  $tpl->setContent($tbl->getHTML());
2750  }
2751 
2755  public function addUserFromAutoComplete(): void
2756  {
2757  $lng = $this->lng;
2758 
2759  $user_login = $this->blog_request->getUserLogin();
2760  $user_type = $this->blog_request->getUserType();
2761 
2762  if (trim($user_login) === '') {
2763  $this->tpl->setOnScreenMessage('failure', $lng->txt('msg_no_search_string'));
2764  $this->contributors();
2765  return;
2766  }
2767  $users = explode(',', $user_login);
2768 
2769  $user_ids = array();
2770  foreach ($users as $user) {
2771  $user_id = ilObjUser::_lookupId($user);
2772 
2773  if (!$user_id) {
2774  $this->tpl->setOnScreenMessage('failure', $lng->txt('user_not_known'));
2775  $this->contributors();
2776  return;
2777  }
2778 
2779  $user_ids[] = (int) $user_id;
2780  }
2781 
2782  $this->addContributor($user_ids, $user_type);
2783  }
2784 
2788  public function addContributor(
2789  array $a_user_ids = array(),
2790  ?string $a_user_type = null
2791  ): void {
2792  $ilCtrl = $this->ctrl;
2793  $lng = $this->lng;
2794  $rbacreview = $this->rbac_review;
2795  $rbacadmin = $this->rbacadmin;
2796  $a_user_type = (int) $a_user_type;
2797 
2798  if (!$this->checkPermissionBool("write")) {
2799  return;
2800  }
2801 
2802  if (!count($a_user_ids) || !$a_user_type) {
2803  $this->tpl->setOnScreenMessage('failure', $lng->txt("no_checkbox"));
2804  $this->contributors();
2805  return;
2806  }
2807 
2808  // get contributor role
2809  $local_roles = array_keys($this->object->getAllLocalRoles($this->node_id));
2810  if (!in_array($a_user_type, $local_roles)) {
2811  $this->tpl->setOnScreenMessage('failure', $lng->txt("missing_perm"));
2812  $this->contributors();
2813  return;
2814  }
2815 
2816  foreach ($a_user_ids as $user_id) {
2817  if (!$rbacreview->isAssigned($user_id, $a_user_type)) {
2818  $rbacadmin->assignUser($a_user_type, $user_id);
2819  }
2820  }
2821 
2822  $this->tpl->setOnScreenMessage('success', $lng->txt("settings_saved"), true);
2823  $ilCtrl->redirect($this, "contributors");
2824  }
2825 
2829  public function confirmRemoveContributor(): void
2830  {
2831  $ids = $this->blog_request->getIds();
2832 
2833  if (count($ids) === 0) {
2834  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
2835  $this->ctrl->redirect($this, "contributors");
2836  }
2837 
2838  $confirm = new ilConfirmationGUI();
2839  $confirm->setHeaderText($this->lng->txt('blog_confirm_delete_contributors'));
2840  $confirm->setFormAction($this->ctrl->getFormAction($this, 'removeContributor'));
2841  $confirm->setConfirm($this->lng->txt('delete'), 'removeContributor');
2842  $confirm->setCancel($this->lng->txt('cancel'), 'contributors');
2843 
2844  foreach ($ids as $user_id) {
2845  $confirm->addItem(
2846  'id[]',
2847  $user_id,
2848  ilUserUtil::getNamePresentation($user_id, false, false, "", true)
2849  );
2850  }
2851 
2852  $this->tpl->setContent($confirm->getHTML());
2853  }
2854 
2855  public function removeContributor(): void
2856  {
2857  $ilCtrl = $this->ctrl;
2858  $lng = $this->lng;
2859  $rbacadmin = $this->rbacadmin;
2860 
2861  $ids = $this->blog_request->getIds();
2862 
2863  if (count($ids) === 0) {
2864  $this->tpl->setOnScreenMessage('failure', $lng->txt("select_one"), true);
2865  $ilCtrl->redirect($this, "contributors");
2866  }
2867 
2868  // get contributor role
2869  $local_roles = array_keys($this->object->getAllLocalRoles($this->node_id));
2870  if (!$local_roles) {
2871  $this->tpl->setOnScreenMessage('failure', $lng->txt("missing_perm"));
2872  $this->contributors();
2873  return;
2874  }
2875 
2876  foreach ($ids as $user_id) {
2877  foreach ($local_roles as $role_id) {
2878  $rbacadmin->deassignUser($role_id, $user_id);
2879  }
2880  }
2881 
2882  $this->tpl->setOnScreenMessage('success', $lng->txt("settings_saved"), true);
2883  $this->ctrl->redirect($this, "contributors");
2884  }
2885 
2886  public function deactivateAdmin(): void
2887  {
2888  if ($this->checkPermissionBool("write") && $this->apid > 0) {
2889  // ilBlogPostingGUI::deactivatePage()
2890  $post = new ilBlogPosting($this->apid);
2891  $post->setApproved(false);
2892  $post->setActive(false);
2893  $post->update(true, false, false);
2894 
2895  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
2896  }
2897 
2898  $this->ctrl->redirect($this, "render");
2899  }
2900 
2901 
2905 
2906  public function setContentStyleSheet(
2907  ilGlobalTemplateInterface $a_tpl = null
2908  ): void {
2909  $tpl = $this->tpl;
2910 
2911  if ($a_tpl) {
2912  $ctpl = $a_tpl;
2913  } else {
2914  $ctpl = $tpl;
2915  }
2916 
2917  $this->content_style_gui->addCss(
2918  $ctpl,
2919  $this->object->getRefId(),
2920  $this->object->getId()
2921  );
2922  }
2923 
2927  public static function _goto(string $a_target): void
2928  {
2929  global $DIC;
2930 
2931  $ilCtrl = $DIC->ctrl();
2932  $access = $DIC->access();
2933 
2934  $id = explode("_", $a_target);
2935  if (substr($a_target, -3) === "wsp") {
2936  $ilCtrl->setParameterByClass("ilSharedResourceGUI", "wsp_id", $id[0]);
2937 
2938  if (count($id) >= 2) {
2939  if (is_numeric($id[1])) {
2940  $ilCtrl->setParameterByClass("ilSharedResourceGUI", "gtp", $id[1]);
2941  } else {
2942  $ilCtrl->setParameterByClass("ilSharedResourceGUI", "kwd", $id[1]);
2943  }
2944  if (($id[2] ?? "") === "edit") {
2945  $ilCtrl->setParameterByClass("ilSharedResourceGUI", "edt", $id[2]);
2946  }
2947  }
2948  $ilCtrl->redirectByClass("ilSharedResourceGUI", "");
2949  } else {
2950  $ilCtrl->setParameterByClass("ilRepositoryGUI", "ref_id", $id[0]);
2951 
2952  if (count($id) >= 2) {
2953  if (is_numeric($id[1])) {
2954  $ilCtrl->setParameterByClass("ilRepositoryGUI", "gtp", $id[1]);
2955  } else {
2956  $ilCtrl->setParameterByClass("ilRepositoryGUI", "kwd", $id[1]);
2957  }
2958 
2959  if (($id[2] ?? "") === "edit") {
2960  $ilCtrl->setParameterByClass("ilRepositoryGUI", "edt", $id[2]);
2961  }
2962  }
2963  if ($access->checkAccess("read", "", $id[0])) {
2964  $ilCtrl->redirectByClass("ilRepositoryGUI", "preview");
2965  }
2966  if ($access->checkAccess("visible", "", $id[0])) {
2967  $ilCtrl->redirectByClass("ilRepositoryGUI", "infoScreen");
2968  }
2969  }
2970  }
2971 
2975  protected function exportWithComments(): void
2976  {
2977  $this->export(true);
2978  }
2979 
2983 
2984  public function getPrintView(): \ILIAS\Export\PrintProcessGUI
2985  {
2986  $style_sheet_id = $this->content_style_domain->getEffectiveStyleId();
2987 
2989  $blog = $this->object;
2990  $provider = new \ILIAS\Blog\BlogPrintViewProviderGUI(
2991  $this->lng,
2992  $this->ctrl,
2993  $blog,
2994  $this->node_id,
2995  $this->access_handler,
2996  $style_sheet_id,
2997  $this->blog_request->getObjIds()
2998  );
2999 
3000  return new \ILIAS\Export\PrintProcessGUI(
3001  $provider,
3002  $this->http,
3003  $this->ui,
3004  $this->lng
3005  );
3006  }
3007 
3008  public function printViewSelection(): void
3009  {
3010  $view = $this->getPrintView();
3011  $view->sendForm();
3012  }
3013 
3014  public function printPostings(): void
3015  {
3016  $print_view = $this->getPrintView();
3017  $print_view->sendPrintView();
3018  }
3019 
3020  protected function forwardExport(): void
3021  {
3022  $this->ctrl->redirectByClass(ilExportGUI::class);
3023  }
3024 }
ilNavigationHistory $nav_history
setLocator()
set Locator
checkPermission(string $perm, string $cmd="", string $type="", int $ref_id=null)
filterInactivePostings()
Filter inactive items from items list.
export(bool $a_with_comments=false)
Build and deliver export file.
ilRbacReview $rbac_review
const ABSTRACT_DEFAULT_IMAGE_WIDTH
static _lookupActive(int $a_id, string $a_parent_type, bool $a_check_scheduled_activation=false, string $a_lang="-")
lookup activation status
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$res
Definition: ltiservices.php:69
addUserFromAutoComplete()
Autocomplete submit.
getNextPosting(array $a_items)
Get next posting.
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 ilInfoScreenGUI.
getLinkTargetByClass( $a_class, string $a_cmd=null, string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
mayContribute()
Check if user may contribute at all.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const ANONYMOUS_USER_ID
Definition: constants.php:27
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:
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...
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.
getItemByPostVar(string $a_post_var)
static _numericMonthToString(int $a_month, bool $a_long=true)
numeric month to string
addHeaderActionForCommand(string $a_cmd)
buildPostingList(int $a_obj_id)
Gather all blog postings.
insertHeaderAction(?ilObjectListGUI $list_gui=null)
Insert header action into main template.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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.
setInfo(string $a_info)
Class ilBlogPosting GUI class.
static exists(int $a_blog_id, int $a_posting_id)
Checks whether a posting exists.
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) ...
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
Help GUI class.
addComponent(\ILIAS\UI\Component\Component $a_comp)
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.
getPreviousMonth(array $a_items)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
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
getLatestMonth(array $a_items)
static _lookupId($a_user_str)
This class represents a checkbox property in a property form.
setParameterByClass(string $a_class, string $a_parameter, $a_value)
const NAV_MODE_LIST
prepareOutput(bool $show_sub_objects=true)
static _lookupOwner(int $obj_id)
Lookup owner user ID for object ID.
loadLanguageModule(string $a_module)
Load language module.
static _goto(string $a_target)
Deep link.
updateCustom(ilPropertyFormGUI $form)
setMultiValues(array $a_values)
getPreviousPosting(array $a_items)
Get previous posting.
static getRelevanceClass(int $cnt, int $max)
const ABSTRACT_DEFAULT_SHORTEN_LENGTH
renderFullScreen(string $a_content, string $a_navigation)
Build fullscreen context.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setTitleIcon(string $a_icon_path, string $a_icon_desc="")
set title icon
static _getExportDirectory(int $a_obj_id, string $a_type="xml", string $a_obj_type="", string $a_entity="")
Get export directory for an repository object.
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
Class ilBlogExerciseGUI.
initEditCustomForm(ilPropertyFormGUI $a_form)
catch(\Exception $e) $req
Definition: xapiproxy.php:93
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
getEditFormCustomValues(array &$a_values)
global $DIC
Definition: feed.php:28
ilToolbarGUI $toolbar
$auth
Definition: metadata.php:76
if($format !==null) $name
Definition: metadata.php:247
$provider
Definition: ltitoken.php:83
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getListItems(bool $a_show_inactive=false)
Filter blog postings by month, keyword or author.
initHeaderAction(?string $sub_type=null, ?int $sub_id=null, bool $is_preview=false)
checkForParentType(int $a_ref_id, string $a_type, bool $a_exclude_source_check=false)
Check for parent type e.g check if a folder (ref_id 3) is in a parent course obj => checkForParentTyp...
static http()
Fetches the global http state from ILIAS.
This class represents a property in a property form.
getNextMonth(array $a_items)
Get next month.
checkPermissionBool(string $perm, string $cmd="", string $type="", ?int $node_id=null)
$preview
Definition: imgupload.php:81
disableNotes(bool $a_value=false)
setContent(string $a_html)
Sets content for standard template.
$keys
Definition: metadata.php:204
static setNotification(int $type, int $user_id, int $id, bool $status=true)
Set notification status for object and user.
const ABSTRACT_DEFAULT_IMAGE_HEIGHT
Class ilObjBlogGUI.
confirmRemoveContributor()
Used in ilContributorTableGUI.
This class represents a number property in a property form.
static _createExportDirectory(int $a_obj_id, string $a_export_type="xml", string $a_obj_type="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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)
static isCommentsExportPossible(int $blog_id)
ILIAS Style Content Object ObjectFacade $content_style_domain
ilGlobalTemplateInterface $tpl
$format
Definition: metadata.php:235
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...
initCreationForms(string $new_type)
mayEditPosting(int $a_posting_id, int $a_author_id=null)
Check if user may edit posting.
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.
setRequired(bool $a_required)
renderFullscreenHeader(ilGlobalTemplateInterface $a_tpl, int $a_user_id, bool $a_export=false)
Render banner, user name.
addOnLoadCode(string $a_code, int $a_batch=2)
Add on load code.
Navigation History of Repository Items.
static get(string $a_type, string $a_href="")
Get icon html.
$img
Definition: imgupload.php:83
createPosting()
Create new posting.
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)
getPermanentLinkWidget(string $append=null, bool $center=false)
static lookupBlogId(int $a_posting_id)
ILIAS Blog ReadingTime BlogSettingsGUI $reading_time_gui
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
activateTab(string $a_id)
getLatestPosting(array $a_items)
Get previous posting.
const IL_CAL_DATE
getLinkTarget(object $a_gui_obj, string $a_cmd=null, string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
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)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ILIAS HTTP Services $http
global $ilSetting
Definition: privfeed.php:17
addContributor(array $a_user_ids=array(), ?string $a_user_type=null)
Centralized method to add contributors.
__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...
$ilUser
Definition: imgupload.php:34
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.
addItem(string $a_title, string $a_link, string $a_frame="", int $a_ref_id=0, ?string $type=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)
static signFile(string $path_to_file)
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.
New PermissionGUI (extends from old ilPermission2GUI) RBAC related output.
renderToolbarNavigation(array $a_items, bool $single_posting=false)
Toolbar navigation.
$url
Class ilRbacAdmin Core functions for role based access control.
buildEmbedded(string $a_content, string $a_nav)
Combine content (list/posting) and navigation to html chunk.
setParameter(object $a_gui_obj, string $a_parameter, $a_value)
const NAV_MODE_MONTH
renderList(array $items, string $a_cmd="preview", string $a_link_template="", bool $a_show_inactive=false, string $a_export_directory="")
Build posting month list.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupType(int $id, bool $reference=false)
ilRbacAdmin $rbacadmin
$post
Definition: ltitoken.php:49
addHeaderAction()
Add header action menu.
ilSetting $settings
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
buildExportLink(string $a_template, string $a_type, string $a_id)
Build export link.
$i
Definition: metadata.php:41
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__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
getHTML()
Return embeddable HTML chunk.
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?