结合约束和数据转换器 [英] Combine constraints and data transformers

查看:95
本文介绍了结合约束和数据转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做一些看起来像如何使用数据变形金刚教程。但是我想添加一个流程,但我找不到任何示例。



在symfony教程中,数据转换是将问题编号更改为发行对象。这是在 IssueToNumberTransformer
reverseTransform() pre $ public function reverseTransform($ number)
{
if(!$ number){
return null;

$ b $ issue $ $ this-> om
- > getRepository('AcmeTaskBundle:Issue')
- > findOneBy(array('number '=> $ number))
;

if(null === $ issue){
throw new TransformationFailedException(sprintf(
'数字%s不存在问题!',
$ number
));
}

return $ issue;





$ b

我们可以看到,如果提供了无效的问题编号,转换将失败,该函数会抛出 TransformationFailedException 。因此,该表单与消息此值无效的错误。个人化这个信息会很好。

数据转换过程在任何验证之前执行(限制应用于字段),所以我找不到方法在尝试转换之前验证问题编号。



另一个为什么我必须在转换前验证的例子是使用MongoDB文档管理器将Issue mongo id指向问题(表单由REST API服务器使用,这就是为什么我收到一个id)。所以:

$ $ p $ public function reverseTransform($ id)
{
if(!$ number){
返回null;


$ issue = $ this-> dm
- > getRepository('AcmeTaskBundle:Issue')
- > find(new \ MongoId ($ id))
;

if(null === $ issue){
throw new TransformationFailedException(sprintf(
'数字%s不存在问题!',
$ number
));
}

return $ issue;
}

这里,如果我在我的API表单中收到的ID不是正确的MongoID,客户端将获得500.因此,我想检查,如果收到的id是正确的,在转换之前,因为如果不是,转换会引发致命错误。如果我在我的转换中管理所有的案例,比如检查$ id是否正确,就好像我在变换器中进行验证,这是不正确的。



我的问题是:有没有办法在数据转换之前应用约束?或者有没有办法在转换失败时在表单上添加摘要constraintViolation?解析方案

这是一种解决方法,但是我建议编写代表无效问题的类来个性化错误。

  class InvalidIssue extends Issue 
{
public $ message ='这个问题无效';

public function __construct($ message = null)
{
if(null!== $ message){
$ this-> message = $ message;
}
}
}

并且在变压器中,if给定值无效,返回InvalidIssue对象,而不是抛出一个异常。

  public function reverseTransform($ id)
{
if(!$ number){
return null;


$ issue = $ this-> dm
- > getRepository('AcmeTaskBundle:Issue')
- > find(new \ MongoId ($ id))
;

if(null === $ issue){
返回新的InvalidIssue(sprintf(
'数字%s不存在问题!',
$ number
));
}

return $ issue;
}

然后,将验证器添加到您的模型中。

  / ** Assert\Callback(callback=validateIssueIsValid)* / 
class YourModel
{
protected $问题;

公共函数setIssue(Issue $ issue)
{
$ this-> issue = $ issue;


public function validateIssueIsValid(ExecutionContextInterface $ context)
{
if($ this-> issue instanceof InvalidIssue){
$ context-> ; addViolationAt('issue',$ this-> issue-> message,array());
}
}
}


I would like to do something looking like what is done in How to use Data Transformers tutorial. But I would like to add a process and I can't find any example.

In the symfony tutorial, data transformation is about changing an issue number to an Issue object. This is done in the reverseTransform() function of IssueToNumberTransformer

public function reverseTransform($number)
{
    if (!$number) {
        return null;
    }

    $issue = $this->om
        ->getRepository('AcmeTaskBundle:Issue')
        ->findOneBy(array('number' => $number))
    ;

    if (null === $issue) {
        throw new TransformationFailedException(sprintf(
            'An issue with number "%s" does not exist!',
            $number
        ));
    }

    return $issue;
}

We can see that if an invalid issue number is provided, transformation will failed and the function throw a TransformationFailedException. As a result, the form as an error with message "This value is not valid". It would be great to personalize this message.

The data transformation process is executed before any validation (with constraints applied to the field), so I can't find a way to validate the issue number before trying to transform it.

As another example of why I have to validate before transformation is I use the MongoDB Document Manager to convert the "Issue mongo id" to an Issue (the form is used by a REST API server, that's why I receive an id). So :

public function reverseTransform($id)
{
    if (!$number) {
        return null;
    }

    $issue = $this->dm
        ->getRepository('AcmeTaskBundle:Issue')
        ->find(new \MongoId($id))
    ;

    if (null === $issue) {
        throw new TransformationFailedException(sprintf(
            'An issue with number "%s" does not exist!',
            $number
        ));
    }

    return $issue;
}

Here, if the id I receive in my API form is not formated as correct MongoID, client will receive a 500. So I want to check, before transformation if received id is correct, because if it's not, transformation will throw a fatal error. And if I manage all cases in my transformation, like checking if $id is correct, it's like I'm doing validation in the transformer and it's not correct.

My question is : is there a way to apply constraints before the data transformation ? or is there a way to add a digest constraintViolation on the form when transformation failed ?

解决方案

This is like a workaround, however I suggest writing the class that represents "an invalid issue" to personalize error.

class InvalidIssue extends Issue
{
    public $message = 'This issue is invalid';

    public function __construct($message = null)
    {
        if (null !== $message) {
            $this->message = $message;
        }
    }
}

and in the transformer, if given value is invalid, return InvalidIssue Object instead of throwing an Exception.

public function reverseTransform($id)
{
    if (!$number) {
        return null;
    }

    $issue = $this->dm
        ->getRepository('AcmeTaskBundle:Issue')
        ->find(new \MongoId($id))
    ;

    if (null === $issue) {
        return new InvalidIssue(sprintf(
            'An issue with number "%s" does not exist!',
            $number
        ));
    }

    return $issue;
}

then, add validator onto your model.

/** Assert\Callback("callback"="validateIssueIsValid") */
class YourModel
{
    protected $issue;

    public function setIssue(Issue $issue)
    {
        $this->issue = $issue;
    }

    public function validateIssueIsValid(ExecutionContextInterface $context)
    {
        if ($this->issue instanceof InvalidIssue) {
            $context->addViolationAt('issue', $this->issue->message, array());
        }
    }
}

这篇关于结合约束和数据转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