Location: PHPKode > scripts > User Register Login Online script > users/class.Logare.php
<?php
// Logare class Logare
class Logare {
  // properties
  protected $conn = false;           // store the connection to mysql
  protected $conn_datas = array();    // will contain the data for connecting to mysql
  protected $sid;                   // for the session ID
  protected $nr_logs = 1;            // for the current number of login attempts
  public $users = array();           // will store the total users, last registered, and online users
  protected $eror = false;          // to store the errors
  protected $ip;                    // for the user IP (the IP saved in cookie or the current IP)
  public $dir = 'users/';          // the directory that contains the classes for this script
  protected $file_log = 'index.php';   // the file in which the instances of the classes are created
  public $logat = '';               // stores the login form or the "Welcome" message
  public $js = '';                 // for the code that include the file with JavaScript functions

  // constructor
  public function __construct($conn_datas) {
    // daca parametrul e array
    if(is_array($conn_datas)) {
      $this->conn_datas = $conn_datas;        // add data from parameter in 'conn_datas' property
      $this->sid = session_id();             // add the session ID in $sid property

      // define the $js property
      $this->js = '<script src="'. $this->dir. 'logare.js" type="text/javascript"></script>';

      // if no $_POST['ajax'], define the login form in "logat" property
      if(!isset($_POST['ajax'])) $this->logat = '<form action="" method="post" id="log_form"> Name: &nbsp; &nbsp; &nbsp; <input type="text" name="nume" id="nume" size="12" maxlength="30" /> &nbsp; <input type="submit" name="login"  class="submit" value="Login" /><br /> Password: <input type="password" name="pass" id="pass" size="11" maxlength="30" /> <label for="rem" id="lrem"><input type="checkbox" name="rem" id="rem" />Remember</label><br/><br/>
  <a href="'. $this->dir.$this->file_log. '?rc=Recover" title="Recover data" id="recdat">Recover data</a>
  <span id="log_reg"><a href="'. $this->dir.$this->file_log. '?submit=Register" title="Register" id="linkreg">Register</a></span></form>'.$this->js;

      // if $_COOKIE['ip'] exists, get the IP from cookie, else, get the current IP and save it in cookie
      if(isset($_COOKIE['ip'])) $this->ip = $_COOKIE['ip'];
      else {
        $this->ip = $_SERVER['REMOTE_ADDR'];
        setcookie("ip", $this->ip, time()+60*60*24*100, "/");
      }

      $this->setConn();       // calls setConn() method (that sets the mysql connection)

      // if the connection to database is set ('conn' property isn't false)
      if($this->conn!==false) {
        // if there is data from the login form, calls the getLogin() method
        if(isset($_POST['login']) && isset($_POST['nume']) && isset($_POST['pass'])) {
          $_POST = array_map("trim", $_POST);        // removes whitespace from the beginning and end
          $this->getLogin($_POST);
        }
        // if request for logout ($_GET['lout']), calls logOut() method
        else if(isset($_GET['lout'])) $this->logOut();
        else $this->setLogat();        // else, calls setLogat() method that sets the $logat property

        if($this->nr_logs>1) $this->logOut(2);        // $nr_logs>1 means two logins with the same name. Logout the user
      }
    }
    else $this->eror = 'The argument for class instance must be an Array';

    // if $eror property isn't false, add it in $logat property
    if($this->eror!==false) $this->logat = '<div id="logeror">'.$this->eror. '</div>'. $this->logat;
  }

  // method that create the connection to mysql
  public function setConn() {
    // if the connection is successfully established
    if($conn = new mysqli($this->conn_datas['host'], $this->conn_datas['user'], $this->conn_datas['pass'], $this->conn_datas['bdname'])) {
      $sql = "SET NAMES 'utf8'";
      $conn->query($sql);
      $this->conn = $conn;          // add the connection in the $conn property
    }
    else if (mysqli_connect_errno()) $this->eror = 'MySQL connection failed: '. mysqli_connect_error();
    return $this->conn;
  }

