Foros del Web » Programando para Internet » PHP » Zend »

Zend_Validate_Callback

Estas en el tema de Zend_Validate_Callback en el foro de Zend en Foros del Web. Saludos corillo, Creando unos formularios he tenido que crear verificaciones especiales y con Zend_Validate_Callback lo he logrado. Ahora lo que único que me hace falta ...
  #1 (permalink)  
Antiguo 22/04/2011, 19:14
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Zend_Validate_Callback

Saludos corillo,

Creando unos formularios he tenido que crear verificaciones especiales y con Zend_Validate_Callback lo he logrado. Ahora lo que único que me hace falta es indicar el error en la página. Pero me interesa que el error se muestre donde está el campo específicamente, así como lo hace Zend_Form cuando uno usa el método de isValid.

Hasta ahora lo he logrado, en la clase que estoy usando para el Zend_Validate_Callback, con la clase Zend_Session_Namespace y luego en el formulario llamo un método que lo coloca en el Description del campo que tiene el error. Pero el problema es que se muestra el error la segunda que vez que se pulsa el boton de submit.

¿De que forma podría, una vez que se haya hecho la validación y haya fallado, se coloque el mensaje en el description o si hay alguna forma que lo haga automático y lo coloque donde es que debe estar en los Errors?, así como hace cuando isValid encuentra algún error e indica el error donde está.

Muchas gracias
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #2 (permalink)  
Antiguo 22/04/2011, 19:28
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 10 meses
Puntos: 845
Respuesta: Zend_Validate_Callback

No entendí muy bien abimael, pero por defecto callback si hay un error en la validación muestra un mensaje genérico, no te lo muestra ? o lo que queres es personalizar ese mensaje ?.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #3 (permalink)  
Antiguo 22/04/2011, 19:39
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

Pues fijate nunca me ha salido. ¿Donde se supone que salga? Yo lo que hago es algo super sencillo

/reports/controllers/fooController.php
Código PHP:
Ver original
  1. .....
  2. public function indexAction()
  3. {
  4.     $form = new Reports_Form_Foo;
  5.     $form->setAction('/reports/foo/index');
  6.     $this->view->form = $form;
  7.  
  8.     $extraValid = new Zend_Validate_Callback(new Reports_Model_ExtraValidate);
  9.     if($this->getRequest()->isPost()){
  10.         if($form->isValid($this->getRequest()->getPost()) && $extraValid->isValid($this->getRequest()->getPost())){
  11.             $form = $form->getValues();
  12.             .......
  13.         }
  14.     }
  15. }
  16. ......

/reports/models/ExtraValidate.php
Código PHP:
Ver original
  1. <?php
  2. class Reports_Model_ExtraValidate
  3. {
  4.     public function __invoke($post)
  5.     {
  6.         /**
  7.          * Verificar si existe el campo porque está disable y dependiendo de lo
  8.          * que haya seleccionado se muestra el campo, y si está activado entonces
  9.          * es requisito seleccionar un valor (es un dropdown)
  10.          */
  11.         if(isset($post['foo']) && empty($post['foo'])){
  12.             return false;
  13.         }
  14.         return true;
  15.     }
  16. }

No me muestra ningún mensaje en el formulario Sí me muestra el de $form->isValid pero el de $extraValid->isValid no. Y si se puede, ¿cómo hago para personalizar un mensaje, usando Zend_Validate_Callback?

Edito: Como que últimamente no se me entiende lo que digo, voy a tener que dejar de decir las cosas tan específicas
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos

Última edición por abimaelrc; 22/04/2011 a las 21:48 Razón: corregir código
  #4 (permalink)  
Antiguo 22/04/2011, 20:33
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

