<?php
class USER
{
    private $db;

    function __construct($DB_con)
    {
      $this->db = $DB_con;
    }

    public function register($fname,$lname,$uname,$umail,$upass)
    {
       try
       {
           $new_password = password_hash($upass, PASSWORD_DEFAULT);
           $userpin      = $this->GeneratePIN(8);

           $stmt = $this->db->prepare("INSERT INTO WEBUSER(USERID,USERPASSWORD,USERLEVEL,USEREMAIL,USERACTIVATIONPIN,USERACTIVATIONPINUSEDBY,ACTIVATED,DATECREATED)
                                                    VALUES(:uid, :upass, 0, :umail, :upin, dateadd(hh,1,getdate()), 0, getdate())");

           $stmt->bindparam(":uid",   $uname);
           $stmt->bindparam(":upass", $new_password);
           $stmt->bindparam(":umail", $umail);
           $stmt->bindparam(":upin",  $userpin);
           $stmt->execute();

           $stmt = $this->db->prepare("INSERT INTO WEBUSERPROFILE(USERID,FULLNAME,EMAIL,DATEMODIFIED)
                                                    VALUES(:uid, :ufname, :umail, getdate())");

           $stmt->bindparam(":uid",    $uname);
           $stmt->bindparam(":ufname", $fname);
           $stmt->bindparam(":umail",  $umail);
           $stmt->execute();

           return $stmt;
       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }
    }
    
    public function registernew($fname,$lname,$uname,$umail,$usecure,$upass)
    {
       try
       {
           $new_password = password_hash($upass, PASSWORD_DEFAULT);
           $userpin      = $this->GeneratePIN(8);

           $stmt = $this->db->prepare("INSERT INTO WEBUSER(USERID,USERPASSWORD,USERSECUREWORD,USERLEVEL,USEREMAIL,USERACTIVATIONPIN,USERACTIVATIONPINUSEDBY,ACTIVATED,DATECREATED)
                                                    VALUES(:uid, :upass, :usecure, 0, :umail, :upin, dateadd(hh,1,getdate()), 0, getdate())");

           $stmt->bindparam(":uid",   $uname);
           $stmt->bindparam(":upass", $new_password);
           $stmt->bindparam(":usecure", $usecure);
           $stmt->bindparam(":umail", $umail);
           $stmt->bindparam(":upin",  $userpin);
           $stmt->execute();

           $stmt = $this->db->prepare("INSERT INTO WEBUSERPROFILE(USERID,FULLNAME,EMAIL,DATEMODIFIED)
                                                    VALUES(:uid, :ufname, :umail, getdate())");

           $stmt->bindparam(":uid",    $uname);
           $stmt->bindparam(":ufname", $fname);
           $stmt->bindparam(":umail",  $umail);
           $stmt->execute();

           return $stmt;
       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }
    }    

    public function login($uname,$upass)
    {
       try
       {
          // to get rowCount to work, need to add the array parameter for the prepare function
          $stmt = $this->db->prepare("SELECT A.*, B.FULLNAME FROM WEBUSER A LEFT OUTER JOIN WEBUSERPROFILE B ON B.USERID=A.USERID WHERE A.USERID=:uname", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
          $stmt->execute(array(':uname'=>$uname));
          $userRow=$stmt->fetch(PDO::FETCH_ASSOC);
          // Check if it is hardcoded admin
          if ($uname==EW_ADMIN_USER_NAME and $upass==EW_ADMIN_PASSWORD){
              $_SESSION[EW_SESSION_SYS_ADMIN]  = 1;
              $_SESSION[EW_SESSION_USER_LEVEL] = -999;
              $_SESSION[EW_SESSION_STATUS]     = "login";

              if($stmt->rowCount() == 1) {
                  $_SESSION['user_session']    = $userRow['USERID'];
                  $_SESSION['user_name']       = 'System Administrator';
                  $_SESSION['last_login']      = $userRow['LASTLOGIN'];
                  $_SESSION['date_created']    = $userRow['DATECREATED'];
              } else {
                  $_SESSION['user_session']    = 'admin';
                  $_SESSION['user_name']       = 'System Administrator';

              }

              $query = "UPDATE WEBUSER
                           SET LASTLOGIN = getdate()
                         WHERE USERID =:uid
                       ";
              $stmt = $this->db->prepare($query);
              $stmt->bindparam(":uid",   $uname);
              $stmt->execute();

              return true;
          } else {
              // check if user exists
              if($stmt->rowCount() == 1) {
                  if(password_verify($upass, $userRow['USERPASSWORD'])) {
                      if ($userRow['ACTIVATED']==1 || $userRow['USERLEVEL']==-1 || $userRow['USERLEVEL']==-2  || $userRow['USERLEVEL']==50){

                          $_SESSION['user_session']        = $userRow['USERID'];
                          $_SESSION['last_login']          = $userRow['LASTLOGIN'];
                          $_SESSION['date_created']        = $userRow['DATECREATED'];
                          $_SESSION[EW_SESSION_USER_LEVEL] = $userRow['USERLEVEL'];
                          $_SESSION[EW_SESSION_STATUS] = "login";

                          $query = "UPDATE WEBUSER
                                       SET LASTLOGIN = getdate()
                                     WHERE USERID =:uid
                                   ";
                          $stmt = $this->db->prepare($query);
                          $stmt->bindparam(":uid",   $uname);
                          $stmt->execute();

                          if ($userRow['USERLEVEL']==-999){
                              $_SESSION[EW_SESSION_SYS_ADMIN] = 1; // administrator
                              $_SESSION['user_name']          = 'System Administrator';
                          } else {
                              $_SESSION[EW_SESSION_SYS_ADMIN] = 0;

                              $stmt2 = $this->db->prepare("DECLARE @uname varchar(10) SET @uname=:uid SET @uname=RIGHT('0000000'+ CAST (@uname AS varchar),7) SELECT PersonnelID, RIGHT(PersonnelID,1) AS MILRANK, PersonnelName FROM [dbo].[LTAT_tbl_statementcurrent] WHERE LEFT(PersonnelID,7)=@uname");
                              $stmt2->execute(array(":uid"=>$uname));
                              //$row   = $stmt->fetch(PDO::FETCH_ASSOC);
                              while($row = $stmt2->fetch(PDO::FETCH_ASSOC))
                              {
                                 $myid_array[]          = $row['PersonnelID'].$row['MILRANK'];
                                 $myrank_array[]        = $row['MILRANK'];
                                 $_SESSION['user_name'] = $row['PersonnelName'];
                              }                              
                              

                              

                              // No records found in TBMILITARIES, search from LTAT_tbl_statementcurrent
                              if (empty($myid_array)){                              
                                  $stmt2 = $this->db->prepare("SELECT * FROM TBMILITARIES WHERE MILITARYID=:uid ORDER BY NPID");
                                  $stmt2->execute(array(":uid"=>$uname));
                                  //$row   = $stmt->fetch(PDO::FETCH_ASSOC);
                                  while($row = $stmt2->fetch(PDO::FETCH_ASSOC))
                                  {
                                     $myid_array[]          = $row['MILITARYID'].$row['RANK'];
                                     $myrank_array[]        = $row['RANK'];
                                     $_SESSION['user_name'] = $row['NAME'];
                                  }
                              } 

                              $_SESSION['MILITARYID']   = $myid_array;
                              $_SESSION['MILITARYRANK'] = $myrank_array;

                              if ($_SESSION['user_name']==""){
                                  $_SESSION['user_name'] = $userRow['FULLNAME'];
                              }

                          }

                          $_SESSION[EW_SESSION_STATUS] = "login";
                          return true;
                      } else {
                          // user haven't activate account
                          return false;
                      }
                  } else {
                      // wrong password
                     return false;
                  }
              }
          }
       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }
    }
    
    
    public function checkLoginID($uname)
    {
       try
       {
          // to get rowCount to work, need to add the array parameter for the prepare function
          $stmt = $this->db->prepare("SELECT A.*, B.FULLNAME FROM WEBUSER A LEFT OUTER JOIN WEBUSERPROFILE B ON B.USERID=A.USERID WHERE A.USERID=:uname", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
          $stmt->execute(array(':uname'=>$uname));
          $userRow=$stmt->fetch(PDO::FETCH_ASSOC);
          // Check if it is hardcoded admin
          if ($uname==EW_ADMIN_USER_NAME){
              return true;
          } else {
              // check if user exists
              if($stmt->rowCount() == 1) {
                  if ($userRow['ACTIVATED']==1 || $userRow['USERLEVEL']==-1 || $userRow['USERLEVEL']==-2  || $userRow['USERLEVEL']==50){
                      return true;
                  } else {
                      // user haven't activate account
                      return false;
                  }
              }
          }
       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }
    }    

    public function is_loggedin()
    {
       if(isset($_SESSION['user_session']))
       {
          return true;
       }
    }

    public function redirect($url)
    {
        header("Location: $url");
    }

    public function logout()
    {
         session_destroy();
         unset($_SESSION['user_session']);
         unset($_SESSION['MILITARYID']);
         unset($_SESSION['MILITARYRANK']);
         unset($_SESSION['CURRENTMILITARYRANK']);
         return true;
    }

    public function sendactivation($uname,$upass,$umail)
    {
        $stmt3 = $this->db->prepare("SELECT USEREMAIL,USERACTIVATIONPIN FROM WEBUSER WHERE USERID=:uname");
        $stmt3->execute(array(':uname'=>$uname));
        $row    = $stmt3->fetch(PDO::FETCH_ASSOC);
        $hash   = $row['USERACTIVATIONPIN'];
        $umail2 = $row['USEREMAIL'];

        if ($umail==""){
            $umail = $umail2;
        }

        $from    = 'noreply-ltat-iWira <noreply@ltat.org.my>';
        $to      = $umail; // Send email to our user
        //$subject = 'LTAT Online Caruman Activation'; // Give the email a subject
        $subject = 'Pengaktifan Caruman Online LTAT';  // Give the email a subject

        //BM version email content
        $message = '
        Terima kasih atas pendaftaran ini!<br><br>

        Akaun anda telah diwujudkan, anda boleh log masuk menggunakan maklumat berikut selepas anda mengaktifkan akaun anda dengan klik alamat URL di bawah.<br>
        <p><br>
        ------------------------<br>
        Nama pengguna: '.$uname.'<br>
        Kata laluan: ******<br>
        ------------------------<br><br>

        Jika anda tidak melakukan pendaftaran ini, anda boleh mengabaikan e-mel ini.<br>
        Pengguna yang menggunakan alamat e-mel anda menggunakan IP: '.$_SERVER['REMOTE_ADDR'].'<br><br>

        Sila klik pautan ini untuk mengaktifkan akaun anda:<br>
        https://iwira.ltat.org.my/ltatonline/verify.php?id='.$uname.'&email='.$umail.'&hash='.$hash.'<br><br>

        --------------------<br>
        Ini adalah mel automatik, jangan membalas e-mel ini.<br>

        ';



        /*
        //English version email content
        $message = '
        Thank you for registration!<br><br>
        Your account has been created, you can login with the following credentials after you have activated your account by clicking the URL below.<br>
        <p><br>
        ------------------------<br>
        Username: '.$uname.'<br>
        Password: ******<br>
        ------------------------<br><br>

        If you did not do this you may ignore this email.<br>
        The person who used your email address had the IP: '.$_SERVER['REMOTE_ADDR'].'<br><br>

        Please click this link to activate your account:<br>
        http://iwira.ltatl.org.my/ltatonline/verify.php?id='.$uname.'&email='.$umail.'&hash='.$hash.'<br><br>

        --------------------<br>
        This is an automated mail, do not reply to this email.<br>

        '; // Our message above including the link
        */

        try {
          $res = ew_SendEmail($from, $to, '', '', $subject, $message, 'html', '', $sSmtpSecure = EW_SMTP_SECURE_OPTION, $arAttachments = array(), $arImages = array(), $arProperties = NULL);
          //ew_SendEmail($from, $to, '', '', $subject, $message, 'html', '', $sSmtpSecure = "SSL", $arAttachments = array(), $arImages = array(), $arProperties = NULL);
        } catch (phpmailerException $e) {
          die("Error=".$e->errorMessage()); //Pretty error messages from PHPMailer
        } catch (Exception $e) {
          die("Error=".$e->getMessage()); //Boring error messages from anything else!
        }

        return $res;
    }

    public function sendforgotpassword($uname)
    {
        $stmt4 = $this->db->prepare("SELECT USEREMAIL,USERACTIVATIONPIN FROM WEBUSER WHERE USERID=:uname");
        $stmt4->execute(array(':uname'=>$uname));
        $row   = $stmt4->fetch(PDO::FETCH_ASSOC);
        $umail = $row['USEREMAIL'];
        $uhash = $row['USERACTIVATIONPIN'];

        $from    = 'noreply-ltat-iWira <noreply@ltat.org.my>';
        $to      = $umail; // Send email to our user
        $subject = 'LTAT Online Caruman - Change Password'; // Give the email a subject
        $message = '

        You have request for password reset!<br><br>
        You can change your password by clicking the URL below.<br>
        <p><br>

        If you did not do this you may ignore this email.<br>
        The person who request for Forgot Password had the IP: '.$_SERVER['REMOTE_ADDR'].'<br><br>

        Please click this link to activate your account:<br>
        https://iwira.ltat.org.my/ltatonline/changepwd.php?id='.$uname.'&email='.$umail.'&hash='.$uhash.'<br><br>

        --------------------<br>
        This is an automated mail, do not reply to this email.<br>

        '; // Our message above including the link

        try {
          $res = ew_SendEmail($from, $to, '', '', $subject, $message, 'html', '', $sSmtpSecure = EW_SMTP_SECURE_OPTION, $arAttachments = array(), $arImages = array(), $arProperties = NULL);
          //ew_SendEmail($from, $to, '', '', $subject, $message, 'html', '', $sSmtpSecure = "SSL", $arAttachments = array(), $arImages = array(), $arProperties = NULL);
        } catch (phpmailerException $e) {
          echo $e->errorMessage(); //Pretty error messages from PHPMailer
        } catch (Exception $e) {
          echo $e->getMessage(); //Boring error messages from anything else!
        }

        return $res;
    }


    public function GeneratePIN($length)
    {
         $random= "";

         srand((double)microtime()*1000000);

         $data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

         for($i = 0; $i < $length; $i++)
         {
              $random .= substr($data, (rand()%(strlen($data))), 1);
         }

         return $random;
    }

    public function GenerateRandom($length, $charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
    {
        $randString = '';
        $count = strlen($charset);
        while ($length--)
        {
            $randString .= $charset[mt_rand(0, $count-1)];
        }
        return $randString;
    }

    public function log($userid, $statusid, $msg)
    {
        // Get IP address
        if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $remote_addr = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $remote_addr = $_SERVER['REMOTE_ADDR'];
        }

        $query = "INSERT INTO WEBACTIVITYLOGS
                  (
                    USER_ID
                   ,REMOTE_ADDR
                   ,STATUS_ID
                   ,ACTIVITY_MESSAGE
                   ,CREATED_AT
                  ) VALUES (
                    :user_id
                   ,:remote_addr
                   ,:statusid
                   ,:msg
                   ,getdate()
                  )
                 ";
        $stmt = $this->db->prepare($query);
        $stmt->bindparam(":user_id",     $userid);
        $stmt->bindparam(":remote_addr", $remote_addr);
        $stmt->bindparam(":statusid",    $statusid);
        $stmt->bindparam(":msg",    $msg);
        $stmt->execute();

    }
    
    public function ellipsis($text, $max=100, $append='&hellip;') {
      if (strlen($text) <= $max) return $text;

      //$out = substr($text,0,$max);
      //if (strpos($text,' ') === FALSE) return $out.$append;
      //return preg_replace('/\w+$/','',$out).$append;

      return rtrim(mb_strimwidth($text, 0, $max)).$append;
    }

    /**
    * Find the starting Monday for the given week (or for the current week if no date is passed)
    *
    * This is required as by default in PHP, strtotime considers Sunday the first day of a week,
    * making strtotime('Monday this week') on a Sunday return the adjacent Monday instead of the
    * previous one.
    *
    * @param string|\DateTime|null $date
    * @return \DateTime
    */

    public function getStartOfWeekDate($beginend = 'begin', $date = null)
    {
      if ($beginend=='begin'){
        if ($date instanceof \DateTime) {
          $date = clone $date;
        } else if (!$date) {
          $date = new \DateTime();
        } else {
          $date = new \DateTime($date);
        }
        $date->setTime(0, 0, 0);
        if ($date->format('N') == 1) {

          // If the date is already a Monday, return it as-is
          return $date;
        } else {

          // Otherwise, return the date of the nearest Monday in the past
          // This includes Sunday in the previous week instead of it being the start of a new week

          return $date->modify('last monday');
        }
      } else {
        if ($date instanceof \DateTime) {
          $date = clone $date;
        } else if (!$date) {
          $date = new \DateTime();
        } else {
          $date = new \DateTime($date);
        }
        $date->setTime(0, 0, 0);
        if ($date->format('N') == 7) {

          // If the date is already a Sunday, return it as-is
          return $date;
        } else {

          // Otherwise, return the date of the nearest Monday in the past
          // This includes Sunday in the previous week instead of it being the start of a new week

          return $date->modify('Sunday this week');
        }
      }
    }    
    
    
}
?>