  // method that sets the $logat property (the $sl is passed to the call of the userOn() method)
  private function setLogat($sl=0) {
    // If the user is stored in cookie, add the data in session
    if(isset($_COOKIE['cookname']) && isset($_COOKIE['cookpass'])) {
      $_SESSION['nume'] = $_COOKIE['cookname'];
      $_SESSION['parola'] = $_COOKIE['cookpass'];
    }

    // if the name and password are stored in session
    if(isset($_SESSION['nume']) && isset($_SESSION['parola'])) {
      // calls the confirmUser() method to confirm if the name and passord are valid
      if($this->confirmUser($_SESSION['nume'], $_SESSION['parola'])===0) {
        $this->logat = '<div id="logat">Welcome <b>'.$_SESSION['nume'].'<br />Click <a href="'.$this->dir.$this->file_log.'?usr='.$_SESSION['nume'].'" id="idpp">Personal page</a><br/><a href="'.$_SERVER['PHP_SELF'].'?lout=lo">LogOut</a></b></div>'.$this->js;
      }
      else {
        // else, the variables are incorrect, calls logOut() to delete the session and cookies
        $this->logOut(0);
        $this->logat = 'Incorrect data logging session';
      }
    }

    // calls the method that gets and adds total users, last and registered users in $users property
    $this->usersOn($sl);
  }

  // method for checking the existence of these characters (= , ` ' & % $ # = ^ * + ") in a string
  protected function checkStr($str) {
    $interzis = '/[=,`\'"#$%\^&\*\+]/';
    if(preg_match($interzis, $str)) return false;
    else return true;
  }

  // method that checks data from the login form (passed in parameter) and from the database
  private function getLogin($ar_post) {
    // check for not allowed character (= , ` ' & % $ # = ^ * + ")
    if(!$this->checkStr($ar_post['nume']) || !$this->checkStr($ar_post['pass'])) $this->eror = 'The data should not contain any of these characters: <b>= , ` \' & % $ # = ^ * + "</b>';

    // check the length of the name
    else if(strlen($ar_post['nume'])<3 || strlen($ar_post['nume'])>32) $this->eror = 'Name must be between 3 and 32 characters';

    // check the length of the password
    else if(strlen($ar_post['pass'])<7 || strlen($ar_post['pass'])>18) $this->eror = 'Password must be between 7 and 18 characters';
    else {
      // Check and register with userTemp() method the log in attempt
      $continua = $this->userTemp($ar_post['nume']);

      if($continua==='continue') {
        $md5pass = md5($ar_post['pass']);    // encript the password
        $re = $this->confirmUser($ar_post['nume'], $md5pass);      // uses confirmUser() to check if name and password are correct

        // sets 'eror' if name or password are incorrect
        if($re===1) $this->eror = 'The name <b>'. stripslashes($ar_post['nume']). '</b> not registered';
        else if($re===2) $this->eror = 'Incorrect password';
        else if($re===3) {
          exit('<center><h4 style="color:red">Registration for <u>'. stripslashes($ar_post['nume']). '</u> is unconfirmed.</h4>Check your e-mail used for registration (including in Spamm directory), for the message with the confirmation link.<br /><br />If you wish to request a new confirmation e-mail <a href="'.$this->dir.$this->file_log.'?rc=Confirm">Click here</a></center>');
        }
        else {
          // user name and password are correct
          // if the "Remember" checkbox is checked, sets 2 cookies, for name and password (expires in 100 days)
          if(isset($ar_post['rem'])) {
            setcookie("cookname", $_SESSION['nume'], time()+60*60*24*100, "/");
            setcookie("cookpass", $_SESSION['parola'], time()+60*60*24*100, "/");
          }

          // UPDATE `ip_visit` with the user's IP, and the `visits` number
          $sql = "UPDATE `users` SET `ip_visit`='$this->ip', `visits`=`visits`+1 WHERE `nume`='". $_SESSION['nume']. "' LIMIT 1";
          $this->conn->query($sql);

          $this->setLogat(1);        // calls the method that sets $logat property
        }
      }
      else {
        // Sets a message with the remaining time to a new allowed authentication attempt
        $continua = floor($continua/60). ' minute, '. ($continua%60). ' secunde';
        $this->eror = 'Exceeding number of login attempts.<br/>You can retry after:<br /><b>'. $continua. '</b>';
      }
    }
  }
 
