Symfony 4 Validator - автоматический выход из строя, если он недействителен - PullRequest
0 голосов
/ 03 ноября 2018

Я хотел проверить свой пользовательский объект ($ user) с помощью Symfony Validator и вернуть JsonResponse ($ response), если входные данные формы верны / недействительны. Но у меня есть проблема, когда я выхожу из системы автоматически, когда данные не могут быть проверены. Я должен снова войти в систему, и это не то поведение, которое я ожидаю, когда некоторые данные не являются действительными. Я нашел обходной путь (см. Комментарии ниже), но это не очень удовлетворяет: /

Вот метод моего контроллера:

 /**
 * Update user profile data
 *
 * @Route("/api/users/updateprofile")
 * @Security("is_granted('USERS_LIST')")
 */

public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
{
    $request = Request::createFromGlobals();
    // Prepare Response
    $response = new JsonResponse();
    $response->setData([]);
    /** @var User $user */
    $user = $this->getUser();
    $oldName = $user->getName();
    $oldEmail = $user->getEmail();

    $user->setName($request->request->get('name'));
    $user->setEmail($request->request->get('email'));

    $errors = $validator->validate($user);
    if (count($errors) > 0) { // if this -> auto logout
        $user->setName($oldName); // if I set the both attributes back to the old value
        $user->setEmail($oldEmail); // then I don't get logged out automatically but this is just a workaround and not satisfying
        $entityManager = $this->getDoctrine()->getManager(); // forgot to remove this
        $entityManager->persist($user); // and this line, this is actually deleted in the real code

        foreach ($errors as $error) {
            $errorMessage = $error->getMessage();
            $errorField = $error->getPropertyPath();
            $flashMessageBuilder->addErrorMessage($errorMessage, $errorField);
        };

        return $response;
    }

    $entityManager = $this->getDoctrine()->getManager();
    $entityManager->persist($user);
    $entityManager->flush();

    $flashMessageBuilder->addSuccessMessage("Success!");
    return $response;
}

Извините за мой плохой английский и заранее спасибо!

1 Ответ

0 голосов
/ 03 ноября 2018

Вы сохраняете пользовательский объект, даже если в процессе проверки есть ошибки, которые могут вызвать проблемы с выходом из системы.

Попробуйте обновить ТОЛЬКО в случае отсутствия ошибки проверки:

public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
{
    $request = Request::createFromGlobals();

    // Prepare Response
    $response = new JsonResponse();
    $response->setData([]);

    /** @var User $user */
    $user = $this->getUser();

    $user->setName($request->request->get('name'));
    $user->setEmail($request->request->get('email'));

    $errors = $validator->validate($user);
    if (count($errors) == 0) {
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($user);
        $entityManager->flush();

        $flashMessageBuilder->addSuccessMessage("Success!");
        return $response;
    }

    foreach ($errors as $error) {
        $errorMessage = $error->getMessage();
        $errorField = $error->getPropertyPath();
        $flashMessageBuilder->addErrorMessage($errorMessage, $errorField);
    };

    return $response;
}

Но я думаю, что вам не следует смешивать вызовы API и классический подход к формам, использующий FlashMessages, вместо этого возвращать правильный результат JSON.

Итак, рассмотрите возможность изменения кода соответствующим образом:

public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
{
    $request = Request::createFromGlobals();

    /** @var User $user */
    $user = $this->getUser();

    $user->setName($request->request->get('name'));
    $user->setEmail($request->request->get('email'));

    $errors = $validator->validate($user);
    if (count($errors) == 0) {
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($user);
        $entityManager->flush();

        return new JsonResponse(['success' => true]);
    }

    $data = [];
    foreach ($errors as $error) {
        $data[$error->getPropertyPath()] = $error->getMessage();
    };

    return new JsonResponse(['success' => false, 'errors' => $data], 400);
}

Теперь ваш вызывающий код может обрабатывать результат 200 (успех) и случай ошибки с кодом состояния 400 и отображать сообщения об ошибках для всех ошибочных полей из части errors в теле результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...