Oh y se me olvidaba, el formulario
Código PHP:
Ver original
  1. <?php
  2. class Reports_Form_Foo extends Zend_Form
  3. {
  4.     public function init()
  5.     {
  6.         $n=1;
  7.         // initialize form
  8.         $this->setMethod('post')
  9.             ->setAttrib('accept-charset', 'utf-8')
  10.             ->setDecorators(
  11.                 array(
  12.                     'FormElements',
  13.                     'Form',
  14.                 )
  15.             );
  16.  
  17.         // create select input for foo
  18.         $foo = new Zend_Form_Element_Select('foo');
  19.         $foo->setLabel('Foo:')
  20.             ->setDecorators(
  21.                 array(
  22.                     'Description',
  23.                     'Errors',
  24.                     'ViewHelper',
  25.                     array('HtmlTag', array('tag'=>'div')),
  26.                     array('Label', array('tag'=>'div')),
  27.                 )
  28.             )
  29.             ->setOptions(array('tabindex'=>$n++));
  30.         $fooArray = array(
  31.             ''=>'[Selecciona uno]',
  32.             'Foo' => array(
  33.                 1=>'Foo',
  34.                 2=>'Bar'
  35.             ),
  36.             'Baz' => array(
  37.                 3=>'Baz',
  38.                 4=>'Candy',
  39.                 5=>'Fruits'
  40.             ),
  41.         );
  42.         $foo->addMultiOptions($fooArray);
  43.  
  44.         // create submit button
  45.         $submit = new Zend_Form_Element_Submit('submit');
  46.         $submit->setLabel('Submit')
  47.             ->setOptions(array('class' => 'submit', 'tabindex'=>$n++))
  48.             ->setDecorators(
  49.                 array(
  50.                     'ViewHelper',
  51.                     array('HtmlTag', array('tag'=>'div')),
  52.                 )
  53.             );
  54.  
  55.  
  56.         $this->addElements(
  57.             array(
  58.                 $foo,
  59.                 $submit
  60.             )
  61.         );
  62.     }
  63. }
Logicamente aquí no coloqué que está disable, en mi formulario si lo está, pero para que funcione lo coloqué aquí así.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos

Última edición por abimaelrc; 22/04/2011 a las 21:48
  #5 (permalink)  
Antiguo 22/04/2011, 20:47
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Zend_Validate_Callback

Creo para el control que quieres usar, deberías de mejor crear un validador personalizado y agregarlo al elemento que quieras validar, de esa forma puedes mostrar el mensaje, ya que ahorita como lo tienes, solamente validas un array, y no esta "atado" a ningun elemento Zend Form como debería de estarlo, puedes extender el validador de Abstract para usarlo de la forma personalizado que quieres, por ejemplo:
Código PHP:
Ver original
  1. <?php
  2. class My_Validate_Extra extends Zend_Validate_Abstract
  3. {
  4.     const REQUIRED = 'required';
  5.    
  6.     protected $_messageTemplates = array(
  7.         self::REQUIRED => 'Element is required if set'
  8.     );
  9.    
  10.     public function isValid($value, $context = null)
  11.     {
  12.         if (is_array($context)) {
  13.             if (isset($context['foo']) && empty($context['foo'])) {
  14.                 return true;
  15.             }
  16.            
  17.             $this->_error(self::REQUIRED);
  18.             return false;
  19.         }
  20.        
  21.         return true;
  22.     }
  23. }

Así se lo puedes anexar al elemento en concreto que necesites, y no tienes que hacer una doble validación o guardar el mensaje en una sesión.

Saludos.
  #6 (permalink)  
Antiguo 22/04/2011, 21:44
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

Gracias GatorV. Lo traté y no me salio. Lo que hice fue
/reports/models/ExtraValidate.php
Código PHP:
Ver original
  1. <?php
  2. class Reports_Model_ExtraValidate extends Zend_Validate_Abstract
  3. {
  4.     const REQUIRED = 'required';
  5.  
  6.     protected $_messageTemplates = array(
  7.         self::REQUIRED => 'Valor no puede estar vacio'
  8.     );
  9.  
  10.     public function isValid($value, $context = null)
  11.     {
  12.         if (is_array($context)) {
  13.             if (isset($context['foo']) && empty($context['foo'])) {
  14.                 $this->_error(self::REQUIRED);
  15.                 return false;
  16.             }
  17.         }
  18.         return true;
  19.     }
  20. }
En el formulario hice esto
Código PHP:
Ver original
  1. // create select input for foo
  2.         $foo = new Zend_Form_Element_Select('foo');
  3.         $foo->setLabel('Foo:')
  4.             ->setDecorators(
  5.                 array(
  6.                     'Errors',
  7.                     'ViewHelper',
  8.                     array('HtmlTag', array('tag'=>'div')),
  9.                     array('Label', array('tag'=>'div')),
  10.                 )
  11.             )
  12.             ->addValidator(new Reports_Model_ExtraValidate())
  13.             ->setOptions(array('tabindex'=>$n++));
  14.         $fooArray = array(
  15.             ''=>'[Selecciona uno]',
  16.             'Foo' => array(
  17.                 1=>'Foo',
  18.                 2=>'Bar'
  19.             ),
  20.             'Baz' => array(
  21.                 3=>'Baz',
  22.                 4=>'Candy',
  23.                 5=>'Fruits'
  24.             ),
  25.         );
  26.         $foo->addMultiOptions($fooArray);

