在Symfony形式的孩子上递归循环

时间:2016-07-28 15:23:53

标签: php recursion symfony symfony-forms

我正在尝试构建一个方法将Symfony表单错误转换为可以序列化的多维数组。

目前我只在表单中有一个表单(字段集类型)。我已经创建了一个新的系统,用于在表单中嵌入N个表单。我需要能够遍历所有有错误的孩子来填充$errors数组。

我需要跟踪深度或我走过的距离。

例如,表单中的表单为$errors[depth1][depth2]['message']。包含多个嵌入表单(最多5个)的表单将为$errors[depth1][depth2][depth3][depth4][depth5]['message'] $errors[depth1][depth2] e.t.c。

NB: [depth(N)]将替换为当前的表单名称。

最干净的方法是什么。

这是我的当前函数,它获取了字段集但是我能够在不考虑深度的情况下获得任何错误并保持位置(键)完好无损?

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();
                        }
                    }
                }
            }
        }
    }

它可能看起来像:

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;
    }

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:1)

Symfony provides a function for this

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