1 <?php
2 
3 namespace dokuwiki\Form;
4 
5 /**
6  * Class Element
7  *
8  * The basic building block of a form
9  *
10  * @package dokuwiki\Form
11  */
12 abstract class Element
13 {
14     /**
15      * @var array the attributes of this element
16      */
17     protected $attributes = [];
18 
19     /**
20      * @var string The type of this element
21      */
22     protected $type;
23 
24     /**
25      * @param string $type The type of this element
26      * @param array $attributes
27      */
28     public function __construct($type, $attributes = [])
29     {
30         $this->type = $type;
31         $this->attributes = $attributes;
32     }
33 
34     /**
35      * Type of this element
36      *
37      * @return string
38      */
39     public function getType()
40     {
41         return $this->type;
42     }
43 
44     /**
45      * Gets or sets an attribute
46      *
47      * When no $value is given, the current content of the attribute is returned.
48      * An empty string is returned for unset attributes.
49      *
50      * When a $value is given, the content is set to that value and the Element
51      * itself is returned for easy chaining
52      *
53      * @param string $name Name of the attribute to access
54      * @param null|string $value New value to set
55      * @return string|$this
56      */
57     public function attr($name, $value = null)
58     {
59         // set
60         if ($value !== null) {
61             $this->attributes[$name] = $value;
62             return $this;
63         }
64 
65         // get
66         if (isset($this->attributes[$name])) {
67             return $this->attributes[$name];
68         } else {
69             return '';
70         }
71     }
72 
73     /**
74      * Removes the given attribute if it exists
75      *
76      * @param string $name
77      * @return $this
78      */
79     public function rmattr($name)
80     {
81         if (isset($this->attributes[$name])) {
82             unset($this->attributes[$name]);
83         }
84         return $this;
85     }
86 
87     /**
88      * Gets or adds a all given attributes at once
89      *
90      * @param array|null $attributes
91      * @return array|$this
92      */
93     public function attrs($attributes = null)
94     {
95         // set
96         if ($attributes) {
97             foreach ((array) $attributes as $key => $val) {
98                 $this->attr($key, $val);
99             }
100             return $this;
101         }
102         // get
103         return $this->attributes;
104     }
105 
106     /**
107      * Adds a class to the class attribute
108      *
109      * This is the preferred method of setting the element's class
110      *
111      * @param string $class the new class to add
112      * @return $this
113      */
114     public function addClass($class)
115     {
116         $classes = explode(' ', $this->attr('class'));
117         $classes[] = $class;
118         $classes = array_unique($classes);
119         $classes = array_filter($classes);
120         $this->attr('class', implode(' ', $classes));
121         return $this;
122     }
123 
124     /**
125      * Get or set the element's ID
126      *
127      * This is the preferred way of setting the element's ID
128      *
129      * @param null|string $id
130      * @return string|$this
131      */
132     public function id($id = null)
133     {
134         if (strpos($id, '__') === false) {
135             throw new \InvalidArgumentException('IDs in DokuWiki have to contain two subsequent underscores');
136         }
137 
138         return $this->attr('id', $id);
139     }
140 
141     /**
142      * Get or set the element's value
143      *
144      * This is the preferred way of setting the element's value
145      *
146      * @param null|string $value
147      * @return string|$this
148      */
149     public function val($value = null)
150     {
151         return $this->attr('value', $value);
152     }
153 
154     /**
155      * The HTML representation of this element
156      *
157      * @return string
158      */
159     abstract public function toHTML();
160 }
161