使用 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 许可证获得许可。