This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace BootPress\Form; |
||
4 | |||
5 | use BootPress\Page\Component as Page; |
||
6 | use BootPress\Validator\Component as Validator; |
||
7 | |||
8 | class Component |
||
9 | { |
||
10 | /** |
||
11 | * @var \BootPress\Validator\Component |
||
12 | */ |
||
13 | public $validator; |
||
14 | |||
15 | /** |
||
16 | * If a form is submitted successfully then you should ``$page->eject()`` them using this value. |
||
17 | * |
||
18 | * @var string |
||
19 | */ |
||
20 | public $eject = ''; |
||
21 | |||
22 | /** |
||
23 | * You should set this ``array($field => $value)`` to all of the default values for the form you are going to create. Once the form has been submitted and passed validation, then these will be all of your filtered and validated values. |
||
24 | * |
||
25 | * @var string[] |
||
26 | */ |
||
27 | public $values = array(); |
||
28 | |||
29 | /** |
||
30 | * An array of attributes and their values that will be included in the opening ``<form>`` tag. |
||
31 | * |
||
32 | * @var string[] |
||
33 | */ |
||
34 | public $header = array(); |
||
35 | |||
36 | /** |
||
37 | * Any additional html that you want to be included just before the ``</form>`` tag. |
||
38 | * |
||
39 | * @var string[] |
||
40 | */ |
||
41 | public $footer = array(); |
||
42 | |||
43 | /** |
||
44 | * All of your hidden form inputs that we put after ``$this->footer``. |
||
45 | * |
||
46 | * @var string[] |
||
47 | */ |
||
48 | public $hidden = array(); |
||
49 | |||
50 | /** |
||
51 | * Used by select menus to prepend a default value at the beginning eg. |
||
52 | * |
||
53 | * @var array |
||
54 | */ |
||
55 | protected $prepend = array(); |
||
56 | |||
57 | /** |
||
58 | * Stores all of the values you submitted in ``$this->menu()`` for radio, checkbox, and select menus. |
||
59 | * |
||
60 | * @var array |
||
61 | */ |
||
62 | protected $menus = array(); |
||
63 | |||
64 | /** |
||
65 | * @var \BootPress\Page\Component |
||
66 | */ |
||
67 | protected $page; |
||
68 | |||
69 | /** |
||
70 | * Creates a BootPress\Form\Component object. |
||
71 | * |
||
72 | * @param string $name The name of your form. |
||
73 | * @param string $method How you would like the form to be sent ie. '**post**' or '**get**' |
||
74 | */ |
||
75 | 16 | public function __construct($name = 'form', $method = 'post') |
|
76 | { |
||
77 | 16 | $this->page = Page::html(); |
|
78 | 16 | $headers = (is_array($name)) ? $name : array('name' => $name, 'method' => $method); |
|
79 | 16 | $this->header['name'] = (isset($headers['name'])) ? $headers['name'] : 'form'; |
|
80 | 16 | if (isset($headers['method']) && strtolower($headers['method']) == 'get') { |
|
81 | 4 | $this->header['method'] = 'get'; |
|
82 | 4 | $this->header['action'] = (isset($headers['action'])) ? $headers['action'] : $this->page->url(); |
|
83 | 4 | $this->eject = $this->header['action']; |
|
84 | 4 | $values = (strpos($this->header['action'], $this->page->url()) === 0) ? $this->page->request->query->all() : array(); |
|
85 | 4 | } else { |
|
86 | 14 | $this->header['method'] = 'post'; |
|
87 | 14 | $this->header['action'] = $this->page->url('add', '', 'submitted', $name); |
|
88 | 14 | $this->eject = $this->page->url('delete', $this->header['action'], 'submitted'); |
|
89 | 14 | $values = (strpos($this->header['action'], $this->page->url()) === 0) ? $this->page->request->request->all() : array(); |
|
90 | } |
||
91 | 16 | $this->header['accept-charset'] = $this->page->charset; |
|
92 | 16 | $this->header['autocomplete'] = 'off'; |
|
93 | 16 | $this->header = array_merge($this->header, $headers); |
|
0 ignored issues
–
show
|
|||
94 | 16 | $this->validator = new Validator($values); |
|
95 | 16 | } |
|
96 | |||
97 | /** |
||
98 | * This establishes the options for a checkbox, radio, or select menu field. |
||
99 | * |
||
100 | * @param string $field The name of the field. |
||
101 | * @param array $menu An ``array($value => $options), ...)`` of options to display in the menu. |
||
102 | * @param string $prepend An optional non-value to prepend to the menu eg. ' '. This is used for select menus when you would like a blank option up top. |
||
103 | * |
||
104 | * @return string A comma-separated list of values from your menu that is useful for using inList Validation. |
||
105 | * |
||
106 | * ```php |
||
107 | * $form->menu('save[]', array( |
||
108 | * 4 => 'John Locke', |
||
109 | * 8 => 'Hugo Reyes', |
||
110 | * 15 => 'James Ford', |
||
111 | * 16 => 'Sayid Jarrah', |
||
112 | * 23 => 'Jack Shephard', |
||
113 | * 42 => 'Jin & Sun Kwon' |
||
114 | * )); // A multiselect menu |
||
115 | * |
||
116 | * $form->menu('transport', array(1=>'Airplane', 2=>'Boat', 3=>'Submarine'), ' '); // A select menu |
||
117 | * |
||
118 | * $form->menu('vehicle', array( |
||
119 | * 'hier' => 'transport', |
||
120 | * 1 => array('Boeing'=>array(4=>'777', 5=>'737'), 'Lockheed'=>array(6=>'L-1011', 7=>'HC-130'), 8=>'Douglas DC-3', 9=>'Beechcraft'), |
||
121 | * 2 => array(11=>'Black Rock', 12=>'Kahana', 13=>'Elizabeth', 14=>'Searcher'), |
||
122 | * 3 => array(15=>'Galaga', '16'=>'Yushio') |
||
123 | * ), ' '); // A hierselect menu |
||
124 | * |
||
125 | * $gender = $form->menu('gender', array('M'=>'Male', 'F'=>'Female')); // A radio menu |
||
126 | * $form->validator->set('gender', "required|inList[{$gender}]"); |
||
127 | * |
||
128 | * $form->menu('remember', array('Y'=>'Remember Me')); // A checkbox |
||
129 | * ``` |
||
130 | */ |
||
131 | 5 | public function menu($field, array $menu = array(), $prepend = null) |
|
0 ignored issues
–
show
|
|||
132 | { |
||
133 | 5 | $args = func_get_args(); |
|
134 | 5 | $field = array_shift($args); |
|
135 | 5 | if (empty($args)) { |
|
136 | 5 | return (isset($this->menus[$field])) ? $this->menus[$field] : array(); |
|
137 | } |
||
138 | 5 | $this->menus[$field] = array_shift($args); |
|
139 | 5 | if (!empty($args)) { |
|
140 | 2 | $this->prepend[$field] = array_shift($args); |
|
141 | 2 | } |
|
142 | |||
143 | 5 | return implode(',', array_keys($this->flatten($this->menus[$field]))); |
|
144 | } |
||
145 | |||
146 | /** |
||
147 | * This will begin the form with all of the attributes you have established in ``$this->headers`` array. The values we have already set (but may be overridden) are: |
||
148 | * |
||
149 | * - '**name**' - The name of your form. |
||
150 | * - '**method**' - Either 'get' or 'post'. |
||
151 | * - '**action**' - If 'post' then the current page with a 'submitted' query parameter added. If 'get' then the current page with all it's query parameters moved to hidden input fields. |
||
152 | * - '**accept-charset**' - ``$this->page->charset`` |
||
153 | * - '**autocomplete**' - Set to 'off'. |
||
154 | * |
||
155 | * If you add a numeric (megabytes) 'upload' field then then we convert the megabytes to bytes, add the enctype="multipart/form-data" to the header, and set a 'MAX_FILE_SIZE' hidden input with the number of bytes allowed. |
||
156 | * |
||
157 | * @return string The opening ``<form>`` tag. |
||
158 | * |
||
159 | * ```php |
||
160 | * echo $form->header(); |
||
161 | * ``` |
||
162 | */ |
||
163 | 4 | public function header() |
|
164 | { |
||
165 | 4 | if (isset($this->header['upload']) && is_numeric($this->header['upload'])) { |
|
166 | 1 | $this->header['enctype'] = 'multipart/form-data'; |
|
167 | 1 | if ($this->header['upload'] <= 100) { |
|
168 | 1 | $this->header['upload'] *= 1048576; // megabytes to bytes |
|
169 | 1 | } |
|
170 | 1 | $this->hidden['MAX_FILE_SIZE'] = $this->header['upload']; |
|
171 | 1 | unset($this->header['upload']); |
|
172 | 1 | } |
|
173 | 4 | if ($this->header['method'] == 'get') { |
|
174 | 3 | $params = $this->page->url('params', $this->header['action']); |
|
175 | 3 | foreach ($params as $key => $value) { |
|
0 ignored issues
–
show
The expression
$params of type string|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
176 | 1 | $this->hidden[$key] = $value; |
|
177 | 3 | } |
|
178 | 3 | $this->header['action'] = $this->page->url('delete', $this->header['action'], '?'); |
|
179 | 3 | } |
|
180 | |||
181 | 4 | return "\n".$this->page->tag('form', $this->header); |
|
182 | } |
||
183 | |||
184 | /** |
||
185 | * This will wrap a ``<fieldset>`` around the included $html, and place a nice ``<legend>`` up top. This is not very difficult to do by hand, but it does look nice with all of the $html ``$form->field()``'s nicely indented and looking like they belong where they are. |
||
186 | * |
||
187 | * @param string $legend The fieldset's legend value. |
||
188 | * @param string $html The html you would like this fieldset to enclose (if any). These args can go on forever, and they are all included as additional $html (strings) to place in the fieldset just after the legend. If this is an array then we ``implode('', $html)`` and include that. |
||
189 | * |
||
190 | * @return string |
||
191 | * |
||
192 | * ```php |
||
193 | * echo $form->fieldset('Sign In', |
||
194 | * $form->field('text', 'username'), |
||
195 | * $form->field('password', 'password') |
||
196 | * ); |
||
197 | * ``` |
||
198 | */ |
||
199 | 1 | public function fieldset($legend, $html = '') |
|
0 ignored issues
–
show
|
|||
200 | { |
||
201 | 1 | $args = func_get_args(); |
|
202 | 1 | $legend = array_shift($args); |
|
203 | 1 | $html = array_shift($args); |
|
204 | 1 | if (is_array($html)) { |
|
205 | 1 | $html = implode('', $html); |
|
206 | 1 | } |
|
207 | 1 | if (!empty($args)) { |
|
208 | 1 | $html .= implode('', $args); |
|
209 | 1 | } |
|
210 | |||
211 | 1 | return "\n<fieldset><legend>{$legend}</legend>{$html}\n</fieldset>"; |
|
212 | } |
||
213 | |||
214 | /** |
||
215 | * Retrieves an input's default value to display using the Validator::value method. This is used internally when creating form fields using this class. |
||
216 | * |
||
217 | * @param string $field The input's name. |
||
218 | * @param false|mixed $escape If set to anything but false, then we run the value(s) through ``htmlspecialchars``. |
||
219 | * |
||
220 | * @return array|string The field's default value. |
||
221 | */ |
||
222 | 9 | public function defaultValue($field, $escape = false) |
|
223 | { |
||
224 | 9 | if (null === $value = $this->validator->value($field)) { |
|
225 | 9 | $value = (isset($this->values[$field])) ? $this->values[$field] : ''; |
|
226 | 9 | } |
|
227 | 9 | if ($escape === false) { |
|
228 | 5 | return $value; |
|
229 | } |
||
230 | |||
231 | 6 | return (is_array($value)) ? array_map('htmlspecialchars', $value) : htmlspecialchars($value); |
|
232 | } |
||
233 | |||
234 | /** |
||
235 | * This adds the jQuery Validation rules and messages set earlier to the input field's submitted attributes. This is used internally when creating form fields using this class. |
||
236 | * |
||
237 | * @param string $field The input's name. |
||
238 | * @param array $attributes The currently constituted attributes. |
||
239 | * |
||
240 | * @return array The submitted attributes with the data rules and messages applied. |
||
241 | * |
||
242 | * @see http://johnnycode.com/2014/03/27/using-jquery-validate-plugin-html5-data-attribute-rules/ |
||
243 | * |
||
244 | * ```php |
||
245 | * $form->validator->set('field', array('required' => 'Do this or else.')); |
||
246 | * $attributes = $form->validate('field', array('name' => 'field')); |
||
247 | * ``` |
||
248 | */ |
||
249 | 10 | public function validate($field, array $attributes = array()) |
|
250 | { |
||
251 | 10 | foreach ($this->validator->rules($field) as $validate => $param) { |
|
252 | 9 | $attributes["data-rule-{$validate}"] = htmlspecialchars($param); |
|
253 | 10 | } |
|
254 | 10 | foreach ($this->validator->messages($field) as $rule => $message) { |
|
255 | 4 | $attributes["data-msg-{$rule}"] = htmlspecialchars($message); |
|
256 | 10 | } |
|
257 | |||
258 | 10 | return $attributes; |
|
259 | } |
||
260 | |||
261 | /** |
||
262 | * Creates an input field from an array of attributes. This is used internally when creating form fields using this class. |
||
263 | * |
||
264 | * @param string $type The type of input. |
||
265 | * @param string[] $attributes The input's other attributes. |
||
266 | * |
||
267 | * @return string An html input tag. |
||
268 | * |
||
269 | * ```php |
||
270 | * $form->footer[] = $form->input('submit', array('name' => 'Submit')); |
||
271 | * |
||
272 | * echo $form->input('hidden', array('name' => 'field', 'value' => 'default')); |
||
273 | * ``` |
||
274 | */ |
||
275 | 9 | public function input($type, array $attributes) |
|
276 | { |
||
277 | 9 | unset($attributes['type']); |
|
278 | |||
279 | 9 | return $this->page->tag('input type="'.$type.'"', $attributes); |
|
280 | } |
||
281 | |||
282 | /** |
||
283 | * Creates a text input field. |
||
284 | * |
||
285 | * @param string $field The text input's name. |
||
286 | * @param string[] $attributes Anything else you would like to add besides the 'name', 'id', 'value', and data validation attributes. |
||
287 | * |
||
288 | * @return string An ``<input type="text" ...>`` html tag. |
||
289 | * |
||
290 | * ```php |
||
291 | * $form->validator->set('name', 'required'); |
||
292 | * $form->validator->set('email', 'required|email'); |
||
293 | * |
||
294 | * echo $form->field('name'); |
||
295 | * echo $form->field('email'); |
||
296 | * ``` |
||
297 | */ |
||
298 | 4 | public function text($field, array $attributes = array()) |
|
299 | { |
||
300 | 4 | $attributes['name'] = $field; |
|
301 | 4 | $attributes['id'] = $this->validator->id($field); |
|
302 | 4 | $attributes['value'] = $this->defaultValue($field, 'escape'); |
|
303 | |||
304 | 4 | return $this->input('text', $this->validate($field, $attributes)); |
|
305 | } |
||
306 | |||
307 | /** |
||
308 | * Creates a password input field. |
||
309 | * |
||
310 | * @param string $field The password input's name. |
||
311 | * @param string[] $attributes Anything else you would like to add besides the 'name', 'id', 'value', and data validation attributes. |
||
312 | * |
||
313 | * @return string An ``<input type="password" ...>`` html tag. |
||
314 | * |
||
315 | * ```php |
||
316 | * $form->validator->set('password', 'required|alphaNumeric|minLength[5]|noWhiteSpace'); |
||
317 | * $form->validator->set('confirm', 'required|matches[password]'); |
||
318 | * |
||
319 | * echo $form->field('password'); |
||
320 | * echo $form->field('confirm'); |
||
321 | * ``` |
||
322 | */ |
||
323 | 1 | public function password($field, array $attributes = array()) |
|
324 | { |
||
325 | 1 | $attributes['name'] = $field; |
|
326 | 1 | $attributes['id'] = $this->validator->id($field); |
|
327 | 1 | unset($attributes['value']); |
|
328 | |||
329 | 1 | return $this->input('password', $this->validate($field, $attributes)); |
|
330 | } |
||
331 | |||
332 | /** |
||
333 | * Creates checkboxes from the ``$form->menu($field)`` you set earlier. |
||
334 | * |
||
335 | * @param string $field The checkbox's name. |
||
336 | * @param string[] $attributes Anything else you would like to add besides the 'name', 'value', 'checked', and data validation attributes. |
||
337 | * @param string $wrap The html that surrounds each checkbox. |
||
338 | * |
||
339 | * @return string A checkbox ``<label><input type="checkbox" ...></label>`` html tag. |
||
340 | * |
||
341 | * ```php |
||
342 | * $form->menu('remember', array('Y'=>'Remember Me')); |
||
343 | * |
||
344 | * echo $form->checkbox('remember'); |
||
345 | * ``` |
||
346 | */ |
||
347 | 2 | public function checkbox($field, array $attributes = array(), $wrap = '<label>%s</label>') |
|
348 | { |
||
349 | 2 | $boxes = array(); |
|
350 | 2 | $checked = (array) $this->defaultValue($field); |
|
351 | 2 | foreach ($this->menu($field) as $value => $description) { |
|
0 ignored issues
–
show
|
|||
352 | 2 | $attributes['name'] = $field; |
|
353 | 2 | $attributes['value'] = $value; |
|
354 | 2 | unset($attributes['checked']); |
|
355 | 2 | if (in_array($value, $checked)) { |
|
356 | 2 | $attributes['checked'] = 'checked'; |
|
357 | 2 | } |
|
358 | 2 | if (empty($boxes)) { |
|
359 | 2 | $boxes[] = $this->input('checkbox', $this->validate($field, $attributes)).' '.$description; |
|
360 | 2 | } else { |
|
361 | 2 | $boxes[] = $this->input('checkbox', $attributes).' '.$description; |
|
362 | } |
||
363 | 2 | } |
|
364 | 2 | if (is_array($wrap)) { |
|
365 | 1 | return $boxes; |
|
366 | } |
||
367 | 2 | if (!empty($wrap)) { |
|
368 | 2 | foreach ($boxes as $key => $value) { |
|
369 | 2 | $boxes[$key] = sprintf($wrap, $value); |
|
370 | 2 | } |
|
371 | 2 | } |
|
372 | |||
373 | 2 | return implode(' ', $boxes); |
|
374 | } |
||
375 | |||
376 | /** |
||
377 | * Creates radio buttons from the ``$form->menu($field)`` you set earlier. |
||
378 | * |
||
379 | * @param string $field The radio button's name. |
||
380 | * @param string[] $attributes Anything else you would like to add besides the 'name', 'value', 'checked', and data validation attributes. |
||
381 | * @param string $wrap The html that surrounds each radio button. |
||
382 | * |
||
383 | * @return string Radio ``<label><input type="radio" ...></label>`` html tags. |
||
384 | * |
||
385 | * ```php |
||
386 | * $gender = $form->menu('gender', array('M'=>'Male', 'F'=>'Female')); // A radio menu |
||
387 | * $form->validator->set('gender', "required|inList[{$gender}]"); |
||
388 | * |
||
389 | * echo $form->radio('gender'); |
||
390 | * ``` |
||
391 | */ |
||
392 | 2 | public function radio($field, array $attributes = array(), $wrap = '<label>%s</label>') |
|
393 | { |
||
394 | 2 | $radios = array(); |
|
395 | 2 | $checked = (array) $this->defaultValue($field); |
|
396 | 2 | foreach ($this->menu($field) as $value => $description) { |
|
0 ignored issues
–
show
|
|||
397 | 2 | $attributes['name'] = $field; |
|
398 | 2 | $attributes['value'] = $value; |
|
399 | 2 | unset($attributes['checked']); |
|
400 | 2 | if (in_array($value, $checked)) { |
|
401 | 2 | $attributes['checked'] = 'checked'; |
|
402 | 2 | } |
|
403 | 2 | if (empty($radios)) { |
|
404 | 2 | $radios[] = $this->input('radio', $this->validate($field, $attributes)).' '.$description; |
|
405 | 2 | } else { |
|
406 | 2 | $radios[] = $this->input('radio', $attributes).' '.$description; |
|
407 | } |
||
408 | 2 | } |
|
409 | 2 | if (is_array($wrap)) { |
|
410 | 1 | return $radios; |
|
411 | } |
||
412 | 2 | if (!empty($wrap)) { |
|
413 | 2 | foreach ($radios as $key => $value) { |
|
414 | 2 | $radios[$key] = sprintf($wrap, $value); |
|
415 | 2 | } |
|
416 | 2 | } |
|
417 | |||
418 | 2 | return implode(' ', $radios); |
|
419 | } |
||
420 | |||
421 | /** |
||
422 | * Creates a select menu from the ``$form->menu($field)`` you set earlier. |
||
423 | * |
||
424 | * If the $field is an array (identified by '[]' at the end), then this will be a multiple select menu unless you set ``$attributes['multiple'] = false``. You can optionally include a 'size' attribute to override our sensible defaults. |
||
425 | * |
||
426 | * You can get fairly fancy with these creating optgroups and hier menus. We'll let the examples speak for themselves. |
||
427 | * |
||
428 | * @param string $field The select menu's name. |
||
429 | * @param string[] $attributes Anything else you would like to add besides the 'name', 'id', and data validation attributes. |
||
430 | * |
||
431 | * @return string A ``<select ...>`` tag with all it's ``<option>``'s. |
||
432 | * |
||
433 | * ```php |
||
434 | * $save = $form->menu('save[]', array( |
||
435 | * 4 => 'John Locke', |
||
436 | * 8 => 'Hugo Reyes', |
||
437 | * 15 => 'James Ford', |
||
438 | * 16 => 'Sayid Jarrah', |
||
439 | * 23 => 'Jack Shephard', |
||
440 | * 42 => 'Jin & Sun Kwon' |
||
441 | * )); // A multiselect menu |
||
442 | * |
||
443 | * $form->menu('transport', array(1=>'Airplane', 2=>'Boat', 3=>'Submarine'), ' '); // A select menu |
||
444 | * |
||
445 | * $vehicles = $form->menu('vehicle', array( |
||
446 | * 'hier' => 'transport', |
||
447 | * 1 => array('Boeing'=>array(4=>'777', 5=>'737'), 'Lockheed'=>array(6=>'L-1011', 7=>'HC-130'), 8=>'Douglas DC-3', 9=>'Beechcraft'), |
||
448 | * 2 => array(11=>'Black Rock', 12=>'Kahana', 13=>'Elizabeth', 14=>'Searcher'), |
||
449 | * 3 => array(15=>'Galaga', '16'=>'Yushio') |
||
450 | * ), ' '); // A hierselect menu |
||
451 | * |
||
452 | * $form->validator->set(array( |
||
453 | * 'save' => 'required|inList[{$save}]|minLength[2]', |
||
454 | * 'vehicle' => "required|inList[{$vehicles}]", |
||
455 | * )); |
||
456 | * |
||
457 | * echo $form->fieldset('LOST', |
||
458 | * $form->select('save[]'), |
||
459 | * $form->select('transport'), |
||
460 | * $form->select('vehicle') |
||
461 | * ); |
||
462 | * ``` |
||
463 | */ |
||
464 | 2 | public function select($field, array $attributes = array()) |
|
465 | { |
||
466 | 2 | $select = $this->menu($field); |
|
467 | 2 | $attributes['name'] = $field; |
|
468 | 2 | $attributes['id'] = $this->validator->id($field); |
|
469 | 2 | if (strpos($field, '[]') !== false) { |
|
470 | 1 | if (isset($attributes['multiple']) && $attributes['multiple'] === false) { |
|
471 | 1 | unset($attributes['multiple'], $attributes['size']); |
|
472 | 1 | } else { |
|
473 | 1 | $attributes['multiple'] = 'multiple'; |
|
474 | 1 | $max = (isset($attributes['size'])) ? $attributes['size'] : 15; |
|
475 | 1 | $attributes['size'] = min(count($this->flatten($select)), $max); |
|
0 ignored issues
–
show
$select is of type string , but the function expects a array .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
476 | } |
||
477 | 1 | } |
|
478 | 2 | if (isset($select['hier']) && !isset($attributes['multiple'])) { |
|
479 | 1 | $hier = $select['hier']; |
|
480 | 1 | $selected = $this->defaultValue($select['hier']); |
|
481 | 1 | unset($select['hier']); |
|
482 | 1 | $json = $select; |
|
483 | 1 | if (isset($this->prepend[$field])) { |
|
484 | 1 | foreach ($json as $key => $value) { |
|
0 ignored issues
–
show
|
|||
485 | 1 | array_unshift($json[$key], $this->prepend[$field]); |
|
486 | 1 | } |
|
487 | 1 | } |
|
488 | 1 | $this->page->jquery('$("#'.$this->validator->id($hier).'").hierSelect("#'.$this->validator->id($field).'", '.json_encode($json).');'); |
|
489 | 1 | $this->page->script(' |
|
490 | (function($) { |
||
491 | $.fn.hierSelect = function(select, options) { |
||
492 | $(this).change(function() { |
||
493 | var id = $(this).val(); |
||
494 | var hier = $(select); |
||
495 | var preselect = hier.val(); |
||
496 | hier.each(function(){ |
||
497 | hier.children().remove(); |
||
498 | if (id != "") { |
||
499 | $.each(options[id], function(key,value){ |
||
500 | if (typeof value === "object") { |
||
501 | var optgroup = $("<optgroup />", {label:key}); |
||
502 | $.each(value, function(key,value){ |
||
503 | if (key == 0) key = ""; |
||
504 | var option = $("<option />").val(key).html(value); |
||
505 | if (preselect == key) option.attr("selected", "selected"); |
||
506 | optgroup.append(option); |
||
507 | }); |
||
508 | hier.append(optgroup); |
||
509 | } else { |
||
510 | if (key == 0) key = ""; |
||
511 | var option = $("<option />").val(key).html(value); |
||
512 | if (preselect == key) option.attr("selected", "selected"); |
||
513 | hier.append(option); |
||
514 | } |
||
515 | }); |
||
516 | } // end if id |
||
517 | }); // end each hier |
||
518 | }); // end this change |
||
519 | }; |
||
520 | })(jQuery); |
||
521 | 1 | '); |
|
522 | 1 | $select = (isset($select[$selected])) ? $select[$selected] : array(); |
|
523 | 1 | } |
|
524 | 2 | $values = ''; |
|
525 | 2 | if (!empty($select)) { |
|
526 | 1 | $selected = (array) $this->defaultValue($field); |
|
527 | 1 | if (isset($this->prepend[$field])) { |
|
528 | 1 | $values .= '<option value="">'.$this->prepend[$field].'</option>'; |
|
529 | 1 | } |
|
530 | 1 | foreach ($select as $key => $value) { |
|
0 ignored issues
–
show
The expression
$select of type string|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
531 | 1 | if (is_array($value)) { |
|
532 | 1 | $values .= '<optgroup label="'.htmlspecialchars($key).'">'; |
|
533 | 1 | foreach ($value as $optgroup_key => $optgroup_value) { |
|
534 | 1 | $values .= '<option value="'.$optgroup_key.'"'; |
|
535 | 1 | if (in_array($optgroup_key, $selected)) { |
|
536 | 1 | $values .= ' selected="selected"'; |
|
537 | 1 | } |
|
538 | 1 | $values .= '>'.$optgroup_value.'</option>'; |
|
539 | 1 | } |
|
540 | 1 | $values .= '</optgroup>'; |
|
541 | 1 | } else { |
|
542 | 1 | $values .= '<option value="'.$key.'"'; |
|
543 | 1 | if (in_array($key, $selected)) { |
|
544 | 1 | $values .= ' selected="selected"'; |
|
545 | 1 | } |
|
546 | 1 | $values .= '>'.$value.'</option>'; |
|
547 | } |
||
548 | 1 | } |
|
549 | 1 | } |
|
550 | |||
551 | 2 | return $this->page->tag('select', $this->validate($field, $attributes), $values); |
|
552 | } |
||
553 | |||
554 | /** |
||
555 | * Creates a textarea field. |
||
556 | * |
||
557 | * @param string $field The textarea's name. |
||
558 | * @param string[] $attributes Anything else you would like to add besides the 'name', 'id', and data validation attributes. If you don't set the 'cols' and 'rows' then we will. |
||
559 | * |
||
560 | * @return string A ``<textarea ...>`` html tag. |
||
561 | * |
||
562 | * ```php |
||
563 | * $form->values['description'] = '"default"'; |
||
564 | * |
||
565 | * echo $form->textarea('description'); |
||
566 | * ``` |
||
567 | */ |
||
568 | 2 | public function textarea($field, array $attributes = array()) |
|
569 | { |
||
570 | 2 | $attributes['name'] = $field; |
|
571 | 2 | $attributes['id'] = $this->validator->id($field); |
|
572 | 2 | if (!isset($attributes['cols'])) { |
|
573 | 2 | $attributes['cols'] = 40; |
|
574 | 2 | } |
|
575 | 2 | if (!isset($attributes['rows'])) { |
|
576 | 2 | $attributes['rows'] = 10; |
|
577 | 2 | } |
|
578 | |||
579 | 2 | return $this->page->tag('textarea', $this->validate($field, $attributes), $this->defaultValue($field, 'escape')); |
|
580 | } |
||
581 | |||
582 | /** |
||
583 | * Closes and cleans up shop. |
||
584 | * |
||
585 | * @return string The closing ``</form>`` tag with ``$this->footer`` and ``$this->hidden`` form fields preceding it. |
||
586 | * |
||
587 | * ```php |
||
588 | * echo $form->close(); |
||
589 | * ``` |
||
590 | */ |
||
591 | 4 | public function close() |
|
592 | { |
||
593 | 4 | $html = implode('', $this->footer); |
|
594 | 4 | foreach ($this->hidden as $key => $value) { |
|
595 | 1 | $html .= "\n\t".$this->input('hidden', array( |
|
596 | 1 | 'name' => $key, |
|
597 | 1 | 'value' => htmlspecialchars((string) $value), |
|
598 | 1 | )); |
|
599 | 4 | } |
|
600 | |||
601 | 4 | return $html."\n</form>"; |
|
602 | } |
||
603 | |||
604 | /** |
||
605 | * This is used with menus for getting to the bottom of multi-dimensional arrays, and determining it's root keys and values |
||
606 | * |
||
607 | * @param array $array |
||
608 | * |
||
609 | * @return array A single-dimensional ``array($key => $value, ...)``'s. |
||
610 | */ |
||
611 | 5 | private function flatten(array $array) |
|
612 | { |
||
613 | 5 | $single = array(); |
|
614 | 5 | if (isset($array['hier'])) { |
|
615 | 1 | unset($array['hier']); |
|
616 | 1 | } |
|
617 | 5 | foreach ($array as $key => $value) { |
|
618 | 5 | if (is_array($value)) { |
|
619 | 2 | foreach ($this->flatten($value) as $key => $value) { |
|
620 | 2 | $single[$key] = $value; |
|
621 | 2 | } |
|
622 | 2 | } else { |
|
623 | 5 | $single[$key] = $value; |
|
624 | } |
||
625 | 5 | } |
|
626 | |||
627 | 5 | return $single; |
|
628 | } |
||
629 | } |
||
630 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..