2017-12-18 9 views
1

ConstraintViolationListInterfaceのオブジェクトを1つの例外に変換する必要があります。これは、検証が失敗したときにメッセージがリスト上の各制約違反からのメッセージを連結したものです。SymfonyのConstraintViolationListInterfaceから

これを達成するために検証を使用してすべてのバンドルでforeachループを繰り返すことはできません。したがって、ConstraintViolationListInterfaceを受け入れて単一の例外を返す単純なサービスを提供するバンドルをもう1つ作成することを考えました。 Symfonyに標準的なソリューションがありますか?私はこのサービスを書く必要があることが奇妙に見えますが、問題は私にとって共通のようです。

答えて

1

私も、symfonyは私が私のカスタム例外を作成した理由です、このために役立つものを持っていないことに驚きました。

class ValidationException extends \Exception 
{ 
    private $violations; 

    public function __construct(array $violations) 
    { 
     $this->violations = $violations; 
     parent::__construct('Validation failed.'); 
    } 

    public function getMessages() 
    { 
     $messages = []; 
     foreach ($this->violations as $paramName => $violationList) { 
      foreach ($violationList as $violation) { 
       $messages[$paramName][] = $violation->getMessage(); 
      } 
     } 
     return $messages; 
    } 

    public function getJoinedMessages() 
    { 
     $messages = []; 
     foreach ($this->violations as $paramName => $violationList) { 
      foreach ($violationList as $violation) { 
       $messages[$paramName][] = $violation->getMessage(); 
      } 
      $messages[$paramName] = implode(' ', $messages[$paramName]); 
     } 
     return $messages; 
    } 
} 

here可能なすべてのコードを。

そして、私は次の方法でこの例外を使用します。

try { 
    $errors = $validator->validate(...); 
    if (0 !== count($errors)) { 
     throw new ValidationException($errors); 
    } 
} catch (ValidationException $e) { 
    // Here you can obtain your validation errors. 
    var_dump($e->getMessages()); 
} 
+0

質問はちょうどカスタム例外を作成するに関連するか、正しく違反を検出した後にスローされた例外を処理する方法に関連していましたの? @Sergey –

0

たぶん、あなたはこのようにConstraintViolationsEventを作成することができます。そして、あなたは、このイベントのリスナーを作成することができ、そしてこのリスナーの内側に、あなたがたすべての違反に基づいて例外を作成

namespace AppBundle\Event; 

use Symfony\Component\EventDispatcher\Event; 
use Symfony\Component\Validator\ConstraintViolationListInterface; 

/** 
* The order.placed event is dispatched each time an order is created 
* in the system. 
*/ 
class ConstraintViolationsEvent extends Event 
{ 
    const VIOLATIONS_DETECTED = 'constraint_violations.detected'; 

    protected $constraintViolationList; 

    public function __construct(ConstraintViolationListInterface $constraintViolationList) 
    { 
     $this->constraintViolationList = $constraintViolationList; 
    } 

    public function getConstraintViolationList() 
    { 
     return $this->constraintViolationList; 
    } 
} 

。あなたが違反を見つけるたびに、ちょうどこのようなあなたのコントローラ内のあなたのイベントをディスパッチ:

class MyController extends Controller 
{ 
    public function myFormAction(Request $request) 
    { 
     /** handle the request, get the form data, validate the form...etc. **/ 
     $event = new ConstraintViolationsEvent($constraintViolationList); 
     $dispatcher->dispatch(ConstraintViolationsEvent::VIOLATIONS_DETECTED, $event); 
    } 
} 

は、実際には、あなたがサービス中にあなたの例外の作成を管理し、リスナーでサービスを呼び出すことができます。それはあなた次第です。

関連する問題