表单字段在没有内容的情况下提交时无法验证

时间:2018-08-22 13:01:22

标签: php symfony symfony-forms symfony-validator

我有用于编辑元素的api端点。

我发送的请求没有字段'sortOrder',所以我的表单从以前的记录状态获取此值而没有进行任何验证。

这是我的实体

use App\Validator\Constraints\SortOrderConsecutive;

class SurveyElement
{
    private $id
    private $survey;
    private $libraryElement;
    private $parent;
    /**
     *
     * @SortOrderConsecutive
    */
    private $sortOrder
}

我的FormType:SurveyElementType

class SurveyElementType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         $builder
           ->add('survey')
           ->add('libraryElement')
           ->add('parent')
           ->add('sortOrder', IntegerType::class);
    }
}

验证:

class SortOrderConsecutiveValidator extends ConstraintValidator
{
    /**
     * @param mixed $value
     * @param Constraint $constraint
     */
    public function validate($value, Constraint $constraint)
    {
        /** @var SurveyElement $surveyElement */
        $surveyElement = $this->context->getObject();
        if ($surveyElement->getParent()) {
          $sortOrderList = new ArrayCollection();
          $surveyElement->getParent()->getChildren()->map($this->prepareSortOrderArray($sortOrderList));
          $this->checkForViolations($sortOrderList, $value);
        }

     private function prepareSortOrderArray(ArrayCollection $sortOrderList)
     {
        return function (SurveyElement $element) use ($sortOrderList) {
        $sortOrderList->add($element->getSortOrder());
        };
     }

      private function checkForViolations(ArrayCollection $sortOrderList, int $value)
      {
          if ((sizeof($sortOrderList)) < $value) {
              $this->context->buildViolation('Items must be consecutive')->addViolation();
          }
      }
}

和控制器:

public function editAction(int $id, Request $request): Response
{
    $surveyElement = $this->entityManager->getRepository(SurveyElement::class)->findOneBy(['id' => $id]);
    $oldSurveyElementState = clone $surveyElement;
    $previousSortOrder = $surveyElement->getSortOrder();
    $form = $this->formFactory->create(SurveyElementType::class, $surveyElement);
    $form->submit(json_decode($request->getContent(), true), false);
    if ($form->isValid()) {
        $this->surveyElementHelper->editElementsOrder($surveyElement, $previousSortOrder, $oldSurveyElementState);
    } else {
        return $this->errorResponse($form->getErrors(true));
    }
    $this->entityManager->refresh($surveyElement->getSurvey());
    $tree = $this->surveyElementsTreeBuilder->getTree($surveyElement->getSurvey()->getSurveyElements());
    $context = new SerializationContext();
    $context->setGroups(["tree"]);
    return new Response($this->serializer->serialize($tree, 'json', $context));
}

我正在使用JSON在此端点PATCH上发送

{
  "sortOrder": 1
  "libraryElement": 1,
  "parent": 1
}

此时一切正常。但是,当我错过sortOrder时会发生什么?

让我们假设我已经在数据库中记录了

id: 2
libraryElement: 1
parent: 2
sortOrder: 3

我想用json请求对其进行编辑:

url:127.0.1.1/survey_element/2

{
  libraryElement: 1
  parent: 1
}

我的父母1只有1个元素,因此违反了sortOrderConsecutive约束;

我假设is_valid方法将返回false。 但事实并非如此。我猜这很好。因为我为什么必须验证未更改的数据。好吧,我必须。要检查其他父组中的排序顺序是否连续。但是因为没有提交“ sortOrder”字段,所以我的验证器忽略了我的约束。

我现在可以使用ValidatorInterface通过

来验证记录
$validator->validate(form->getData)

但这似乎不对。

我只希望始终将某些数据设置为表单字段“ sortOrder”。因此,当我提交不带sortOrder的请求时,我的表单将拒绝它。但是该怎么做?

0 个答案:

没有答案