  // this method checks the name and password in the database,
  // if they are correct returns 0, otherwise 1 or 2, indicating the error
  private function confirmUser($nume, $parola) {
    // apply real_escape_string() to filter data
    $nume_db = $this->conn->real_escape_string($nume);

    // Check if the name is in the database
    $sql = "SELECT `id`, `parola`, `rank`, DATE_FORMAT(`datevisit`, '%M %D, %Y, %H:%i') AS datavisit FROM `users` WHERE `nume`='$nume_db' LIMIT 1";
    $result = $this->conn->query($sql);
    if(!$result || $result->num_rows<1) return 1;         // Indicates name not confirmed
    else {
       // Find password that is associated with the name
      $dbarray = $result->fetch_assoc();
      $dbarray['parola']  = stripslashes($dbarray['parola']);
  
      // Check if the user is confirmed
      if ($dbarray['rank']==0) return 3;  // Registration has not been confirmed

      // if the password is the same as that found in the database
      else if($parola==$dbarray['parola']) {
        // adds in session name, parola, id, rank, and last-visit-date (if isn't added)
        $_SESSION['nume'] = $nume;
        $_SESSION['parola'] = $parola;
        $_SESSION['idusr'] = $dbarray['id'];
        $_SESSION['rank'] = $dbarray['rank'];
        if(!isset($_SESSION['datavisit'])) $_SESSION['datavisit'] = $dbarray['datavisit'];
        return 0;          // name and password confirmed
      }
      else return 2;    // indicating incorrect password
    }
  }

  // this method deletes rows in the 'user_temp' table, older than 10 minutes
  // if the user already tried 3 times to log in, blocks that name for 10 minutes
  private function userTemp($nume) {
    $dt = time();
    $timp_expir = $dt-601;

    // deletes rows in the 'user_temp' table, older than 10 minutes
    $sql = "DELETE FROM `user_temp` WHERE `dt`<$timp_expir";
    $this->conn->query($sql);

    $nume = $this->conn->real_escape_string($nume);     // Filter the name to add safe

    // add / increment number of attempt by 1, and updates the date-time
    $sql = "INSERT INTO `user_temp` (`nume`, `ip`, `dt`) VALUES ('$nume', '$this->ip', $dt) ON DUPLICATE KEY UPDATE `nri`=`nri`+1";
    $this->conn->query($sql);

    // check if it was performed UPDATE (existing names) [ mysql_affected_rows()=2]
    if($this->conn->affected_rows==2) {
      // select to get the number of attempts
      $sql = "SELECT `nume`, `nri`, `dt` FROM `user_temp` WHERE `nume`='$nume' LIMIT 1";
      $result = $this->conn->query($sql);

      if(!$result || $result->num_rows<1) return 'continue';
      else {
        // get the number of login attempts, 'nri'
        $tbarray = $result->fetch_assoc();
        $nri = $tbarray['nri'];
        if($nri<3) return 'continue';
        else {
          $timp = 600 - ($dt - $tbarray['dt']);
          return $timp;    // Indicates number of attempts exceeded, returns the number of seconds to wait
        }
      }
    }
    else return 'continue';         // otherwise, it was performed INSERT
  }

