1*04fd306cSNickeau<?php 2*04fd306cSNickeau/** 3*04fd306cSNickeau * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4*04fd306cSNickeau * 5*04fd306cSNickeau * This source code is licensed under the GPL license found in the 6*04fd306cSNickeau * COPYING file in the root directory of this source tree. 7*04fd306cSNickeau * 8*04fd306cSNickeau * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9*04fd306cSNickeau * @author ComboStrap <support@combostrap.com> 10*04fd306cSNickeau * 11*04fd306cSNickeau */ 12*04fd306cSNickeau 13*04fd306cSNickeaunamespace ComboStrap; 14*04fd306cSNickeau 15*04fd306cSNickeauuse ComboStrap\TagAttribute\StyleAttribute; 16*04fd306cSNickeauuse ComboStrap\Web\UrlEndpoint; 17*04fd306cSNickeauuse dokuwiki\Menu\Item\AbstractItem; 18*04fd306cSNickeau 19*04fd306cSNickeau/** 20*04fd306cSNickeau * Class MenuItem 21*04fd306cSNickeau * @package ComboStrap 22*04fd306cSNickeau * 23*04fd306cSNickeau */ 24*04fd306cSNickeauclass SlotManagerMenuItem extends AbstractItem 25*04fd306cSNickeau{ 26*04fd306cSNickeau 27*04fd306cSNickeau const CANONICAL = "slot:manager"; 28*04fd306cSNickeau const TAG = "slot-manager"; 29*04fd306cSNickeau 30*04fd306cSNickeau const EDIT_ACTION = "Edit"; 31*04fd306cSNickeau const CREATE_ACTION = "Create"; 32*04fd306cSNickeau 33*04fd306cSNickeau private static function getClass(): string 34*04fd306cSNickeau { 35*04fd306cSNickeau return StyleAttribute::addComboStrapSuffix(self::TAG); 36*04fd306cSNickeau } 37*04fd306cSNickeau 38*04fd306cSNickeau 39*04fd306cSNickeau /** 40*04fd306cSNickeau * 41*04fd306cSNickeau * @return string 42*04fd306cSNickeau */ 43*04fd306cSNickeau public function getLabel(): string 44*04fd306cSNickeau { 45*04fd306cSNickeau return "Manage the slots"; 46*04fd306cSNickeau } 47*04fd306cSNickeau 48*04fd306cSNickeau public function getLinkAttributes($classprefix = 'menuitem '): array 49*04fd306cSNickeau { 50*04fd306cSNickeau 51*04fd306cSNickeau $snippetManager = PluginUtility::getSnippetManager()->addPopoverLibrary(); 52*04fd306cSNickeau $snippetManager->attachJavascriptFromComponentId(self::TAG); 53*04fd306cSNickeau 54*04fd306cSNickeau $linkAttributes = parent::getLinkAttributes($classprefix); 55*04fd306cSNickeau /** 56*04fd306cSNickeau * A class and not an id 57*04fd306cSNickeau * because a menu item can be found twice on 58*04fd306cSNickeau * a page (For instance if you want to display it in a layout at a 59*04fd306cSNickeau * breakpoint and at another in another breakpoint 60*04fd306cSNickeau */ 61*04fd306cSNickeau $linkAttributes['class'] = self::getClass(); 62*04fd306cSNickeau $linkAttributes['href'] = "#"; 63*04fd306cSNickeau $dataAttributeNamespace = Bootstrap::getDataNamespace(); 64*04fd306cSNickeau $linkAttributes["data{$dataAttributeNamespace}-toggle"] = "popover"; 65*04fd306cSNickeau $linkAttributes["data{$dataAttributeNamespace}-html"] = "true"; 66*04fd306cSNickeau $linkAttributes["data{$dataAttributeNamespace}-title"] = "Slot Manager"; 67*04fd306cSNickeau 68*04fd306cSNickeau /** 69*04fd306cSNickeau * TODO: right when rtl language 70*04fd306cSNickeau */ 71*04fd306cSNickeau $linkAttributes["data{$dataAttributeNamespace}-placement"] = "left"; 72*04fd306cSNickeau 73*04fd306cSNickeau // encoding happens 74*04fd306cSNickeau $linkAttributes["data{$dataAttributeNamespace}-content"] = $this->createHtml(); 75*04fd306cSNickeau 76*04fd306cSNickeau 77*04fd306cSNickeau // Dismiss on next click 78*04fd306cSNickeau // To debug, just comment this line 79*04fd306cSNickeau $linkAttributes["data{$dataAttributeNamespace}-trigger"] = "focus"; 80*04fd306cSNickeau 81*04fd306cSNickeau // See for the tabindex 82*04fd306cSNickeau // https://getbootstrap.com/docs/5.1/components/popovers/#dismiss-on-next-click 83*04fd306cSNickeau $linkAttributes['tabindex'] = "0"; 84*04fd306cSNickeau 85*04fd306cSNickeau return $linkAttributes; 86*04fd306cSNickeau 87*04fd306cSNickeau 88*04fd306cSNickeau } 89*04fd306cSNickeau 90*04fd306cSNickeau public function getTitle(): string 91*04fd306cSNickeau { 92*04fd306cSNickeau return "Slot Manager"; 93*04fd306cSNickeau } 94*04fd306cSNickeau 95*04fd306cSNickeau public function getSvg(): string 96*04fd306cSNickeau { 97*04fd306cSNickeau /** @var string icon file */ 98*04fd306cSNickeau return DirectoryLayout::getComboImagesDirectory()->resolve('entypo-text-document-inverted.svg')->toAbsoluteId(); 99*04fd306cSNickeau } 100*04fd306cSNickeau 101*04fd306cSNickeau public function createHtml(): string 102*04fd306cSNickeau { 103*04fd306cSNickeau $requestedPath = WikiPath::getContextPath(); 104*04fd306cSNickeau $url = UrlEndpoint::createComboStrapUrl()->setPath("/" . self::TAG); 105*04fd306cSNickeau $html = "<p>Edit and/or create the <a href=\"{$url->toHtmlString()}\">slots</a> of the page</p>"; 106*04fd306cSNickeau foreach (SlotSystem::getSlotNames() as $secondarySlot) { 107*04fd306cSNickeau 108*04fd306cSNickeau $label = $secondarySlot; 109*04fd306cSNickeau switch ($secondarySlot) { 110*04fd306cSNickeau case SlotSystem::getSidebarName(): 111*04fd306cSNickeau $label = "Page Sidebar"; 112*04fd306cSNickeau break; 113*04fd306cSNickeau case SlotSystem::getMainHeaderSlotName(): 114*04fd306cSNickeau $label = "Content Header"; 115*04fd306cSNickeau break; 116*04fd306cSNickeau case SlotSystem::getMainFooterSlotName(): 117*04fd306cSNickeau $label = "Content Footer"; 118*04fd306cSNickeau break; 119*04fd306cSNickeau case SlotSystem::getPageFooterSlotName(): 120*04fd306cSNickeau $label = "Page Footer"; 121*04fd306cSNickeau break; 122*04fd306cSNickeau case SlotSystem::getPageHeaderSlotName(): 123*04fd306cSNickeau $label = "Page Header"; 124*04fd306cSNickeau break; 125*04fd306cSNickeau } 126*04fd306cSNickeau $html .= "<p class='mb-0 mt-1'><strong>$label</strong></p>"; 127*04fd306cSNickeau $html .= "<table>"; 128*04fd306cSNickeau 129*04fd306cSNickeau $parentPath = $requestedPath; 130*04fd306cSNickeau while (true) { 131*04fd306cSNickeau try { 132*04fd306cSNickeau $parentPath = $parentPath->getParent(); 133*04fd306cSNickeau } catch (ExceptionNotFound $e) { 134*04fd306cSNickeau break; 135*04fd306cSNickeau } 136*04fd306cSNickeau $secondaryPath = $parentPath->resolveId($secondarySlot); 137*04fd306cSNickeau 138*04fd306cSNickeau $secondaryPage = MarkupPath::createPageFromAbsoluteId($secondaryPath->toAbsoluteId()); 139*04fd306cSNickeau $class = StyleAttribute::addComboStrapSuffix(\syntax_plugin_combo_link::TAG); 140*04fd306cSNickeau if (FileSystems::exists($secondaryPath)) { 141*04fd306cSNickeau $action = self::EDIT_ACTION; 142*04fd306cSNickeau $style = ''; 143*04fd306cSNickeau } else { 144*04fd306cSNickeau $action = self::CREATE_ACTION; 145*04fd306cSNickeau $style = ' style="color:rgba(0,0,0,0.65)"'; 146*04fd306cSNickeau } 147*04fd306cSNickeau $url = UrlEndpoint::createDokuUrl() 148*04fd306cSNickeau ->addQueryParameter(DokuwikiId::DOKUWIKI_ID_ATTRIBUTE, $secondaryPage->getWikiId()) 149*04fd306cSNickeau ->addQueryParameter("do", "edit"); 150*04fd306cSNickeau 151*04fd306cSNickeau $html .= "<tr><td class='pe-2'>$action</td><td><a href=\"{$url->toHtmlString()}\" class=\"$class\"$style>{$secondaryPath->toAbsoluteId()}</a></td></tr>"; 152*04fd306cSNickeau 153*04fd306cSNickeau if ($action === self::EDIT_ACTION) { 154*04fd306cSNickeau break; 155*04fd306cSNickeau } 156*04fd306cSNickeau 157*04fd306cSNickeau } 158*04fd306cSNickeau $html .= "</table>"; 159*04fd306cSNickeau 160*04fd306cSNickeau }; 161*04fd306cSNickeau 162*04fd306cSNickeau 163*04fd306cSNickeau return $html; 164*04fd306cSNickeau 165*04fd306cSNickeau } 166*04fd306cSNickeau 167*04fd306cSNickeau 168*04fd306cSNickeau} 169