我正在努力让一个简单的表单在 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
我的架构.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);
}
}
lessen_list
是您的BaseDanserForm
和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);
}
}