Sacandole el jugo a los formularios de Symfony 1.4

A menudo nos encontramos con una problemática vieja y conocida, implementar formularios.
Cuántas veces se encontraron con la necesidad de realizar un Registro (Sign up), un Ingreso (Login) o una edición de perfil de un usuario y tener que volver a pensar (y reimplementar) los mismos pasos para lograrlo?

Bueno, aquí encontrarán un tutorial-ayuda-memoria-paso-a-paso para implementar un formulario, de Registro (Sign up) en este caso, con Synfony 1.4. Se requieren conocimientos previos de Symfony 1.4, uso de formularios y componentes.

Manos a la obra!

  1. Incluir nuestro componente de Registro en nuestra página de home.
    <div id="divRegistroHome">
       <php echo include_component("registro", "form"); >
    </div>
  2. Dentro de la carpeta registro/actions debemos tener el correspondiente archivo components.class.php con el siguiente contenido:
    class RegistroComponents extends sfComponents {
    
        public function executeForm(sfWebRequest $request) {
            $this->form = new RegistroBandaForm();
        }
    }
    
  3. La confiugración del form RegistroBandaForm es la siguiente (nótese que nuestro formulario extiende de RegistroForm):
    class RegistroBandaForm extends RegistroForm {
    
        public function configure() {
            parent::configure();
    
            $this->widgetSchema['tiene_banda'] = new sfWidgetFormInputCheckbox(array(
                        'label' => "¿Tenés una Banda?"
                    ));
            $this->widgetSchema['nombre'] = new sfWidgetFormInputText(
                            array(
                                "label" => "Banda"
                            ),
                            array(
                                'size' => 45
                    ));
    
            $this->validatorSchema['tiene_banda'] = new sfValidatorBoolean();
            $this->validatorSchema['nombre'] = new sfValidatorString(
                            array(
                                'max_length' => 255,
                                'min_length' => 2,
                                'required' => false
                    ));
            $this->validatorSchema->setPostValidator(new BandaNombreValidator());
        }
    
    }
    
    class RegistroForm extends BaseForm {
    
        public function setup() {
    
            $this->setWidgets(array(
                'apodo' => new sfWidgetFormInputText(array(), array(
                    'size' => 45
                )),
                'email' => new sfWidgetFormInputText(array(), array(
                    'size' => 45
                )),
                'clave' => new sfWidgetFormInputPassword(array(), array(
                    'size' => 45
                )),
                'idUsuarioInvitador' => new sfWidgetFormInputHidden(),
            ));
    
            $this->widgetSchema->setNameFormat('UsuarioRegistro[%s]');
    
            $this->setValidators(array(
                'apodo' => new sfValidatorRegex(
                        array(
                            'required' => true,
                            'min_length' => 3,
                            'pattern' => '/^[a-zA-Z0-9_ñÑáéíóúÁÉÍÓÚüÜ[:space:]]*$/i'
                        ),
                        array(
                            'required' => 'Requerido',
                            'min_length' => 'El apodo "%value%" es demasiado corto. Debe tener al menos %min_length% caracteres.',
                            'invalid' => 'Ingresá solo caracteres alfanuméricos.'
                        )
                ),
                'clave' => new sfValidatorString(
                        array(
                            'min_length' => 6,
                            'required' => true
                        ),
                        array(
                            'required' => 'Requerido',
                            'min_length' => 'La clave es demasiado corta. Debe tener al menos %min_length% caracteres.'
                        )
                ),
                'email' => new sfValidatorEmail(array('required' => true), array(
                    'required' => 'Requerido',
                    'invalid' => 'Ingresá un email válido.'
                )),
                'idUsuarioInvitador' => new sfValidatorPropelChoice(array('model' => 'Usuario', 'column' => 'id', 'required' => false))
            ));
    
            $this->validatorSchema->setPostValidator(new EmailUsuarioValidator());
        }
    
    }
    
  4. Dentro de la carpeta registro/templates vamos a definir la vista de nuestro formulario:
    <?php use_helper('jQuery'); ?>
    <?php
    echo jq_form_remote_tag(array(
        'url' => '@registro',
        'update' => 'divRegistroHome',
        'loading' => "mostrarCargando(false);",
        'complete' => "ocultarCargando();",
        'method' => 'post'), array(
        'id' => 'registroForm'
    ));
    ?>
    <div id="registro_div">
        <?php echo $form; ?>
    </div>    
    <input class="btRegistroPreHome" value="Registrate" type="submit">
    
    <?php include_partial('FacebookLogin/linkLoginFacebook', array("ubicacion" => 'registro')) ?>
    </form>
    
    <script type="text/javascript">
        $(function(){
            var $labelBanda = $("label[for='UsuarioRegistro_nombre']");
            var $inputBanda = $("#UsuarioRegistro_nombre");
            var $checkBanda = $("#UsuarioRegistro_tiene_banda");
            if (!$checkBanda.is(":checked")) {
                $inputBanda.hide();
                $labelBanda.hide();
            }
            $checkBanda.live("change", function(){
                $labelBanda.toggle("fast");
                $inputBanda.toggle("fast");
            });
        });
    
    </script>
    
  5. Nuestro formulario realizará una llamada AJAX al routing @registro el cual está definido en el archivo routing.yml así

    registro:
     url: /registro
     param: { module: registro, action: registro }
    
  6.  En la ubicaión registro/actions definiremos nuestra clase action de la siguiente forma:
    class RegistroActions extends sfActions {
    
        public function executeRegistro(sfWebRequest $request) {
            $logger = sfContext::getInstance()->getLogger();
            $this->form = new RegistroBandaForm();
            $this->forward404Unless($request->isMethod('post'));
            $this->form->bind($request->getParameter($this->form->getName()), $request->getFiles($this->form->getName()));
            if ($this->form->isValid()) {
                $valores = $this->form->getValues();
                if ($valores["tiene_banda"]) {
                    $this->form->getValidator("nombre")->setOption("required", true);
                    try {
                        $this->form->getValidatorSchema()->clean($valores);
                    } catch (sfValidatorErrorSchema $e) {
                        $errorSchema = $this->form->getErrorSchema();
                        $errorSchema->addErrors($e);
                        return $this->renderPartial("Registro/form", array("form" => $this->form));
                    }
                }
                try {
                    RegistroUsuario::registrarUsuario($valores);
                } catch (RegistroUsuarioException $e) {
                    $errorSchema = $this->form->getErrorSchema();
                    $errorSchema->addError(new sfValidatorError($this->form->getValidatorSchema(), $e->getMessage()));
                    return $this->renderPartial("Registro/form", array("form" => $this->form));
                }
                return $this->renderPartial("Registro/ok");
            }
            return $this->renderPartial("Registro/form", array("form" => $this->form));
        }
    
    }
    
  7. Y por último el template de registro ok en el archivo registro/templates/_ok.php
    <div id="registro_div">
        <p class="tituloSumaTuBanda">Gracias por registrarte:</p>
        <p>Te hemos enviado un email de activación de cuenta, en unos instantes lo estarás recibiendo.<br />
            Seguí sus instrucciones para formar parte de <span class="color">Comunidad</span><b></b>.
            <br/><br/>
            <span class="consejo">Revisá tu carpeta de "Correo no deseado".</span>
    </div>
    
  8. En conclusión, necesitamos crear un Componente (registroComponents ), dos templates (_form.php y _ok.php), una entrada en el routing.yml, una función action (registroActions) y un formulario (RegistroBandaForm, en este caso extiende de RegistroForm).

Cualquier duda o comentario serán bienvenidos.

Maro

Un comentario en “Sacandole el jugo a los formularios de Symfony 1.4”

Comentarios cerrados.