Páginas

quinta-feira, 23 de dezembro de 2010

EmbedForm no Symfony 1.2 (1.3 e 1.4)

Olá Pessoal,

A quanto tempo, vou postar aqui mais uma dica sobre Symfony, agora sobre EmbedForm, é uma dica de um rapaz chamado AugustoMorais.wordpress.com, porém com algumas alterações para funcionar no symfony 1.4.

Esta dica é sobre fazer um EmbedForm com ativação para utilização.
As alterações que fiz, foram postadas como comentário no blog do autor.

Livro:
  actAs:                  { Timestampable: ~ }
  columns:
    autor_id:               { type: integer   , notnull: true }
    isbn:                   { type: string(50), notnull: true }
    titulo:                 { type: string(50), notnull: true }
  relations:
    Autor: { onDelete: CASCADE, local: autor_id, foreign: id, foreignAlias: Livros }

Autor:
  actAs:               { Timestampable: ~ }
  columns:
    nome:                { type: string(255), notnull: true }
    sobrenome:           { type: string(255), notnull: true }

A intenção inicial é criar uma tela assim:


A dica, em sí é sobre o checkbox do NOVO AUTOR, percebam que existe a combobox, para selecionar um já existente, caso ele não exista o checkbox nos permitirá cadastrar um novo.

Nossas primeiras alterações são
// No Arquivo
// /lib/form/LivrosForm.class.php
class LivroForm extends BaseLivroForm
{
  public function configure()
  {
  $autorForm = new AutorForm();

  //Adicionando Checkbox "adicionar novo cliente"
  $this->getWidgetSchema()->offsetSet(
    'add_new_autor', new sfWidgetFormInputCheckbox(array(
      'label' => 'Novo Autor')));

  $this->embedForm('new_autor', $autorForm);

  $this->widgetSchema['autor_id']->setOption(
    'add_empty', 'Escolher Autor');
  $this->validatorSchema['autor_id']->setMessage(
    'required', 'Por favor, escolha um autor ou crie um novo.');

  $this->setValidatorSchema(
    new LivroValidatorSchema($this->validatorSchema->getFields()));

  // Inserindo campos extras (checkbox no caso)
  $this->validatorSchema->setOption('allow_extra_fields', true);
  $this->validatorSchema->setOption('filter_extra_fields', false);
  }

  public function updateObject($values = null)
  {
  parent::updateObject();

  if ($this->values['autor_id'] <> 0)
  {
    //Salvando nosso livro com o ID do autor Setado no template
    $livro = new Livro();
    $livro->fromArray($this->values);
    //-- $livro->save();
    //++ $this->getObject()->save();
    $this->getObject()->save();

    return $this->object;
  } else {
    //Salvando nosso autor criado
    $autor = new Autor();
    $autor->fromArray($this->values['new_autor']);
    $autor->save();  

    //Salvando nosso Livro com o nosso autor criado
    $this->getObject()->setAutor($autor);
    $this->getObject()->save();
    return $this->object;
  }
  }
}

Chamamos a atenção para as linhas
$autor->save();// onde salvamos o Autor antes de salvar o Livro
$this->getObject()->save();// Aqui atualizamos o livro, para não criar uma Duplicata!

Agora precisamos criar um VALIDATOR especial para aceitar o checkbox, de encapsulamento do autor.

// /lib/validators/AutorValidator.class.php
class LivroValidatorSchema extends sfValidatorSchema {

  protected function doClean($values)
  {
    if (is_null($values)) {
      $values = array();
    }
    if (!is_array($values)) {
      throw new InvalidArgumentException(
        'You must pass an array parameter to the clean() method');
    }
    if (isset($values['add_new_autor'])) {
      $values['autor_id'] = '';
      $this->offsetUnset('autor_id');
    } else {
      if (isset($values['new_autor'])) {
        $values['new_autor'] = '';
        unset($values['new_autor']);
      }
    $this->offsetUnset('new_autor');
    }
  return parent::doClean($values);
  }
}
O Código acima foi retirado de uma idéia do:
http://forum.symfony-project.org/index.php/m/65120/

Agora só falta modificar as Actions do Livros, para que possamos utilizar nossos novos itens.

// /apps/proj/modules/livros/actions/actions.class.php
// Edite o processForm para o seguinte item
protected function processForm(sfWebRequest $request, sfForm $form)
{
  $form->bind($request->getParameter($form->getName()));
  if ($form->isValid()) {
    //-- $livro = $form->save();
    //++ $form->updateObject();
    $form->updateObject();
    $this->redirect('livro/edit?id='.$livro->getId());
  }
}

Ao comentar, o $form->save() para utilizar o $form->updateObject(), você está utilizando toda nossa nova estrutura de validação.

Agora é só adaptar para sua necessidade

Vlw Augusto Morais!

Abraços pessoal!

Fonte: http://augustomorais.wordpress.com/2009/10/28/embedform-no-symfony-1-2/

Nenhum comentário:

Postar um comentário