Otra de las novedades de Symfony 1.3 es la función sfFormDoctrine::embedRelation()
,
que permite al programador embeber automáticamente una relación uno-a-muchos en
un formulario. Imagina que además de permitir al usuario subir dos nuevas fotos,
se le permite modificar cualquier objeto ProductPhoto
relacionado con este
producto.
El siguiente código utiliza el método embedRelation()
para añadir un objeto
ProductPhotoForm
adicional por cada objeto ProductPhoto
existente:
// lib/form/doctrine/ProductForm.class.php
public function configure()
{
// ...
$this->embedRelation('Photos');
}
Internamente el método sfFormDoctrine::embedRelation()
hace casi lo mismo
que añadimos anteriormente para embeber los dos nuevos objetos ProductPhotoForm
.
Si ya existen dos ProductPhoto
relacionadas, los arrays widgetSchema
y
validatorSchema
resultantes del formulario tendrían el siguiente aspecto:
widgetSchema => array
(
[id] => sfWidgetFormInputHidden,
[name] => sfWidgetFormInputText,
[price] => sfWidgetFormInputText,
[newPhotos] => array(...)
[Photos] => array(
[0] => array(
[id] => sfWidgetFormInputHidden,
[caption] => sfWidgetFormInputText,
),
[1] => array(
[id] => sfWidgetFormInputHidden,
[caption] => sfWidgetFormInputText,
),
),
)
validatorSchema => array
(
[id] => sfValidatorDoctrineChoice,
[name] => sfValidatorString,
[price] => sfValidatorNumber,
[newPhotos] => array(...)
[Photos] => array(
[0] => array(
[id] => sfValidatorDoctrineChoice,
[caption] => sfValidatorString,
),
[1] => array(
[id] => sfValidatorDoctrineChoice,
[caption] => sfValidatorString,
),
),
)
El siguiente paso consiste en añadir en la vista el código necesario para mostrar los nuevos formularios de tipo Photo embebidos:
// apps/frontend/module/product/templates/_form.php
<?php foreach ($form['Photos'] as $photo): ?>
<?php echo $photo['caption']->renderRow() ?>
<?php echo $photo['filename']->renderRow(array('width' => 100)) ?>
<?php endforeach; ?>
El código anterior es exactamente el mismo que se utilizó anteriormente para embeber los nuevos formularios de fotos.
El último paso consiste en convertir el campo para subir archivos en un campo
que permita al usuario ver la foto actual y modificarla por una nueva
(sfWidgetFormInputFileEditable
):
public function configure()
{
$this->useFields(array('filename', 'caption'));
$this->setValidator('filename', new sfValidatorFile(array(
'mime_types' => 'web_images',
'path' => sfConfig::get('sf_upload_dir').'/products',
'required' => false,
)));
$this->setWidget('filename', new sfWidgetFormInputFileEditable(array(
'file_src' => '/uploads/products/'.$this->getObject()->filename,
'edit_mode' => !$this->isNew(),
'is_image' => true,
'with_delete' => false,
)));
$this->validatorSchema['caption']->setOption('required', false);
}