【问题标题】:Preferred Choices for Entity Field - Symfony2实体字段的首选 - Symfony2
【发布时间】:2013-06-24 13:44:43
【问题描述】:

我已将实体字段类型添加到我正在使用的表单中,但是当我尝试设置 preferred_choices 时,我收到以下错误消息

警告:spl_object_hash() 期望参数 1 是对象,字符串在 /srv/www/amber/public_html/Symfony/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php 中给出第 98 行

你可以看到下面的代码

    $builder->add('candStatus', 'entity', array(
        'label' => 'Candidate Status', 
        'class' => 'AmberAtsBundle:SelCandStatus',
        'query_builder' => function(EntityRepository $er) {
            return $er->createQueryBuilder('sc')
            ->orderBy('sc.rank', 'ASC');
            },
         'property' => 'candStatus',
         'preferred_choices' => array('1'),
        ));

我对 Symfony 还很陌生,所以任何帮助都将不胜感激

【问题讨论】:

  • 很确定这是与实体有关的问题..如果可能的话,实体的邮政编码..
  • 我环顾四周,在以下 2 个问题中找到了答案:stackoverflow.com/questions/15776867/…stackoverflow.com/questions/5425819/… 我已经从 formType 中删除了 preferred_choices,而是在控制器在对象用于创建表单之前预先填充对象。我会在几个小时内回答时发布更多详细信息
  • 您可以使用实体管理器的 getReference 方法来构造一个适用于实体表单字段上的“preferred_choices”的数组。见this question

标签: symfony


【解决方案1】:

这适用于 Symfony 2.7:

$builder->add('license', 'entity', [
    'class' => 'CmfcmfMediaModule:License\LicenseEntity',
    'preferred_choices' => function (LicenseEntity $license) {
        return !$license->isOutdated();
    },
    // ...
])

preferred_choices 需要一个匿名函数,该函数为每个实体调用,并且必须根据是否首选返回 true 或 false。

【讨论】:

  • 这应该是 Symfony 2.7 的公认答案。
  • 我正在使用 SF 2.8,它对我有用。但接受的没有。
【解决方案2】:

我相信您需要将EntityRepository(或类似的)传递到您的表单中,并实际向preferred_choices 提供一组实体。根据记忆,在以前的 Symfony 版本中,它允许实体 ID 数组,但现在不行。

可能preferred_choices 也应该是一个回调,比如query_builder

实际确定来自preferred_choices 的内容是否与特定选项匹配的代码如下。这只是一个简单的 PHP array_search().

Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList #

protected function isPreferred($choice, array $preferredChoices)
{
    return false !== array_search($choice, $preferredChoices, true);
}

【讨论】:

    【解决方案3】:

    从您的示例中,您希望将第一个结果作为首选,您必须返回具有第一排名的实体而不是其索引。

    为此,您可以在控制器中检索它,然后将其作为参数传递给$options

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //prevent error if $options['prefered_choices'] is not set
        $prefered_choices = isset($options['prefered_choices']) ? $options['prefered_choices'] : array();
        $builder->add('candStatus', 'entity', array(
            'label' => 'Candidate Status', 
            'class' => 'AmberAtsBundle:SelCandStatus',
            'query_builder' => function(EntityRepository $er) {
                return $er->createQueryBuilder('sc')
                    ->orderBy('sc.rank', 'ASC')
                ;
            },
            'property' => 'candStatus',
            'preferred_choices' => $prefered_choices,
        ));
        //...
    }
    

    您也可以使用 getReference,正如 j_goldman 指出的 in their comment,但由于您的等级可以改变(我认为),我认为它不适合您的用例:

    $builder->add('candStatus', 'entity', array(
        'label' => 'Candidate Status', 
        'class' => 'AmberAtsBundle:SelCandStatus',
        'query_builder' => function(EntityRepository $er) {
            return $er->createQueryBuilder('sc')
                ->orderBy('sc.rank', 'ASC')
            ;
        },
        'property' => 'candStatus',
        'prefered_choices' => $this->em->getReference('AmberAtsBundle:SelCandStatus', 1),
    ));
    

    最后,您可以使用回调返回所选实体,例如使用与限制为 1 的相同 DQL:(这就是我要做的)

    $builder->add('candStatus', 'entity', array(
        'label' => 'Candidate Status', 
        'class' => 'AmberAtsBundle:SelCandStatus',
        'query_builder' => function(EntityRepository $er) {
            return $er->createQueryBuilder('sc')
                ->orderBy('sc.rank', 'ASC')
            ;
        },
        'property' => 'candStatus',
        'preferred_choices' => function(EntityRepository $er) {
            return $er->createQueryBuilder('sc')
                ->orderBy('sc.rank', 'ASC')
                ->setMaxResults(1)
            ;
        },
    ));
    

    【讨论】:

    • 你的最后一个例子不起作用。您将获得实体对象,而不是 preferred_choices 闭包中的存储库。至少这是我得到的唯一对象。
    【解决方案4】:

    在 Symfony3 中,以下对我有用:

    'preferred_choices' => function($entity) {
                    $preferred = [1, 2];
                    $choices = [];
    
                    if(in_array($entity->getId(), $preferred)) {
                        $choices[] = $entity;
                    }
    
                    return $choices;
                },
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-10
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多