1
|
|
|
<?php defined('SYSPATH') or die('No direct access allowed.'); |
2
|
|
|
/** |
3
|
|
|
* Form helper class. |
4
|
|
|
* |
5
|
|
|
* $Id: form.php 4291 2009-04-29 22:51:58Z kiall $ |
6
|
|
|
* |
7
|
|
|
* @package Core |
8
|
|
|
* @author Kohana Team |
9
|
|
|
* @copyright (c) 2007-2008 Kohana Team |
10
|
|
|
* @license http://kohanaphp.com/license.html |
11
|
|
|
*/ |
12
|
|
|
class form_Core |
13
|
|
|
{ |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Generates an opening HTML form tag. |
17
|
|
|
* |
18
|
|
|
* @param string form action attribute |
19
|
|
|
* @param array extra attributes |
20
|
|
|
* @param array hidden fields to be created immediately after the form tag |
21
|
|
|
* @return string |
22
|
|
|
*/ |
23
|
|
|
public static function open($action = null, $attr = array(), $hidden = null) |
24
|
|
|
{ |
25
|
|
|
// Make sure that the method is always set |
26
|
|
|
empty($attr['method']) and $attr['method'] = 'post'; |
27
|
|
|
|
28
|
|
|
if ($attr['method'] !== 'post' and $attr['method'] !== 'get') { |
29
|
|
|
// If the method is invalid, use post |
30
|
|
|
$attr['method'] = 'post'; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
if ($action === null) { |
34
|
|
|
// Use the current URL as the default action |
35
|
|
|
$action = url::site(Router::$complete_uri); |
36
|
|
|
} elseif (strpos($action, '://') === false) { |
37
|
|
|
// Make the action URI into a URL |
38
|
|
|
$action = url::site($action); |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
// Set action |
42
|
|
|
$attr['action'] = $action; |
43
|
|
|
|
44
|
|
|
// Form opening tag |
45
|
|
|
$form = '<form'.form::attributes($attr).'>'."\n"; |
46
|
|
|
|
47
|
|
|
// Add hidden fields immediate after opening tag |
48
|
|
|
empty($hidden) or $form .= form::hidden($hidden); |
49
|
|
|
|
50
|
|
|
return $form; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Generates an opening HTML form tag that can be used for uploading files. |
55
|
|
|
* |
56
|
|
|
* @param string form action attribute |
57
|
|
|
* @param array extra attributes |
58
|
|
|
* @param array hidden fields to be created immediately after the form tag |
59
|
|
|
* @return string |
60
|
|
|
*/ |
61
|
|
|
public static function open_multipart($action = null, $attr = array(), $hidden = array()) |
62
|
|
|
{ |
63
|
|
|
// Set multi-part form type |
64
|
|
|
$attr['enctype'] = 'multipart/form-data'; |
65
|
|
|
|
66
|
|
|
return form::open($action, $attr, $hidden); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Generates a fieldset opening tag. |
71
|
|
|
* |
72
|
|
|
* @param array html attributes |
73
|
|
|
* @param string a string to be attached to the end of the attributes |
74
|
|
|
* @return string |
75
|
|
|
*/ |
76
|
|
|
public static function open_fieldset($data = null, $extra = '') |
77
|
|
|
{ |
78
|
|
|
return '<fieldset'.html::attributes((array) $data).' '.$extra.'>'."\n"; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Generates a fieldset closing tag. |
83
|
|
|
* |
84
|
|
|
* @return string |
85
|
|
|
*/ |
86
|
|
|
public static function close_fieldset() |
87
|
|
|
{ |
88
|
|
|
return '</fieldset>'."\n"; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Generates a legend tag for use with a fieldset. |
93
|
|
|
* |
94
|
|
|
* @param string legend text |
95
|
|
|
* @param array HTML attributes |
96
|
|
|
* @param string a string to be attached to the end of the attributes |
97
|
|
|
* @return string |
98
|
|
|
*/ |
99
|
|
|
public static function legend($text = '', $data = null, $extra = '') |
100
|
|
|
{ |
101
|
|
|
return '<legend'.form::attributes((array) $data).' '.$extra.'>'.$text.'</legend>'."\n"; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Generates hidden form fields. |
106
|
|
|
* You can pass a simple key/value string or an associative array with multiple values. |
107
|
|
|
* |
108
|
|
|
* @param string|array input name (string) or key/value pairs (array) |
109
|
|
|
* @param string input value, if using an input name |
110
|
|
|
* @return string |
111
|
|
|
*/ |
112
|
|
|
public static function hidden($data, $value = '') |
113
|
|
|
{ |
114
|
|
|
if (! is_array($data)) { |
115
|
|
|
$data = array( |
116
|
|
|
$data => $value |
117
|
|
|
); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
$input = ''; |
121
|
|
|
foreach ($data as $name => $value) { |
122
|
|
|
$attr = array( |
123
|
|
|
'type' => 'hidden', |
124
|
|
|
'name' => $name, |
125
|
|
|
'value' => $value |
126
|
|
|
); |
127
|
|
|
|
128
|
|
|
$input .= form::input($attr)."\n"; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
return $input; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Creates an HTML form input tag. Defaults to a text type. |
136
|
|
|
* |
137
|
|
|
* @param string|array input name or an array of HTML attributes |
138
|
|
|
* @param string input value, when using a name |
139
|
|
|
* @param string a string to be attached to the end of the attributes |
140
|
|
|
* @return string |
141
|
|
|
*/ |
142
|
|
|
public static function input($data, $value = '', $extra = '') |
143
|
|
|
{ |
144
|
|
|
if (! is_array($data)) { |
145
|
|
|
$data = array('name' => $data); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
// Type and value are required attributes |
149
|
|
|
$data += array( |
150
|
|
|
'type' => 'text', |
151
|
|
|
'value' => $value |
152
|
|
|
); |
153
|
|
|
|
154
|
|
|
return '<input'.form::attributes($data).' '.$extra.' />'; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Creates a HTML form password input tag. |
159
|
|
|
* |
160
|
|
|
* @param string|array input name or an array of HTML attributes |
161
|
|
|
* @param string input value, when using a name |
162
|
|
|
* @param string a string to be attached to the end of the attributes |
163
|
|
|
* @return string |
164
|
|
|
*/ |
165
|
|
View Code Duplication |
public static function password($data, $value = '', $extra = '') |
|
|
|
|
166
|
|
|
{ |
167
|
|
|
if (! is_array($data)) { |
168
|
|
|
$data = array('name' => $data); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
$data['type'] = 'password'; |
172
|
|
|
|
173
|
|
|
return form::input($data, $value, $extra); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Creates an HTML form upload input tag. |
178
|
|
|
* |
179
|
|
|
* @param string|array input name or an array of HTML attributes |
180
|
|
|
* @param string input value, when using a name |
181
|
|
|
* @param string a string to be attached to the end of the attributes |
182
|
|
|
* @return string |
183
|
|
|
*/ |
184
|
|
View Code Duplication |
public static function upload($data, $value = '', $extra = '') |
|
|
|
|
185
|
|
|
{ |
186
|
|
|
if (! is_array($data)) { |
187
|
|
|
$data = array('name' => $data); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
$data['type'] = 'file'; |
191
|
|
|
|
192
|
|
|
return form::input($data, $value, $extra); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Creates an HTML form textarea tag. |
197
|
|
|
* |
198
|
|
|
* @param string|array input name or an array of HTML attributes |
199
|
|
|
* @param string input value, when using a name |
200
|
|
|
* @param string a string to be attached to the end of the attributes |
201
|
|
|
* @param boolean encode existing entities |
202
|
|
|
* @return string |
203
|
|
|
*/ |
204
|
|
|
public static function textarea($data, $value = '', $extra = '', $double_encode = true) |
205
|
|
|
{ |
206
|
|
|
if (! is_array($data)) { |
207
|
|
|
$data = array('name' => $data); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
// Use the value from $data if possible, or use $value |
211
|
|
|
$value = isset($data['value']) ? $data['value'] : $value; |
212
|
|
|
|
213
|
|
|
// Value is not part of the attributes |
214
|
|
|
unset($data['value']); |
215
|
|
|
|
216
|
|
|
return '<textarea'.form::attributes($data, 'textarea').' '.$extra.'>'.html::specialchars($value, $double_encode).'</textarea>'; |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Creates an HTML form select tag, or "dropdown menu". |
221
|
|
|
* |
222
|
|
|
* @param string|array input name or an array of HTML attributes |
223
|
|
|
* @param array select options, when using a name |
224
|
|
|
* @param string|array option key(s) that should be selected by default |
225
|
|
|
* @param string a string to be attached to the end of the attributes |
226
|
|
|
* @return string |
227
|
|
|
*/ |
228
|
|
|
public static function dropdown($data, $options = null, $selected = null, $extra = '') |
229
|
|
|
{ |
230
|
|
|
if (! is_array($data)) { |
231
|
|
|
$data = array('name' => $data); |
232
|
|
|
} else { |
233
|
|
|
if (isset($data['options'])) { |
234
|
|
|
// Use data options |
235
|
|
|
$options = $data['options']; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
if (isset($data['selected'])) { |
239
|
|
|
// Use data selected |
240
|
|
|
$selected = $data['selected']; |
241
|
|
|
} |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
if (is_array($selected)) { |
245
|
|
|
// Multi-select box |
246
|
|
|
$data['multiple'] = 'multiple'; |
247
|
|
|
} else { |
248
|
|
|
// Single selection (but converted to an array) |
249
|
|
|
$selected = array($selected); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
$input = '<select'.form::attributes($data, 'select').' '.$extra.'>'."\n"; |
253
|
|
|
foreach ((array) $options as $key => $val) { |
254
|
|
|
// Key should always be a string |
255
|
|
|
$key = (string) $key; |
256
|
|
|
|
257
|
|
|
if (is_array($val)) { |
258
|
|
|
$input .= '<optgroup label="'.$key.'">'."\n"; |
259
|
|
|
foreach ($val as $inner_key => $inner_val) { |
260
|
|
|
// Inner key should always be a string |
261
|
|
|
$inner_key = (string) $inner_key; |
262
|
|
|
|
263
|
|
|
$sel = in_array($inner_key, $selected) ? ' selected="selected"' : ''; |
264
|
|
|
$input .= '<option value="'.$inner_key.'"'.$sel.'>'.$inner_val.'</option>'."\n"; |
265
|
|
|
} |
266
|
|
|
$input .= '</optgroup>'."\n"; |
267
|
|
|
} else { |
268
|
|
|
$sel = in_array($key, $selected) ? ' selected="selected"' : ''; |
269
|
|
|
$input .= '<option value="'.$key.'"'.$sel.'>'.$val.'</option>'."\n"; |
270
|
|
|
} |
271
|
|
|
} |
272
|
|
|
$input .= '</select>'; |
273
|
|
|
|
274
|
|
|
return $input; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Creates an HTML form checkbox input tag. |
279
|
|
|
* |
280
|
|
|
* @param string|array input name or an array of HTML attributes |
281
|
|
|
* @param string input value, when using a name |
282
|
|
|
* @param boolean make the checkbox checked by default |
283
|
|
|
* @param string a string to be attached to the end of the attributes |
284
|
|
|
* @return string |
285
|
|
|
*/ |
286
|
|
View Code Duplication |
public static function checkbox($data, $value = '', $checked = false, $extra = '') |
|
|
|
|
287
|
|
|
{ |
288
|
|
|
if (! is_array($data)) { |
289
|
|
|
$data = array('name' => $data); |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
$data['type'] = 'checkbox'; |
293
|
|
|
|
294
|
|
|
if ($checked == true or (isset($data['checked']) and $data['checked'] == true)) { |
|
|
|
|
295
|
|
|
$data['checked'] = 'checked'; |
296
|
|
|
} else { |
297
|
|
|
unset($data['checked']); |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
return form::input($data, $value, $extra); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
/** |
304
|
|
|
* Creates an HTML form radio input tag. |
305
|
|
|
* |
306
|
|
|
* @param string|array input name or an array of HTML attributes |
307
|
|
|
* @param string input value, when using a name |
308
|
|
|
* @param boolean make the radio selected by default |
309
|
|
|
* @param string a string to be attached to the end of the attributes |
310
|
|
|
* @return string |
311
|
|
|
*/ |
312
|
|
View Code Duplication |
public static function radio($data = '', $value = '', $checked = false, $extra = '') |
|
|
|
|
313
|
|
|
{ |
314
|
|
|
if (! is_array($data)) { |
315
|
|
|
$data = array('name' => $data); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
$data['type'] = 'radio'; |
319
|
|
|
|
320
|
|
|
if ($checked == true or (isset($data['checked']) and $data['checked'] == true)) { |
|
|
|
|
321
|
|
|
$data['checked'] = 'checked'; |
322
|
|
|
} else { |
323
|
|
|
unset($data['checked']); |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
return form::input($data, $value, $extra); |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
/** |
330
|
|
|
* Creates an HTML form submit input tag. |
331
|
|
|
* |
332
|
|
|
* @param string|array input name or an array of HTML attributes |
333
|
|
|
* @param string input value, when using a name |
334
|
|
|
* @param string a string to be attached to the end of the attributes |
335
|
|
|
* @return string |
336
|
|
|
*/ |
337
|
|
|
public static function submit($data = '', $value = '', $extra = '') |
338
|
|
|
{ |
339
|
|
|
if (! is_array($data)) { |
340
|
|
|
$data = array('name' => $data); |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
if (empty($data['name'])) { |
344
|
|
|
// Remove the name if it is empty |
345
|
|
|
unset($data['name']); |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
$data['type'] = 'submit'; |
349
|
|
|
|
350
|
|
|
return form::input($data, $value, $extra); |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
/** |
354
|
|
|
* Creates an HTML form button input tag. |
355
|
|
|
* |
356
|
|
|
* @param string|array input name or an array of HTML attributes |
357
|
|
|
* @param string input value, when using a name |
358
|
|
|
* @param string a string to be attached to the end of the attributes |
359
|
|
|
* @return string |
360
|
|
|
*/ |
361
|
|
|
public static function button($data = '', $value = '', $extra = '') |
362
|
|
|
{ |
363
|
|
|
if (! is_array($data)) { |
364
|
|
|
$data = array('name' => $data); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
if (empty($data['name'])) { |
368
|
|
|
// Remove the name if it is empty |
369
|
|
|
unset($data['name']); |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
if (isset($data['value']) and empty($value)) { |
373
|
|
|
$value = arr::remove('value', $data); |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
return '<button'.form::attributes($data, 'button').' '.$extra.'>'.$value.'</button>'; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
/** |
380
|
|
|
* Closes an open form tag. |
381
|
|
|
* |
382
|
|
|
* @param string string to be attached after the closing tag |
383
|
|
|
* @return string |
384
|
|
|
*/ |
385
|
|
|
public static function close($extra = '') |
386
|
|
|
{ |
387
|
|
|
return '</form>'."\n".$extra; |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
/** |
391
|
|
|
* Creates an HTML form label tag. |
392
|
|
|
* |
393
|
|
|
* @param string|array label "for" name or an array of HTML attributes |
394
|
|
|
* @param string label text or HTML |
395
|
|
|
* @param string a string to be attached to the end of the attributes |
396
|
|
|
* @return string |
397
|
|
|
*/ |
398
|
|
|
public static function label($data = '', $text = null, $extra = '') |
399
|
|
|
{ |
400
|
|
|
if (! is_array($data)) { |
401
|
|
|
if (is_string($data)) { |
402
|
|
|
// Specify the input this label is for |
403
|
|
|
$data = array('for' => $data); |
404
|
|
|
} else { |
405
|
|
|
// No input specified |
406
|
|
|
$data = array(); |
407
|
|
|
} |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
if ($text === null and isset($data['for'])) { |
411
|
|
|
// Make the text the human-readable input name |
412
|
|
|
$text = ucwords(inflector::humanize($data['for'])); |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
return '<label'.form::attributes($data).' '.$extra.'>'.$text.'</label>'; |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
/** |
419
|
|
|
* Sorts a key/value array of HTML attributes, putting form attributes first, |
420
|
|
|
* and returns an attribute string. |
421
|
|
|
* |
422
|
|
|
* @param array HTML attributes array |
423
|
|
|
* @return string |
424
|
|
|
*/ |
425
|
|
|
public static function attributes($attr, $type = null) |
426
|
|
|
{ |
427
|
|
|
if (empty($attr)) { |
428
|
|
|
return ''; |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
if (isset($attr['name']) and empty($attr['id']) and strpos($attr['name'], '[') === false) { |
432
|
|
|
if ($type === null and ! empty($attr['type'])) { |
433
|
|
|
// Set the type by the attributes |
434
|
|
|
$type = $attr['type']; |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
switch ($type) { |
438
|
|
|
case 'text': |
439
|
|
|
case 'textarea': |
440
|
|
|
case 'password': |
441
|
|
|
case 'select': |
442
|
|
|
case 'checkbox': |
443
|
|
|
case 'file': |
444
|
|
|
case 'image': |
445
|
|
|
case 'button': |
446
|
|
|
case 'submit': |
447
|
|
|
// Only specific types of inputs use name to id matching |
448
|
|
|
$attr['id'] = $attr['name']; |
449
|
|
|
break; |
450
|
|
|
} |
451
|
|
|
} |
452
|
|
|
|
453
|
|
|
$order = array( |
454
|
|
|
'action', |
455
|
|
|
'method', |
456
|
|
|
'type', |
457
|
|
|
'id', |
458
|
|
|
'name', |
459
|
|
|
'value', |
460
|
|
|
'src', |
461
|
|
|
'size', |
462
|
|
|
'maxlength', |
463
|
|
|
'rows', |
464
|
|
|
'cols', |
465
|
|
|
'accept', |
466
|
|
|
'tabindex', |
467
|
|
|
'accesskey', |
468
|
|
|
'align', |
469
|
|
|
'alt', |
470
|
|
|
'title', |
471
|
|
|
'class', |
472
|
|
|
'style', |
473
|
|
|
'selected', |
474
|
|
|
'checked', |
475
|
|
|
'readonly', |
476
|
|
|
'disabled' |
477
|
|
|
); |
478
|
|
|
|
479
|
|
|
$sorted = array(); |
480
|
|
|
foreach ($order as $key) { |
481
|
|
|
if (isset($attr[$key])) { |
482
|
|
|
// Move the attribute to the sorted array |
483
|
|
|
$sorted[$key] = $attr[$key]; |
484
|
|
|
|
485
|
|
|
// Remove the attribute from unsorted array |
486
|
|
|
unset($attr[$key]); |
487
|
|
|
} |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
// Combine the sorted and unsorted attributes and create an HTML string |
491
|
|
|
return html::attributes(array_merge($sorted, $attr)); |
492
|
|
|
} |
493
|
|
|
} // End form |
494
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.