Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Clase Formulario

Estas en el tema de Clase Formulario en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola, estoy buscando alguna clase que gestione los formularios o información relacionada. Puntualizo lo de gestionar porque no quiero que genere el html del formulario ...
  #1 (permalink)  
Antiguo 10/12/2007, 06:38
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Clase Formulario

Hola, estoy buscando alguna clase que gestione los formularios o información relacionada. Puntualizo lo de gestionar porque no quiero que genere el html del formulario ya que trabajo con plantillas.

Un saludo
  #2 (permalink)  
Antiguo 11/12/2007, 12:14
 
Fecha de Ingreso: septiembre-2006
Mensajes: 37
Antigüedad: 17 años, 7 meses
Puntos: 0
Re: Clase Formulario

http://www.phpclasses.org/
  #3 (permalink)  
Antiguo 11/12/2007, 12:33
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

No me acordaba de esa web. Gracias!
  #4 (permalink)  
Antiguo 12/12/2007, 18:57
 
Fecha de Ingreso: septiembre-2005
Mensajes: 142
Antigüedad: 18 años, 7 meses
Puntos: 3
Re: Clase Formulario

también puedes usar el repositorio PEAR el paquete HTML_QuickForm para php4
o HTML_QuickForm2 para php5.
  #5 (permalink)  
Antiguo 24/12/2007, 13:10
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Pregunta Re: Clase Formulario

He buscado por internet pero no he encontrado lo que busco.
Me gustaría poner en común mis ideas para poder aclararme ya que tengo varias dudas de cómo implementarlo.

La estructura sería la siguiente:
Código:
formulario -> proceso -> resultado (que podría ser el mismo formulario)
Hasta ahora, yo devolvía un único valor del proceso con variables de sesión. Lo leía y mostraba el mensaje correspondiente.
Esto tiene el claro inconveniente de no poder listar más de un error. Esto es una funcionalidad que quiero implementar.

Tengo una clase CForm y una clase CFormField con los siguientes campos: (no pongo los métodos para no hacer el post muy extenso)
Código PHP:
        abstract class CForm
        
{
        
// atributos
        
            
private $mode;
            private 
$name;
            private 
$method;
            private 
$enctype;
            private 
$backup;
            private 
$validations;        // validaciones globales (que afecten a mas de un campo)
            
private $errors;            // array de errores
            
private $fields;
                }

        class 
CFormField
        
