title: Recover password
body: <p>I'm trying to add the ability for users to recover their passwords by sending them an email with a link to a page where they can change their password. I added a new table called recover in the database with the fields id, user_id, key and created and when they enter an email to the account they want to recover the password from I add a row in the recover table. Then I send an email to the entered email with a link to a page where they should enter a new password.</p>
  
  <p>My question is why won't the row in the recover table get deleted even though the password is changed?</p>
  
  <p>This is the code I have:</p>
  
  <p><strong>recover.php:</strong></p>
  
  <pre><code>&lt;?php
  require_once 'core/init.php';
  
  $user = new User();
  if ($user-&gt;isLoggedIn()) {
      Redirect::to('index.php');
  }
  
  if (isset($_GET['success']) === true &amp;&amp; empty($_GET['success']) === true) {
  ?&gt;
      &lt;!-- Create your message --&gt;
      &lt;p&gt;We've emailed you&lt;/p&gt;
  &lt;?php
  } else if (isset($_GET['key']) === true &amp;&amp; empty($_GET['key']) === false) {
  
      $key = $_GET['key'];
      $userInfo = $user-&gt;get_user_by_key($key);
  
      if (!$userInfo) {
          echo 'user not found';
          //prompt to resend link
      } else {
          //display change password form
          //session_start();
          $_SESSION['user_id'] = $userInfo['user_id'];
          $_SESSION['key'] = $key;
  ?&gt;
          &lt;div class="page-content"&gt;
  
              &lt;form action="" method="post"&gt;
                  &lt;h1&gt;Change password&lt;/h1&gt;
                  &lt;div class="inset"&gt;
                  &lt;?php
                  if (Input::exists()) {
                      if (Token::check(Input::get('token'))) {
  
                          $validate = new Validate();
                          $validation = $validate-&gt;check($_POST, array(
                              'password' =&gt; array(
                                  'alias' =&gt; 'Password',
                                  'required' =&gt; true,
                                  'min' =&gt; 6
                              ),
                              'password_again' =&gt; array(
                                  'alias' =&gt; 'Password confirmation', // &lt;--- using the alias
                                  'required' =&gt; true,
                                  'min' =&gt; 6,
                                  'matches' =&gt; 'password'
                              )
                          ));
  
                          if ($validation-&gt;passed()) {
  
                              $salt = Hash::salt(100);
  
                              session_start();
                              if(isset($_POST['password'], 
                                       $_POST['password_again'], 
                                       $_SESSION['user_id'], 
                                       $_SESSION['key'])){
  
                                  if ($_POST['password'] === $_POST['password_again']) {
                                      //password should be hashed
                                      $password = Hash::make(Input::get('password'), $salt);
                                      $success = $user-&gt;update_user_password($password, $salt, $_SESSION['user_id']);
  
                                      if ($success) {
                                          $user-&gt;delete_key($_SESSION['key']);
                                      } else {
                                          //failed to update password
                                      }
                                  } else {
                                      echo 'Password not matching';
                                  }
                              }
  
                              Session::flash('home', 'Your password has been changed');
                              Redirect::to('index.php');
  
  
                          } else {
                              foreach ($validation-&gt;errors() as $error) {
                                  echo '&lt;i class="fa fa-exclamation-triangle"&gt;&lt;/i&gt;&amp;nbsp;&amp;nbsp;', $error, '&lt;br&gt;';
                                  echo '&lt;br /&gt;';
                              }
                          }
                      }
                  }
                  ?&gt;
  
                  &lt;p&gt;
                      &lt;label for="password"&gt;PASSWORD&lt;/label&gt;
                      &lt;input type="password" name="password" id="password" required&gt;
                  &lt;/p&gt;
                  &lt;p&gt;
                      &lt;label for="password_again"&gt;CONFIRM PASSWORD&lt;/label&gt;
                      &lt;input type="password" name="password_again" id="password_again" required&gt;
                  &lt;/p&gt;
                  &lt;/div&gt;
  
                  &lt;input type="hidden" name="token" value="&lt;?php echo Token::generate(); ?&gt;"&gt;
                  &lt;p class="p-container"&gt;
                      &lt;input type="submit" name="go" id="go" value="Change password"&gt;
                  &lt;/p&gt;
  
              &lt;/form&gt;
          &lt;/div&gt;
  &lt;?php   
      }
  
  } else {
  
      $mode_allowed = array('username', 'password');
  
      if (isset($_GET['mode']) === true &amp;&amp; in_array($_GET['mode'], $mode_allowed) === true) {
          if (isset($_POST['email']) === true &amp;&amp; empty($_POST['email']) === false) {
              $email = Input::get('email');
              $result = $user-&gt;emailExists($email);
  
              if (!$result) {
                  //Your custom error saying that that email does not exist
                  echo 'That email does not exist';
              } else {
                  $user-&gt;recover($_GET['mode'], $email);
                  Redirect::to('recover.php?success');
              }
          }
      ?&gt;
          &lt;form action="" method="post"&gt;
              &lt;ul&gt;
                  &lt;li&gt;
                      Please enter your email address:&lt;br&gt;
                      &lt;input type="text" name="email" placeholder="Enter Email"&gt;
                  &lt;/li&gt;
                  &lt;li&gt;&lt;input type="submit" class="sub-btn tx-shadow" value="Recover"&gt;&lt;/li&gt;
              &lt;/ul&gt;
          &lt;/form&gt;
  
      &lt;?php
      } else {
          Redirect::to('index.php');
      }
  }
  </code></pre>
  
  <p><strong>The classes in User.php:</strong></p>
  
  <pre><code>    public function emailExists($email){
      $sql = "SELECT *
              FROM `users`
              WHERE `email` = ?
      ";
      $data =  $this-&gt;_db-&gt;query_single($sql, array($email));
      return $data;
  }
  public function recover($mode, $email) {
  
      //Get data of user
      $user_data = $this-&gt;getUserByEmail($email);
      // Email User
  
      if ($mode == 'username') {
          $this-&gt;sendActivation($email, 'Your Username', 'Hello'.$user_data['username']. '\n\nYour username is: '.$user_data['username'].'\n\nThank you\nBusarna');
      } else if ($mode == 'password') {
          $key = substr(sha1(rand(999, 999999)), 0, 10);
          //update password
          $this-&gt;_db-&gt;insert('recover', array(
              'user_id' =&gt; $user_data['id'],
              'key' =&gt; $key,
              'created' =&gt; date('Y-m-d H:i:s')
          ));
          //email user password link
          $this-&gt;sendActivation($email, 'Your Password', 'Hello'.$user_data['username']. '\n\nClick &lt;a href="localhost/website/recover.php?key='.$key.'"&gt;here&lt;/a&gt; to change your password\n\nThank you\nBusarna');
      }
  }
  
  public function getUserByEmail($email) {
      $sql = "SELECT *
              FROM `users`
              WHERE `email` = ?
              ";
  
      $result = $this-&gt;_db-&gt;query_single($sql, array($email));
  
      return $result;
  }
  
  public function get_user_by_key($key) {
      $sql = "SELECT *
              FROM `recover`
              WHERE `key` = ?
              ";
  
      $result = $this-&gt;_db-&gt;query_single($sql, array($key));
  
      return $result;
  }
  
  public function delete_key($key) {
      $sql = "DELETE
              FROM `recover`
              WHERE `key` = ?
              ";
      //replace with your delete function
      $result = $this-&gt;_db-&gt;query_single($sql, array($key));
  
      return $result;
  }
  
  
  public function update_user_password($password, $salt, $user_id) {
      $sql = "UPDATE users
              SET `password`= ?,
                  `salt` = ?
              WHERE `id`= ?";
      //replace with your update function
      $result = $this-&gt;_db-&gt;query_single($sql, array($password, $salt, $user_id));
  
      return $result;
  }
  </code></pre>
  
  <p><strong>The two different query functions:</strong></p>
  
  <pre><code>public function query($sql, $params = array()) {
      $this-&gt;_error = false;
      if($this-&gt;_query = $this-&gt;_pdo-&gt;prepare($sql)) {
          $x = 1;
          if(count($params)) {
              foreach ($params as $param) {
                  $this-&gt;_query-&gt;bindValue($x, $param);
                  $x++;
              }
          }
  
          if ($this-&gt;_query-&gt;execute()) {
              $this-&gt;_results = $this-&gt;_query-&gt;fetchAll(PDO::FETCH_OBJ);
              $this-&gt;_count = $this-&gt;_query-&gt;rowCount();
          } else {
              $this-&gt;_error = true;
          }
      }
  
      return $this;
  }
  
  public function query_single($sql, $params = array()) {
      $this-&gt;_error = false;
      if($this-&gt;_query = $this-&gt;_pdo-&gt;prepare($sql)) {
          $x = 1;
          if(count($params)) {
              foreach ($params as $param) {
                  $this-&gt;_query-&gt;bindValue($x, $param);
                  $x++;
              }
          }
  
          if ($this-&gt;_query-&gt;execute()) {
              $this-&gt;_results = $this-&gt;_query-&gt;fetch(PDO::FETCH_ASSOC);
              $this-&gt;_count = $this-&gt;_query-&gt;rowCount();
          } else {
              $this-&gt;_error = true;
          }
      }
  
      return $this-&gt;_results;
  }
  </code></pre>
  
  <p>If you guys need anything else to help me just let me know.</p>
  
  <p>Does anyone know how I should continue? All help appreciated.</p>
  
  <p>Thanks in advance,</p>
  
  <p>Busarna</p>