双重列表不适用于Symfony 1.4嵌入式表单

时间:2013-05-09 11:30:50

标签: doctrine symfony-1.4

我很难在Symfony 1.4后端模块中使用简单的表单。

我们的想法是创建一个嵌入式表单(一对多关系,Inschrijvingen - > Danser)。每个嵌入的表单都有一对多关系。 (Lessen)表单正确显示但不保存lessen_list。 (多对多关系)

我嵌入的DanserForm确实可以自行运行。但是将它嵌入到InschrijvingenForm中时不起作用。

我尝试了以下教程。但那对我不起作用:http://inluck.net/Blog/Many-to-many-relations-in-embedded-form-in-Symfony-1_4

我的schema.yml

Inschrijving:
  actAs:
    Timestampable: ~
  columns:
    voornaam: { type: string(100), notnull: true, minlength: 2 }
    achternaam: { type: string(100), notnull: true, minlength: 2 }
    straat: { type: string(100), notnull: true, minlength: 2 }
    nr: { type: string(5) }
    postcode: { type: int(9), notnull: true, minlength: 4 }
    gemeente: { type: string(100), notnull: true, minlength: 2 }
    land: { type: string(2), notnull: true, default: 'BE' }
    telefoon: { type: string(100), notnull: true, minlength: 8 }
    email:  { type: string(100), notnull: true, minlength: 4, nospace: true }
    gestructureerde_mededeling: { type: string(20) }
    interne_opmerking: { type: string(1000) }
    gebruiker_id: { type: int(9) }
    is_gearchiveerd:  { type: boolean, default:false }
  relations:
    Danser:
      local: id
      foreign: inschrijving_id
      type: many
      onDelete: CASCADE
      foreignAlias: Dansers

Danser:
  columns:
    voornaam: { type: string(100), notnull: true, minlength: 2 }
    achternaam: { type: string(100), notnull: true, minlength: 2 }
    geboortedatum: { type: date(), notnull: true }
    email:  { type: string(100), notnull: true, minlength: 4, nospace: true }
    medische_opmerkingen: { type: string(2000) }
    inschrijving_id: { type: int(9), notnull: true }
    is_verzekering_ok: { type: boolean, default:false }
  relations:
    Inschrijving:
      local: inschrijving_id
      foreign: id
      type: one
      onDelete: CASCADE
      foreignAlias: Inschrijvingen
    Lessen:
      class:              Lessen
      refClass:           LessenVanDanser
      local:              danser_id
      foreign:            lessen_id

LessenVanDanser:
  columns:
    lessen_id:             { primary: true, type: integer }
    danser_id:            { primary: true, type: integer }
  relations:
    Lessen:                { onDelete: CASCADE, local: lessen_id, foreign: id ,class: Lessen}
    Danser:          { onDelete: CASCADE, local: danser_id, foreign: id, class: Danser }

Lessen:
  actAs:
    Timestampable: ~
  columns:
    naam: { type: string(100), notnull: true, minlength: 2 }
    leeftijd_van: { type: string(3) }
    leeftijd_tot: { type: string(3) }
    dag:  { type: enum(),values: ['Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'],default: Maandag }
    van: { type: time() }
    tot: { type: time() }
    beschrijving: { type: string(5000) }
    max_aantal_deelnemers: { type: int(9) }    
    lesgever_id: { type: int(9), notnull: true }
    locatie_id: { type: int(9), notnull: true }
    lessenreeks_id: { type: int(9), notnull: true }
  relations:
    Danser:
      class:              Danser
      refClass:           LessenVanDanser
      local:              lessen_id
      foreign:            danser_id

InschrijvingenForm.class.php

<?php
class InschrijvingForm extends BaseInschrijvingForm
{
  public function configure()
  {
      unset(
      $this['created_at'], $this['updated_at'],$this['gestructureerde_mededeling']
      );

      $choices = CountryCodes::get();
      $this->widgetSchema['land'] = new sfWidgetFormChoice(array('choices' => $choices));

      $choice_keys = array();
      foreach ($choices as $choice) {
          $choice_keys = array_merge($choice_keys,array_keys($choice));
      }

      $this->setValidator('land', new sfValidatorChoice(array('choices'=>$choice_keys,'required'=>true)));
      $this->setDefault('land','BE');

      //Many to many relations
      $data = $this->getObject();
      $data_count = @count($_POST['inschrijving']['danser']);
      $data_count = $data_count > 0 ? $data_count:1;

        $subForm = new sfForm();

        for ($i = 0; $i < $data_count; $i++){
            if($data['Danser'][$i]){
                $subForm->embedForm($i, new DanserForm($data['Danser'][$i]));
            }else{
                $subForm->embedForm($i, new DanserForm());
            }
        }
        $this->embedForm('danser', $subForm);
  }