{
        
// atributos
        
            
private $name;
            private 
$value;
            private 
$label;
            private 
$default;
            private 
$validations;        // array de validaciones
            
private $maxlength;            
            private 
$errors;            // array de errores
                

Uno de los quebraderos de cabeza que tuve (y tengo) es que hay validaciones que afectan a más de un campo (ej: password y su confirmación) es por eso que he puesto un campo validations en la clase CForm a parte de las validaciones de cada campo.

Otro quebradero de cabeza es dónde instanciar los mensajes de error. Ahora mismo, lo hago en la clase CForm pero me pregunto si no sería mejor devolver unos códigos de error e instanciar los mensajes fuera de la clase.

En definitiva, tengo muchas dudas y agradecería cualquier crítica o consejo.

Última edición por jerkan; 27/12/2007 a las 06:10
  #6 (permalink)  
Antiguo 26/12/2007, 17:44
Avatar de pragone  
Fecha de Ingreso: diciembre-2007
Ubicación: Madrid
Mensajes: 223
Antigüedad: 16 años, 4 meses
Puntos: 2
Re: Clase Formulario

Hola, no entiendo bien tus quebraderos de cabeza. Creo que vas bien. Tiene sentido lo que comentas:
1.- Hay validaciones que son propias del formato del campo y validaciones que tienen que ver con la relación entre los campos.
2.- De la misma forma, hay errores de cada tipo.
3.- Con respecto a instanciar los errores a qué te refieres exactamente? El String que representa un error?
  #7 (permalink)  
Antiguo 27/12/2007, 06:13
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

Hola pragone, gracias por tu respuesta.

Sobre el punto 3, me refiero al string que describe el error. Creo que lo mejor es instanciar los mensajes dentro de la clase. Así, tengo esta tarea centralizada.

Comentar que he cambiado los atributos $errors por $log ya que no sólo pondré mensajes de error sino también mensajes de información como 'guardado correctamente'.
También he añadido un campo $result que indicará si se ha producido algún error en la validación del formulario.
  #8 (permalink)  
Antiguo 27/12/2007, 19:55
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Clase Formulario

Creo vas bien en tu concepto, aunque a lo mejor podrias separar mas lo que son dos cosas, por decir, validador de campo y validador de formulario (para validar grupos de validadores) asi no rompes la estructura que tienes.

Saludos.
  #9 (permalink)  
Antiguo 28/12/2007, 04:10
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

¿Te refieres a hacer una clase validador_campo y otra clase validador_formulario o cómo?
Las validaciones de los campos las hago en la clase CFormField y las validaciones del formulario en la clase CForm.

Última edición por jerkan; 28/12/2007 a las 04:40
  #10 (permalink)  
Antiguo 28/12/2007, 12:41
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Clase Formulario

Así es, así tendrás dos grupos de validadores y separas un poco la lógica de tu clase y la haces mas extensible.

Saludos.
  #11 (permalink)  
Antiguo 28/12/2007, 16:11
Avatar de pragone  
Fecha de Ingreso: diciembre-2007
Ubicación: Madrid
Mensajes: 223
Antigüedad: 16 años, 4 meses
Puntos: 2
Re: Clase Formulario

Como comentario, te recomendaría que usaran interfaces para los objetos validadores de forma de que sea fácilmente extensible.

Con respecto a los mensajes, si lo que quieres es extensibilidad, entonces mejor ten una clase que reciba uno de los códigos y devuelva el String. De esta forma podrías, en un futuro, utilizar distintos idiomas.
  #12 (permalink)  
Antiguo 29/12/2007, 07:01
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

Me parece una buena idea hacer una clase para cada validador, pero no tengo claro cómo implementarlo.
A ver qué os parece esta primera idea:
Código PHP:
    interface iValidator
    
{
        public function 
check();
    }
    
    
    class 
cValidatorEmpty implements iValidator 
    
{        
        private 
$value;
        
        public function 
__construct($value)    {    $this->value $value; }
        
        public function 
check()    { return empty($value);    }
    }

    
    class 
cValidatorPasswordConfirm implements iValidator 
    
{    
        private 
$value1;
        private 
$value2;
        
        public function 
__construct($value1$value2)        
        {    
            
$this->value1 $value1;
            
$this->value2 $value2;    
        }
            
        public function 
check()    { return $value1 == $value2; }
    } 
De esta aproximación, lo que no me convence es que hay que crear un objeto de la clase y luego llamar al método check. Había pensado en hacer el método check estático pero tendría que obtener los argumentos con las funciones func_num_args y func_get_args con lo que, seguramente, el rendimiento se vería afectado.
  #13 (permalink)  
Antiguo 29/12/2007, 11:45
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Clase Formulario

No importa que los tengas que crear, por decir te dejo un ejemplo del Beta de mi clase form de mi libreria:
Código PHP:
$usrTxt = new GeckoFormFieldTextbox"usuario" );
$pwdTxt = new GeckoFormFieldPassword();
$confirmpwdTxt = new GeckoFormFieldPassword();

$noEmpty = new GeckoFormFieldValidatorEmpty(false"El campo no puede estar vacio");
$validLength = new GeckoFormFieldValidatorLength(5,30"El campo solo acepta entre 5 y 30 caracteres");
$equal = new GeckoFormValidatorEquals$pwdTxt$confirmpwdTxt );

$usrTxt->addValidator$noEmpty )->addValidator$validLength );
$pwdTxt->addValidator$noEmpty );

$form = new GeckoForm();
$form->addField$usrTxt )->addField$pwdTxt )->addField$confirmpwdTxt );

