2016-07-28 21 views
1

Symfonyフォームのエラーを直列化できる多次元配列に変換するメソッドを構築しようとしています。Symfonyフォームの子を再帰的にループ

現在、私はフォーム内のフォーム(フィールドセットタイプ)のみを持っています。フォーム内にN個のフォームを埋め込むための新しいシステムを作成しました。私は、$errors配列に移入するためにエラーが発生したすべての子をトラバースできる必要があります。

私は奥行きや移動距離を把握する必要があります。

たとえば、フォーム内のフォームは$errors[depth1][depth2]['message']となります。複数の埋め込みフォーム(例えば5まで)を持つフォームは、$errors[depth1][depth2][depth3][depth4][depth5]['message']$errors[depth1][depth2] e.t.cです。

NB:[depth(N)]は、現在のフォーム名に置き換えられます。

これを行う最もクリーンな方法は何ですか。

これはフィールドセットを取得する私の現在の機能ですが、深度に関係なくエラーを受け取り、位置(キー)をそのまま維持できるようにするために使用しましたか?任意の助けをいただければ幸いです:)

+0

private static function getFieldErrorsRecursively(Form $form, &$errors, $position = []) { foreach ($form as $child) { $fieldsArray = $child->getConfig()->getOptions()['fields'] ?? []; if (count($fieldsArray) === 0) { if (!$child->isValid()) { foreach ($child->getErrors() as $error) { $errors[$child->getName()]['message'] = $error->getMessage(); $errors[$child->getName()]['messageTemplate'] = $error->getMessageTemplate(); $errors[$child->getName()]['messagePluralization'] = $error->getMessagePluralization(); $errors[$child->getName()]['messageParameters'] = $error->getMessageParameters(); $errors[$child->getName()]['cause'] = $errors[$child->getName()]; if ($errorCause = $error->getCause()) { $errors[$child->getName()]['cause']['plural'] = $errorCause->getPlural(); $errors[$child->getName()]['cause']['propertyPath'] = $errorCause->getPropertyPath(); $errors[$child->getName()]['cause']['invalidValue'] = $errorCause->getInvalidValue(); $errors[$child->getName()]['cause']['constraint'] = serialize($errorCause->getConstraint()); $errors[$child->getName()]['cause']['code'] = $errorCause->getCode(); $errors[$child->getName()]['cause']['cause'] = $errorCause->getCause(); } } return true; } } elseif (count($fieldsArray) > 0) { self::getFieldErrorsRecursively($child, $errors, $child->getName()); if (count($errors) > 0) { return true; } return true; } } return false; } 

(追跡すること)しないでください:

private static function getFieldSetErrors(Form $form, &$errors) { foreach ($form->all() as $formField) { if ($formField->getConfig()->getType()->getInnerType() instanceof FieldsetComponentType) { // ...then loop over the fields to extract any errors. foreach ($formField as $element) { foreach ($element->getErrors() as $error) { $errors[$formField->getName()][$element->getName()]['message'] = $error->getMessage(); $errors[$formField->getName()][$element->getName()]['messageTemplate'] = $error->getMessageTemplate(); $errors[$formField->getName()][$element->getName()]['messagePluralization'] = $error->getMessagePluralization(); $errors[$formField->getName()][$element->getName()]['messageParameters'] = $error->getMessageParameters(); $errors[$formField->getName()][$element->getName()]['cause'] = $errors[$formField->getName()][$element->getName()]; if ($errorCause = $error->getCause()) { $errors[$formField->getName()][$element->getName()]['cause']['plural'] = $errorCause->getPlural(); $errors[$formField->getName()][$element->getName()]['cause']['propertyPath'] = $errorCause->getPropertyPath(); $errors[$formField->getName()][$element->getName()]['cause']['invalidValue'] = $errorCause->getInvalidValue(); $errors[$formField->getName()][$element->getName()]['cause']['constraint'] = serialize($errorCause->getConstraint()); $errors[$formField->getName()][$element->getName()]['cause']['code'] = $errorCause->getCode(); $errors[$formField->getName()][$element->getName()]['cause']['cause'] = $errorCause->getCause(); } } } } } } 

それは次のように見えるかもしれません。配列で呼び出され、ネストされた配列で自身を呼び出す再帰関数を構築します。参照渡しの場合は、常に '$ errors ['cause'] .. 'を使用することができます。 – kero

+0

私は位置を追跡しなければならないと思いますが、それらを再び適用するときに発生します。エラーを元のフィールドに戻すときに使用します。 – Kal

+0

元の原因フィールドと一致するフィールドを検索するだけでそれらを適用すると、追跡する必要はありませんか? – Kal

答えて

1

Symfony provides a function for this

// a FormErrorIterator instance representing the form tree structure 
$errors = $form->getErrors(true, false); 
+0

それは確かにコードを整えて美しいです。私はクロージャが含まれているので、あなたはその関数の出力をシリアル化できないので、私はまだ何かを再帰的に書く必要があると思います。 – Kal

関連する問題