1<?php namespace ILIAS\MainMenu\Provider; 2 3use ILIAS\DI\Container; 4use ILIAS\GlobalScreen\Helper\BasicAccessCheckClosures; 5use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Information\TypeInformation; 6use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Information\TypeInformationCollection; 7use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\ComplexItemRenderer; 8use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\LinkListItemRenderer; 9use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\LostItemRenderer; 10use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\SeparatorItemRenderer; 11use ILIAS\GlobalScreen\Scope\MainMenu\Collector\Renderer\TopParentItemRenderer; 12use ILIAS\GlobalScreen\Scope\MainMenu\Factory\hasAction; 13use ILIAS\GlobalScreen\Scope\MainMenu\Factory\hasTitle; 14use ILIAS\GlobalScreen\Scope\MainMenu\Factory\isChild; 15use ILIAS\GlobalScreen\Scope\MainMenu\Factory\isItem; 16use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\Complex; 17use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\Link; 18use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\LinkList; 19use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\Lost; 20use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\RepositoryLink; 21use ILIAS\GlobalScreen\Scope\MainMenu\Factory\Item\Separator; 22use ILIAS\GlobalScreen\Scope\MainMenu\Factory\TopItem\TopLinkItem; 23use ILIAS\GlobalScreen\Scope\MainMenu\Factory\TopItem\TopParentItem; 24use ILIAS\GlobalScreen\Scope\MainMenu\Provider\AbstractStaticMainMenuProvider; 25use ILIAS\GlobalScreen\Scope\MainMenu\Provider\StaticMainMenuProvider; 26use ILIAS\UI\Component\Component; 27use ILIAS\UI\Component\JavaScriptBindable; 28use ilMMCustomItemStorage; 29use ilMMItemStorage; 30use ilMMTypeHandlerLink; 31use ilMMTypeHandlerRepositoryLink; 32use ilMMTypeHandlerSeparator; 33use ilMMTypeHandlerTopLink; 34 35/** 36 * Class CustomMainBarProvider 37 * 38 * @author Fabian Schmid <fs@studer-raimann.ch> 39 */ 40class CustomMainBarProvider extends AbstractStaticMainMenuProvider implements StaticMainMenuProvider 41{ 42 43 /** 44 * @var BasicAccessCheckClosures 45 */ 46 private $access_helper; 47 /** 48 * @var \ILIAS\DI\Container 49 */ 50 protected $dic; 51 52 53 /** 54 * @inheritDoc 55 */ 56 public function __construct(Container $dic) 57 { 58 parent::__construct($dic); 59 $this->access_helper = BasicAccessCheckClosures::getInstance(); 60 } 61 62 63 /** 64 * @return TopParentItem[] 65 */ 66 public function getStaticTopItems() : array 67 { 68 /** 69 * @var $item ilMMCustomItemStorage 70 */ 71 $top_items = []; 72 foreach (ilMMCustomItemStorage::where(['top_item' => true])->get() as $item) { 73 $top_items[] = $this->getSingleCustomItem($item, true); 74 } 75 76 return $top_items; 77 } 78 79 80 /** 81 * @return isItem[] 82 */ 83 public function getStaticSubItems() : array 84 { 85 /** 86 * @var $item ilMMCustomItemStorage 87 */ 88 $items = []; 89 foreach (ilMMCustomItemStorage::where(['top_item' => false])->get() as $item) { 90 $items[] = $this->getSingleCustomItem($item, true); 91 } 92 93 return $items; 94 } 95 96 97 /** 98 * @param ilMMCustomItemStorage $storage 99 * @param bool $register 100 * 101 * @return isItem 102 */ 103 public function getSingleCustomItem(ilMMCustomItemStorage $storage, $register = false) : isItem 104 { 105 $identification = $this->globalScreen()->identification()->core($this)->identifier($storage->getIdentifier()); 106 107 $item = $this->globalScreen()->mainBar()->custom($storage->getType(), $identification); 108 109 // See https://mantis.ilias.de/view.php?id=30743 110 if ($item instanceof Link || $item instanceof TopLinkItem) { 111 $item = $item->withVisibilityCallable(function () { 112 $active = $this->access_helper->isPublicSectionActive(); 113 if ($active()) { 114 return true; 115 } 116 117 return $this->access_helper->isUserLoggedIn()(); 118 }); 119 } 120 121 if ($item instanceof hasTitle && $storage->getDefaultTitle() !== '') { 122 $item = $item->withTitle($storage->getDefaultTitle()); 123 } 124 if ($item instanceof hasAction) { 125 $item = $item->withAction("#"); 126 // always close MainBar when a link has been clicked 127 $item = $item->addComponentDecorator(static function (Component $c) : Component { 128 if ($c instanceof JavaScriptBindable) { 129 return $c->withAdditionalOnLoadCode(function ($id) { 130 return "$('#$id').click(function() { il.UI.maincontrols.mainbar.disengageAll();})"; 131 }); 132 } 133 }); 134 } 135 if ($item instanceof isChild) { 136 $mm_item = ilMMItemStorage::find($identification->serialize()); 137 $parent_identification = ''; 138 if ($mm_item instanceof ilMMItemStorage) { 139 $parent_identification = $mm_item->getParentIdentification(); 140 } 141 142 if ($parent_identification) { 143 $item = $item->withParent( 144 $this->globalScreen() 145 ->identification() 146 ->fromSerializedIdentification($parent_identification) 147 ); 148 } 149 } 150 151 if ($register) { 152 ilMMItemStorage::register($item); 153 } 154 155 return $item; 156 } 157 158 159 /** 160 * @inheritDoc 161 */ 162 public function provideTypeInformation() : TypeInformationCollection 163 { 164 $c = new TypeInformationCollection(); 165 // TopParentItem 166 $c->add(new TypeInformation( 167 TopParentItem::class, 168 $this->translateType(TopParentItem::class), 169 new TopParentItemRenderer()) 170 ); 171 // TopLinkItem 172 $c->add(new TypeInformation( 173 TopLinkItem::class, 174 $this->translateType(TopLinkItem::class), 175 new \ilMMTopLinkItemRenderer(), 176 new ilMMTypeHandlerTopLink()) 177 ); 178 // Link 179 $c->add(new TypeInformation( 180 Link::class, 181 $this->translateType(Link::class), 182 new \ilMMLinkItemRenderer(), 183 new ilMMTypeHandlerLink()) 184 ); 185 186 // LinkList 187 $link_list = new TypeInformation( 188 LinkList::class, 189 $this->translateType(LinkList::class), 190 new LinkListItemRenderer() 191 ); 192 $link_list->setCreationPrevented(true); 193 $c->add($link_list); 194 195 // Separator 196 $c->add(new TypeInformation( 197 Separator::class, 198 $this->translateType(Separator::class), 199 new SeparatorItemRenderer(), 200 new ilMMTypeHandlerSeparator(), 201 $this->translateByline(Separator::class)) 202 ); 203 204 // RepositoryLink 205 $c->add(new TypeInformation( 206 RepositoryLink::class, 207 $this->translateType(RepositoryLink::class), 208 new \ilMMRepositoryLinkItemRenderer(), 209 new ilMMTypeHandlerRepositoryLink()) 210 ); 211 212 // Lost 213 $lost = new TypeInformation( 214 Lost::class, 215 $this->translateType(Lost::class), 216 new LostItemRenderer() 217 ); 218 $lost->setCreationPrevented(true); 219 $c->add($lost); 220 221 // Complex 222 $complex = new TypeInformation( 223 Complex::class, 224 $this->translateType(Complex::class), 225 new ComplexItemRenderer() 226 ); 227 $complex->setCreationPrevented(true); 228 $c->add($complex); 229 230 return $c; 231 } 232 233 234 /** 235 * @param string $type 236 * 237 * @return string 238 */ 239 private function translateType(string $type) : string 240 { 241 $last_part = substr(strrchr($type, "\\"), 1); 242 $last_part = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $last_part)); 243 244 return $this->dic->language()->txt("type_" . strtolower($last_part)); 245 } 246 247 248 /** 249 * @param string $type 250 * 251 * @return string 252 */ 253 private function translateByline(string $type) : string 254 { 255 $last_part = substr(strrchr($type, "\\"), 1); 256 $last_part = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $last_part)); 257 258 return $this->dic->language()->txt("type_" . strtolower($last_part) . "_info"); 259 } 260 261 262 /** 263 * @inheritDoc 264 */ 265 public function getProviderNameForPresentation() : string 266 { 267 return "Custom"; 268 } 269} 270