Los formularios están casi siempre asociados a un objeto, cuyas propiedades se asocian a los campos del formulario. Esto es exactamente lo que se ha visto hasta ahora en este capítulo con la clase Task
.
No obstante, en ocasiones puede que necesites utilizar un formulario sin una clase, y obtener un array de los datos enviados por el usuario. El siguiente ejemplo muestra cómo puedes hacerlo:
// asegúrate de importar el espacio de nombres Request
use Symfony\Component\HttpFoundation\Request;
// ...
public function contactAction(Request $request)
{
$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
->add('name', 'text')
->add('email', 'email')
->add('message', 'textarea')
->getForm();
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
// data es un array con claves 'name', 'email', y 'message'
$data = $form->getData();
}
// ... renderiza el formulario ...
}
Por omisión, los formularios suponen que quieres trabajar con arrays de datos en vez de con objteos. Existen dos maneras de cambiar este comportamiento para asociar los datos a un objeto:
- Pasa un objeto al crear el formulario (como primer argumento de
createFormBuilder
o segundo argumento decreateForm
); - Declara la opción
data_class
en tu formulario.
Si no haces ninguna de estas dos cosas, entonces el formulario devolverá los datos como un array. En este ejemplo, como $defaultData
no es un objeto (y no se ha establecido la opción data_class
), el método $form->getData()
, devuelve un array.
Truco También puedes acceder a los valores POST (en este caso name
) directamente a través del objeto Request
, de la siguiente manera:
$this->get('request')->request->get('name');
No obstante, ten en cuenta que en la mayoría de los casos es mejor utilizar el método getData()
, ya que devuelve los datos (generalmente un objeto), después de que el componente de formularios los haya transformado.
12.11.1. Añadiendo la validación
Lo único que le falta a todos los formularios anteriores es la validación. Por lo general, cuando llamas a $form->isValid()
, el objeto es validado aplicando las restricciones que añadiste a esa clase. Pero si el formulario no está asociado a una clase, ¿cómo se pueden definir reglas de validación en el formulario?
La respuesta es configurar las restricciones a mano y añadirlas al formulario. La idea está mejor explicada en el capítulo de validación de este mismo libro, pero a continuación se muestra un ejemplo sencillo:
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\Collection;
$collectionConstraint = new Collection(array(
'name' => new MinLength(5),
'email' => new Email(array('message' => 'Invalid email address')),
));
// crear un formulario sin valore por defecto y pasarle las
// reglas de validación
$form = $this->createFormBuilder(null, array(
'validation_constraint' => $collectionConstraint,
))->add('email', 'email')
// ...
;
Ahora, al ejecutar el método $form->bindRequest($request)
, se aplicarán las reglas de validación a todos los datos enviados por el usuario. Si utilizas una clase de formulario, redefine el método getDefaultOptions
para especificar la opción:
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\Collection;
class ContactType extends AbstractType
{
// ...
public function getDefaultOptions(array $options)
{
$collectionConstraint = new Collection(array(
'name' => new MinLength(5),
'email' => new Email(
array('message' => 'Invalid email address')
),
));
return array('validation_constraint' => $collectionConstraint);
}
}
Ahora ya dispones de la flexibilidad de crear formularios con validación y que devuelvan un array de datos en vez de un objeto. Casi siempre es mejor asociar los formularios a objetos, pero para los formularios sencillos este es un método muy práctico.