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