[ 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      public const CTX_DESKTOP = 1;
  24      /** menu item is to be shown on mobile screens only */
  25      public const CTX_MOBILE = 2;
  26      /** menu item is to be shown in all contexts */
  27      public 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 = [];
  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      {
  63          global $ID;
  64          $this->id = $ID;
  65          $this->type = $this->getType();
  66          $this->params['do'] = $this->type;
  67  
  68          if (!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}");
  69      }
  70  
  71      /**
  72       * Return this item's label
  73       *
  74       * When the label property was set, it is simply returned. Otherwise, the action's type
  75       * is used to look up the translation in the main language file and, if used, the replacement
  76       * is applied.
  77       *
  78       * @return string
  79       */
  80      public function getLabel()
  81      {
  82          if ($this->label !== '') return $this->label;
  83  
  84          /** @var array $lang */
  85          global $lang;
  86          $label = $lang['btn_' . $this->type];
  87          if (strpos($label, '%s')) {
  88              $label = sprintf($label, $this->replacement);
  89          }
  90          if ($label === '') $label = '[' . $this->type . ']';
  91          return $label;
  92      }
  93  
  94      /**
  95       * Return this item's title
  96       *
  97       * This title should be used to display a tooltip (using the HTML title attribute). If
  98       * a title property was not explicitly set, the label will be returned.
  99       *
 100       * @return string
 101       */
 102      public function getTitle()
 103      {
 104          if ($this->title === '') return $this->getLabel();
 105          return $this->title;
 106      }
 107  
 108      /**
 109       * Return the link this item links to
 110       *
 111       * Basically runs wl() on $id and $params. However if the ID is a hash it is used directly
 112       * as the link
 113       *
 114       * Please note that the generated URL is *not* XML escaped.
 115       *
 116       * @return string
 117       * @see wl()
 118       */
 119      public function getLink()
 120      {
 121          if ($this->id && $this->id[0] == '#') {
 122              return $this->id;
 123          } else {
 124              return wl($this->id, $this->params, false, '&');
 125          }
 126      }
 127  
 128      /**
 129       * Convenience method to get the attributes for constructing an <a> element
 130       *
 131       * @param string|false $classprefix create a class from type with this prefix, false for no class
 132       * @return array
 133       * @see buildAttributes()
 134       */
 135      public function getLinkAttributes($classprefix = 'menuitem ')
 136      {
 137          $attr = ['href' => $this->getLink(), 'title' => $this->getTitle()];
 138          if ($this->isNofollow()) $attr['rel'] = 'nofollow';
 139          if ($this->getAccesskey()) {
 140              $attr['accesskey'] = $this->getAccesskey();
 141              $attr['title'] .= ' [' . $this->getAccesskey() . ']';
 142          }
 143          if ($classprefix !== false) $attr['class'] = $classprefix . $this->getType();
 144  
 145          return $attr;
 146      }
 147  
 148      /**
 149       * Convenience method to create a full <a> element
 150       *
 151       * Wraps around the label and SVG image
 152       *
 153       * @param string|false $classprefix create a class from type with this prefix, false for no class
 154       * @param bool $svg add SVG icon to the link
 155       * @return string
 156       */
 157      public function asHtmlLink($classprefix = 'menuitem ', $svg = true)
 158      {
 159          $attr = buildAttributes($this->getLinkAttributes($classprefix));
 160          $html = "<a $attr>";
 161          if ($svg) {
 162              $html .= '<span>' . hsc($this->getLabel()) . '</span>';
 163              $html .= inlineSVG($this->getSvg());
 164          } else {
 165              $html .= hsc($this->getLabel());
 166          }
 167          $html .= "</a>";
 168  
 169          return $html;
 170      }
 171  
 172      /**
 173       * Convenience method to create a <button> element inside it's own form element
 174       *
 175       * Uses html_btn()
 176       *
 177       * @return string
 178       */
 179      public function asHtmlButton()
 180      {
 181          return html_btn(
 182              $this->getType(),
 183              $this->id,
 184              $this->getAccesskey(),
 185              $this->getParams(),
 186              $this->method,
 187              $this->getTitle(),
 188              $this->getLabel(),
 189              $this->getSvg()
 190          );
 191      }
 192  
 193      /**
 194       * Should this item be shown in the given context
 195       *
 196       * @param int $ctx the current context
 197       * @return bool
 198       */
 199      public function visibleInContext($ctx)
 200      {
 201          return (bool)($ctx & $this->context);
 202      }
 203  
 204      /**
 205       * @return string the name of this item
 206       */
 207      public function getType()
 208      {
 209          if ($this->type === '') {
 210              $this->type = strtolower(substr(strrchr(get_class($this), '\\'), 1));
 211          }
 212          return $this->type;
 213      }
 214  
 215      /**
 216       * @return string
 217       */
 218      public function getAccesskey()
 219      {
 220          return $this->accesskey;
 221      }
 222  
 223      /**
 224       * @return array
 225       */
 226      public function getParams()
 227      {
 228          return $this->params;
 229      }
 230  
 231      /**
 232       * @return bool
 233       */
 234      public function isNofollow()
 235      {
 236          return $this->nofollow;
 237      }
 238  
 239      /**
 240       * @return string
 241       */
 242      public function getSvg()
 243      {
 244          return $this->svg;
 245      }
 246  
 247      /**
 248       * Return this Item's settings as an array as used in tpl_get_action()
 249       *
 250       * @return array
 251       */
 252      public function getLegacyData()
 253      {
 254          return [
 255              'accesskey' => $this->accesskey ?: null,
 256              'type' => $this->type,
 257              'id' => $this->id,
 258              'method' => $this->method,
 259              'params' => $this->params,
 260              'nofollow' => $this->nofollow,
 261              'replacement' => $this->replacement
 262          ];
 263      }
 264  }