我创建了一个对象到 ID 数据转换器。它是自定义 ObjectIdType 的一部分,它允许我输入文档的 ID,而不是使用“文档”表单类型。这对 MongoDB 来说很方便(当有 1 亿个文档可供选择时)。
数据转换器对 ID 进行查询并返回一个对象。如果找不到对象,则返回 null。问题是 - 有时 null 是可接受的值,有时则不是。
即使我添加了 NotNull 验证器,我也会收到以下错误 -
可捕获的致命错误:传递给 Character::setPlayer() 的参数 1 必须是 Document\Player 的实例,给定 null
因此,无论验证失败,它都会调用 setter。我通过在变压器中抛出 TransformationFailedException 来解决这个问题——但这似乎是个坏主意。我真的不应该使用数据转换器来验证。
变压器的代码如下。我想要的是能够将验证器放在正确的位置,并拦截设置器,这样它就不会被调用。一般来说,这似乎有点代码味道,我很想知道其他人是如何解决这个问题的。
class ObjectToIdTransformer implements DataTransformerInterface
{
private $objectLocator;
private $objectName;
private $optional;
/**
* @param ObjectLocator $objectLocator
* @param $objectName
*/
public function __construct(ObjectLocator $objectLocator, $objectName, $optional = false)
{
$this->objectLocator = $objectLocator;
$this->objectName = $objectName;
$this->optional = $optional;
}
/**
* {@inheritdoc}
*/
public function transform($value)
{
if (null === $value) {
return null;
}
if (!$value instanceof BaseObject) {
throw new TransformationFailedException("transform() expects an instance of BaseObject.");
}
return $value->getId();
}
/**
* {@inheritdoc}
*/
public function reverseTransform($value)
{
if (null === $value) {
return null;
}
$repo = $this->objectLocator->getRepository($this->objectName);
$object = $repo->find($value);
if (!$this->optional && !$object) {
throw new TransformationFailedException("This is probably a bad place to validate data.");
}
return $object;
}
}