Failed Conditions
Push — stable ( 017e16...b83837 )
by
unknown
07:54 queued 02:55
created

Input::has()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki\Input;
4
5
/**
6
 * Encapsulates access to the $_REQUEST array, making sure used parameters are initialized and
7
 * have the correct type.
8
 *
9
 * All function access the $_REQUEST array by default, if you want to access $_POST or $_GET
10
 * explicitly use the $post and $get members.
11
 *
12
 * @author Andreas Gohr <[email protected]>
13
 */
14
class Input
15
{
16
17
    /** @var Post Access $_POST parameters */
18
    public $post;
19
    /** @var Get Access $_GET parameters */
20
    public $get;
21
    /** @var Server Access $_SERVER parameters */
22
    public $server;
23
24
    protected $access;
25
26
    /**
27
     * @var Callable
28
     */
29
    protected $filter;
30
31
    /**
32
     * Intilizes the dokuwiki\Input\Input class and it subcomponents
33
     */
34
    public function __construct()
35
    {
36
        $this->access = &$_REQUEST;
37
        $this->post = new Post();
38
        $this->get = new Get();
39
        $this->server = new Server();
40
    }
41
42
    /**
43
     * Apply the set filter to the given value
44
     *
45
     * @param string $data
46
     * @return string
47
     */
48
    protected function applyfilter($data)
49
    {
50
        if (!$this->filter) return $data;
51
        return call_user_func($this->filter, $data);
52
    }
53
54
    /**
55
     * Return a filtered copy of the input object
56
     *
57
     * Expects a callable that accepts one string parameter and returns a filtered string
58
     *
59
     * @param Callable|string $filter
60
     * @return Input
61
     */
62
    public function filter($filter = 'stripctl')
63
    {
64
        $this->filter = $filter;
65
        $clone = clone $this;
66
        $this->filter = '';
67
        return $clone;
68
    }
69
70
    /**
71
     * Check if a parameter was set
72
     *
73
     * Basically a wrapper around isset. When called on the $post and $get subclasses,
74
     * the parameter is set to $_POST or $_GET and to $_REQUEST
75
     *
76
     * @see isset
77
     * @param string $name Parameter name
78
     * @return bool
79
     */
80
    public function has($name)
81
    {
82
        return isset($this->access[$name]);
83
    }
84
85
    /**
86
     * Remove a parameter from the superglobals
87
     *
88
     * Basically a wrapper around unset. When NOT called on the $post and $get subclasses,
89
     * the parameter will also be removed from $_POST or $_GET
90
     *
91
     * @see isset
92
     * @param string $name Parameter name
93
     */
94
    public function remove($name)
95
    {
96
        if (isset($this->access[$name])) {
97
            unset($this->access[$name]);
98
        }
99
        // also remove from sub classes
100
        if (isset($this->post) && isset($_POST[$name])) {
101
            unset($_POST[$name]);
102
        }
103
        if (isset($this->get) && isset($_GET[$name])) {
104
            unset($_GET[$name]);
105
        }
106
    }
107
108
    /**
109
     * Access a request parameter without any type conversion
110
     *
111
     * @param string $name Parameter name
112
     * @param mixed $default Default to return if parameter isn't set
113
     * @param bool $nonempty Return $default if parameter is set but empty()
114
     * @return mixed
115
     */
116
    public function param($name, $default = null, $nonempty = false)
117
    {
118
        if (!isset($this->access[$name])) return $default;
119
        $value = $this->applyfilter($this->access[$name]);
120
        if ($nonempty && empty($value)) return $default;
121
        return $value;
122
    }
123
124
    /**
125
     * Sets a parameter
126
     *
127
     * @param string $name Parameter name
128
     * @param mixed $value Value to set
129
     */
130
    public function set($name, $value)
131
    {
132
        $this->access[$name] = $value;
133
    }
134
135
    /**
136
     * Get a reference to a request parameter
137
     *
138
     * This avoids copying data in memory, when the parameter is not set it will be created
139
     * and intialized with the given $default value before a reference is returned
140
     *
141
     * @param string $name Parameter name
142
     * @param mixed $default If parameter is not set, initialize with this value
143
     * @param bool $nonempty Init with $default if parameter is set but empty()
144
     * @return mixed (reference)
145
     */
146
    public function &ref($name, $default = '', $nonempty = false)
147
    {
148
        if (!isset($this->access[$name]) || ($nonempty && empty($this->access[$name]))) {
149
            $this->set($name, $default);
150
        }
151
152
        return $this->access[$name];
153
    }
154
155
    /**
156
     * Access a request parameter as int
157
     *
158
     * @param string $name Parameter name
159
     * @param int $default Default to return if parameter isn't set or is an array
160
     * @param bool $nonempty Return $default if parameter is set but empty()
161
     * @return int
162
     */
163
    public function int($name, $default = 0, $nonempty = false)
164
    {
165
        if (!isset($this->access[$name])) return $default;
166
        if (is_array($this->access[$name])) return $default;
167
        $value = $this->applyfilter($this->access[$name]);
168
        if ($value === '') return $default;
169
        if ($nonempty && empty($value)) return $default;
170
171
        return (int)$value;
172
    }
173
174
    /**
175
     * Access a request parameter as string
176
     *
177
     * @param string $name Parameter name
178
     * @param string $default Default to return if parameter isn't set or is an array
179
     * @param bool $nonempty Return $default if parameter is set but empty()
180
     * @return string
181
     */
182
    public function str($name, $default = '', $nonempty = false)
183
    {
184
        if (!isset($this->access[$name])) return $default;
185
        if (is_array($this->access[$name])) return $default;
186
        $value = $this->applyfilter($this->access[$name]);
187
        if ($nonempty && empty($value)) return $default;
188
189
        return (string)$value;
190
    }
191
192
    /**
193
     * Access a request parameter and make sure it is has a valid value
194
     *
195
     * Please note that comparisons to the valid values are not done typesafe (request vars
196
     * are always strings) however the function will return the correct type from the $valids
197
     * array when an match was found.
198
     *
199
     * @param string $name Parameter name
200
     * @param array $valids Array of valid values
201
     * @param mixed $default Default to return if parameter isn't set or not valid
202
     * @return null|mixed
203
     */
204
    public function valid($name, $valids, $default = null)
205
    {
206
        if (!isset($this->access[$name])) return $default;
207
        if (is_array($this->access[$name])) return $default; // we don't allow arrays
208
        $value = $this->applyfilter($this->access[$name]);
209
        $found = array_search($value, $valids);
210
        if ($found !== false) return $valids[$found]; // return the valid value for type safety
211
        return $default;
212
    }
213
214
    /**
215
     * Access a request parameter as bool
216
     *
217
     * Note: $nonempty is here for interface consistency and makes not much sense for booleans
218
     *
219
     * @param string $name Parameter name
220
     * @param mixed $default Default to return if parameter isn't set
221
     * @param bool $nonempty Return $default if parameter is set but empty()
222
     * @return bool
223
     */
224
    public function bool($name, $default = false, $nonempty = false)
225
    {
226
        if (!isset($this->access[$name])) return $default;
227
        if (is_array($this->access[$name])) return $default;
228
        $value = $this->applyfilter($this->access[$name]);
229
        if ($value === '') return $default;
230
        if ($nonempty && empty($value)) return $default;
231
232
        return (bool)$value;
233
    }
234
235
    /**
236
     * Access a request parameter as array
237
     *
238
     * @param string $name Parameter name
239
     * @param mixed $default Default to return if parameter isn't set
240
     * @param bool $nonempty Return $default if parameter is set but empty()
241
     * @return array
242
     */
243
    public function arr($name, $default = array(), $nonempty = false)
244
    {
245
        if (!isset($this->access[$name])) return $default;
246
        if (!is_array($this->access[$name])) return $default;
247
        if ($nonempty && empty($this->access[$name])) return $default;
248
249
        return (array)$this->access[$name];
250
    }
251
252
    /**
253
     * Create a simple key from an array key
254
     *
255
     * This is useful to access keys where the information is given as an array key or as a single array value.
256
     * For example when the information was submitted as the name of a submit button.
257
     *
258
     * This function directly changes the access array.
259
     *
260
     * Eg. $_REQUEST['do']['save']='Speichern' becomes $_REQUEST['do'] = 'save'
261
     *
262
     * This function returns the $INPUT object itself for easy chaining
263
     *
264
     * @param string $name
265
     * @return Input
266
     */
267
    public function extract($name)
268
    {
269
        if (!isset($this->access[$name])) return $this;
270
        if (!is_array($this->access[$name])) return $this;
271
        $keys = array_keys($this->access[$name]);
272
        if (!$keys) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $keys of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
273
            // this was an empty array
274
            $this->remove($name);
275
            return $this;
276
        }
277
        // get the first key
278
        $value = array_shift($keys);
279
        if ($value === 0) {
280
            // we had a numeric array, assume the value is not in the key
281
            $value = array_shift($this->access[$name]);
282
        }
283
284
        $this->set($name, $value);
285
        return $this;
286
    }
287
}
288