apply PSR-12 constant visibility rule
[dokuwiki.git] / inc / Menu / Item / AbstractItem.php
blobe64b3f827253d85e58ea69b203353e23b77fd9da
1 <?php
3 namespace dokuwiki\Menu\Item;
5 /**
6 * Class AbstractItem
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.
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.
17 * Children usually just need to overwrite the different properties, but for complex things
18 * the accessors may be overwritten instead.
20 abstract class AbstractItem
23 /** menu item is to be shown on desktop screens only */
24 public const CTX_DESKTOP = 1;
25 /** menu item is to be shown on mobile screens only */
26 public const CTX_MOBILE = 2;
27 /** menu item is to be shown in all contexts */
28 public const CTX_ALL = 3;
30 /** @var string name of the action, usually the lowercase class name */
31 protected $type = '';
32 /** @var string optional keyboard shortcut */
33 protected $accesskey = '';
34 /** @var string the page id this action links to */
35 protected $id = '';
36 /** @var string the method to be used when this action is used in a form */
37 protected $method = 'get';
38 /** @var array parameters for the action (should contain the do parameter) */
39 protected $params = [];
40 /** @var bool when true, a rel=nofollow should be used */
41 protected $nofollow = true;
42 /** @var string this item's label may contain a placeholder, which is replaced with this */
43 protected $replacement = '';
44 /** @var string the full path to the SVG icon of this menu item */
45 protected $svg = DOKU_INC . 'lib/images/menu/00-default_checkbox-blank-circle-outline.svg';
46 /** @var string can be set to overwrite the default lookup in $lang.btn_* */
47 protected $label = '';
48 /** @var string the tooltip title, defaults to $label */
49 protected $title = '';
50 /** @var int the context this titme is shown in */
51 protected $context = self::CTX_ALL;
53 /**
54 * AbstractItem constructor.
56 * Sets the dynamic properties
58 * Children should always call the parent constructor!
60 * @throws \RuntimeException when the action is disabled
62 public function __construct()
64 global $ID;
65 $this->id = $ID;
66 $this->type = $this->getType();
67 $this->params['do'] = $this->type;
69 if (!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}");
72 /**
73 * Return this item's label
75 * When the label property was set, it is simply returned. Otherwise, the action's type
76 * is used to look up the translation in the main language file and, if used, the replacement
77 * is applied.
79 * @return string
81 public function getLabel()
83 if ($this->label !== '') return $this->label;
85 /** @var array $lang */
86 global $lang;
87 $label = $lang['btn_' . $this->type];
88 if (strpos($label, '%s')) {
89 $label = sprintf($label, $this->replacement);
91 if ($label === '') $label = '[' . $this->type . ']';
92 return $label;
95 /**
96 * Return this item's title
98 * This title should be used to display a tooltip (using the HTML title attribute). If
99 * a title property was not explicitly set, the label will be returned.
101 * @return string
103 public function getTitle()
105 if ($this->title === '') return $this->getLabel();
106 return $this->title;
110 * Return the link this item links to
112 * Basically runs wl() on $id and $params. However if the ID is a hash it is used directly
113 * as the link
115 * Please note that the generated URL is *not* XML escaped.
117 * @return string
118 * @see wl()
120 public function getLink()
122 if ($this->id && $this->id[0] == '#') {
123 return $this->id;
124 } else {
125 return wl($this->id, $this->params, false, '&');
130 * Convenience method to get the attributes for constructing an <a> element
132 * @param string|false $classprefix create a class from type with this prefix, false for no class
133 * @return array
134 * @see buildAttributes()
136 public function getLinkAttributes($classprefix = 'menuitem ')
138 $attr = ['href' => $this->getLink(), 'title' => $this->getTitle()];
139 if ($this->isNofollow()) $attr['rel'] = 'nofollow';
140 if ($this->getAccesskey()) {
141 $attr['accesskey'] = $this->getAccesskey();
142 $attr['title'] .= ' [' . $this->getAccesskey() . ']';
144 if ($classprefix !== false) $attr['class'] = $classprefix . $this->getType();
146 return $attr;
150 * Convenience method to create a full <a> element
152 * Wraps around the label and SVG image
154 * @param string|false $classprefix create a class from type with this prefix, false for no class
155 * @param bool $svg add SVG icon to the link
156 * @return string
158 public function asHtmlLink($classprefix = 'menuitem ', $svg = true)
160 $attr = buildAttributes($this->getLinkAttributes($classprefix));
161 $html = "<a $attr>";
162 if ($svg) {
163 $html .= '<span>' . hsc($this->getLabel()) . '</span>';
164 $html .= inlineSVG($this->getSvg());
165 } else {
166 $html .= hsc($this->getLabel());
168 $html .= "</a>";
170 return $html;
174 * Convenience method to create a <button> element inside it's own form element
176 * Uses html_btn()
178 * @return string
180 public function asHtmlButton()
182 return html_btn(
183 $this->getType(),
184 $this->id,
185 $this->getAccesskey(),
186 $this->getParams(),
187 $this->method,
188 $this->getTitle(),
189 $this->getLabel(),
190 $this->getSvg()
195 * Should this item be shown in the given context
197 * @param int $ctx the current context
198 * @return bool
200 public function visibleInContext($ctx)
202 return (bool)($ctx & $this->context);
206 * @return string the name of this item
208 public function getType()
210 if ($this->type === '') {
211 $this->type = strtolower(substr(strrchr(get_class($this), '\\'), 1));
213 return $this->type;
217 * @return string
219 public function getAccesskey()
221 return $this->accesskey;
225 * @return array
227 public function getParams()
229 return $this->params;
233 * @return bool
235 public function isNofollow()
237 return $this->nofollow;
241 * @return string
243 public function getSvg()
245 return $this->svg;
249 * Return this Item's settings as an array as used in tpl_get_action()
251 * @return array
253 public function getLegacyData()
255 return [
256 'accesskey' => $this->accesskey ?: null,
257 'type' => $this->type,
258 'id' => $this->id,
259 'method' => $this->method,
260 'params' => $this->params,
261 'nofollow' => $this->nofollow,
262 'replacement' => $this->replacement