0

我正在努力获得一个在 Symfony 1.4 后端模块中工作的简单表单。

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

我嵌入的 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);
    }
}
4

1 回答 1

0

你和班级中有lessen_list一个领域吗?Symfony 通常提供一个小部件来管理多对多关系,就像您在基类中的关系一样。我只是以为它会被命名。BaseDanserFormBaseInchrijvingFormlessenvandanser_list

我认为您没有正确嵌入 Danser 表单。尝试类似于我在下面所做的操作,在其中将 Danser 对象分配给 Inschrijving 对象,然后使用这些 Danser 对象实例化嵌入的表单。我所做的是创建一个新的 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);
    }
}
于 2013-05-09T14:08:49.957 回答