跳到内容

使用 DataMapper 处理没有每个字段设置器的域实体

编辑此页

这是一个 DataMapper 与避免为每个字段设置 setter/getter 的实体一起使用的示例。

先决条件

  • 您已经安装并运行了 SonataAdmin 和 DoctrineORM。
  • 您已经有一个实体类,在本例中,该类将被称为 Example
  • 您已经设置了一个 Admin,在本例中它被称为 ExampleAdmin

方法

如果实体需要具有特定于域的方法而不是每个实体字段的 getter/setter,则它将无法与开箱即用的 SonataAdmin 一起使用。但是 Symfony Form 组件提供了 DataMapper,可以用来使其工作。Symfony 本身缺乏使用 DataMapper 的示例,但 webmozart 有一篇文章涵盖了它 - https://webmozart.io/blog/2015/09/09/value-objects-in-symfony-forms/

示例实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Entity/Example.php

namespace App\Entity;

final class Example
{
    private string $name;

    private string $description;

    public function __construct(string $name, string $description)
    {
        $this->name = $name;
        $this->description = $description;
    }

    public function update(string $description)
    {
        $this->description = $description
    }

    // rest of the code goes here
}

DataMapper

为了能够在无法使用 setter 的情况下设置实体数据,应该创建一个 DataMapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// src/Form/DataMapper/ExampleDataMapper.php

namespace App\Form\DataMapper;

use Symfony\Component\Form\DataMapperInterface;
use App\Entity\Example;

final class ExampleDataMapper implements DataMapperInterface
{
    /**
     * @param Example $data
     * @param FormInterface[]|\Traversable $forms
     */
    public function mapDataToForms($data, $forms)
    {
        if (null !== $data) {
            $forms = iterator_to_array($forms);
            $forms['name']->setData($data->getName());
            $forms['description']->setData($data->getDescription());
        }
    }

    /**
     * @param FormInterface[]|\Traversable $forms
     * @param Example $data
     */
    public function mapFormsToData($forms, &$data)
    {
        $forms = iterator_to_array($forms);

        if (null === $data->getId()) {
            $name = $forms['name']->getData();
            $description = $forms['description']->getData();

            // New entity is created
            $data = new Example(
                $name,
                $description
            );
        } else {
            $data->update(
                $forms['description']->getData()
            );
        }
    }
}

Admin 类

现在我们需要配置表单以使用我们的 ExampleDataMapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Admin/ExampleAdmin.php

namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use App\Form\DataMapper\ExampleDataMapper;

final class ExampleAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $form): void
    {
        $form
            ->add('name', null)
            ->add('description', null);
        ;

        $builder = $form->getFormBuilder();
        $builder->setDataMapper(new ExampleDataMapper());
    }

    // ...
}
这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可证获得许可。
目录
    版本