En el controller solo tengo
Código PHP:
Ver original
  1. public function indexAction()
  2. {
  3.     $form = new Reports_Form_Foo;
  4.     $form->setAction('/reports/foo/index');
  5.     $this->view->form = $form;
  6.     if($this->getRequest()->isPost()){
  7.         if($form->isValid($this->getRequest()->getPost())){
  8.             $form = $form->getValues();
  9.             .......
  10.         }
  11.     }
  12. }
Le trate de colocar a ver si reconocía el validator y no lo hace, le coloqué un exit al principio de isValid
Código PHP:
Ver original
  1. public function isValid($value, $context = null)
  2.     {
  3.         exit;
  4. ...............
Y no se detuvo. ¿Me falta algo más? No me da error y siempre pasa la validación.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #7 (permalink)  
Antiguo 22/04/2011, 22:09
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

Intente usar el addElementPrefixPath y tampoco me funcionó
Código PHP:
Ver original
  1. <?php
  2. class Reports_Form_Foo extends Zend_Form
  3. {
  4.     public function init()
  5.     {
  6.         $n=1;
  7.         // initialize form
  8.         $this->setMethod('post')
  9.             ->addElementPrefixPath('Reports_Model', 'reports/models/',
  10.                             Zend_Form_Element::VALIDATE)
  11.             ->setAttrib('accept-charset', 'utf-8')
  12.             ->setDecorators(
  13.                 array(
  14.                     'FormElements',
  15.                     'Form',
  16.                 )
  17.             );
  18.  
  19.         // create select input for foo
  20.         $foo = new Zend_Form_Element_Select('foo');
  21.         $foo->setLabel('Foo:')
  22.             ->setDecorators(
  23.                 array(
  24.                     'Errors',
  25.                     'ViewHelper',
  26.                     array('HtmlTag', array('tag'=>'div')),
  27.                     array('Label', array('tag'=>'div')),
  28.                 )
  29.             )
  30.             ->addValidator('ExtraValidate')
  31.             ->setOptions(array('tabindex'=>$n++));
  32.         $fooArray = array(
  33.             ''=>'[Selecciona uno]',
  34.             'Foo' => array(
  35.                 1=>'Foo',
  36.                 2=>'Bar'
  37.             ),
  38.             'Baz' => array(
  39.                 3=>'Baz',
  40.                 4=>'Candy',
  41.                 5=>'Fruits'
  42.             ),
  43.         );
  44.         $foo->addMultiOptions($fooArray);
  45.  
  46.         // create submit button
  47.         $submit = new Zend_Form_Element_Submit('submit');
  48.         $submit->setLabel('Submit')
  49.             ->setOptions(array('class' => 'submit', 'tabindex'=>$n++))
  50.             ->setDecorators(
  51.                 array(
  52.                     'ViewHelper',
  53.                     array('HtmlTag', array('tag'=>'div')),
  54.                 )
  55.             );
  56.  
  57.  
  58.         $this->addElements(
  59.             array(
  60.                 $foo,
  61.                 $submit
  62.             )
  63.         );
  64.     }
  65. }
Hace nada
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #8 (permalink)  
Antiguo 22/04/2011, 22:41
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Zend_Validate_Callback

¿Tiene más validadores el elemento? Porque recuerda que se validan en cadena, y si se esta ejecutando otro antes, no va a llegar a ese validador (como el validador NotEmpty que se agrega al usar setRequired).

Saludos.
  #9 (permalink)  
Antiguo 22/04/2011, 22:46
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

No, exactamente ese es el que te indico. Probé colocando __contruct y dentro el exit y sí detuvo la página, pero si lo coloco en el isValid no lo lee.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #10 (permalink)  
Antiguo 22/04/2011, 23:23
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

No sé si es porque es un select no me acepta el valor Pero ni colocando por ejemplo addValidator('NotEmpty') solo me lo reconoce.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #11 (permalink)  
Antiguo 23/04/2011, 01:39
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

Bueno esto me tiene frustrado

Quité todos los campos que tengo, deje solo el de select y submit. Envié la información y como quiera pasa el isValid. Para verificar si funcionaba, lo declaré directamente en el if del controlador y se detuvo, pero claro está no me dijo mensaje alguno. Si lo quito y trato nuevamente no lo lee, es como si no estuviera leyendo el isValid. ¿Falta algo que declare para que lo reconozca?

Acabo de bajar la última versión 1.11.5 por si acaso y todavía nada
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #12 (permalink)  
Antiguo 23/04/2011, 02:31
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

Mal rayo parta, por fin lo saque. El problema era una bobería. El primer valor, lo tenía declarado como ''=>'[Selecciona uno]' y debía tener un valor en la llave, como por ejemplo 0=>'[Selecciona uno]'. Lo descubrí porque vi que si seleccionaba un valor entonces se ejecutaba el isValid. Como empty toma el valor del 0 como vacio se ejecutó correctamente.

GatorV muchas gracias por la idea, de verdad que me ayudaste mucho, y masterpuppet también te agradezco por la ayuda
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #13 (permalink)  
Antiguo 23/04/2011, 05:43
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 10 meses
Puntos: 845
Respuesta: Zend_Validate_Callback

Que tal abimael,

En realidad no es un problema, es el comportamiento normal, si el valor que recibe Zend_Form_Element::isValid es un string vació y el element no esta marcado como required o allowEmpty es false, el validator ni siquiera se dispara, simplemente devuelve true, para cambiar el comportamiento deberías setear allowEmpty a false, en tu ejemplo seria:

Código PHP:
Ver original
  1. $foo = new Zend_Form_Element_Select('foo');
  2. $foo->setLabel('Foo:')
  3.     ->setAllowEmpty(false)
  4.     ...

Hay algo que no entiendo, que es lo que queres validar exactamente ?, porque si es que no sea vació lo podes lograr así:

Código PHP:
Ver original
  1. $element->setRequired(true)

o bien así:

Código PHP:
Ver original
  1. $element->setAllowEmpty(false)        
  2.         ->addValidator('NotEmpty', false, array('type' => Zend_Validate_NotEmpty::STRING));

No veo la necesidad de crear un validator para lo que estas haciendo.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)

