193b8c351SAndreas Gohr<?php 293b8c351SAndreas Gohr 393b8c351SAndreas Gohrnamespace dokuwiki\Menu\Item; 493b8c351SAndreas Gohr 593b8c351SAndreas Gohr/** 693b8c351SAndreas Gohr * Class AbstractItem 793b8c351SAndreas Gohr * 893b8c351SAndreas Gohr * This class defines a single Item to be displayed in one of DokuWiki's menus. Plugins 993b8c351SAndreas Gohr * can extend those menus through action plugins and add their own instances of this class, 1093b8c351SAndreas Gohr * overwriting some of its properties. 1193b8c351SAndreas Gohr * 1293b8c351SAndreas Gohr * Items may be shown multiple times in different contexts. Eg. for the default template 1393b8c351SAndreas Gohr * all menus are shown in a Dropdown list on mobile, but are split into several places on 1493b8c351SAndreas Gohr * desktop. The item's $context property can be used to hide the item depending on the current 1593b8c351SAndreas Gohr * context. 1693b8c351SAndreas Gohr * 1793b8c351SAndreas Gohr * Children usually just need to overwrite the different properties, but for complex things 1893b8c351SAndreas Gohr * the accessors may be overwritten instead. 1993b8c351SAndreas Gohr */ 2093b8c351SAndreas Gohrabstract class AbstractItem { 2193b8c351SAndreas Gohr 2293b8c351SAndreas Gohr /** menu item is to be shown on desktop screens only */ 2393b8c351SAndreas Gohr const CTX_DESKTOP = 1; 2493b8c351SAndreas Gohr /** menu item is to be shown on mobile screens only */ 2593b8c351SAndreas Gohr const CTX_MOBILE = 2; 2693b8c351SAndreas Gohr /** menu item is to be shown in all contexts */ 2793b8c351SAndreas Gohr const CTX_ALL = 3; 2893b8c351SAndreas Gohr 2993b8c351SAndreas Gohr protected $type = ''; 3093b8c351SAndreas Gohr protected $accesskey = ''; 3193b8c351SAndreas Gohr protected $id = ''; 3293b8c351SAndreas Gohr protected $method = 'get'; 3393b8c351SAndreas Gohr protected $params = array(); 3493b8c351SAndreas Gohr protected $nofollow = true; 3593b8c351SAndreas Gohr protected $replacement = ''; 3693b8c351SAndreas Gohr protected $category = 'page'; 37c2b9771aSAndreas Gohr protected $svg = DOKU_INC . 'lib/images/menu/00-default_checkbox-blank-circle-outline.svg'; 3893b8c351SAndreas Gohr protected $label = ''; 3993b8c351SAndreas Gohr protected $context = self::CTX_ALL; 4093b8c351SAndreas Gohr 4193b8c351SAndreas Gohr public function __construct() { 4293b8c351SAndreas Gohr global $ID; 4393b8c351SAndreas Gohr $this->id = $ID; 4493b8c351SAndreas Gohr $this->type = strtolower(substr(strrchr(get_class($this), '\\'), 1)); 4593b8c351SAndreas Gohr $this->params['do'] = $this->type; 4693b8c351SAndreas Gohr 4793b8c351SAndreas Gohr if(!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}"); 4893b8c351SAndreas Gohr } 4993b8c351SAndreas Gohr 5093b8c351SAndreas Gohr /** 5193b8c351SAndreas Gohr * Return this item's label 5293b8c351SAndreas Gohr * 5393b8c351SAndreas Gohr * When the label property was set, it is simply returned. Otherwise, the action's type 5493b8c351SAndreas Gohr * is used to look up the translation in the main language file and, if used, the replacement 5593b8c351SAndreas Gohr * is applied. 5693b8c351SAndreas Gohr * 5793b8c351SAndreas Gohr * @return string 5893b8c351SAndreas Gohr */ 5993b8c351SAndreas Gohr public function getLabel() { 6093b8c351SAndreas Gohr if($this->label !== '') return $this->label; 6193b8c351SAndreas Gohr 6293b8c351SAndreas Gohr /** @var array $lang */ 6393b8c351SAndreas Gohr global $lang; 6493b8c351SAndreas Gohr $label = $lang['btn_' . $this->type]; 6593b8c351SAndreas Gohr if(strpos($label, '%s')) { 6693b8c351SAndreas Gohr $label = sprintf($label, $this->replacement); 6793b8c351SAndreas Gohr } 6893b8c351SAndreas Gohr if($label === '') $label = '[' . $this->type . ']'; 6993b8c351SAndreas Gohr return $label; 7093b8c351SAndreas Gohr } 7193b8c351SAndreas Gohr 7293b8c351SAndreas Gohr /** 7393b8c351SAndreas Gohr * Return the link this item links to 7493b8c351SAndreas Gohr * 7593b8c351SAndreas Gohr * Basically runs wl() on $id and $params. However if the ID is a hash it is used directly 7693b8c351SAndreas Gohr * as the link 7793b8c351SAndreas Gohr * 7893b8c351SAndreas Gohr * @see wl() 7993b8c351SAndreas Gohr * @return string 8093b8c351SAndreas Gohr */ 8193b8c351SAndreas Gohr public function getLink() { 8293b8c351SAndreas Gohr if($this->id[0] == '#') { 8393b8c351SAndreas Gohr return $this->id; 8493b8c351SAndreas Gohr } else { 8593b8c351SAndreas Gohr return wl($this->id, $this->params); 8693b8c351SAndreas Gohr } 8793b8c351SAndreas Gohr } 8893b8c351SAndreas Gohr 8993b8c351SAndreas Gohr /** 9093b8c351SAndreas Gohr * Convenience method to get the attributes for constructing an <a> element 9193b8c351SAndreas Gohr * 9293b8c351SAndreas Gohr * @see buildAttributes() 9393b8c351SAndreas Gohr * @param string|false $classprefix create a class from type with this prefix, false for no class 9493b8c351SAndreas Gohr * @return array 9593b8c351SAndreas Gohr */ 9693b8c351SAndreas Gohr public function getLinkAttributes($classprefix = 'menuitem ') { 9793b8c351SAndreas Gohr $attr = array( 9893b8c351SAndreas Gohr 'href' => $this->getLink(), 9993b8c351SAndreas Gohr 'title' => $this->getLabel(), 10093b8c351SAndreas Gohr ); 10193b8c351SAndreas Gohr if($this->isNofollow()) $attr['rel'] = 'nofollow'; 10293b8c351SAndreas Gohr if($this->getAccesskey()) { 10393b8c351SAndreas Gohr $attr['accesskey'] = $this->getAccesskey(); 10493b8c351SAndreas Gohr $attr['title'] .= ' [' . $this->getAccesskey() . ']'; 10593b8c351SAndreas Gohr } 10693b8c351SAndreas Gohr if($classprefix !== false) $attr['class'] = $classprefix . $this->getType(); 10793b8c351SAndreas Gohr 10893b8c351SAndreas Gohr return $attr; 10993b8c351SAndreas Gohr } 11093b8c351SAndreas Gohr 11193b8c351SAndreas Gohr /** 11293b8c351SAndreas Gohr * Convenience method to create a full <a> element 11393b8c351SAndreas Gohr * 11493b8c351SAndreas Gohr * Wraps around the label and SVG image 11593b8c351SAndreas Gohr * 11693b8c351SAndreas Gohr * @param string|false $classprefix create a class from type with this prefix, false for no class 117*2f7a5efdSAndreas Gohr * @param bool $svg add SVG icon to the link 11893b8c351SAndreas Gohr * @return string 11993b8c351SAndreas Gohr */ 120*2f7a5efdSAndreas Gohr public function asHtmlLink($classprefix = 'menuitem ', $svg = true) { 12193b8c351SAndreas Gohr $attr = buildAttributes($this->getLinkAttributes($classprefix)); 12293b8c351SAndreas Gohr $html = "<a $attr>"; 123*2f7a5efdSAndreas Gohr if($svg) { 12493b8c351SAndreas Gohr $html .= '<span>' . hsc($this->getLabel()) . '</span>'; 125c3766a92SAndreas Gohr $html .= inlineSVG($this->getSvg()); 126*2f7a5efdSAndreas Gohr } else { 127*2f7a5efdSAndreas Gohr $html .= hsc($this->getLabel()); 128*2f7a5efdSAndreas Gohr } 12993b8c351SAndreas Gohr $html .= "</a>"; 13093b8c351SAndreas Gohr 13193b8c351SAndreas Gohr return $html; 13293b8c351SAndreas Gohr } 13393b8c351SAndreas Gohr 13493b8c351SAndreas Gohr /** 13593b8c351SAndreas Gohr * Should this item be shown in the given context 13693b8c351SAndreas Gohr * 13793b8c351SAndreas Gohr * @param int $ctx the current context 13893b8c351SAndreas Gohr * @return bool 13993b8c351SAndreas Gohr */ 14093b8c351SAndreas Gohr public function visibleInContext($ctx) { 14193b8c351SAndreas Gohr return (bool) ($ctx & $this->context); 14293b8c351SAndreas Gohr } 14393b8c351SAndreas Gohr 14493b8c351SAndreas Gohr /** 14593b8c351SAndreas Gohr * @return string the name of this item 14693b8c351SAndreas Gohr */ 14793b8c351SAndreas Gohr public function getType() { 14893b8c351SAndreas Gohr return $this->type; 14993b8c351SAndreas Gohr } 15093b8c351SAndreas Gohr 15193b8c351SAndreas Gohr /** 15293b8c351SAndreas Gohr * @return string 15393b8c351SAndreas Gohr */ 15493b8c351SAndreas Gohr public function getAccesskey() { 15593b8c351SAndreas Gohr return $this->accesskey; 15693b8c351SAndreas Gohr } 15793b8c351SAndreas Gohr 15893b8c351SAndreas Gohr /** 15993b8c351SAndreas Gohr * @return array 16093b8c351SAndreas Gohr */ 16193b8c351SAndreas Gohr public function getParams() { 16293b8c351SAndreas Gohr return $this->params; 16393b8c351SAndreas Gohr } 16493b8c351SAndreas Gohr 16593b8c351SAndreas Gohr /** 16693b8c351SAndreas Gohr * @return bool 16793b8c351SAndreas Gohr */ 16893b8c351SAndreas Gohr public function isNofollow() { 16993b8c351SAndreas Gohr return $this->nofollow; 17093b8c351SAndreas Gohr } 17193b8c351SAndreas Gohr 17293b8c351SAndreas Gohr /** 17393b8c351SAndreas Gohr * @return string 17493b8c351SAndreas Gohr */ 17593b8c351SAndreas Gohr public function getSvg() { 17693b8c351SAndreas Gohr return $this->svg; 17793b8c351SAndreas Gohr } 17893b8c351SAndreas Gohr 17993b8c351SAndreas Gohr} 180