0

Symfony 1.4 バックエンド モジュールで単純なフォームを動作させるのに苦労しています。

アイデアは、埋め込みフォームを作成することです (1 対多の関係、Inschrijvingen -> Danser)。各埋め込みフォームには、多対多の関係が 1 つあります。(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);
    }
}
4

1 に答える 1

0

andクラスlessen_listにフィールドはありますか? symfony は通常、基本クラスにあるような多対多の関係を管理するためのウィジェットを提供します。名前が付けられると思っただけです。BaseDanserFormBaseInchrijvingFormlessenvandanser_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);
    }
}
于 2013-05-09T14:08:49.957 に答える