  // this method gets the total number of users, last registered user, and online users
  private function usersOn($sl) {
    $re = array('total'=>0, 'last'=>'', 'online'=>0);        // this array will be added in $users property
    $dt = time();
    $timp_expir = $dt-120;         // Current time minus 2 minutes

    // deletes rows in the 'useron' table, older than 2 minutes
    $sql = "DELETE FROM `useron` WHERE `dt`<$timp_expir";
    $this->conn->query($sql);

    // If the user is logged in, insert or update him in 'useron'
    if(isset($_SESSION['nume'])) {
      $nume = $this->conn->real_escape_string($_SESSION['nume']);     // Filter the name to add safe

      // add the users, or if already in the table, update date-time
      $upd_sid = ($sl==1) ? ", `sid`='$this->sid'" : '';       //if $sl is 1 (the user is logging) sets to update the SID too
      $sql = "INSERT INTO `useron` (`nume`, `sid`, `dt`) VALUES ('$nume', '$this->sid', $dt) ON DUPLICATE KEY UPDATE `dt`=$dt". $upd_sid;
      $this->conn->query($sql);
    }

    // select that gets the total number of users, last registered user, and online users
    $sql = "SELECT `useron`.`nume`, `useron`.`sid`, (SELECT count(*) FROM `users`) AS nrusers, (SELECT `nume` FROM `users` WHERE `rank`>0 ORDER BY `id` DESC LIMIT 1) AS last FROM `useron`";
    $result = $this->conn->query($sql);

    // if the select returns at least one row
    if($result->num_rows>0) {
      while ($rand = $result->fetch_assoc()) {
        $useron = stripslashes($rand['nume']);
        if($useron!==NULL) $numeon[] = '<a href="'.$this->dir.$this->file_log.'?usr='.$useron.'" title="'.$useron.'">'.$useron.'</a>';

        // if $_SESSION['nume'] exists and the SID from table is different from $sid, increment $nr_logs
        if(isset($_SESSION['nume'])) {
          if(strtolower($useron)==strtolower($_SESSION['nume']) && $rand['sid']!==$this->sid) $this->nr_logs++;
        }

        // adds the total number of users, last registered user, and online users in $nrusers property
        $re['total'] = $rand['nrusers'];
        $re['last'] = '<a href="'.$this->dir.$this->file_log.'?usr='.$rand['last'].'" title="'.$rand['last'].'">'.$rand['last'].'</a>';
        $re['online'] = implode('<br/>', $numeon);
      }
    }
    else {
      // if 0 returned rows, perform another Select for total users (when 'useron' is empty, the "nrusers" also returns 0)
      $sql = "SELECT `nume` AS last, (SELECT count(*) FROM `users`) AS nrusers FROM `users` WHERE `rank`>0 ORDER BY `id` DESC LIMIT 1";
      $result = $this->conn->query($sql);
      if($result->num_rows>0) {
        $rand = $result->fetch_assoc();
        $re['total'] = $rand['nrusers'];
        $re['last'] = '<a href="'.$this->dir.$this->file_log.'?usr='.$rand['last'].'" title="'.$rand['last'].'">'.$rand['last'].'</a>';
      }
    }

    $this->users = $re;          // adds in the $users property the array stored in $re
  }

  // the method for LogOut
  private function logOut($rd=1) {
    // if there are cookies for name and password, sets to remove them
    if(isset($_COOKIE['cookname']) && isset($_COOKIE['cookpass'])){
      setcookie("cookname", "", time()-60*60*24*100, "/");
      setcookie("cookpass", "", time()-60*60*24*100, "/");
    }

    // if $rd parameter different from 2, delete the user from the onlinwe-users
    if($rd!==2) {
      $sql = "DELETE FROM `useron` WHERE `nume`='".$_SESSION['nume']."'";
      $this->conn->query($sql);
    }

    // if exist sessions with: nume, parola, idusr, and datavisit, delete them, then perform redirect
    if(isset($_SESSION['nume'])) unset($_SESSION['nume']);
    if(isset($_SESSION['parola'])) unset($_SESSION['parola']);
    if(isset($_SESSION['idusr'])) unset($_SESSION['idusr']);
    if(isset($_SESSION['rank'])) unset($_SESSION['rank']);
    if(isset($_SESSION['datavisit'])) unset($_SESSION['datavisit']);

      // if $rd=1, auto-redirect to avoid resending data on refresh
    if($rd===1) echo '<meta http-equiv="Refresh" content="1;url=/"><script type="text/javascript">alert("Logged Out");</script>';
    else if($rd===2) echo '<meta http-equiv="Refresh" content="1;url=/"><script type="text/javascript">alert("Logged Out\nThere is another Login with this account.\nYou can re-login.");</script>';
    exit;
  }
}
?>
Return current item: User Register Login Online script