Symfony sfWidgetFormDoctrineChoice带有多个选项


Symfony sfWidgetFormDoctrineChoice with multiple option on

我创建了一个表单,在其中嵌入了另一个表单。我的问题是关于这个嵌入的表单-我使用的是sfWidgetFormDoctrineChoice小部件,选项multiple设置为true。此嵌入表单的配置方法的代码:

public function configure()
  {
    unset($this['prerequisite_id']);
    $this->setWidget('prerequisite_id', new sfWidgetFormDoctrineChoice(array(
        'model' => 'Stage',
        'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
        'multiple' => true
    )));
    $this->setValidator('prerequisite_id', new sfValidatorDoctrineChoice(array(
        'model' => 'Stage',
        'multiple' => true,
        'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
        'column' => 'id'
    )));
  }

我取消设置prerequisite_id字段,因为它包含在基本表单中,但我希望它是多选字段。现在,当我添加验证器时,一切似乎都正常(它通过了验证),但如果发送了多个选择,那么它在保存记录时似乎有问题。

我在提交表单后收到以下PHP警告:

警告:strlen()要求参数1为字符串,中给定的数组D: ''Development''www''flow_dms''lib''vendor''symfony''lib''plugins''sfDoctrinePlugin''lib''database''sfDoctrineConnection Profiler.class.php198线上

在symfony的调试模式中,我可以在堆栈跟踪中看到以下内容:

在Doctrine_Connection->exec('INSERT INTO stage_has_prerequities(prerequisite_id,stage_id)VALUES(?,?)',array(array('12','79'),103))

因此,Symfony所做的是向Doctrine发送一系列选择——正如我在调试sql查询中看到的,Doctrine无法正确呈现查询。

有什么办法解决的吗?我需要为两个选项生成两个查询:

INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (12, 103);
INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (79, 103);

stage_id总是一样的(我的意思是,它是由它所嵌入的表单设置在这个表单之外的)。

我已经花了4个小时在这个问题上了,所以也许有人能提供一些帮助。

好吧,我似乎找到了一个解决方案(尽管我想不是最好的)。希望它能对某些人有所帮助。

最后,经过深思熟虑,我得出结论,如果问题来自Doctrine_Record,如果它遇到一个数组而不是单个值,则无法保存记录,那么最简单的解决方案是覆盖Doctrine_Recordsave()方法。我就是这么做的:

class StageHasPrerequisites extends BaseStageHasPrerequisites
{
  public function save(Doctrine_Connection $conn = null)
  {
    if( is_array( $this->getPrerequisiteId() ) )
    {
      foreach( $this->getPrerequisiteId() as $prerequisite_id )
      {
        $obj = new StageHasPrerequisites();
        $obj->setPrerequisiteId( $prerequisite_id );
        $obj->setStageId( $this->getStageId() );
        $obj->save();
      }
    }
    else
    {
      parent::save($conn);
    }
  }
  (...)
}

因此,现在如果它遇到一个数组而不是单个值,它只会创建一个临时对象,并为该数组的每个值保存它。

当然,这不是一个优雅的解决方案,但它是有效的(请记住,它是为数据的特定结构而写的,这只是我的方法的效果,即查看调试模式中的错误,然后尝试以任何可能的方式更正)。