No meu post anterior, comentei sobre uma tabela (imovel) que possui diversos telefones (1-N). Nesse post vou tentar explicar como fiz o formulário de edição para tratar os N telefones dos imoveis.
O jeito que fiz vai ficar como a imagem abaixo. Vou deixar sempre 3 campos em branco para adicionar novos telefones. Para remover um telefone, basta deixa-lo em branco (em breve eu crio um botão com ajax para remover).

Vamos começar editando o lib/form/ImovelForm.class.php
class ImovelForm
extends BaseImovelForm
{
public function configure
()
{
$todoWrapperForm =
new sfForm
();
if ($this->
getObject()->
countTelefoneImovels() >
0) {
foreach ($this->
getObject()->
getTelefoneImovels() as $telefone){
$todoWrapperForm->
embedForm(‘tel_’.
$telefone->
getId(),
new TelefoneImovelForm
($telefone));
}
}
// adiciona os 3 forms em branco
$todoWrapperForm->
embedForm(‘tel_A’,
new TelefoneImovelForm
());
$todoWrapperForm->
embedForm(‘tel_B’,
new TelefoneImovelForm
());
$todoWrapperForm->
embedForm(‘tel_C’,
new TelefoneImovelForm
());
$this->
embedForm(‘tels’,
$todoWrapperForm);
$this->
validatorSchema->
setOption(‘filter_extra_fields’,
false);
$this->
validatorSchema->
setOption(‘allow_extra_fields’,
true);
}
public function bind
(array $taintedValues =
null,
array $taintedFiles =
null) {
foreach($this->
embeddedForms[‘tels’]->
getEmbeddedForms() as $key=>
$telForm)
{
if ($taintedValues[‘tels’][$key][‘telefone’] ==
"")
{
unset($this->
embeddedForms[‘tels’]->
embeddedForms[$key],
$taintedValues[‘tels’][$key]);
$telForm->
getObject()->
delete();
}
}
parent::
bind($taintedValues,
$taintedFiles);
}
// http://trac.symfony-project.org/ticket/5842
public function saveEmbeddedForms
($con =
null,
$forms =
null,
$taintedValues =
null,
$taintedFiles =
null)
{
//atualiza o imovel_id da telefone_imovel depois de ter o imovel salvo
//http://www.thatsquality.com/articles/embedding-child-forms-with-sfformpropel-a-practical-example
foreach($this->
embeddedForms[‘tels’]->
getEmbeddedForms() as $telForm)
{
if (!
$telForm->
getObject()->
getImovelId())
{
$telForm->
getObject()->
setImovelId($this->
getObject()->
getId());
}
}
if (is_null($con))
{
$con =
$this->
getConnection();
}
if (is_null($forms))
{
$forms =
$this->
embeddedForms;
}
if (is_null($taintedValues))
{
$taintedValues =
$this->
taintedValues;
}
if (is_null($taintedFiles))
{
$taintedFiles =
$this->
taintedFiles;
}
foreach ($forms as $key =>
$form)
{
// é esse trecho que corrige o problema
if ($form instanceof sfFormPropel
)
{
$form->
bindAndSave($taintedValues[$key],
$taintedFiles);
} else {
$this->
saveEmbeddedForms($con,
$form->
getEmbeddedForms(),
$taintedValues[$key],
$taintedFiles);
}
}
}
}
Agora vamos criar um partial para mostrar os telefones no formulário. Crie o arquivo apps/backend/imovel/templates/_tels.php
<div id=
"embed_tels">
<?php foreach ($form->
getEmbeddedForms() as $key =>
$itemForm) {
if (substr($key ,
0 ,
8) ==
‘tels’):
?>
<div
class=
"sf_admin_form_row sf_admin_text sf_admin_form_field_telefone<?php echo preg_replace("/
[^
0-9]/
", ‘’, $key); //only number ?>">
<div>
<?php echo $form[$key];
?>
</div>
</div>
<?php endif ?>
<?php } ?>
</div>
Depois de ter criado o partial, basta adiciona-lo ao apps/backend/imovel/config/generator.yml
edit:
display: [_tels, campo1, campo2]
É isso.. tive como referência diversos sites, mas principalmente o blog that’s quality.
http://www.thatsquality.com/search?query=embedded