Completed
Push — 1.0 ( f095f8...1b624d )
by joanhey
10s
created

Form::getField()   B

Complexity

Conditions 9
Paths 12

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 9
eloc 13
c 3
b 1
f 0
nc 12
nop 5
dl 0
loc 21
rs 7.041
1
<?php
2
/**
3
 * KumbiaPHP web & app Framework
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to the new BSD license that is bundled
8
 * with this package in the file LICENSE.txt.
9
 * It is also available through the world-wide-web at this URL:
10
 * http://wiki.kumbiaphp.com/Licencia
11
 * If you did not receive a copy of the license and are unable to
12
 * obtain it through the world-wide-web, please send an email
13
 * to [email protected] so we can send you a copy immediately.
14
 *
15
 * @category   KumbiaPHP
16
 * @package    Helpers
17
 * @copyright  Copyright (c) 2005 - 2016 KumbiaPHP Team (http://www.kumbiaphp.com)
18
 * @license    http://wiki.kumbiaphp.com/Licencia     New BSD License
19
 */
20
21
/**
22
 * Helper para Formularios
23
 *
24
 * @category   KumbiaPHP
25
 * @package    Helpers
26
 */
27
class Form {
28
    /**
29
     * Utilizado para generar los id de los radio button,
30
     * lleva un conteo interno
31
     *
32
     * @var array
33
     */
34
    protected static $_radios = array();
35
36
    /**
37
     * Utilizado para avisar al programador,si usa Form::file()
38
     * y no tiene el form mulipart muestra un error
39
     *
40
     * @var bool
41
     */
42
    protected static $_multipart = FALSE;
43
44
    /**
45
     * Obtiene el valor de un componente tomado
46
     * del mismo valor del nombre del campo y formulario
47
     * que corresponda a un atributo del mismo nombre
48
     * que sea un string, objeto o array.
49
     *
50
     * @param string $field
51
     * @param mixed $value valor de campo
52
     * @param boolean $filter filtrar caracteres especiales html
53
     * @param boolean $check si esta marcado el checkbox
54
     * @param boolean $is_check
55
     * @return Array devuelve un array de longitud 3 con la forma array(id, name, value)
56
     */
57
    public static function getField($field, $value = null, $is_check = FALSE, $filter = TRUE, $check = FALSE) {
58
        // Obtiene considerando el patrón de formato form.field
59
        $formField       = explode('.', $field, 2);
60
        list($id, $name) = self::fieldName($formField);
61
        // Verifica en $_POST
62
        if (Input::hasPost($field)) {
63
            $value = $is_check ?
64
            Input::post($field) == $value : Input::post($field);
65
        } else if ($is_check) {
66
            $value = (bool) $check;
67
        } elseif ($tmp_val = self::getFromModel($formField)) {
68
            // Autocarga de datos
69
            $value = $is_check ? $tmp_val == $value : $tmp_val;
70
        }
71
        // Filtrar caracteres especiales
72
        if (!$is_check && $value !== null && $filter) {
73
            $value = htmlspecialchars($value, ENT_COMPAT, APP_CHARSET);
74
        }
75
        // Devuelve los datos
76
        return array($id, $name, $value);
77
    }
78
79
    /**
80
     * Devuelve el valor del modelo
81
     * @param  Array  $formField array [modelo, campo]
82
     * @return Mixed
83
     */
84
    protected static function getFromModel(Array $formField) {
85
        $form = View::getVar($formField[0]);
86
        if (is_scalar($form) || is_null($form)) {
87
            return $form;
88
        }
89
        $form = (object) $form;
90
        return isset($form->{$formField[1]}) ? $form->{$formField[1]} : NULL;
91
    }
92
93
    /**
94
     * Devuelve el nombre y el id de un campo
95
     * @param  Array  $field array del explode
96
     * @return Array     array(id, name)
97
     */
98
    protected static function fieldName(Array $field) {
99
        return isset($field[1]) ?
100
        array("{$field[0]}_{$field[1]}", "{$field[0]}[{$field[1]}]") :
101
        array($field[0], $field[0]);
102
    }
103
104
    /**
105
     * Obtiene el valor de un componente tomado
106
     * del mismo valor del nombre del campo y formulario
107
     * que corresponda a un atributo del mismo nombre
108
     * que sea un string, objeto o array.
109
     *
110
     * @param string $field
111
     * @param mixed $value valor de campo
112
     * @param boolean $filter filtrar caracteres especiales html
113
     * @return Array devuelve un array de longitud 3 con la forma array(id, name, value)
114
     */
115
    public static function getFieldData($field, $value = null, $filter = true) {
116
        return self::getField($field, $value, FALSE, $filter);
117
    }
118
119
    /**
120
     * Obtiene el valor de un componente check tomado
121
     * del mismo valor del nombre del campo y formulario
122
     * que corresponda a un atributo del mismo nombre
123
     * que sea un string, objeto o array.
124
     *
125
     * @param string $field
126
     * @param string $checkValue
127
     * @param boolean $checked
128
     * @return array Devuelve un array de longitud 3 con la forma array(id, name, checked);
129
     */
130
    public static function getFieldDataCheck($field, $checkValue, $checked = false) {
131
        return self::getField($field, $checkValue, TRUE, FALSE, $checked);
132
    }
133
134
    /**
135
     * @param string $tag
136
     * @param string $field
137
     * @param string $value
138
     * @param string|array $attrs
139
     */
140
    protected static function tag($tag, $field, $attrs = '', $value = NULL, $extra = '', $close = TRUE) {
141
        $attrs = Tag::getAttrs($attrs);
142
        $end   = $close?">{{value}}</$tag>":'/>';
143
        // Obtiene name, id y value (solo para autoload) para el campo y los carga en el scope
144
        list($id, $name, $value) = self::getFieldData($field, $value);
145
        return str_replace('{{value}}', $value, "<$tag id=\"$id\" name=\"$name\" $extra $attrs $end");
146
    }
147
148
    /*
149
     * Crea un campo input
150
     *
151
     * @param string|array $attrs Atributos de campo (opcional)
152
     * @param string $type
153
     * @param string $field
154
     * @param string $value
155
     * @return string
156
     */
157
    public static function input($type, $field, $attrs = '', $value = NULL) {
158
        return self::tag('input', $field, $attrs, $value, "type=\"$type\" value=\"{{value}}\"", FALSE);
159
    }
160
161
    /**
162
     * Crea una etiqueta de formulario
163
     *
164
     * @param string $action Acción del formulario (opcional)
165
     * @param string $method Por defecto es post (opcional)
166
     * @param string $attrs Atributos de etiqueta (opcional)
167
     * @return string
168
     */
169
    public static function open($action = '', $method = 'post', $attrs = '') {
170
        $attrs = Tag::getAttrs($attrs);
171
        if ($action) {
172
            $action = PUBLIC_PATH.$action;
173
        } else {
174
            $action = PUBLIC_PATH.ltrim(Router::get('route'), '/');
175
        }
176
        return "<form action=\"$action\" method=\"$method\" $attrs>";
177
    }
178
179
    /**
180
     * Crea una etiqueta de formulario multipart
181
     *
182
     * @param string $action Acción del formulario (opcional)
183
     * @param string|array $attrs Atributos de etiqueta (opcional)
184
     * @return string
185
     */
186
    public static function openMultipart($action = NULL, $attrs = '') {
187
        self::$_multipart = TRUE;
188
        if (is_array($attrs)) {
189
            $attrs['enctype'] = 'multipart/form-data';
190
            $attrs            = Tag::getAttrs($attrs);
191
        } else {
192
            $attrs .= ' enctype="multipart/form-data"';
193
        }
194
        return self::open($action, 'post', $attrs);
195
    }
196
197
    /**
198
     * Crea una etiqueta para cerrar un formulario
199
     *
200
     * @return string
201
     */
202
    public static function close() {
203
        self::$_multipart = FALSE;
204
        return '</form>';
205
    }
206
207
    /**
208
     * Crea un botón de submit para el formulario actual
209
     *
210
     * @param string $text Texto del botón
211
     * @param string|array $attrs Atributos de campo (opcional)
212
     * @return string
213
     */
214
    public static function submit($text, $attrs = '') {
215
        return self::button($text, $attrs, 'submit');
216
    }
217
218
    /**
219
     * Crea un botón reset
220
     *
221
     * @param string $text Texto del botón
222
     * @param string|array $attrs Atributos de campo (opcional)
223
     * @return string
224
     */
225
    public static function reset($text, $attrs = '') {
226
        return self::button($text, $attrs, 'reset');
227
    }
228
229
    /**
230
     * Crea un botón
231
     *
232
     * @param string $text Texto del botón
233
     * @param array|string $attrs Atributos de campo (opcional)
234
     * @param string $type tipo de botón
235
     * @param string $value Valor para el boton
236
     * @todo FALTA AGREGAR NOMBRE YA QUE SIN ESTE EL VALUE NO LLEGA AL SERVER
237
     * @return string
238
     */
239
    public static function button($text, $attrs = '', $type = 'button', $value = NULL) {
240
        $attrs = Tag::getAttrs($attrs);
241
        $value = is_null($value)?'':"value=\"$value\"";
242
        return "<button type=\"$type\" $value $attrs>$text</button>";
243
    }
244
245
    /**
246
     * Crea un label
247
     *
248
     * @param string $text Texto a mostrar
249
     * @param string $field Campo al que hace referencia
250
     * @param string|array Atributos de campo (opcional)
251
     * @return string
252
     */
253
    public static function label($text, $field, $attrs = '') {
254
        $attrs = Tag::getAttrs($attrs);
255
        return "<label for=\"$field\" $attrs>$text</label>";
256
    }
257
258
    /**
259
     * Crea un campo text
260
     *
261
     * @param string $field Nombre de campo
262
     * @param string|array $attrs Atributos de campo (opcional)
263
     * @param string $value (opcional)
264
     * @return string
265
     */
266
    public static function text($field, $attrs = '', $value = NULL) {
267
        return self::input('text', $field, $attrs, $value);
268
    }
269
270
    /**
271
     * Crea un campo select
272
     *
273
     * @param string $field Nombre de campo
274
     * @param array $data Array de valores para la lista desplegable
275
     * @param string|array $attrs Atributos de campo (opcional)
276
     * @param string|array $value Array para select multiple (opcional)
277
     * @param string $blank agrega un item vacio si es diferente de empty
278
     * @param string $itemId En caso de usar array de objeto propiedad a tomar como id
279
     * @param string $show texto a mostrar, si es empty usa el to string
280
     * @return string
281
     */
282
    public static function select($field, $data, $attrs = '', $value = NULL, $blank = '', $itemId = 'id', $show = '') {
283
        $attrs = Tag::getAttrs($attrs);
284
        // Obtiene name, id y value (solo para autoload) para el campo y los carga en el scope
285
        list($id, $name, $value) = self::getFieldData($field, $value);
286
        //Si se quiere agregar blank
287
        $options = empty($blank)?'':
288
        '<option value="">'.htmlspecialchars($blank, ENT_COMPAT, APP_CHARSET).'</option>';
289
        foreach ($data as $k => $v) {
290
            $val      = self::selectValue($v, $k, $itemId);
291
            $text     = self::selectShow($v, $show);
292
            $selected = self::selectedValue($value, $val);
293
            $options .= "<option value=\"$val\" $selected>$text</option>";
294
        }
295
        return "<select id=\"$id\" name=\"$name\" $attrs>$options</select>";
296
    }
297
298
    /**
299
     * Retorna el value de un item de un select
300
     * @param mixed $item item de un array
301
     * @param string $key valor de item dentro del select
302
     * @param string $id valor posible de la propiedad del objecto para el value
303
     * @return string
304
     */
305
    public static function selectValue($item, $key, $id) {
306
        return htmlspecialchars(is_object($item)?
307
            $item->$id:$key, ENT_COMPAT, APP_CHARSET);
308
    }
309
310
    /**
311
     * retorna el atributo para que quede seleccionado el item de un
312
     * select
313
     * @param string|array $value valor(es) que deben estar seleccionados
314
     * @param string $key valor del item actual
315
     * @return string
316
     */
317
    public static function selectedValue($value, $key) {
318
        return ((is_array($value) && in_array($key, $value)) || ($key == $value))?
319
        'selected="selected"':'';
320
    }
321
322
    /**
323
     * Retorna el valor a mostrar del item del select
324
     * @param mixed $item item del array
325
     * @param string $show propiedad el objeto
326
     * @return string
327
     */
328
    public static function selectShow($item, $show) {
329
        $value = (is_object($item) && !empty($show)) ? $item->$show : (string) $item;
330
        return htmlspecialchars($value, ENT_COMPAT, APP_CHARSET);
331
    }
332
333
    /**
334
     * Crea un campo checkbox
335
     *
336
     * @param string $field Nombre de campo
337
     * @param string $checkValue Valor en el checkbox
338
     * @param string|array $attrs Atributos de campo (opcional)
339
     * @param boolean $checked Indica si se marca el campo (opcional)
340
     * @return string
341
     */
342
    public static function check($field, $checkValue, $attrs = '', $checked = false) {
343
        $attrs = Tag::getAttrs($attrs);
344
        // Obtiene name y id para el campo y los carga en el scope
345
        list($id, $name, $checked) = self::getFieldDataCheck($field, $checkValue, $checked);
346
347
        if ($checked) {
348
            $checked = 'checked="checked"';
349
        }
350
351
        return "<input id=\"$id\" name=\"$name\" type=\"checkbox\" value=\"$checkValue\" $attrs $checked/>";
352
    }
353
354
    /**
355
     * Crea un campo radio button
356
     *
357
     * @param string $field Nombre de campo
358
     * @param string $radioValue Valor en el radio
359
     * @param string|array $attrs Atributos de campo (opcional)
360
     * @param boolean $checked Indica si se marca el campo (opcional)
361
     * @return string
362
     */
363
    public static function radio($field, $radioValue, $attrs = '', $checked = FALSE) {
364
        $attrs = Tag::getAttrs($attrs);
365
        // Obtiene name y id para el campo y los carga en el scope
366
        list($id, $name, $checked) = self::getFieldDataCheck($field, $radioValue, $checked);
367
368
        if ($checked) {
369
            $checked = 'checked="checked"';
370
        }
371
372
        // contador de campos radio
373
        if (isset(self::$_radios[$field])) {
374
            self::$_radios[$field]++;
375
        } else {
376
            self::$_radios[$field] = 0;
377
        }
378
        $id .= self::$_radios[$field];
379
380
        return "<input id=\"$id\" name=\"$name\" type=\"radio\" value=\"$radioValue\" $attrs $checked/>";
381
    }
382
383
    /**
384
     * Crea un botón de tipo imagen
385
     *
386
     * @param string $img Nombre o ruta de la imagen
387
     * @param string|array $attrs Atributos de campo (opcional)
388
     * @return string
389
     */
390
    public static function submitImage($img, $attrs = '') {
391
        $attrs = Tag::getAttrs($attrs);
392
        return "<input type=\"image\" src=\"".PUBLIC_PATH."img/$img\" $attrs/>";
393
    }
394
395
    /**
396
     * Crea un campo hidden
397
     *
398
     * @param string $field Nombre de campo
399
     * @param string|array $attrs Atributos de campo (opcional)
400
     * @param string $value
401
     * @return string
402
     */
403
    public static function hidden($field, $attrs = '', $value = NULL) {
404
        return self::input('hidden', $field, $attrs, $value);
405
    }
406
407
    /**
408
     * Crea un campo password
409
     * @deprecated Obsoleta desde la versión 1.0, usar password
410
     * @param string $field Nombre de campo
411
     * @param string|array $attrs Atributos de campo (opcional)
412
     * @param string $value
413
     */
414
    public static function pass($field, $attrs = '', $value = NULL) {
415
        return self::password($field, $attrs, $value);
416
    }
417
418
    /**
419
     * Crea un campo passwordop
420
     * @param string $field Nombre de campo
421
     * @param string|array $attrs Atributos de campo (opcional)
422
     * @param string $value
423
     */
424
    public static function password($field, $attrs = '', $value = NULL) {
425
        return self::input('password', $field, $attrs, $value);
426
    }
427
428
    /**
429
     * Crea un campo select que toma los valores de un array de objetos
430
     *
431
     * @param string $field Nombre de campo
432
     * @param string $show Campo que se mostrara (opcional)
433
     * @param array $data Array('modelo','metodo','param') (opcional)
434
     * @param string $blank Campo en blanco (opcional)
435
     * @param string|array $attrs Atributos de campo (opcional)
436
     * @param string|array $value (opcional) Array en select multiple
437
     * @return string
438
     */
439
440
    public static function dbSelect($field, $show = NULL, $data = NULL, $blank = 'Seleccione', $attrs = '', $value = NULL) {
441
442
        $model = ($data === NULL) ? substr($field, strpos($field, '.')+1, -3) : $data[0];
443
        $model = Util::camelcase($model);
444
        $model_asoc = new $model;
445
        //por defecto el primer campo no pk
446
        $show = $show ? : $model_asoc->non_primary[0];
447
        $pk   = $model_asoc->primary_key[0];
448
        if ($data === NULL) {
449
            $data = $model_asoc->find("columns: $pk,$show", "order: $show asc");//mejor usar array
450
        } else {
451
            $data = (isset($data[2]))?
452
            $model_asoc->{$data[1]}($data[2]):
453
            $model_asoc->{$data[1]}();
454
        }
455
        return self::select($field, $data, $attrs, $value, $blank, $pk, $show);
456
    }
457
458
    /**
459
     * Crea un campo file
460
     *
461
     * @param string $field Nombre de campo
462
     * @param string|array $attrs Atributos de campo (opcional)
463
     * @return string
464
     */
465
    public static function file($field, $attrs = '') {
466
        // aviso al programador
467
        if (!self::$_multipart) {
468
            Flash::error('Para poder subir ficheros, debe abrir el form con Form::openMultipart()');
469
        }
470
471
        $attrs = Tag::getAttrs($attrs);
472
473
        // Obtiene name y id, y los carga en el scope
474
        list($id, $name, ) = self::getFieldData($field, FALSE);
475
        return "<input id=\"$id\" name=\"$name\" type=\"file\" $attrs/>";
476
    }
477
478
    /**
479
     * Crea un campo textarea
480
     *
481
     * @param string $field Nombre de campo
482
     * @param string|array $attrs Atributos de campo (opcional)
483
     * @param string $value (opcional)
484
     * @return string
485
     */
486
    public static function textarea($field, $attrs = '', $value = NULL) {
487
        return self::tag('textarea', $field, $attrs, $value);
488
    }
489
490
    /**
491
     * Crea un campo fecha nativo (HTML5)
492
     *
493
     * @param string $field Nombre de campo
494
     * @param string|array $attrs Atributos de campo (opcional)
495
     * @param string $value (opcional)
496
     * @return string
497
     */
498
    public static function date($field, $attrs = '', $value = NULL) {
499
        return self::input('date', $field, $attrs, $value);
500
    }
501
502
    /**
503
     * Crea un campo de texo para fecha (Requiere JS )
504
     *
505
     * @param string $field Nombre de campo
506
     * @param string $class Clase de estilo (opcional)
507
     * @param string|array $attrs Atributos de campo (opcional)
508
     * @param string $value (opcional)
509
     * @return string
510
     */
511
    public static function datepicker($field, $class = '', $attrs = '', $value = NULL) {
512
        return self::tag('input', $field, $attrs, NULL, "class=\"js-datepicker $class\" type=\"text\" value=\"$value\" ");
513
    }
514
515
    /**
516
     * Crea un campo tiempo nativo (HTML5)
517
     *
518
     * @param string $field Nombre de campo
519
     * @param string|array $attrs Atributos de campo (opcional)
520
     * @param string $value (opcional)
521
     * @return string
522
     */
523
    public static function time($field, $attrs = '', $value = NULL) {
524
        return self::input('time', $field, $attrs, $value);
525
    }
526
527
    /**
528
     * Crea un campo fecha/tiempo nativo (HTML5)
529
     *
530
     * @param string $field Nombre de campo
531
     * @param string|array $attrs Atributos de campo (opcional)
532
     * @param string $value (opcional)
533
     * @return string
534
     */
535
    public static function datetime($field, $attrs = '', $value = NULL) {
536
        return self::input('datetime', $field, $attrs, $value);
537
    }
538
539
    /**
540
     * Crea un campo numerico nativo (HTML5)
541
     *
542
     * @param string $field Nombre de campo
543
     * @param string|array $attrs Atributos de campo (opcional)
544
     * @param string $value (opcional)
545
     * @return string
546
     */
547
    public static function number($field, $attrs = '', $value = NULL) {
548
        return self::input('number', $field, $attrs, $value);
549
    }
550
551
    /**
552
     * Crea un campo url nativo (HTML5)
553
     *
554
     * @param string $field Nombre de campo
555
     * @param string|array $attrs Atributos de campo (opcional)
556
     * @param string $value (opcional)
557
     * @return string
558
     */
559
    public static function url($field, $attrs = '', $value = NULL) {
560
        return self::input('url', $field, $attrs, $value);
561
    }
562
563
    /**
564
     * Crea un campo email nativo (HTML5)
565
     *
566
     * @param string $field Nombre de campo
567
     * @param string|array $attrs Atributos de campo (opcional)
568
     * @param string $value (opcional)
569
     * @return string
570
     */
571
    public static function email($field, $attrs = '', $value = NULL) {
572
        return self::input('email', $field, $attrs, $value);
573
    }
574
}
575