[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/Menu/Item/ -> AbstractItem.php (source)

   1  <?php
   2  
   3  namespace dokuwiki\Menu\Item;
   4  
   5  /**
   6   * Class AbstractItem
   7   *
   8   * This class defines a single Item to be displayed in one of DokuWiki's menus. Plugins
   9   * can extend those menus through action plugins and add their own instances of this class,
  10   * overwriting some of its properties.
  11   *
  12   * Items may be shown multiple times in different contexts. Eg. for the default template
  13   * all menus are shown in a Dropdown list on mobile, but are split into several places on
  14   * desktop. The item's $context property can be used to hide the item depending on the current
  15   * context.
  16   *
  17   * Children usually just need to overwrite the different properties, but for complex things
  18   * the accessors may be overwritten instead.
  19   */
  20  abstract class AbstractItem {
  21  
  22      /** menu item is to be shown on desktop screens only */
  23      const CTX_DESKTOP = 1;
  24      /** menu item is to be shown on mobile screens only */
  25      const CTX_MOBILE = 2;
  26      /** menu item is to be shown in all contexts */
  27      const CTX_ALL = 3;
  28  
  29      /** @var string name of the action, usually the lowercase class name */
  30      protected $type = '';
  31      /** @var string optional keyboard shortcut */
  32      protected $accesskey = '';
  33      /** @var string the page id this action links to */
  34      protected $id = '';
  35      /** @var string the method to be used when this action is used in a form */
  36      protected $method = 'get';
  37      /** @var array parameters for the action (should contain the do parameter) */
  38      protected $params = array();
  39      /** @var bool when true, a rel=nofollow should be used */
  40      protected $nofollow = true;
  41      /** @var string this item's label may contain a placeholder, which is replaced with this */
  42      protected $replacement = '';
  43      /** @var string the full path to the SVG icon of this menu item */
  44      protected $svg = DOKU_INC . 'lib/images/menu/00-default_checkbox-blank-circle-outline.svg';
  45      /** @var string can be set to overwrite the default lookup in $lang.btn_* */
  46      protected $label = '';
  47      /** @var string the tooltip title, defaults to $label */
  48      protected $title = '';
  49      /** @var int the context this titme is shown in */
  50      protected $context = self::CTX_ALL;
  51  
  52      /**
  53       * AbstractItem constructor.
  54       *
  55       * Sets the dynamic properties
  56       *
  57       * Children should always call the parent constructor!
  58       *
  59       * @throws \RuntimeException when the action is disabled
  60       */
  61      public function __construct() {
  62          global $ID;
  63          $this->id = $ID;
  64          $this->type = $this->getType();
  65          $this->params['do'] = $this->type;
  66  
  67          if(!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}");
  68      }
  69  
  70      /**
  71       * Return this item's label
  72       *
  73       * When the label property was set, it is simply returned. Otherwise, the action's type
  74       * is used to look up the translation in the main language file and, if used, the replacement
  75       * is applied.
  76       *
  77       * @return string
  78       */
  79      public function getLabel() {
  80          if($this->label !== '') return $this->label;
  81  
  82          /** @var array $lang */
  83          global $lang;
  84          $label = $lang['btn_' . $this->type];
  85          if(strpos($label, '%s')) {
  86              $label = sprintf($label, $this->replacement);
  87          }
  88          if($label === '') $label = '[' . $this->type . ']';
  89          return $label;
  90      }
  91  
  92      /**
  93       * Return this item's title
  94       *
  95       * This title should be used to display a tooltip (using the HTML title attribute). If
  96       * a title property was not explicitly set, the label will be returned.
  97       *
  98       * @return string
  99       */
 100      public function getTitle() {
 101          if($this->title === '') return $this->getLabel();
 102          return $this->title;
 103      }
 104  
 105      /**
 106       * Return the link this item links to
 107       *
 108       * Basically runs wl() on $id and $params. However if the ID is a hash it is used directly
 109       * as the link
 110       *
 111       * Please note that the generated URL is *not* XML escaped.
 112       *
 113       * @see wl()
 114       * @return string
 115       */
 116      public function getLink() {
 117          if($this->id[0] == '#') {
 118              return $this->id;
 119          } else {
 120              return wl($this->id, $this->params, false, '&');
 121          }
 122      }
 123  
 124      /**
 125       * Convenience method to get the attributes for constructing an <a> element
 126       *
 127       * @see buildAttributes()
 128       * @param string|false $classprefix create a class from type with this prefix, false for no class
 129       * @return array
 130       */
 131      public function getLinkAttributes($classprefix = 'menuitem ') {
 132          $attr = array(
 133              'href' => $this->getLink(),
 134              'title' => $this->getTitle(),
 135          );
 136          if($this->isNofollow()) $attr['rel'] = 'nofollow';
 137          if($this->getAccesskey()) {
 138              $attr['accesskey'] = $this->getAccesskey();
 139              $attr['title'] .= ' [' . $this->getAccesskey() . ']';
 140          }
 141          if($classprefix !== false) $attr['class'] = $classprefix . $this->getType();
 142  
 143          return $attr;
 144      }
 145  
 146      /**
 147       * Convenience method to create a full <a> element
 148       *
 149       * Wraps around the label and SVG image
 150       *
 151       * @param string|false $classprefix create a class from type with this prefix, false for no class
 152       * @param bool $svg add SVG icon to the link
 153       * @return string
 154       */
 155      public function asHtmlLink($classprefix = 'menuitem ', $svg = true) {
 156          $attr = buildAttributes($this->getLinkAttributes($classprefix));
 157          $html = "<a $attr>";
 158          if($svg) {
 159              $html .= '<span>' . hsc($this->getLabel()) . '</span>';
 160              $html .= inlineSVG($this->getSvg());
 161          } else {
 162              $html .= hsc($this->getLabel());
 163          }
 164          $html .= "</a>";
 165  
 166          return $html;
 167      }
 168  
 169      /**
 170       * Convenience method to create a <button> element inside it's own form element
 171       *
 172       * Uses html_btn()
 173       *
 174       * @return string
 175       */
 176      public function asHtmlButton() {
 177          return html_btn(
 178              $this->getType(),
 179              $this->id,
 180              $this->getAccesskey(),
 181              $this->getParams(),
 182              $this->method,
 183              $this->getTitle(),
 184              $this->getLabel(),
 185              $this->getSvg()
 186          );
 187      }
 188  
 189      /**
 190       * Should this item be shown in the given context
 191       *
 192       * @param int $ctx the current context
 193       * @return bool
 194       */
 195      public function visibleInContext($ctx) {
 196          return (bool) ($ctx & $this->context);
 197      }
 198  
 199      /**
 200       * @return string the name of this item
 201       */
 202      public function getType() {
 203          if($this->type === '') {
 204              $this->type = strtolower(substr(strrchr(get_class($this), '\\'), 1));
 205          }
 206          return $this->type;
 207      }
 208  
 209      /**
 210       * @return string
 211       */
 212      public function getAccesskey() {
 213          return $this->accesskey;
 214      }
 215  
 216      /**
 217       * @return array
 218       */
 219      public function getParams() {
 220          return $this->params;
 221      }
 222  
 223      /**
 224       * @return bool
 225       */
 226      public function isNofollow() {
 227          return $this->nofollow;
 228      }
 229  
 230      /**
 231       * @return string
 232       */
 233      public function getSvg() {
 234          return $this->svg;
 235      }
 236  
 237      /**
 238       * Return this Item's settings as an array as used in tpl_get_action()
 239       *
 240       * @return array
 241       */
 242      public function getLegacyData() {
 243          return array(
 244              'accesskey' => $this->accesskey ?: null,
 245              'type' => $this->type,
 246              'id' => $this->id,
 247              'method' => $this->method,
 248              'params' => $this->params,
 249              'nofollow' => $this->nofollow,
 250              'replacement' => $this->replacement
 251          );
 252      }
 253  }