~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:
82
82
         */
83
83
        private function _validate($model, $update = FALSE)
84
84
        {
85
 
                // Obtiene la definición de validadores
86
 
                $validatorsDefinition = $model->validators();
 
85
                // Obtiene los validadores
 
86
                $validators = $model->validators();
87
87
                
88
88
                // Si no hay validadores definidos
89
 
                if(!$validatorsDefinition) {
 
89
                if(!$validators) {
90
90
                        return TRUE;
91
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
                }
92
119
                
93
120
                // Por defecto es valido
94
121
                $valid = TRUE;
95
122
                
96
 
                // Realiza las validaciones por columna
97
 
                foreach($validatorsDefinition  as $column => $validators) {     
98
 
                        // Si es una validación simple column => validador
99
 
                        if(is_string($validators)) {
100
 
                                $valid = $this->_validatorOnColumn($model, $column, $validators, NULL, $update) && $valid;
101
 
                        } else { // Se trata de un conjunto de validadores
102
 
                                // Itera en los validadores
103
 
                                foreach($validators as $k => $v) {
104
 
                                        if(is_int($k)) { // Un validador simple
105
 
                                                $valid = $this->_validatorOnColumn($model, $column, $v, NULL, $update) && $valid;
106
 
                                        } else { // Un validador con parametros de configuracion
107
 
                                                $valid = $this->_validatorOnColumn($model, $column, $k, $v, $update) && $valid;
108
 
                                        }
109
 
                                }
110
 
                                
111
 
                        }
112
 
                                        
 
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
                        
113
189
                }
114
190
                
115
191
                // Resultado de validacion
116
192
                return $valid;
117
193
        }
118
 
        
 
194
                
119
195
        /**
120
 
         * Aplica un validador a una columna
 
196
         * Validator para columnas con valores autogenerados
121
197
         * 
122
198
         * @param ActiveRecord $model
123
 
         * @param string $column
124
 
         * @param string $validator
 
199
         * @param string $column columna a validar
125
200
         * @param array $params
126
201
         * @param boolean $update
127
202
         * @return boolean
128
203
         */
129
 
        private function _validatorOnColumn($model, $column, $validator, $params, $update)
 
204
        public function autoValidator($model, $column, $params, $update)
130
205
        {
131
 
                // Validador notNull es especial
132
 
                if($validator == 'notNull') {
133
 
                        return $this->notNullValidator($model, $column, $params);
134
 
                } elseif(isset($model->$column) && $model->$column != '') {
135
 
                        return $this->{"{$validator}Validator"}($model, $column, $params, $update);
136
 
                }
137
 
                
138
 
                return TRUE;
 
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;
139
225
        }
140
226
        
141
227
        /**
147
233
         */
148
234
        public function notNullValidator($model, $column, $params = NULL) 
149
235
        {
150
 
                // TODO: Se puede optimizar en conjunto a validate, hay que revisarlo mejor
151
236
                if(!isset($model->$column) || Validate::isNull($model->$column)) {
152
237
                        if($params && isset($params['message'])) {
153
238
                                Flash::error($params['message']);
173
258
        public function uniqueValidator($model, $column, $params = NULL, $update = FALSE) 
174
259
        {       
175
260
                // Condiciones
176
 
                $q = $model->get()->where("$column = :$column");                        
177
 
                $values = array($column => $model->$column);
 
261
                $q = $model->get();
 
262
                
 
263
                $values = array();
178
264
                
179
265
                // Si es para actualizar debe verificar que no sea la fila que corresponde
180
266
                // a la clave primaria
181
 
                if($update) {
182
 
                        // Obtiene la metadata
183
 
                        $metadata = DbAdapter::factory($model->getConnection())->describe($model->getTable(), $model->getSchema());
184
 
                                        
 
267
                if($update) {   
185
268
                        // Obtiene la clave primaria
186
 
                        $pk = $metadata->getPK();
 
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
                                        }
187
279
                                        
188
 
                        // Verifica que este definida la clave primaria
189
 
                        if(!isset($model->$pk) || $model->$pk !== '') {
190
 
                                throw new KumbiaException("Debe definir valor para la clave primaria $pk");
 
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);
191
293
                        }
192
 
                                        
193
 
                        $q->where("NOT $pk = :$pk");
194
 
                        $values[$pk] = $model->$pk;
195
294
                }
196
295
                
197
 
                if($params && isset($params['with'])) {                 
 
296
                if(is_array($column)) { 
198
297
                        // Establece condiciones con with
199
 
                        foreach($params['with'] as $k) {
 
298
                        foreach($column as $k) {
200
299
                                // En un indice UNIQUE si uno de los campos es NULL, entonces el indice
201
300
                                // no esta completo y no se considera la restriccion
202
301
                                if(!isset($model->$k) || $model->$k === '') {
222
321
                                Flash::error($msg);
223
322
                                return FALSE;
224
323
                        }
225
 
                } else {                                                                 
226
 
                        $q->bind($values);
 
324
                } else {                
 
325
                        $values[$column] = $model->$column;
227
326
                        
 
327
                        $q->where("$column = :$column")->bind($values);
228
328
                        // Verifica si existe
229
329
                        if($model->existsOne()) {
230
330
                                if(!isset($params['message'])) {
238
338
                        }
239
339
                }
240
340
                
241
 
                return TRUE;    
 
341
                return TRUE;
242
342
        }
243
343
        
244
344
        /**
249
349
         */
250
350
        public function primaryValidator($model, $column, $params = NULL, $update = FALSE)
251
351
        {
252
 
                
 
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;
253
421
        }
254
422
        
255
423
        /**
273
441
                                
274
442
                return TRUE;    
275
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
        }
276
510
}