Tutorial Symfony - Jobeet dia 10 - Formularios
The Form Framework
Los formularios forman parte de cualquier página web, generalmente suelen ser el punto más sensible a nivel de seguridad y errores, por lo que su correcta implementación es un punto crítico de cualquier web.
Symfony tiene un framework para manejarlos que se divide en tres partes:
Validación: tipos básicos como integer hasta complejos, como mail.
Widgets: Clases para mostrar distintos elementos HTML como inputs o selects...
Forms: conjunto de clases para manejar formularios, cada uno contiene validator+widget.
Forms
Cada formulario se configura en el método configure() mediante el uso de setValidators() y setWidgets().
Doctrine Forms
Como los formularios suelen manejar el CRUD del modelo de la base de datos, existen métodos para realizar la cargar de los mismos mediante un doctrine:build --forms, pero NO ES NECESARIO ahora, ya que está incluido al hacer doctrine:build --all.
Estos archivos se guardarán en lib/form/doctrine/*
Customizing the Job Form
Vamos a actualizar el formulario para crear una nueva oferta de trabajo "Post a Job", así que nos vamos a /lib/form/doctrine/JobeetJobForm.class.php.
PARTE 1: CREAR EL WIDGET
Por defecto aparecen todos los campos, así que vamos a ocultar los que no nos interesan mediante unset(), también podemos hacerlo al revés, es decir, indicando los que queremos mediante useFields() que además nos permite indicar el orden de los elementos.
Esta segunda opción es mejor, ya que si añades algún campo a la bd controlas en todo momento los campos que verá el usuario.
PARTE 2: VALIDACIÓN
Ahora vamos a realizar la validación de los datos, el correo se valida como un string pero tenemos métodos para controlar que es un correo, también es recomendable concatenar validators con sfValidatorAnd(), de este modo ayudas al usuario y reduces errores.
Hecho esto vamos a controlar los horarios de trabajo, queremos que sea uno de los 3 valores predefinidos, para ello:
Nos vamos al modelo y creamos un atributo $types que puede tomar tres valores posibles.
Creamos un accesor para poder recuperarlos mediante un getTypes()
Volvemos al formulario y utilizamos sfWidgetFormChoice(), donde le indicamos que sea uno de los valores disponibles en getTypes()
Si queremos algún valor por defecto, tenemos que cambiarlo en el schema de la base de datos.
Symfony carga automáticamente un label asociado a cada campo, también podemos editar estos valores con $this->widgetSchema->setLabels()
Otro punto importante es la validación de ficheros mediante sfValidatorFile(), muy útil para:
Validar que el fichero tiene el tipo correcto (mime_types)
Dar un nombre único al archivo
Almacenar el fichero en la ruta dada en el action
Actualiza la columna logo en la base de datos con el nombre
The Form Template
Ahora que tenemos el formulario creado vamos a preparar la template, el formulario se renderiza a partir de la vista, es decir /apps/frontend/modules/job/templates/_form.php
Aquí añadimos las llamadas a los css y js en la cabecera, después necesitamos dos cosas:
form_tag_for() que genera una etiqueta <form> y se encarga de de hacer los métodos POST y PUT mediante los objetos que ya hemos visto de sf.
echo $form al mostrar esta variable hacemos un render de todos los widgets, sería lo mismo que hacer
foreach ($form as $widget){ echo $widget->renderRow() }
El objeto form tiene muchos métodos que conviene conocer para manejar el contenido, errores o etiquetas de los formularios.
The Form Action
El diagrama de flujo del formulario se puede sintetizar en esto,
Como ya tenemos las rutas creadas (ver día 5) vemos que antes de realizar cualquier petición al modelo, para modificar la base de datos, el controlador se encarga de procesar/validar el formulario a partir de los validators implementados.
También vemos que cuando se crea un nuevo trabajo, en executeNew(), el sistema manda un valor por defecto para Type, en este caso "full-time", esto también se podría hacer en el schema de la base de datos.
Protecting the Job Form with a Token
El token es un identificador único, este token se generará al crear un nuevo trabajo. Lo que buscamos es que aunque un usuario conozca una ruta, no pueda acceder a ella directamente, así protegemos la información de los ataques por fuerza bruta.
Seguimos los pasos que nos indican y editamos también el routing, ahora todas las URL tendrán la estructura:
http://jobeet.localhost.com/job/TOKEN/edit
The Preview Page
Vamos a añadir una pequeña barra de administración en la vista showSuccess, lo implementaremos mediante un partial (visto en los primeros días). Si no recuerdo mal, son pequeños includes de código que podemos reutilizar, en este caso _admin.php
Ahora cuando creamos un trabajo, tenemos que pulsar en "Publish" para que se publique y empiece el contador de expiración.
Job Activation and Publication
En vez de crear una nueva ruta, vamos a reutilizar "job:" sólo tenemos que modificar object_actions en el mismo fichero para enviarle un array con el resto de información.
Como sf maneja las peticiones como objetos podemos capturar ese put en el controlador actions.class.php
Por último vamos cerrar el acceso a las rutas de los trabajos, por un lado mediante el método checkCSRFProtection() que bloquea la mayoría de las inyecciones sql, luego para terminar comprobamos que no se muestren los trabajos que no estén activos.
Con esto ya hemos terminado
Final Thoughts
Los formularios cuentan con validators y widgets, los primeros deben ser anidados para acotar al máximo los valores de entrada, los segundos permiten pintar cualquier objeto de tipo input.
Desde la clase form los vamos invocando para pintarlos en cualquier Vista, su validación se realiza dentro del mismo formulario antes de procesarlos.