Última edición por masterpuppet; 23/04/2011 a las 08:12 Razón: typo
  #14 (permalink)  
Antiguo 23/04/2011, 10:30
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

@masterpuppet, de verdad que gracias, ya me sacaste de otra duda.

Bueno el de setRequired no es viable ya que el campo no es requisito de por sí a menos que seleccione algún valor anterior y que habilite el campo. El de setAllowEmpty lo desconocía y mira que busque como hacerlo y nadie contestaba eso Por cuestión de desconocimiento, no sabía como obligar a que addValidator('NotEmpty') se ejecutara. Ahora que soy menos ignorante lo hago así como tu dices y a la vez aprendí como crear validadores

Muchas gracias a todos
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #15 (permalink)  
Antiguo 23/04/2011, 10:52
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

Verificando el addValidator estaba verificando que se puede agregar en el options, por si en un futuro necesito usar algo que se pueda indicar ahí, pero no doy con información que me indique lo que se puede indicar ahí. Estoy verificando la clase zend/fom/element y el _loadValidator pero me lleva a varios lugares y me perdí un poco. Solo vi que se puede colocar messages (aunque me falta ver que puede haber en message porque vi que se puede indicar un array, tambien está lo que indicaste de type y sus valores son los Zend_Validate_*. ¿Podrías indicar que tipo de opciones puedo agregar en el tercer parametro de addValidator?
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #16 (permalink)  
Antiguo 23/04/2011, 11:12
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 10 meses
Puntos: 845
Respuesta: Zend_Validate_Callback

El tercer parametro son las opciones del validator que se inyectan via constructor, esto:

Código PHP:
Ver original
  1. addValidator('NotEmpty', false, array('type' => Zend_Validate_NotEmpty::STRING));

se transforma en esto:

Código PHP:
Ver original
  1. new Zend_Validate_NotEmpty(array('type' => Zend_Validate_NotEmpty::STRING));

Lo único que tenes que mirar es el validator, para ver que opciones podes pasar via constructor.

cya.
__________________
http://es.phptherightway.com/
thats us riders :)
  #17 (permalink)  
Antiguo 23/04/2011, 11:58
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Zend_Validate_Callback

Ok, muchas gracias
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos

Etiquetas: frameworks-y-php-orientado-a-objetos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:18.