ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilContainerRenderer.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 require_once('./Services/Repository/classes/class.ilObjectPlugin.php');
4 
12 {
16  protected $lng;
17 
21  protected $settings;
22 
26  protected $obj_definition;
27 
28  // switches
29  protected $enable_manage_select_all; // [bool]
30  protected $enable_multi_download; // [bool]
31  protected $active_block_ordering; // [bool]
32 
33  // properties
34  protected $type_blocks = array(); // [array]
35  protected $custom_blocks = array(); // [array]
36  protected $items = array(); // [array]
37  protected $hidden_items = array(); // [array]
38  protected $block_items = array(); // [array]
39  protected $details = array(); // [array]
40  protected $item_ids = array(); // [array]
41 
42  // block (unique) ids
43  protected $rendered_blocks = array(); // [array]
44  protected $bl_cnt = 0; // [int]
45  protected $cur_row_type; // [string]
46 
47  // ordering
48  protected $block_pos = array(); // [array]
49  protected $block_custom_pos = array(); // [array]
50  protected $order_cnt = 0; // [int]
51 
55  protected $show_more = [];
56 
57  const UNIQUE_SEPARATOR = "-";
58 
62  protected $view_mode;
63 
67  protected $ui;
68 
72  protected $ctrl;
73 
82  public function __construct($a_enable_manage_select_all = false, $a_enable_multi_download = false, $a_active_block_ordering = false, $a_block_custom_positions, $container_gui_obj, $a_view_mode =
84  {
85  global $DIC;
86 
87  $this->lng = $DIC->language();
88  $this->settings = $DIC->settings();
89  $this->ui = $DIC->ui();
90  $this->obj_definition = $DIC["objDefinition"];
91  $this->enable_manage_select_all = (bool) $a_enable_manage_select_all;
92  $this->enable_multi_download = (bool) $a_enable_multi_download;
93  $this->active_block_ordering = (bool) $a_active_block_ordering;
94  $this->block_custom_pos = $a_block_custom_positions;
95  $this->view_mode = $a_view_mode;
96  $this->container_gui = $container_gui_obj;
97  $this->ctrl = $DIC->ctrl();
98  }
99 
103  protected function getViewMode()
104  {
105  return $this->view_mode;
106  }
107 
108  //
109  // blocks
110  //
111 
120  public function addTypeBlock($a_type, $a_prefix = null, $a_postfix = null)
121  {
122  if ($a_type != "itgr" &&
123  !$this->hasTypeBlock($a_type)) {
124  $this->type_blocks[$a_type] = array(
125  "prefix" => $a_prefix
126  ,"postfix" => $a_postfix
127  );
128  return true;
129  }
130  return false;
131  }
132 
139  public function hasTypeBlock($a_type)
140  {
141  return array_key_exists($a_type, $this->type_blocks);
142  }
143 
152  public function addCustomBlock($a_id, $a_caption, $a_actions = null, $a_data = array())
153  {
154  if (!$this->hasCustomBlock($a_id)) {
155  $this->custom_blocks[$a_id] = array(
156  "caption" => $a_caption
157  ,"actions" => $a_actions
158  ,"data" => $a_data
159  );
160  return true;
161  }
162  return false;
163  }
164 
171  public function hasCustomBlock($a_id)
172  {
173  return array_key_exists($a_id, $this->custom_blocks);
174  }
175 
182  public function isValidBlock($a_id)
183  {
184  return ($this->hasTypeBlock($a_id) ||
185  $this->hasCustomBlock($a_id));
186  }
187 
188 
189  //
190  // items
191  //
192 
198  public function hideItem($a_id)
199  {
200  // see hasItem();
201  $this->hidden_items[$a_id] = true;
202 
203  // #16629 - do not remove hidden items from other blocks
204  // $this->removeItem($a_id);
205  }
206 
212  public function removeItem($a_id)
213  {
214  if (!$this->hasItem($a_id)) {
215  return;
216  }
217 
218  unset($this->item_ids[$a_id]);
219  unset($this->hidden_items[$a_id]);
220 
221  foreach (array_keys($this->items) as $item_id) {
222  if (array_pop(explode(self::UNIQUE_SEPARATOR, $item_id)) == $a_id) {
223  unset($this->items[$item_id]);
224  }
225  }
226 
227  foreach ($this->block_items as $block_id => $items) {
228  foreach ($items as $idx => $item_id) {
229  if (array_pop(explode(self::UNIQUE_SEPARATOR, $item_id)) == $a_id) {
230  unset($this->block_items[$block_id][$idx]);
231  if (!sizeof($this->block_items[$block_id])) {
232  unset($this->block_items[$block_id]);
233  }
234  break;
235  }
236  }
237  }
238  }
239 
246  public function hasItem($a_id)
247  {
248  return (array_key_exists($a_id, $this->item_ids) ||
249  array_key_exists($a_id, $this->hidden_items));
250  }
251 
262  public function addItemToBlock($a_block_id, $a_item_type, $a_item_id, $a_item_html, $a_force = false)
263  {
264  if ($this->isValidBlock($a_block_id) &&
265  $a_item_type != "itgr" &&
266  (!$this->hasItem($a_item_id) || $a_force)) {
267  if (is_string($a_item_html) && trim($a_item_html) == "") {
268  return false;
269  }
270  if (!$a_item_html) {
271  return false;
272  }
273 
274 
275  // #16563 - item_id (== ref_id) is NOT unique, adding parent block id
276  $uniq_id = $a_block_id . self::UNIQUE_SEPARATOR . $a_item_id;
277 
278  $this->items[$uniq_id] = array(
279  "type" => $a_item_type
280  ,"html" => $a_item_html
281  );
282 
283  // #18326
284  $this->item_ids[$a_item_id] = true;
285 
286  $this->block_items[$a_block_id][] = $uniq_id;
287  return true;
288  }
289  return false;
290  }
291 
295  public function addShowMoreButton($a_block_id)
296  {
297  $this->show_more[] = $a_block_id;
298  }
299 
307  public function addDetailsLevel($a_level, $a_url, $a_active = false)
308  {
309  $this->details[$a_level] = array(
310  "url" => $a_url
311  ,"active" => (bool) $a_active
312  );
313  }
314 
318  public function resetDetails()
319  {
320  $this->details = array();
321  }
322 
323 
324  //
325  // render
326  //
327 
334  public function setBlockPosition($a_block_id, $a_pos)
335  {
336  if ($this->isValidBlock($a_block_id)) {
337  $this->block_pos[$a_block_id] = $a_pos;
338  }
339  }
340 
346  public function getHTML()
347  {
348  $valid = false;
349 
350  $block_tpl = $this->initBlockTemplate();
351 
352  foreach ($this->processBlockPositions() as $block_id) {
353  if (array_key_exists($block_id, $this->custom_blocks)) {
354  if ($this->renderHelperCustomBlock($block_tpl, $block_id)) {
355  $this->addSeparatorRow($block_tpl);
356  $valid = true;
357  }
358  }
359  if (array_key_exists($block_id, $this->type_blocks)) {
360  if ($this->renderHelperTypeBlock($block_tpl, $block_id)) {
361  $this->addSeparatorRow($block_tpl);
362  $valid = true;
363  }
364  }
365  }
366 
367  if ($valid) {
368  $this->renderDetails($block_tpl);
369 
370  return $block_tpl->get();
371  }
372  }
373 
381  {
382  $block_tpl = $this->initBlockTemplate();
383 
384  if ($this->renderHelperTypeBlock($block_tpl, $a_type, true)) {
385  return $block_tpl->get();
386  }
387  }
388 
395  public function renderSingleCustomBlock($a_id)
396  {
397  $block_tpl = $this->initBlockTemplate();
398 
399  if ($this->renderHelperCustomBlock($block_tpl, $a_id, true)) {
400  return $block_tpl->get();
401  }
402  }
403 
404 
405  //
406  // render (helper)
407  //
408 
414  protected function processBlockPositions()
415  {
416  // manual order
417  if (is_array($this->block_custom_pos) && sizeof($this->block_custom_pos)) {
418  $tmp = $this->block_pos;
419  $this->block_pos = array();
420  foreach ($this->block_custom_pos as $idx => $block_id) {
421  if ($this->isValidBlock($block_id)) {
422  $this->block_pos[$block_id] = $idx;
423  }
424  }
425 
426  // at least some manual are valid
427  if (sizeof($this->block_pos)) {
428  // append missing blocks from default order
429  $last = max($this->block_pos);
430  foreach (array_keys($tmp) as $block_id) {
431  if (!array_key_exists($block_id, $this->block_pos)) {
432  $this->block_pos[$block_id] = ++$last;
433  }
434  }
435  }
436  // all manual invalid, use default
437  else {
438  $this->block_pos = $tmp;
439  }
440  }
441 
442  // add missing blocks to order
443  $last = sizeof($this->block_pos)
444  ? max($this->block_pos)
445  : 0;
446  foreach (array_keys($this->custom_blocks) as $block_id) {
447  if (!array_key_exists($block_id, $this->block_pos)) {
448  $this->block_pos[$block_id] = ++$last;
449  }
450  }
451  foreach (array_keys($this->type_blocks) as $block_id) {
452  if (!array_key_exists($block_id, $this->block_pos)) {
453  $this->block_pos[$block_id] = ++$last;
454  }
455  }
456 
457  asort($this->block_pos);
458 
459  return array_keys($this->block_pos);
460  }
461 
470  protected function renderHelperCustomBlock(ilTemplate $a_block_tpl, $a_block_id, $a_is_single = false)
471  {
472  if ($this->hasCustomBlock($a_block_id)) {
473  return $this->renderHelperGeneric($a_block_tpl, $a_block_id, $this->custom_blocks[$a_block_id], $a_is_single);
474  }
475  return false;
476  }
477 
486  protected function renderHelperTypeBlock(ilTemplate $a_block_tpl, $a_type, $a_is_single = false)
487  {
488  if ($this->hasTypeBlock($a_type)) {
489  $block = $this->type_blocks[$a_type];
490  $block["type"] = $a_type;
491  return $this->renderHelperGeneric($a_block_tpl, $a_type, $block, $a_is_single);
492  }
493  return false;
494  }
495 
505  protected function renderHelperGeneric(ilTemplate $a_block_tpl, $a_block_id, array $a_block, $a_is_single = false)
506  {
507  $ctrl = $this->ctrl;
508  if (!in_array($a_block_id, $this->rendered_blocks)) {
509  $this->rendered_blocks[] = $a_block_id;
510 
511  $block_types = array();
512  if (is_array($this->block_items[$a_block_id])) {
513  foreach ($this->block_items[$a_block_id] as $item_id) {
514  if (isset($this->items[$item_id]["type"])) {
515  $block_types[] = $this->items[$item_id]["type"];
516  }
517  }
518  }
519 
520  // #14610 - manage empty item groups
521  if (is_array($this->block_items[$a_block_id]) ||
522  is_numeric($a_block_id)) {
523  $cards = [];
524 
525  $order_id = (!$a_is_single && $this->active_block_ordering)
526  ? $a_block_id
527  : null;
528  $this->addHeaderRow($a_block_tpl, $a_block["type"], $a_block["caption"], array_unique($block_types), $a_block["actions"], $order_id, $a_block["data"]);
529 
531  if ($a_block["prefix"]) {
532  $this->addStandardRow($a_block_tpl, $a_block["prefix"]);
533  }
534  }
535 
536  if (is_array($this->block_items[$a_block_id])) {
537  foreach ($this->block_items[$a_block_id] as $item_id) {
539  $this->addStandardRow($a_block_tpl, $this->items[$item_id]["html"], $item_id);
540  } else {
541  $cards[] = $this->items[$item_id]["html"];
542  }
543  }
544  }
545 
547  if ($a_block["postfix"]) {
548  $this->addStandardRow($a_block_tpl, $a_block["postfix"]);
549  }
550  }
551 
553  $f = $this->ui->factory();
554  $renderer = $this->ui->renderer();
555 
556  //Create a deck with large cards
557  $deck = $f->deck($cards)->withNormalCardsSize();
558  //$deck = $f->deck($cards)->withSmallCardsSize();
559 
560 
561  $html = $renderer->render($deck);
562  $a_block_tpl->setCurrentBlock("tile_rows");
563  $a_block_tpl->setVariable("TILE_ROWS", $html);
564  $a_block_tpl->parseCurrentBlock();
565  }
566 
567  // show more
568  if (in_array($a_block_id, $this->show_more)) {
569  $a_block_tpl->setCurrentBlock("show_more");
570 
571  $ctrl->setParameter($this->container_gui, "type", $a_block_id);
572  $url = $ctrl->getLinkTarget($this->container_gui, "renderBlockAsynch", "", true);
573  $ctrl->setParameter($this->container_gui, "type", "");
574 
575  $f = $this->ui->factory();
576  $renderer = $this->ui->renderer();
577  $button = $f->button()->standard($this->lng->txt("cont_show_more"), "")
579  ->withOnLoadCode(function ($id) use ($a_block_id, $url) {
580  return "il.Container.initShowMore('$id', '$a_block_id', '" . $url . "');";
581  });
582  if ($ctrl->isAsynch()) {
583  $a_block_tpl->setVariable("SHOW_MORE_BUTTON", $renderer->renderAsync($button));
584  } else {
585  $a_block_tpl->setVariable("SHOW_MORE_BUTTON", $renderer->render($button));
586  }
587  $a_block_tpl->parseCurrentBlock();
588  $a_block_tpl->setCurrentBlock("show_more");
589  $a_block_tpl->parseCurrentBlock();
590  }
591 
592  return true;
593  }
594  }
595 
596  return false;
597  }
598 
604  protected function initBlockTemplate()
605  {
606  // :TODO: obsolete?
607  $this->cur_row_type = "row_type_1";
608 
609  return new ilTemplate("tpl.container_list_block.html", true, true, "Services/Container");
610  }
611 
622  protected function addHeaderRow(ilTemplate $a_tpl, $a_type = "", $a_text = "", array $a_types_in_block = null, $a_commands_html = null, $a_order_id = null, $a_data = array())
623  {
624  $lng = $this->lng;
626  $objDefinition = $this->obj_definition;
627 
628  $a_tpl->setVariable("CB_ID", ' id="bl_cntr_' . (++$this->bl_cnt) . '"');
629 
630  if ($this->enable_manage_select_all) {
631  $this->renderSelectAllBlock($a_tpl);
632  } elseif ($this->enable_multi_download) {
633  if ($a_type) {
634  $a_types_in_block = array($a_type);
635  }
636  foreach ($a_types_in_block as $type) {
637  if (in_array($type, $this->getDownloadableTypes())) {
638  $this->renderSelectAllBlock($a_tpl);
639  break;
640  }
641  }
642  }
643 
644  if ($a_text == "" && $a_type != "") {
645  if (!$objDefinition->isPlugin($a_type)) {
646  $title = $lng->txt("objs_" . $a_type);
647  } else {
648  include_once("./Services/Component/classes/class.ilPlugin.php");
650  $title = $pl->txt("objs_" . $a_type);
651  }
652  } else {
653  $title = $a_text;
654  }
655 
656  include_once("./Modules/ItemGroup/classes/class.ilItemGroupBehaviour.php");
657  if (is_array($a_data)) {
658  foreach ($a_data as $k => $v) {
659  $a_tpl->setCurrentBlock("cb_data");
660  $a_tpl->setVariable("DATA_KEY", $k);
661  $a_tpl->setVariable("DATA_VALUE", $v);
662  $a_tpl->parseCurrentBlock();
663 
664  if ($k == "behaviour" && $v == ilItemGroupBehaviour::EXPANDABLE_CLOSED) {
665  $a_tpl->touchBlock("container_items_hide");
666  }
667  }
668  }
669 
670  if ($ilSetting->get("icon_position_in_lists") != "item_rows" &&
671  $a_type != "") {
672  $icon = ilUtil::getImagePath("icon_" . $a_type . ".svg");
673 
674  $a_tpl->setCurrentBlock("container_header_row_image");
675  $a_tpl->setVariable("HEADER_IMG", $icon);
676  $a_tpl->setVariable("HEADER_ALT", $title);
677  } else {
678  $a_tpl->setCurrentBlock("container_header_row");
679  }
680 
681  if ($a_order_id) {
682  $a_tpl->setVariable("BLOCK_HEADER_ORDER_NAME", "position[blocks][" . $a_order_id . "]");
683  $a_tpl->setVariable("BLOCK_HEADER_ORDER_NUM", (++$this->order_cnt) * 10);
684  }
685 
686  $a_tpl->setVariable("BLOCK_HEADER_CONTENT", $title);
687  $a_tpl->setVariable("CHR_COMMANDS", $a_commands_html);
688  $a_tpl->parseCurrentBlock();
689 
690  //$a_tpl->touchBlock("container_row");
691 
692  $this->resetRowType();
693  }
694 
702  protected function addStandardRow(ilTemplate $a_tpl, $a_html, $a_ref_id = 0)
703  {
704  // :TODO: obsolete?
705  $this->cur_row_type = ($this->cur_row_type == "row_type_1")
706  ? "row_type_2"
707  : "row_type_1";
708 
709  if ($a_ref_id > 0) {
710  $a_tpl->setCurrentBlock($this->cur_row_type);
711  $a_tpl->setVariable("ROW_ID", 'id="item_row_' . $a_ref_id . '"');
712  $a_tpl->parseCurrentBlock();
713  } else {
714  $a_tpl->touchBlock($this->cur_row_type);
715  }
716 
717  $a_tpl->setCurrentBlock("container_standard_row");
718  $a_tpl->setVariable("BLOCK_ROW_CONTENT", $a_html);
719  $a_tpl->parseCurrentBlock();
720 
721  $a_tpl->touchBlock("container_row");
722  }
723 
727  protected function renderSelectAllBlock(ilTemplate $a_tpl)
728  {
729  $lng = $this->lng;
730 
731  $a_tpl->setCurrentBlock("select_all_row");
732  $a_tpl->setVariable("CHECKBOXNAME", "bl_cb_" . $this->bl_cnt);
733  $a_tpl->setVariable("SEL_ALL_PARENT", "bl_cntr_" . $this->bl_cnt);
734  $a_tpl->setVariable("SEL_ALL_PARENT", "bl_cntr_" . $this->bl_cnt);
735  $a_tpl->setVariable("TXT_SELECT_ALL", $lng->txt("select_all"));
736  $a_tpl->parseCurrentBlock();
737  }
738 
744  protected function addSeparatorRow(ilTemplate $a_tpl)
745  {
746  $a_tpl->setCurrentBlock("container_block");
747  $a_tpl->parseCurrentBlock();
748  }
749 
753  protected function resetRowType()
754  {
755  // :TODO: obsolete?
756  $this->cur_row_type = "";
757  }
758 
764  protected function getDownloadableTypes()
765  {
766  return array("fold", "file");
767  }
768 
774  public function renderDetails(ilTemplate $a_tpl)
775  {
776  $lng = $this->lng;
777 
778  if (sizeof($this->details)) {
779  $a_tpl->setCurrentBlock('container_details_row');
780  $a_tpl->setVariable('TXT_DETAILS', $lng->txt('details'));
781  $a_tpl->parseCurrentBlock();
782  }
783  }
784 }
settings()
Definition: settings.php:2
$type
global $DIC
Definition: saml.php:7
getDownloadableTypes()
Get downloadable repository object types.
renderSingleCustomBlock($a_id)
Get rendered html of single custom block.
$valid
addSeparatorRow(ilTemplate $a_tpl)
Render separator row.
if(!array_key_exists('StateId', $_REQUEST)) $id
addStandardRow(ilTemplate $a_tpl, $a_html, $a_ref_id=0)
Render item row.
addTypeBlock($a_type, $a_prefix=null, $a_postfix=null)
Add type block.
__construct($a_enable_manage_select_all=false, $a_enable_multi_download=false, $a_active_block_ordering=false, $a_block_custom_positions, $container_gui_obj, $a_view_mode=ilContainerContentGUI::VIEW_MODE_LIST)
Constructor.
static getPluginObjectByType($type)
Return either a repoObject plugin or a orgunit extension plugin or null if the type is not a plugin...
hasItem($a_id)
Item with id exists?
$a_type
Definition: workflow.php:92
renderDetails(ilTemplate $a_tpl)
Render detail level.
addHeaderRow(ilTemplate $a_tpl, $a_type="", $a_text="", array $a_types_in_block=null, $a_commands_html=null, $a_order_id=null, $a_data=array())
Render block header.
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:613
addShowMoreButton($a_block_id)
Add show more button to a block.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
touchBlock($block)
overwrites ITX::touchBlock.
special template class to simplify handling of ITX/PEAR
withLoadingAnimationOnClick(bool $loading_animation_on_click=true)
resetDetails()
Reset/remove all detail levels.
renderHelperCustomBlock(ilTemplate $a_block_tpl, $a_block_id, $a_is_single=false)
Render custom block.
setCurrentBlock($part="DEFAULT")
Überladene Funktion, die sich hier lokal noch den aktuellen Block merkt.
isValidBlock($a_id)
Any block with id exists?
hasTypeBlock($a_type)
Type block already exists?
hasCustomBlock($a_id)
Custom block already exists?
hideItem($a_id)
Mark item id as used, but do not render.
renderHelperGeneric(ilTemplate $a_block_tpl, $a_block_id, array $a_block, $a_is_single=false)
Render block.
addCustomBlock($a_id, $a_caption, $a_actions=null, $a_data=array())
Add custom block.
renderSingleTypeBlock($a_type)
Get rendered html of single type block.
global $ilSetting
Definition: privfeed.php:17
removeItem($a_id)
Remove item (from any block)
addDetailsLevel($a_level, $a_url, $a_active=false)
Add details level.
$url
renderHelperTypeBlock(ilTemplate $a_block_tpl, $a_type, $a_is_single=false)
Render type block.
Class ilContainerRenderer.
$html
Definition: example_001.php:87
parseCurrentBlock($part="DEFAULT")
Überladene Funktion, die auf den aktuelle Block vorher noch ein replace ausführt public...
processBlockPositions()
Process block positions.
resetRowType()
Reset internal row type.
renderSelectAllBlock(ilTemplate $a_tpl)
Render "select all".
setBlockPosition($a_block_id, $a_pos)
Set block position.
addItemToBlock($a_block_id, $a_item_type, $a_item_id, $a_item_html, $a_force=false)
Add item to existing block.
getHTML()
Get rendered html (of all blocks)