if( 
$form->validate() ) {
         
$user $usrTxt->getValue();
         
$pwd $pwdTxt->getValue();

Lo que hace el metodo validate de la clase form es primero ciclar por todos los validadores de formulario, y posteriormente por todos los validadores de los campos que tenga (cada campo tiene un metodo validate()).

Todo se hace con dos interfaces:
Código PHP:
interface GeckoFormValidatorInterface {
        public function 
validate();
        public function 
getErrorMessage();
        public function 
getHTMLErrorMessage();
        public function 
getErrorCode();
}

interface 
GeckoFormFieldValidatorInterface {
        public function 
validate(GeckoFormFieldInterface $field);
        public function 
getErrorMessage();
        public function 
getHTMLErrorMessage();
        public function 
getErrorCode();

Asi no importa si cada validador tiene diferentes mensajes o diferentes argumentos, con que implementen la interfaz la clase form puede validar el campo.

Saludos.

Última edición por GatorV; 29/12/2007 a las 13:04
  #14 (permalink)  
Antiguo 29/12/2007, 12:16
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

Gracias, GatorV, por la aportación.

Al ver tú código, me ha surgido una curiosidad acerca de tus clases 'FormField'. ¿Por qué tienes una clase para cada tipo de input (text, password, etc.) ?

Otra duda que tengo es por qué los validadores son interfaces y no clases abstractas.

Un saludo
  #15 (permalink)  
Antiguo 29/12/2007, 13:06
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Clase Formulario

Porque asi separo todos los "componentes" que mi clase implementa como Textboxes, Textareas, Input Fields, HTML Areas, Date Picker, Color Picker, Select Box, SQL Select Box, etc. Al tener todas separadas es mas facil de leer en el codigo.

Los validadores "superiores" solo son interfaces que implementan los validadores reales, esto hace que tu puedas hacer validadores "on the fly" y que funcionen con la clase:
Código PHP:
class GeckoFormFieldValidatorEmpty implements GeckoFormFieldValidatorInterface {
          private 
$canBeEmpty false;
          public function 
__construct($canBeEmpty) {
                   
$this->canBeEmpty $canBeEmpty;
          }

          public function 
validate(GeckoFormFieldInterface $field) {
                   
$value $field->getValue();
                   
$isEmpty = empty( $value );

                   return 
$this->canBeEmpty && $isEmpty;
          }

Aunque todavia le estoy moviendo mucho al codigo, como te comento esta en Beta, no es ni para produccion ni mucho menos y ando viendo como hacerlo lo mas sencillo, ya que la clase tambien implementa validacion en el cliente (via Javascript), pero desde PHP. Es decir, tu con solo crear el codigo PHP, la clase te hace los validadores en Javascript.

Saludos.
  #16 (permalink)  
Antiguo 29/12/2007, 13:15
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

Cita:
Iniciado por GatorV Ver Mensaje
Los validadores "superiores" solo son interfaces que implementan los validadores reales, esto hace que tu puedas hacer validadores "on the fly" y que funcionen con la clase
Esto no lo entendí
  #17 (permalink)  
Antiguo 29/12/2007, 13:18
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Clase Formulario

Si, sabia que no me habia explicado bien, la idea de una interface es asegurarte que todas las clases compartan una "firma", asi tu codigo puede funcionar con cualquier clase que tenga esa "firma" en particular, y sabes que puedes crear tus propios validadores que compartan esa firma, por decir:

Código PHP:
class ValidadorPersonal implements GeckoFormFieldValidator {
        
// cosas locas
        
public function validateGeckoFormFieldInterface $campo ) {

        }

Espero haber sido mas claro.

Saludos.
  #18 (permalink)  
Antiguo 29/12/2007, 13:53
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

Ahora sí, gracias.

De todas formas, no entiendo por qué lo implementas con interfaces y no con una clase base abstracta. Yo es que lo veo más como una clase base Validator de la que heredan todos los validadores específicos.
  #19 (permalink)  
Antiguo 29/12/2007, 16:26
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Clase Formulario

Mmm se me hace mas sencillo obligar la implementacion de la firma, a usar una clase base, porque creo cuando usas Class Hinting (o sea forzar a que un parametro sea de una clase) solo funciona con clases especificas e interfaces...

Aparte no tengo niguna funcionalidad especifica en la interfaz, solo necesito que implementen los metodos en especifico, cualquier otro metodo o funcion es de ese validador.

Saludos.
  #20 (permalink)  
Antiguo 30/12/2007, 07:55
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

Intentando implementar el validador con una clase base abstracta he encontrado el por qué no se puede hacer así.
Haciéndolo con una clase base abstracta, el intérprete de PHP da error si en las clases hijo no coincide la definición del método validate. Es decir, ésto da error:
Código PHP:
    // clase abstracta cValidator
    
        
abstract class cValidator
        
{
            abstract public function 
validate();
            
        } 
// end interface cValidator
        
        
    // class CValidatorEmpty
    
        
class CValidatorEmpty extends cValidator 
        
{
            public function 
validate($value)    {    return empty($value);    }
            
        } 
// end class CValidatorEmpty
    
        
    // class CValidatorPasswordConfirm
    
        
class CValidatorPasswordConfirm extends cValidator 
        
{                
            public function 
validate($value1$value2)    {    return $value1 == $value2;    }
            
        } 
// end class CValidatorPasswordConfirm 
  #21 (permalink)  
Antiguo 30/12/2007, 12:56
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Clase Formulario

Es por eso que yo separe los validadores en dos grupos, los que actúan sobre el valor de un campo en especifico, y los que comparan valores de dos o varios campos.

Aparte de que la interface también te obliga a usar la firma que hayas definido.

Saludos
  #22 (permalink)  
Antiguo 02/01/2008, 13:22
Avatar de pragone  
Fecha de Ingreso: diciembre-2007
Ubicación: Madrid
Mensajes: 223
Antigüedad: 16 años, 4 meses
Puntos: 2
Re: Clase Formulario

Hola.... feliz año!!!

Veo que esto toma bastante forma. Por mi parte hago otro par de aportaciones:
Por un lado, la diferencia entre utilizar una interfaz y una clase abstracta es que la interfaz no incluye absolutamente nada de código, mientras que una clase abstracta sí... De hecho, se podría decir que una interfaz es una clase abstracta en la que todos sus métodos son abstractos.
En muchas ocasiones pueden ser intercambiados y eso resulta útil sobre todo en lenguajes que no soportan herencias múltiples como es el caso de PHP (que a mi forma de ver es como debería ser... pero eso es otra discusión).
En fin... filosóficamente hablando deberías implementar algo como interfaz si distintos tipos de objeto que no necesariamente deben estar en el mismo "árbol genealógico" deben implementar unas funcionalidades. Si por el contrario todas las clases que deben implementar la funcionalidad (lease métodos y propiedades) deben ser familia y no deben heredar de más nadie, entonces una clase abstracta te sirve.

Con respecto a implementar varias clases para cada tipo de campo, estoy de acuerdo con GatorV. Porque esto te permite añadir funcionalidades especiales por cada tipo de validación sin tener que hacer una sola clase con un gran switch-case.
  #23 (permalink)  
Antiguo 03/01/2008, 13:15
Avatar de jerkan  
Fecha de Ingreso: septiembre-2005
Mensajes: 1.607
Antigüedad: 18 años, 7 meses
Puntos: 19
Re: Clase Formulario

Al final, opté por clases abstractas para los validadores:
Código PHP:
    // clase base CValidator
    
        
abstract class CValidator
        
{
        
// atributos
        
            
protected $field;            // campo de formulario
            
protected $error_msg;        // error message
        
        // métodos
        
            
abstract public function validate();
            
            public function 
setErrorMsg($error_msg)        {    $this->error_msg $error_msg;    }

            public function 
getErrorMsg()    {    return $this->error_msg;     }
                    
        } 
// end clase base CValidator
        
        
    // class CValidatorNotEmpty
    
        
class CValidatorNotEmpty extends CValidator 
        
{
            
            public function 
__construct(CFormField &$oFormField)
            {
                
$this->field $oFormField;
                
$this->error_msg sprintfERROR_VALIDATOR_EMPTY$oFormField->getLabel() );
            }
            
            
            public function 
validate()    
            {    
                
$value $this->field->getValue();
                
                return !empty(
$value);    
            }
            
        } 
// end class CValidatorNotEmpty
        
            
    // class CValidatorEmail
    
        
class CValidatorEmail extends CValidator 
        
{
            
            public function 
__construct(CFormField &$oFormField)
            {
                
$this->field $oFormField;
                
$this->error_msg sprintfERROR_VALIDATOR_EMAIL$oFormField->getLabel() );
            }
            
            public function 
validate()    
            {    
                
$value $this->field->getValue();
                
                return empty(
$value) || is_email($value);    
            }
                        
        } 
// end class CValidatorEmail 
Cada validador tiene su constructor particular (número de campos variable) y su mensaje de error propio (se puede cambiar con el método setErrorMsg).
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 17:19.