Отмена самого старого raw в БД после вызова метода findAll()

#symfony #doctrine

#symfony #доктрина

Вопрос:

У меня есть таблица для запросов пользователей на восстановление паролей. Это его столбцы:

  • ID
  • idUser
  • Дата создания
  • Срок действия
  • токен
  • Истекло

Если пользователь пытается сделать несколько запросов, я хочу найти все строки с его идентификатором, и если они> 1, установите их isExpired = true равными . При этом я хочу считать действительным только последний запрос.

Как я могу этого добиться?

Вот как я это делаю сейчас, предполагая, что в таблице есть только одна строка с его идентификатором:

 if ($request->isMethod('POST')) {

    $form->handleRequest($request);
    $newPassword = $form->get('password')->getData();

    $currentToken = $request->query->get('token'); 

    $em = $this->getDoctrine()->getManager();
    $passwRecovery = $em->getRepository('UserBundleEntityPasswordRecovery')->findOneBy(array('token' => $currentToken));

    if (empty($passwRecovery)) {

        return new Response ("<h3>Access denied!</h3>");
    }

    else {

    if (new DateTime('now') > $passwRecovery->getExpireDate())
    {

        return new Response ("<h3>Token expired!</h3>");
    }

    $idUser = $passwRecovery->getIdUser();

    $userRecoverPassw = $em->getRepository('UserBundleEntityUser')->findOneBy(array('id' => $idUser));

    $userRecoverPassw->setPassword($newPassword);

    $em->persist($userRecoverPassw);
    $em->flush();

    return new Response ("<h3>Password reset ok!</h3>"); }
  

Учтите, что у меня есть 3 строки с одним и тем же идентификатором пользователя, если я использую:

     $passwRecovery = $em->getRepository('UserBundleEntityPasswordRecovery')
    ->findAll(array('token' => $currentToken));
  

Я получу 3 результата. Как я могу установить значение isExpired = true only для первых двух?

Спасибо!

Комментарии:

1. Почему бы просто не устанавливать значение isExpired true каждый раз, когда вы добавляете новую строку восстановления пароля? Также кажется странным, что вы используете один и тот же токен для каждой строки.

2. Я не хочу использовать один и тот же токен более одного раза. Токен уникален и генерируется для каждого отдельного запроса. Я создал столбец IsExpired, чтобы отслеживать все восстановления пароля пользователя, но в то же время я хочу, чтобы действительным был только последний запрос, сделанный пользователем.

3. Если токен уникален, то как findAll в конце вашего вопроса может возвращать более одной записи? И если каждый раз, когда вы добавляете новую запись восстановления, у вас истекает срок действия всех предыдущих записей для этого пользователя, тогда, похоже, ваши требования будут выполнены.

4. Метод findAll() в конце моего вопроса будет искать все одинаковые idUser . Это процесс: пользователь получает электронное письмо с прикрепленным токеном. Он нажимает на ссылку, затем программа ищет этот токен в БД, чтобы проверить, действителен ли он. Если токен находится в БД, то программа получит имя idUser этого пользователя и выполнит поиск других активных запросов. Если есть какие-то запросы, программа их удалит.

5. Я добавил решение

Ответ №1:

Это решение, которое в конце сработало для меня, надеюсь, это поможет. Если есть какие-либо лучшие способы сделать то, что я публикую здесь, я открыт для предложений.

 public function resetPasswordAction(Request $request) {

    $form = $this->createFormBuilder()

    ->add('password', 'password')

    ->add('save', 'submit', ['label' => 'Send'])

    ->getForm();

    if ($request->isMethod('POST')) {

    $form->handleRequest($request);
    $newPassword = $form->get('password')->getData();

    $currentToken = $request->query->get('token'); 

    $em = $this->getDoctrine()->getManager();

    $passwRecoveryObject = $em->getRepository('UserBundleEntityPasswordRecovery')->findOneBy(array('token' => $currentToken));

    if (empty($passwRecoveryObject)) {   

        return new Response ("Impossible to execute the request!");
    }

    else {

    if (new DateTime('now') > $passwRecoveryObject->getExpireDate()) 
    {

        return new Response ("Token expired!");
    }

    $idUser = $passwRecoveryObject->getIdUser()->getId(); 


    $userRecoverPassw = $em->getRepository('UserBundleEntityPasswordRecovery')->findBy(array('idUser' => $idUser)); 

    $end = end($userRecoverPassw);  //$end is the last record of the password_recovery table
    $count = count($userRecoverPassw); //count of the rows in password_recovery with the id of the current User


    foreach ($userRecoverPassw as $element) { //here i'm setting to 1 the isExpired column for all the rows with the same id, except for the last one

        if (--$count <= 0) {
        break; }

        $element->setIsExpired(1);
        $em->persist($element);
        $em->flush(); 

    }

    $userResetPassw = $em->getRepository('UserBundleEntityUser')->findOneBy(array('id' => $end->getIdUser()->getId()));  //User that need to reset the password

    if ($end->getIsExpired()==0) {

    $userResetPassw->setPassword($newPassword);
    $end->setIsExpired(1);

    $em->persist($userResetPassw);
    $em->flush(); 

    $em->persist($end);
    $em->flush(); 

    return new Response ("Password succesfully updated!");
    }

    else { return new Response ("Expired link!");}

} }



    return $this->render('UserBundle:AccountUser:reset_password.html.php', array(
        'form' => $form->createView(),));


}