Tratando múltiplos telefones com embedded forms no admin generator
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
{
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.
