Completed
Push — 1.0 ( 3e9190...eb0a02 )
by joanhey
01:24
created

Form::getField()   C

Complexity

Conditions 9
Paths 12

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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