  public function saveEmbeddedForms($con = null, $forms = null) {
        if (null === $forms){
            $en_forms = $this->getEmbeddedForm('danser');

            foreach ($en_forms as $name => $form){
                if ($form instanceof sfFormObject){
                    $form->getObject()->setInschrijvingId($this->getObject()->getId());
                    $form->getObject()->save($con);
                }
            }
        }
          return parent::saveEmbeddedForms($con, $forms);
    }
}

DanserForm.class.php

<?php

/**
 * Danser form.
 *
 * @package    dansschool
 * @subpackage form
 * @author     Ilias Barthelemy
 * @version    SVN: $Id: sfDoctrineFormTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class DanserForm extends BaseDanserForm
{
  public function configure()
  {
      unset(
      $this['inschrijving_id']
      );

      $years = range(((int) date('Y'))-70, ((int) date('Y'))-3);
      $years_list = array_combine($years, $years);

      //$this->setWidget('geboortedatum', new sfWidgetFormDate(array('format' => '%day%/%month%/%year%','years' => $years_list)));
      $user = sfContext::getInstance()->getUser();
      $inschrijving = $user->getAttribute( 'dansers_form.inschrijving',null,'admin_module' );

      if(!is_null($inschrijving)){
          $this->widgetSchema['inschrijving_id']->setDefault($inschrijving['inschrijving_id']);
      }

      $this->setWidget('geboortedatum',new sfWidgetFormJQueryDate(array(
        'date_widget' => new sfWidgetFormDate(array('format' => '%day%/%month%/%year%','years' => $years_list))
      )));

      $this->widgetSchema['lessen_list'] = new sfWidgetFormDoctrineChoice(array(
      'multiple' => true,
      'model' => 'Lessen',
      'renderer_class' => 'sfWidgetFormSelectDoubleList',
      'renderer_options' => array(
        'label_unassociated' => 'Beschikbare lessen',
        'label_associated' => 'Actief'
    )));

  }

    public function bind(array $taintedValues = null, array $taintedFiles = null)
    {
        if($this->getObject()->getId()>0){
            $taintedValues['id']=$this->getObject()->getId();
            $this->isNew = false;
        }
        parent::bind($taintedValues, $taintedFiles);
    }
}

1 个答案:

答案 0 :(得分:0)

lessen_listBaseDanserForm课程中的字段是BaseInchrijvingForm吗? Symfony通常提供一个小部件来管理多对多关系,就像您在基类中拥有的那样。我只是认为它会被命名为lessenvandanser_list

我认为你没有正确地嵌入你的Danser表格。尝试类似于我在下面所做的操作,在将实例化使用这些Danser对象嵌入的表单之前,将Danser对象分配给Inschrijving对象。 我所做的是创建一个新的DanserCollectionForm类来处理这个逻辑(见下文)。

// lib\form\DanserCollectionForm.class.php
class DanserCollectionForm extends sfForm
{
    if (!$inschrijving = $this->getOption('inschrijving')) {
        throw new InvalidArgumentException(sprintf("%s must be provided with inschrijving object", get_class($this)));
    }

    // Get all danser objects associated with this inschrijving
    $dansers = $inschrijving->getDansers();

    // If no dansers, then creat a new danser
    if (!$dansers) {
        $danser = new Danser();
        // Assign the danser to the inschrijving
        $danser->Inschrijving = $inschrijving;
        $dansers = array($danser);
    }

    // Embed Danser forms
    foreach ($dansers as $key => $danser) {
        $this->embedForm($key, new DanserForm($danser));
    }
}

然后在你的InschrijvingForm类

// lib\form\InschrijvingForm.class.php 
class InschrijvingForm extends BaseInschrijvingForm
{
    public function configure()
    {
        unset(
            $this['created_at'],
            $this['updated_at'],
            $this['gestructureerde_mededeling']
        );

        $choices = CountryCodes::get();
        $this->widgetSchema['land'] = new sfWidgetFormChoice(array('choices' => $choices));

        $choice_keys = array();
        foreach ($choices as $choice) {
                $choice_keys = array_merge($choice_keys,array_keys($choice));
        }

        $this->setValidator('land', new sfValidatorChoice(array('choices' => $choice_keys, 'required' => true)));
        $this->setDefault('land','BE');

        $collectionForm = new DanserCollectionForm(null, array('inschrijving' => $this->getObject()));
        $this->embedForm('dansers', $collectionForm);
    }

    public function saveEmbeddedForms($con = null, $forms = null)
    {
        if (null === $forms) {
            $dansers = $this->getValue('dansers');
            $forms = $this->embeddedForms;

            foreach ($this->embeddedForms['dansers'] as $name => $form) {
                $deleteDanser = // Put logic of whether to ignore/delete danser forms here
                if ($deleteDanser) {
                    unset($forms['dansers'][$name]);
                    $form->getObject()->delete();
                }
            }
        }

        return parent::saveEmbeddedForms($con, $forms);
    }
}