Completed
Push — svgpagetools ( 17ef2a...7c844e )
by Andreas
04:40
created

AbstractItem::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
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
    protected $type        = '';
30
    protected $accesskey   = '';
31
    protected $id          = '';
32
    protected $method      = 'get';
33
    protected $params      = array();
34
    protected $nofollow    = true;
35
    protected $replacement = '';
36
    protected $category    = 'page';
37
    protected $svg         = DOKU_INC . 'lib/images/menu/00-default_checkbox-blank-circle-outline.svg';
38
    protected $label       = '';
39
    protected $context     = self::CTX_ALL;
40
41
    public function __construct() {
42
        global $ID;
43
        $this->id = $ID;
44
        $this->type = strtolower(substr(strrchr(get_class($this), '\\'), 1));
45
        $this->params['do'] = $this->type;
46
47
        if(!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}");
48
    }
49
50
    /**
51
     * Return this item's label
52
     *
53
     * When the label property was set, it is simply returned. Otherwise, the action's type
54
     * is used to look up the translation in the main language file and, if used, the replacement
55
     * is applied.
56
     *
57
     * @return string
58
     */
59
    public function getLabel() {
60
        if($this->label !== '') return $this->label;
61
62
        /** @var array $lang */
63
        global $lang;
64
        $label = $lang['btn_' . $this->type];
65
        if(strpos($label, '%s')) {
66
            $label = sprintf($label, $this->replacement);
67
        }
68
        if($label === '') $label = '[' . $this->type . ']';
69
        return $label;
70
    }
71
72
    /**
73
     * Return the link this item links to
74
     *
75
     * Basically runs wl() on $id and $params. However if the ID is a hash it is used directly
76
     * as the link
77
     *
78
     * @see wl()
79
     * @return string
80
     */
81
    public function getLink() {
82
        if($this->id[0] == '#') {
83
            return $this->id;
84
        } else {
85
            return wl($this->id, $this->params);
86
        }
87
    }
88
89
    /**
90
     * Convenience method to get the attributes for constructing an <a> element
91
     *
92
     * @see buildAttributes()
93
     * @param string|false $classprefix create a class from type with this prefix, false for no class
94
     * @return array
95
     */
96
    public function getLinkAttributes($classprefix = 'menuitem ') {
97
        $attr = array(
98
            'href' => $this->getLink(),
99
            'title' => $this->getLabel(),
100
        );
101
        if($this->isNofollow()) $attr['rel'] = 'nofollow';
102
        if($this->getAccesskey()) {
103
            $attr['accesskey'] = $this->getAccesskey();
104
            $attr['title'] .= ' [' . $this->getAccesskey() . ']';
105
        }
106
        if($classprefix !== false) $attr['class'] = $classprefix . $this->getType();
107
108
        return $attr;
109
    }
110
111
    /**
112
     * Convenience method to create a full <a> element
113
     *
114
     * Wraps around the label and SVG image
115
     *
116
     * @param string|false $classprefix create a class from type with this prefix, false for no class
117
     * @return string
118
     */
119
    public function asHtmlLink($classprefix = 'menuitem ') {
120
        $attr = buildAttributes($this->getLinkAttributes($classprefix));
121
        $html = "<a $attr>";
122
        $html .= '<span>' . hsc($this->getLabel()) . '</span>';
123
        $html .= inlineSVG($this->getSvg());
124
        $html .= "</a>";
125
126
        return $html;
127
    }
128
129
    /**
130
     * Should this item be shown in the given context
131
     *
132
     * @param int $ctx the current context
133
     * @return bool
134
     */
135
    public function visibleInContext($ctx) {
136
        return (bool) ($ctx & $this->context);
137
    }
138
139
    /**
140
     * @return string the name of this item
141
     */
142
    public function getType() {
143
        return $this->type;
144
    }
145
146
    /**
147
     * @return string
148
     */
149
    public function getAccesskey() {
150
        return $this->accesskey;
151
    }
152
153
    /**
154
     * @return array
155
     */
156
    public function getParams() {
157
        return $this->params;
158
    }
159
160
    /**
161
     * @return bool
162
     */
163
    public function isNofollow() {
164
        return $this->nofollow;
165
    }
166
167
    /**
168
     * @return string
169
     */
170
    public function getSvg() {
171
        return $this->svg;
172
    }
173
174
}
175