Комбинированные ограничения и преобразователи данных
Я хотел бы сделать что-то похожее на то, что сделано в Как использовать Data Transformers. Но я хотел бы добавить процесс, и я не могу найти никакого примера.
В учебнике symfony преобразование данных связано с изменением номера проблемы на объект Issue
. Это выполняется в reverseTransform()
функции 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;
}
Мы можем видеть, что если указан недопустимый номер проблемы, преобразование завершится неудачно, а функция выкинет a TransformationFailedException
. В результате форма как ошибка с сообщением "Это значение недействительно". Было бы здорово персонализировать это сообщение.
Процесс преобразования данных выполняется до любой проверки (с ограничениями, применяемыми к полю), поэтому я не могу найти способ проверить номер проблемы перед тем, как ее преобразовать.
В качестве другого примера того, почему я должен проверять перед преобразованием, я использую MongoDB Document Manager для преобразования "Issue mongo id" в проблему (форма используется сервером REST API, поэтому я получаю идентификатор), Итак:
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;
}
Здесь, если идентификатор, который я получаю в моей форме API, не сформирован как правильный MongoID, клиент получит 500. Поэтому я хочу проверить, перед преобразованием, если полученный идентификатор верен, потому что если это не так, фатальная ошибка. И если я управляю всеми случаями в моем преобразовании, например, проверяя, является ли $id правильным, это похоже на то, что я делаю валидацию в трансформаторе, и это неверно.
Мой вопрос: есть ли способ применить ограничения перед преобразованием данных? или есть ли способ добавить ограничение сложения в форму при неудачной трансформации?
Ответы
Ответ 1
Это похоже на обходной путь, однако я предлагаю написать класс, который представляет "недопустимую проблему", чтобы персонализировать ошибку.
class InvalidIssue extends Issue
{
public $message = 'This issue is invalid';
public function __construct($message = null)
{
if (null !== $message) {
$this->message = $message;
}
}
}
и в преобразователе, если данное значение недопустимо, вместо объекта исключения возвращается объект InvalidIssue
.
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;
}
Затем добавьте валидатор на вашу модель.
/** 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());
}
}
}