1*93b8c351SAndreas Gohr<?php 2*93b8c351SAndreas Gohr 3*93b8c351SAndreas Gohrnamespace dokuwiki\Menu\Item; 4*93b8c351SAndreas Gohr 5*93b8c351SAndreas Gohr/** 6*93b8c351SAndreas Gohr * Class AbstractItem 7*93b8c351SAndreas Gohr * 8*93b8c351SAndreas Gohr * This class defines a single Item to be displayed in one of DokuWiki's menus. Plugins 9*93b8c351SAndreas Gohr * can extend those menus through action plugins and add their own instances of this class, 10*93b8c351SAndreas Gohr * overwriting some of its properties. 11*93b8c351SAndreas Gohr * 12*93b8c351SAndreas Gohr * Items may be shown multiple times in different contexts. Eg. for the default template 13*93b8c351SAndreas Gohr * all menus are shown in a Dropdown list on mobile, but are split into several places on 14*93b8c351SAndreas Gohr * desktop. The item's $context property can be used to hide the item depending on the current 15*93b8c351SAndreas Gohr * context. 16*93b8c351SAndreas Gohr * 17*93b8c351SAndreas Gohr * Children usually just need to overwrite the different properties, but for complex things 18*93b8c351SAndreas Gohr * the accessors may be overwritten instead. 19*93b8c351SAndreas Gohr */ 20*93b8c351SAndreas Gohrabstract class AbstractItem { 21*93b8c351SAndreas Gohr 22*93b8c351SAndreas Gohr /** menu item is to be shown on desktop screens only */ 23*93b8c351SAndreas Gohr const CTX_DESKTOP = 1; 24*93b8c351SAndreas Gohr /** menu item is to be shown on mobile screens only */ 25*93b8c351SAndreas Gohr const CTX_MOBILE = 2; 26*93b8c351SAndreas Gohr /** menu item is to be shown in all contexts */ 27*93b8c351SAndreas Gohr const CTX_ALL = 3; 28*93b8c351SAndreas Gohr 29*93b8c351SAndreas Gohr protected $type = ''; 30*93b8c351SAndreas Gohr protected $accesskey = ''; 31*93b8c351SAndreas Gohr protected $id = ''; 32*93b8c351SAndreas Gohr protected $method = 'get'; 33*93b8c351SAndreas Gohr protected $params = array(); 34*93b8c351SAndreas Gohr protected $nofollow = true; 35*93b8c351SAndreas Gohr protected $replacement = ''; 36*93b8c351SAndreas Gohr protected $category = 'page'; 37*93b8c351SAndreas Gohr protected $svg = DOKU_BASE . 'lib/images/menu/00-default_checkbox-blank-circle-outline.svg'; 38*93b8c351SAndreas Gohr protected $label = ''; 39*93b8c351SAndreas Gohr protected $context = self::CTX_ALL; 40*93b8c351SAndreas Gohr 41*93b8c351SAndreas Gohr public function __construct() { 42*93b8c351SAndreas Gohr global $ID; 43*93b8c351SAndreas Gohr $this->id = $ID; 44*93b8c351SAndreas Gohr $this->type = strtolower(substr(strrchr(get_class($this), '\\'), 1)); 45*93b8c351SAndreas Gohr $this->params['do'] = $this->type; 46*93b8c351SAndreas Gohr 47*93b8c351SAndreas Gohr if(!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}"); 48*93b8c351SAndreas Gohr } 49*93b8c351SAndreas Gohr 50*93b8c351SAndreas Gohr /** 51*93b8c351SAndreas Gohr * Return this item's label 52*93b8c351SAndreas Gohr * 53*93b8c351SAndreas Gohr * When the label property was set, it is simply returned. Otherwise, the action's type 54*93b8c351SAndreas Gohr * is used to look up the translation in the main language file and, if used, the replacement 55*93b8c351SAndreas Gohr * is applied. 56*93b8c351SAndreas Gohr * 57*93b8c351SAndreas Gohr * @return string 58*93b8c351SAndreas Gohr */ 59*93b8c351SAndreas Gohr public function getLabel() { 60*93b8c351SAndreas Gohr if($this->label !== '') return $this->label; 61*93b8c351SAndreas Gohr 62*93b8c351SAndreas Gohr /** @var array $lang */ 63*93b8c351SAndreas Gohr global $lang; 64*93b8c351SAndreas Gohr $label = $lang['btn_' . $this->type]; 65*93b8c351SAndreas Gohr if(strpos($label, '%s')) { 66*93b8c351SAndreas Gohr $label = sprintf($label, $this->replacement); 67*93b8c351SAndreas Gohr } 68*93b8c351SAndreas Gohr if($label === '') $label = '[' . $this->type . ']'; 69*93b8c351SAndreas Gohr return $label; 70*93b8c351SAndreas Gohr } 71*93b8c351SAndreas Gohr 72*93b8c351SAndreas Gohr /** 73*93b8c351SAndreas Gohr * Return the link this item links to 74*93b8c351SAndreas Gohr * 75*93b8c351SAndreas Gohr * Basically runs wl() on $id and $params. However if the ID is a hash it is used directly 76*93b8c351SAndreas Gohr * as the link 77*93b8c351SAndreas Gohr * 78*93b8c351SAndreas Gohr * @see wl() 79*93b8c351SAndreas Gohr * @return string 80*93b8c351SAndreas Gohr */ 81*93b8c351SAndreas Gohr public function getLink() { 82*93b8c351SAndreas Gohr if($this->id[0] == '#') { 83*93b8c351SAndreas Gohr return $this->id; 84*93b8c351SAndreas Gohr } else { 85*93b8c351SAndreas Gohr return wl($this->id, $this->params); 86*93b8c351SAndreas Gohr } 87*93b8c351SAndreas Gohr } 88*93b8c351SAndreas Gohr 89*93b8c351SAndreas Gohr /** 90*93b8c351SAndreas Gohr * Convenience method to get the attributes for constructing an <a> element 91*93b8c351SAndreas Gohr * 92*93b8c351SAndreas Gohr * @see buildAttributes() 93*93b8c351SAndreas Gohr * @param string|false $classprefix create a class from type with this prefix, false for no class 94*93b8c351SAndreas Gohr * @return array 95*93b8c351SAndreas Gohr */ 96*93b8c351SAndreas Gohr public function getLinkAttributes($classprefix = 'menuitem ') { 97*93b8c351SAndreas Gohr $attr = array( 98*93b8c351SAndreas Gohr 'href' => $this->getLink(), 99*93b8c351SAndreas Gohr 'title' => $this->getLabel(), 100*93b8c351SAndreas Gohr ); 101*93b8c351SAndreas Gohr if($this->isNofollow()) $attr['rel'] = 'nofollow'; 102*93b8c351SAndreas Gohr if($this->getAccesskey()) { 103*93b8c351SAndreas Gohr $attr['accesskey'] = $this->getAccesskey(); 104*93b8c351SAndreas Gohr $attr['title'] .= ' [' . $this->getAccesskey() . ']'; 105*93b8c351SAndreas Gohr } 106*93b8c351SAndreas Gohr if($classprefix !== false) $attr['class'] = $classprefix . $this->getType(); 107*93b8c351SAndreas Gohr 108*93b8c351SAndreas Gohr return $attr; 109*93b8c351SAndreas Gohr } 110*93b8c351SAndreas Gohr 111*93b8c351SAndreas Gohr /** 112*93b8c351SAndreas Gohr * Convenience method to create a full <a> element 113*93b8c351SAndreas Gohr * 114*93b8c351SAndreas Gohr * Wraps around the label and SVG image 115*93b8c351SAndreas Gohr * 116*93b8c351SAndreas Gohr * @param string|false $classprefix create a class from type with this prefix, false for no class 117*93b8c351SAndreas Gohr * @return string 118*93b8c351SAndreas Gohr */ 119*93b8c351SAndreas Gohr public function asHtmlLink($classprefix = 'menuitem ') { 120*93b8c351SAndreas Gohr $attr = buildAttributes($this->getLinkAttributes($classprefix)); 121*93b8c351SAndreas Gohr $html = "<a $attr>"; 122*93b8c351SAndreas Gohr $html .= '<span>' . hsc($this->getLabel()) . '</span>'; 123*93b8c351SAndreas Gohr $html .= inlinSVG($this->getSvg()); 124*93b8c351SAndreas Gohr $html .= "</a>"; 125*93b8c351SAndreas Gohr 126*93b8c351SAndreas Gohr return $html; 127*93b8c351SAndreas Gohr } 128*93b8c351SAndreas Gohr 129*93b8c351SAndreas Gohr /** 130*93b8c351SAndreas Gohr * Should this item be shown in the given context 131*93b8c351SAndreas Gohr * 132*93b8c351SAndreas Gohr * @param int $ctx the current context 133*93b8c351SAndreas Gohr * @return bool 134*93b8c351SAndreas Gohr */ 135*93b8c351SAndreas Gohr public function visibleInContext($ctx) { 136*93b8c351SAndreas Gohr return (bool) ($ctx & $this->context); 137*93b8c351SAndreas Gohr } 138*93b8c351SAndreas Gohr 139*93b8c351SAndreas Gohr /** 140*93b8c351SAndreas Gohr * @return string the name of this item 141*93b8c351SAndreas Gohr */ 142*93b8c351SAndreas Gohr public function getType() { 143*93b8c351SAndreas Gohr return $this->type; 144*93b8c351SAndreas Gohr } 145*93b8c351SAndreas Gohr 146*93b8c351SAndreas Gohr /** 147*93b8c351SAndreas Gohr * @return string 148*93b8c351SAndreas Gohr */ 149*93b8c351SAndreas Gohr public function getAccesskey() { 150*93b8c351SAndreas Gohr return $this->accesskey; 151*93b8c351SAndreas Gohr } 152*93b8c351SAndreas Gohr 153*93b8c351SAndreas Gohr /** 154*93b8c351SAndreas Gohr * @return array 155*93b8c351SAndreas Gohr */ 156*93b8c351SAndreas Gohr public function getParams() { 157*93b8c351SAndreas Gohr return $this->params; 158*93b8c351SAndreas Gohr } 159*93b8c351SAndreas Gohr 160*93b8c351SAndreas Gohr /** 161*93b8c351SAndreas Gohr * @return bool 162*93b8c351SAndreas Gohr */ 163*93b8c351SAndreas Gohr public function isNofollow() { 164*93b8c351SAndreas Gohr return $this->nofollow; 165*93b8c351SAndreas Gohr } 166*93b8c351SAndreas Gohr 167*93b8c351SAndreas Gohr /** 168*93b8c351SAndreas Gohr * @return string 169*93b8c351SAndreas Gohr */ 170*93b8c351SAndreas Gohr public function getSvg() { 171*93b8c351SAndreas Gohr return $this->svg; 172*93b8c351SAndreas Gohr } 173*93b8c351SAndreas Gohr 174*93b8c351SAndreas Gohr} 175