使用sonata_type_immutable_array中的对象(特别是像sonata_type_immutable_array)

时间:2015-03-24 15:11:46

标签: symfony doctrine-orm sonata-admin symfony-2.5

问题描述

我需要在 sonata_type_immutable_array 表单类型定义中定义与对象相关的字段(如 sonata_type_model_list ):

$formMapper->add('options', 'sonata_type_immutable_array', array(
    'keys' => array(
        array('linkName', 'text', array()),
        array('linkPath', 'sonata_type_model_list',
            array(
                'model_manager' => $linkAdmin->getModelManager(),
                'class' => $linkAdmin->getClass(),
            )
        )
    )
)

这不起作用,这是错误消息:

Impossible to access an attribute ("associationadmin") on a NULL variable ("") in SonataDoctrineORMAdminBundle:Form:form_admin_fields.html.twig at line 60

我发现了这个问题

我试图找到有关在 sonata_type_immutable_array 中使用 sonata_type_model_list 的任何信息,但信息非常少。 这个(https://github.com/a2lix/TranslationFormBundle/issues/155)主题对我有所帮助,但是以同样的方式做了所有事情我又得到了另一个错误:

Impossible to invoke a method ("id") on a NULL variable ("") in SonataDoctrineORMAdminBundle:Form:form_admin_fields.html.twig at line 60

所以我完全没有理解我必须做的事情。

我的背景

- 我有一个名为 CmsLink 的Doctrine ORM Mapped类,它定义了哪个' linkPath'领域涉及。

- 我有CmsLink类的管理类,它有非常基本的配置:

protected function configureFormFields(FormMapper $formMapper)
{
  $formMapper
    ->add('technicalAlias')
    ->add('url')
  ;
}

- 我有一个名为 CmsMenuItem 的Doctrine ORM Mapped类,它定义了对象和'选项'保存由sonata_type_immutable_array表单类型管理的数据的字段,字段类型为 json_array

/**
* @var string
*
* @ORM\Column(name="options", type="json_array", nullable=true)
*/
private $options;

- 最后我有CmsMenuItem类的管理类,这里是关键代码:

$linkAdmin = $this->configurationPool->getAdminByClass("Argon\\CMSBundle\\Entity\\CmsLink");

$formMapper
    ->add('options', 'sonata_type_immutable_array',
        array(
            'keys' => array(
                array('linkName', 'text', array()),
                array('linkPath', 'sonata_type_model_list',
                        array(
                            'model_manager' => $linkAdmin->getModelManager(),
                            'class' => $linkAdmin->getClass(),
                        )
                ),
                array('description', 'textarea', array()),
                array('image', 'sonata_media_type',
                    array(
                        'provider' => 'sonata.media.provider.image',
                        'context' => 'pages_static',
                        'required'=>false,
                    )
                )
            )
        )
    );

问题目标

  1. 找出我需要做些什么来为这个想法注入活力?
  2. 获取一般信息并了解如何将与对象相关的字段类型包含到sonata_type_immutable_array中

1 个答案:

答案 0 :(得分:0)

I've just come across this problem, and solved it with a custom type and data transformers.

Here's the rough outline, though you need to tailor it to your problem.

Custom Type

class YourImmutableArrayType extends ImmutableArrayType
{
    /**
     * @var YourSettingsObjectTransformer
     */
    private $transformer;

    public function __construct(YourSettingsObjectTransformer $transformer)
    {
        $this->transformer = $transformer;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);
        $builder->addModelTransformer($this->transformer);
    }

    public function getName()
    {
        return 'your_type_name';
    }

    public function getParent()
    {
        return 'sonata_type_immutable_array';
    }
}

Custom model transformer

class NewsListingSettingsTransformer implements DataTransformerInterface
{

    public function __construct(ObjectManager $manager)
    {
        // You'll need the $manager to lookup your objects later
    }

    public function reverseTransform($value)
    {
        if (is_null($value)) {
            return $value;
        }

        // Here convert your objects in array to IDs

        return $value;
    }

    public function transform($value)
    {
        if (is_null($value)) {
            return $value;
        }

        // Here convert ids embedded in your array to objects, 
        // or ArrayCollection containing objects

        return $value;
    }

}

 Building form in admin class

    $formMapper->add('settings', 'your_type_name', array(
        'keys' => array(
            array(
                'collectionOfObjects',
                'sonata_type_model',
                array(
                    'class' => YourObject::class,
                    'multiple' => true,
                    'model_manager' => $this->yourObjectAdmin->getModelManager()
                )
            )
        )
    ));
}

Again, it's a rough outline, so tweak it to your needs.