Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

forms - Combine constraints and data transformers

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 ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

/** AssertCallback("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());
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...