~desarrollokumbia/kumbia/ActiveRecord

« back to all changes in this revision

Viewing changes to active_record2/active_record_validator.php

  • Committer: Emilio Silveira
  • Date: 2010-07-30 03:22:48 UTC
  • Revision ID: emilio.rst@gmail.com-20100730032248-9n4vnvcist5rjze1
Cambios multiples.

Implementado en ActiveRecord create y update con validaciones y 
disparadores before y after

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 license@kumbiaphp.com so we can send you a copy immediately.
 
14
 *
 
15
 * Validador para ActiveRecord
 
16
 * 
 
17
 * @category   Kumbia
 
18
 * @package    ActiveRecord
 
19
 * @copyright  Copyright (c) 2005-2010 Kumbia Team (http://www.kumbiaphp.com)
 
20
 * @license    http://wiki.kumbiaphp.com/Licencia     New BSD License
 
21
 */
 
22
 
 
23
class ActiveRecordValidator
 
24
{       
 
25
        /**
 
26
         * Instancia del validador
 
27
         * 
 
28
         * @var ActiveRecordValidator
 
29
         */ 
 
30
        private static $_instance = NULL;
 
31
        
 
32
        /**
 
33
         * Constructor
 
34
         * 
 
35
         * @param ActiveRecord $model
 
36
         * @param boolean $update
 
37
         */
 
38
        private function __construct()
 
39
        {}
 
40
        
 
41
        /**
 
42
         * Obtiene una instancia
 
43
         * 
 
44
         * @return ActiveRecordValidator
 
45
         */
 
46
        public static function getInstance()
 
47
        {
 
48
                if(!self::$_instance) {
 
49
                        self::$_instance = new self;
 
50
                }
 
51
                return self::$_instance;
 
52
        }
 
53
        
 
54
        /**
 
55
         * Validar en caso de crear
 
56
         * 
 
57
         * @param ActiveRecord $model
 
58
         * @return boolean
 
59
         */
 
60
        public final static function validateOnCreate($model)
 
61
        {
 
62
                return self::getInstance()->_validate($model);
 
63
        }
 
64
        
 
65
        /**
 
66
         * Validar en caso de actualizar
 
67
         * 
 
68
         * @param ActiveRecord $model
 
69
         * @return boolean
 
70
         */
 
71
        public final static function validateOnUpdate($model)
 
72
        {
 
73
                return self::getInstance()->_validate($model, TRUE);
 
74
        }
 
75
        
 
76
        /**
 
77
         * Efectua las validaciones
 
78
         * 
 
79
         * @param ActiveRecord $model
 
80
         * @param boolean $update
 
81
         * @return boolean
 
82
         */
 
83
        private function _validate($model, $update = FALSE)
 
84
        {
 
85
                // Obtiene los validadores
 
86
                $validators = $model->validators();
 
87
                
 
88
                // Si no hay validadores definidos
 
89
                if(!$validators) {
 
90
                        return TRUE;
 
91
                }
 
92
                                
 
93
                // Columnas autogeneradas
 
94
                $autogen = array();
 
95
                
 
96
                // Verifica si existe columnas autogeneradas
 
97
                if(isset($validators['auto'])) {
 
98
                        
 
99
                        // Itera en cada definicion de validacion
 
100
                        foreach($validators['auto'] as $v) {
 
101
                                // Si es una columna sin configuracion especial
 
102
                                if(is_string($v)) {
 
103
                                        $column = $v;                                   
 
104
                                        $params = NULL;
 
105
                                } else {
 
106
                                        $column = $v[0];
 
107
                                        unset($v[0]);
 
108
                                        $params = $v;
 
109
                                }
 
110
                                
 
111
                                // Verifica las condiciones para cuando la columna es autogenerada
 
112
                                $autogen[$column] = $this->autoValidator($model, $column, $params, $update);
 
113
                        }
 
114
                        
 
115
                        // Aprovecha y libera memoria :)
 
116
                        unset($validators['auto']);
 
117
                        
 
118
                }
 
119
                
 
120
                // Por defecto es valido
 
121
                $valid = TRUE;
 
122
                
 
123
                // Verifica si existe columnas no nulas
 
124
                if(isset($validators['notNull'])) {
 
125
                        
 
126
                        // Itera en cada definicion de validacion
 
127
                        foreach($validators['notNull'] as $v) {
 
128
                                // Si es una columna sin configuracion especial
 
129
                                if(is_string($v)) {
 
130
                                        // Si es autogenerada entonces salta la validacion
 
131
                                        if(isset($autogen[$v]) && $autogen[$v]) {
 
132
                                                continue;
 
133
                                        }
 
134
                                        
 
135
                                        $column = $v;                                   
 
136
                                        $params = NULL;
 
137
                                } else {
 
138
                                        // Si es autogenerada entonces salta la validacion
 
139
                                        if(isset($autogen[$v[0]]) && $autogen[$v[0]]) {
 
140
                                                continue;
 
141
                                        }
 
142
                                        
 
143
                                        $column = $v[0];
 
144
                                        unset($v[0]);
 
145
                                        $params = $v;
 
146
                                }
 
147
                                
 
148
                                // Valida si el campo
 
149
                                $valid = $this->notNullValidator($model, $column, $params) && $valid;
 
150
                        }
 
151
                        
 
152
                        // Aprovecha y libera memoria :)
 
153
                        unset($validators['notNull']);
 
154
                        
 
155
                }
 
156
                
 
157
                // Realiza el resto de las validaciones a las columnas
 
158
                foreach($validators as $validator => $validations) {
 
159
                        
 
160
                        // Itera en cada definicion de validacion
 
161
                        foreach($validations as $v) {
 
162
                                
 
163
                                // Si es una columna sin configuracion especial
 
164
                                if(is_string($v)) {
 
165
                                        // Si es autogenerada entonces salta la validacion
 
166
                                        if(isset($autogen[$v]) && $autogen[$v]) {
 
167
                                                continue;
 
168
                                        }
 
169
 
 
170
                                        $column = $v;                                   
 
171
                                        $params = NULL;
 
172
                                } else {
 
173
                                        // Si es autogenerada entonces salta la validacion
 
174
                                        if(is_string($v[0]) && isset($autogen[$v[0]]) && $autogen[$v[0]]) {
 
175
                                                continue;
 
176
                                        }
 
177
                                        
 
178
                                        $column = $v[0];
 
179
                                        unset($v[0]);
 
180
                                        $params = $v;
 
181
                                }
 
182
                                                                
 
183
                                if(is_array($column) || (isset($model->$column) && $model->$column != '')) {
 
184
                                        $valid = $this->{"{$validator}Validator"}($model, $column, $params, $update) && $valid;
 
185
                                }
 
186
                                
 
187
                        }
 
188
                        
 
189
                }
 
190
                
 
191
                // Resultado de validacion
 
192
                return $valid;
 
193
        }
 
194
                
 
195
        /**
 
196
         * Validator para columnas con valores autogenerados
 
197
         * 
 
198
         * @param ActiveRecord $model
 
199
         * @param string $column columna a validar
 
200
         * @param array $params
 
201
         * @param boolean $update
 
202
         * @return boolean
 
203
         */
 
204
        public function autoValidator($model, $column, $params, $update)
 
205
        {
 
206
                // Se ha indicado el campo y no se considera nulo, por lo tanto no se autogenerará
 
207
                if(isset($model->$column) && $model->$column != '') {
 
208
                        // Se considera para autogenerar cuando sea nulo 
 
209
                        return FALSE;
 
210
                }
 
211
                
 
212
                // Se verifica para cuando es autogenerado
 
213
                if($params) {
 
214
                        // Autogenerado al actualizar
 
215
                        if(isset($params['update'])) {
 
216
                                return $update == $params['update'];
 
217
                        }
 
218
                                
 
219
                        // Autogenerado al crear y al actualizar
 
220
                        return isset($params['createAndUpdate']);
 
221
                }
 
222
                
 
223
                // Autogenerado al crear
 
224
                return !$update;
 
225
        }
 
226
        
 
227
        /**
 
228
         * Validador para campo no nulo
 
229
         * 
 
230
         * @param ActiveRecord $model
 
231
         * @param string $column columna a validar
 
232
         * @param array $params
 
233
         */
 
234
        public function notNullValidator($model, $column, $params = NULL) 
 
235
        {
 
236
                if(!isset($model->$column) || Validate::isNull($model->$column)) {
 
237
                        if($params && isset($params['message'])) {
 
238
                                Flash::error($params['message']);
 
239
                        } else {
 
240
                                Flash::error("El campo $column no debe ser Nulo");
 
241
                        }
 
242
                        
 
243
                        return FALSE;
 
244
                }
 
245
                                
 
246
                return TRUE;    
 
247
        }
 
248
        
 
249
        /**
 
250
         * Validador para campo con valor unico
 
251
         * 
 
252
         * @param ActiveRecord $model
 
253
         * @param string $column columna a validar
 
254
         * @param array $params
 
255
         * @param boolean $update
 
256
         * @return boolean
 
257
         */
 
258
        public function uniqueValidator($model, $column, $params = NULL, $update = FALSE) 
 
259
        {       
 
260
                // Condiciones
 
261
                $q = $model->get();
 
262
                
 
263
                $values = array();
 
264
                
 
265
                // Si es para actualizar debe verificar que no sea la fila que corresponde
 
266
                // a la clave primaria
 
267
                if($update) {   
 
268
                        // Obtiene la clave primaria
 
269
                        $pk = $model->getPK();
 
270
                        
 
271
                        if(is_array($pk)) {
 
272
                                // Itera en cada columna de la clave primaria
 
273
                                $conditions = array();
 
274
                                foreach($pk as $k) {
 
275
                                        // Verifica que este definida la clave primaria
 
276
                                        if(!isset($model->$k) || $model->$k === '') {
 
277
                                                throw new KumbiaException("Debe definir valor para la columna $k de la clave primaria");
 
278
                                        }
 
279
                                        
 
280
                                        $conditions[] = "$k = :pk_$k";
 
281
                                        $q->bindValue("pk_$k", $model->$k);
 
282
                                }
 
283
                                
 
284
                                $q->where('NOT (' . implode(' AND ', $conditions) . ')');
 
285
                        } else {
 
286
                                // Verifica que este definida la clave primaria
 
287
                                if(!isset($model->$pk) || $model->$pk === '') {
 
288
                                        throw new KumbiaException("Debe definir valor para la clave primaria $pk");
 
289
                                }
 
290
                                                
 
291
                                $q->where("NOT $pk = :pk_$pk");
 
292
                                $q->bindValue("pk_$pk", $model->$pk);
 
293
                        }
 
294
                }
 
295
                
 
296
                if(is_array($column)) { 
 
297
                        // Establece condiciones con with
 
298
                        foreach($column as $k) {
 
299
                                // En un indice UNIQUE si uno de los campos es NULL, entonces el indice
 
300
                                // no esta completo y no se considera la restriccion
 
301
                                if(!isset($model->$k) || $model->$k === '') {
 
302
                                        return TRUE;
 
303
                                }
 
304
                                
 
305
                                $values[$k] = $model->$k;
 
306
                                $q->where("$k = :$k");
 
307
                        }
 
308
                        
 
309
                        $q->bind($values);
 
310
                                
 
311
                        // Verifica si existe
 
312
                        if($model->existsOne()) {
 
313
                                if(!isset($params['message'])) {
 
314
                                        $v = implode("', '", array_values($values));
 
315
                                        $c = implode("', '", array_keys($values));
 
316
                                        $msg = "Los valores '$v' ya existen para los campos '$c'";
 
317
                                } else {
 
318
                                        $msg = $params['message'];
 
319
                                }
 
320
                                        
 
321
                                Flash::error($msg);
 
322
                                return FALSE;
 
323
                        }
 
324
                } else {                
 
325
                        $values[$column] = $model->$column;
 
326
                        
 
327
                        $q->where("$column = :$column")->bind($values);
 
328
                        // Verifica si existe
 
329
                        if($model->existsOne()) {
 
330
                                if(!isset($params['message'])) {
 
331
                                        $msg = "El valor '{$model->$column}' ya existe para el campo $column";
 
332
                                } else {
 
333
                                        $msg = $params['message'];
 
334
                                }
 
335
                                
 
336
                                Flash::error($msg);
 
337
                                return FALSE;
 
338
                        }
 
339
                }
 
340
                
 
341
                return TRUE;
 
342
        }
 
343
        
 
344
        /**
 
345
         * Validador para clave primaria
 
346
         * 
 
347
         * @param string $column columna a validar
 
348
         * @param array $params
 
349
         */
 
350
        public function primaryValidator($model, $column, $params = NULL, $update = FALSE)
 
351
        {
 
352
                // Condiciones
 
353
                $q = $model->get();
 
354
                
 
355
                if(is_array($column)) { 
 
356
                        $values = array();
 
357
                        
 
358
                        // Establece condiciones
 
359
                        foreach($column as $k) {
 
360
                                // En un indice UNIQUE si uno de los campos es NULL, entonces el indice
 
361
                                // no esta completo y no se considera la restriccion
 
362
                                if(!isset($model->$k) || $model->$k === '') {
 
363
                                        return TRUE;
 
364
                                }
 
365
                                
 
366
                                $values[$k] = $model->$k;
 
367
                                $q->where("$k = :$k");
 
368
                        }
 
369
                        
 
370
                        // Si es para actualizar debe verificar que no sea la fila que corresponde
 
371
                        // a la clave primaria
 
372
                        if($update) {   
 
373
                                $conditions = array();
 
374
                                foreach($column as $k) {
 
375
                                        $conditions[] = "$k = :pk_$k";
 
376
                                        $q->bindValue("pk_$k", $model->$k);
 
377
                                }
 
378
                                
 
379
                                $q->where('NOT (' . implode(' AND ', $conditions) . ')');
 
380
                        }
 
381
                        
 
382
                        $q->bind($values);
 
383
                                
 
384
                        // Verifica si existe
 
385
                        if($model->existsOne()) {
 
386
                                if(!isset($params['message'])) {
 
387
                                        $v = implode("', '", array_values($values));
 
388
                                        $c = implode("', '", array_keys($values));
 
389
                                        $msg = "Los valores '$v' ya existen para los campos '$c'";
 
390
                                } else {
 
391
                                        $msg = $params['message'];
 
392
                                }
 
393
                                        
 
394
                                Flash::error($msg);
 
395
                                return FALSE;
 
396
                        }
 
397
                } else {                
 
398
                        // Si es para actualizar debe verificar que no sea la fila que corresponde
 
399
                        // a la clave primaria
 
400
                        if($update) {   
 
401
                                $q->where("NOT $column = :pk_$column");
 
402
                                $q->bindValue("pk_$column", $model->$column);
 
403
                        }
 
404
                        
 
405
                        $q->where("$column = :$column")->bindValue($column, $model->$column);
 
406
                        
 
407
                        // Verifica si existe
 
408
                        if($model->existsOne()) {
 
409
                                if(!isset($params['message'])) {
 
410
                                        $msg = "El valor '{$model->$column}' ya existe para el campo $column";
 
411
                                } else {
 
412
                                        $msg = $params['message'];
 
413
                                }
 
414
                                
 
415
                                Flash::error($msg);
 
416
                                return FALSE;
 
417
                        }
 
418
                }
 
419
                
 
420
                return TRUE;
 
421
        }
 
422
        
 
423
        /**
 
424
         * Validador para campo con valor numero entero
 
425
         * 
 
426
         * @param string $column columna a validar
 
427
         * @param array $params
 
428
         * @return boolean
 
429
         */
 
430
        public function integerValidator($model, $column, $params = NULL) 
 
431
        {
 
432
                if(!Validate::int($model->$column)) {
 
433
                        if($params && isset($params['message'])) {
 
434
                                Flash::error($params['message']);
 
435
                        } else {
 
436
                                Flash::error("El campo $column debe ser un número entero");
 
437
                        }
 
438
                        
 
439
                        return FALSE;
 
440
                }
 
441
                                
 
442
                return TRUE;    
 
443
        }
 
444
        
 
445
        /**
 
446
         * Validador para longitud de una cadena en un rango determinado
 
447
         * 
 
448
         * @param string $column columna a validar
 
449
         * @param array $params
 
450
         * @return boolean
 
451
         */
 
452
        public function lengthBetween($model, $column, $params)
 
453
        {
 
454
                if(!Validate::between($model->$column, $params['min'], $params['max'])) {
 
455
                        if(isset($params['message'])) {
 
456
                                Flash::error($params['message']);
 
457
                        } else {
 
458
                                Flash::error("El campo $column debe tener una cantidad de caracteres comprendida entre $min y $max");
 
459
                        }
 
460
                        
 
461
                        return FALSE;
 
462
                }
 
463
                                
 
464
                return TRUE;    
 
465
        }
 
466
        
 
467
        /**
 
468
         * Validador para longitud minima de una cadena
 
469
         * 
 
470
         * @param string $column columna a validar
 
471
         * @param array $params
 
472
         * @return boolean
 
473
         */
 
474
        public function minLengthValidator($model, $column, $params)
 
475
        {
 
476
                if(strlen($model->$column) < $params['min']) {
 
477
                        if(isset($params['message'])) {
 
478
                                Flash::error($params['message']);
 
479
                        } else {
 
480
                                Flash::error("El campo $column debe tener una cantidad de caracteres minima de {$params['min']}");
 
481
                        }
 
482
                        
 
483
                        return FALSE;
 
484
                }
 
485
                                
 
486
                return TRUE;    
 
487
        }
 
488
        
 
489
        /**
 
490
         * Validador para longitud maxima de una cadena
 
491
         * 
 
492
         * @param string $column columna a validar
 
493
         * @param array $params
 
494
         * @return boolean
 
495
         */
 
496
        public function maxLengthValidator($model, $column, $params)
 
497
        {
 
498
                if(strlen($model->$column) > $params['max']) {
 
499
                        if(isset($params['message'])) {
 
500
                                Flash::error($params['message']);
 
501
                        } else {
 
502
                                Flash::error("El campo $column debe tener una cantidad de caracteres maxima de {$params['max']}");
 
503
                        }
 
504
                        
 
505
                        return FALSE;
 
506
                }
 
507
                                
 
508
                return TRUE;    
 
509
        }
 
510
}