From 244429f1c125a59d516d2f0611c84c615805bd58 Mon Sep 17 00:00:00 2001 From: doudoudzj Date: Mon, 24 Jun 2019 21:04:26 +0800 Subject: [PATCH] add ClientArea module --- README.md | 2 +- assets/css/clientarea.css | 13 + assets/js/clientarea.js | 5 + clientarea.php | 30 +++ .../controllers/account_deactivation.php | 25 ++ clientarea/controllers/account_verify.php | 22 ++ clientarea/controllers/change_password.php | 57 ++++ clientarea/controllers/details.php | 18 ++ clientarea/controllers/edit_details.php | 82 ++++++ clientarea/controllers/emails.php | 33 +++ clientarea/controllers/forget_password.php | 53 ++++ clientarea/controllers/index.php | 2 + clientarea/controllers/login.php | 60 +++++ clientarea/controllers/logout.php | 23 ++ clientarea/controllers/register.php | 84 ++++++ .../controllers/request-account-activate.php | 43 +++ clientarea/controllers/reset_password.php | 63 +++++ clientarea/controllers/tickets.php | 39 +++ clientarea/data/config.php | 26 ++ clientarea/data/demo.sql | 60 +++++ clientarea/images/11462549B-11560888443.jpg | Bin 0 -> 11442 bytes clientarea/images/114625Mc-01560891624.jpg | Bin 0 -> 14592 bytes ...9dbb55cc3623871b98adc74628081558340869.png | Bin 0 -> 6691 bytes clientarea/index.php | 2 + clientarea/library/email.class.php | 251 ++++++++++++++++++ clientarea/library/functions.php | 217 +++++++++++++++ clientarea/views/account_deactivation.php | 25 ++ clientarea/views/account_verify.php | 25 ++ clientarea/views/change_password.php | 46 ++++ clientarea/views/details.php | 71 +++++ clientarea/views/edit_details.php | 60 +++++ clientarea/views/emails.php | 55 ++++ clientarea/views/footer.php | 32 +++ clientarea/views/forget_password.php | 37 +++ clientarea/views/header.php | 29 ++ clientarea/views/index.php | 2 + clientarea/views/login.php | 43 +++ clientarea/views/logout.php | 26 ++ clientarea/views/main.php | 52 ++++ clientarea/views/navbar.php | 75 ++++++ clientarea/views/register.php | 61 +++++ clientarea/views/request-account-activate.php | 35 +++ clientarea/views/reset_password.php | 43 +++ clientarea/views/tickets.php | 56 ++++ 44 files changed, 1982 insertions(+), 1 deletion(-) create mode 100644 assets/css/clientarea.css create mode 100644 assets/js/clientarea.js create mode 100644 clientarea.php create mode 100644 clientarea/controllers/account_deactivation.php create mode 100644 clientarea/controllers/account_verify.php create mode 100644 clientarea/controllers/change_password.php create mode 100644 clientarea/controllers/details.php create mode 100644 clientarea/controllers/edit_details.php create mode 100644 clientarea/controllers/emails.php create mode 100644 clientarea/controllers/forget_password.php create mode 100644 clientarea/controllers/index.php create mode 100644 clientarea/controllers/login.php create mode 100644 clientarea/controllers/logout.php create mode 100644 clientarea/controllers/register.php create mode 100644 clientarea/controllers/request-account-activate.php create mode 100644 clientarea/controllers/reset_password.php create mode 100644 clientarea/controllers/tickets.php create mode 100644 clientarea/data/config.php create mode 100644 clientarea/data/demo.sql create mode 100644 clientarea/images/11462549B-11560888443.jpg create mode 100644 clientarea/images/114625Mc-01560891624.jpg create mode 100644 clientarea/images/5de69dbb55cc3623871b98adc74628081558340869.png create mode 100644 clientarea/index.php create mode 100755 clientarea/library/email.class.php create mode 100644 clientarea/library/functions.php create mode 100644 clientarea/views/account_deactivation.php create mode 100644 clientarea/views/account_verify.php create mode 100644 clientarea/views/change_password.php create mode 100644 clientarea/views/details.php create mode 100644 clientarea/views/edit_details.php create mode 100644 clientarea/views/emails.php create mode 100644 clientarea/views/footer.php create mode 100644 clientarea/views/forget_password.php create mode 100644 clientarea/views/header.php create mode 100644 clientarea/views/index.php create mode 100644 clientarea/views/login.php create mode 100644 clientarea/views/logout.php create mode 100644 clientarea/views/main.php create mode 100644 clientarea/views/navbar.php create mode 100644 clientarea/views/register.php create mode 100644 clientarea/views/request-account-activate.php create mode 100644 clientarea/views/reset_password.php create mode 100644 clientarea/views/tickets.php diff --git a/README.md b/README.md index c387482..72f433b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A simple Content Management System for Reseller of MyOwnFreeHost - [x] Change language -### member module +### ClientArea module - [x] Account registration - [x] Account verification diff --git a/assets/css/clientarea.css b/assets/css/clientarea.css new file mode 100644 index 0000000..dc2b193 --- /dev/null +++ b/assets/css/clientarea.css @@ -0,0 +1,13 @@ +.mx-auto { + margin-left: auto !important; + margin-right: auto !important; + float: none; +} + +#imageUpload { + display: none; +} + +.img-avatar { + max-height: 200px; +} \ No newline at end of file diff --git a/assets/js/clientarea.js b/assets/js/clientarea.js new file mode 100644 index 0000000..289b621 --- /dev/null +++ b/assets/js/clientarea.js @@ -0,0 +1,5 @@ +$("#uploadNewImage").click(function () { + $("#imageBox").hide(); + $("#imageUpload").show(); + +}); diff --git a/clientarea.php b/clientarea.php new file mode 100644 index 0000000..cbd6e16 --- /dev/null +++ b/clientarea.php @@ -0,0 +1,30 @@ +prepare( + "UPDATE users SET is_active = 0 WHERE id = ?" + ); + $stmt->bind_param("i", $user->id); + if ($stmt->execute()) { + setMsg("msg_notify", "Your account has been deactivated successfully. Request support to activate your account."); + unset($_SESSION["user"]); + redirect("clientarea", "login"); + } + } +} else { + redirect("clientarea", "details"); +} diff --git a/clientarea/controllers/account_verify.php b/clientarea/controllers/account_verify.php new file mode 100644 index 0000000..f05ae21 --- /dev/null +++ b/clientarea/controllers/account_verify.php @@ -0,0 +1,22 @@ + 20 || strlen($old_password) < 5) { + $errors["old_password_err"] = "Old Password min limit is 5 & max is 20 characters"; + } elseif (!password_verify($old_password, $user->password)) { + $errors["old_password_err"] = "Old password incorrect please enter valid password"; + } + + if (strlen($password) > 20 || strlen($password) < 5) { + $errors["password_err"] = "Password min limit is 5 & max is 20 characters"; + } + + if ($password != $confirm_password || empty($confirm_password)) { + $errors["confirm_password_err"] = "Password does not match or empty"; + } + + if (!count($errors)) { + $stmt = $objDB->prepare("UPDATE users SET password = ? WHERE id = ?"); + $stmt->bind_param("si", password_hash($password, PASSWORD_DEFAULT), $user->id); + + if ($stmt->execute()) { + setMsg("msg_notify", "Your account password has been updated successfully."); + unset($_SESSION["user"]); + redirect("clientarea", "login"); + exit(); + } + } else { + $data = [ + "old_password" => $old_password, + "password" => $password, + "confirm_password" => $confirm_password, + ]; + setMsg("form_data", $data); + setMsg("errors", $errors); + } +} diff --git a/clientarea/controllers/details.php b/clientarea/controllers/details.php new file mode 100644 index 0000000..1d03d53 --- /dev/null +++ b/clientarea/controllers/details.php @@ -0,0 +1,18 @@ +image)) ? '/clientarea/images/' . $user->image : "http://via.placeholder.com/150x150"; +$userRegDate = cTime($user->created_at); diff --git a/clientarea/controllers/edit_details.php b/clientarea/controllers/edit_details.php new file mode 100644 index 0000000..1dbc9f6 --- /dev/null +++ b/clientarea/controllers/edit_details.php @@ -0,0 +1,82 @@ +image)) ? '/clientarea/images/' . $user->image : "http://via.placeholder.com/150x150"; + +if (isset($_POST["edit"])) { + + $errors = array(); + + $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING); + $username = filter_input(INPUT_POST, "username", FILTER_SANITIZE_STRING); + $email = filter_input(INPUT_POST, "email", FILTER_SANITIZE_EMAIL); + $website = filter_input(INPUT_POST, "website", FILTER_SANITIZE_URL); + $image = isset($_FILES["image"]) ? $_FILES["image"] : ""; + + $user = $_SESSION["user"]; + + if (strlen($name) > 50 || strlen($name) < 6) { + $errors["name_err"] = "Name min limit is 6 & max is 50 characters"; + } + + if (strlen($username) > 15 || strlen($username) < 5) { + $errors["username_err"] = "Username min limit is 5 & max is 15 characters"; + } + + if (!isemail($email)) { + $errors["email_err"] = "The email address is invalid."; + } + + if (empty($website)) { + $errors["website_err"] = "Invalid entry"; + } + + if ($image["error"] != 4) { + if (!is_dir(APPROOT . "/images")) { + mkdir(APPROOT . "/images"); + } + + if ($image["error"] == 4) { + $errors["image_err"] = "Please, upload file"; + } elseif ($image["type"] != "image/png" && $image["type"] != "image/jpeg") { + $errors["image_err"] = "Only, png/jpeg image is allowed"; + } + + $image_info = pathinfo($image["name"]); + extract($image_info); + $image_convention = $filename . time() . ".$extension"; + + move_uploaded_file($image["tmp_name"], APPROOT . "/images/" . $image_convention); + } else { + $image_convention = $user->image; + } + + if (!count($errors)) { + $stmt = $objDB->prepare( + "UPDATE users SET name = ?, email = ?, username=?, website=?, image=? WHERE id=?" + ); + $stmt->bind_param("sssssi", $name, $email, $username, $website, $image_convention, $user->id); + + if ($stmt->execute()) { + setMsg("msg_notify", "Your account has been updated successfully."); + } + + $_SESSION["user"] = getUserById($user->id); + redirect("clientarea", "details"); + } else { + setMsg("errors", $errors); + redirect("clientarea", "edit_details"); + } +} diff --git a/clientarea/controllers/emails.php b/clientarea/controllers/emails.php new file mode 100644 index 0000000..2bcab20 --- /dev/null +++ b/clientarea/controllers/emails.php @@ -0,0 +1,33 @@ + 12, + "pages" => 4, + "page" => 1, + "list" => [ + [ + "id" => "3453822", + "date" => "Saturday, August 11th, 2018 (04:50)", + "subject" => "Invoice Payment Confirmation" + ], + [ + "id" => "3453821", + "date" => "Friday, August 10th, 2018 (12:00)", + "subject" => "Customer Invoice" + ], + [ + "id" => "3453820", + "date" => "Tuesday, April 3rd, 2018 (00:51)", + "subject" => "Your password has been reset" + ] + ] +]; diff --git a/clientarea/controllers/forget_password.php b/clientarea/controllers/forget_password.php new file mode 100644 index 0000000..a510cb2 --- /dev/null +++ b/clientarea/controllers/forget_password.php @@ -0,0 +1,53 @@ + $email, + ]; + setMsg("form_data", $data); + setMsg("errors", $errors); + redirect("clientarea", "forget_password"); + } else { + $code = md5(crypt(rand(), "aa")); + $stmt = $objDB->prepare( + "UPDATE users SET is_active = 0, reset_code=? WHERE email=?" + ); + $stmt->bind_param("ss", $code, $email); + if ($stmt->execute()) { + setMsg("msg_notify", "You made a password request, please check email to reset your password.", "success"); + $message = "Hi! You requested password reset, . You need to click here to reset your password."; + echo $message; + send_mail([ + "to" => $email, + "message" => $message, + "subject" => "Reset Password Requested" + ]); + } else { + setMsg("msg_notify", "reset password request, Please try again later.", "warning"); + } + } +} diff --git a/clientarea/controllers/index.php b/clientarea/controllers/index.php new file mode 100644 index 0000000..a3de1d1 --- /dev/null +++ b/clientarea/controllers/index.php @@ -0,0 +1,2 @@ + 15 || strlen($username) < 5) { + $errors["username_err"] = "Username min limit is 5 & max is 15 characters"; + } elseif (!checkUserByUsername($username)) { + $errors["username_err"] = "Username not exists"; + } elseif (!checkUserActivation($username)) { + $errors["username_err"] = 'Your account is not verified, click here to verify.'; + } + + if (strlen($password) > 20 || strlen($password) < 5) { + $errors["password_err"] = "Password min limit is 5 & max is 20 characters"; + } + if (!count($errors)) { + $stmt = $objDB->prepare("SELECT * FROM users WHERE username=?"); + $stmt->bind_param("s", $username); + $stmt->execute(); + $result = $stmt->get_result(); + $user = $result->fetch_object(); + if ($result->num_rows == 1) { + if (password_verify($password, $user->password)) { + if ($remember == "Yes") { + setcookie("user", serialize($user), time() + (86400 * 30), "/"); + } else { + $_SESSION["user"] = $user; + } + redirect("clientarea", "details"); + } else { + setMsg("msg_notify", "Account not found, please enter correct credentials", "warning"); + } + } + } else { + $data = [ + "username" => $username, + "password" => $password, + ]; + setMsg("form_data", $data); + setMsg("errors", $errors); + redirect("clientarea", "login"); + } +} diff --git a/clientarea/controllers/logout.php b/clientarea/controllers/logout.php new file mode 100644 index 0000000..25eccc4 --- /dev/null +++ b/clientarea/controllers/logout.php @@ -0,0 +1,23 @@ + 50 || strlen($name) < 6) { + $errors["name_err"] = "Name min limit is 6 & max is 50 characters"; + } + + if (strlen($username) > 15 || strlen($username) < 5) { + $errors["username_err"] = "Username min limit is 5 & max is 15 characters"; + } elseif (checkUserByUsername($username)) { + $errors["username_err"] = "Username already exists"; + } + + if (!isemail($email)) { + $errors["email_err"] = "The email address is invalid."; + } elseif (checkUserByEmail($email)) { + $errors["email_err"] = "The email address already exists in system."; + } + + if (empty($website)) { + $errors["website_err"] = "Invalid entry"; + } + + if (strlen($password) > 20 || strlen($password) < 5) { + $errors["password_err"] = "Password min limit is 5 & max is 20 characters"; + } + + if ($password != $confirm_password || empty($confirm_password)) { + $errors["confirm_password_err"] = "Password does not match or empty"; + } + + if (!count($errors)) { + $password = password_hash($password, PASSWORD_DEFAULT); + $code = md5(crypt(rand(), "aa")); + $stmt = $objDB->prepare( + "INSERT INTO users(name, email, username, password, website, created_at, reset_code) + VALUES(?, ?, ?, ?, ?, ?, ?)" + ); + $stmt->bind_param("sssssis", $name, $email, $username, $password, $website, time(), $code); + if ($stmt->execute()) { + setMsg("msg_notify", "Your account has been created successfully.Please, check your email to verify.", "warning"); + $message = "Hi! You requested an account on our website, in order to use this account. You need to click here to Verify it."; + send_mail([ + "to" => $email, + "message" => $message, + "subject" => "Account Verficiation" + ]); + redirect("clientarea", "login"); + } + } else { + $data = [ + "name" => $name, + "username" => $username, + "email" => $email, + "website" => $website, + "password" => $password, + "confirm_password" => $confirm_password, + ]; + setMsg("form_data", $data); + setMsg("errors", $errors); + redirect("clientarea", "register"); + } +} diff --git a/clientarea/controllers/request-account-activate.php b/clientarea/controllers/request-account-activate.php new file mode 100644 index 0000000..cc1c9f7 --- /dev/null +++ b/clientarea/controllers/request-account-activate.php @@ -0,0 +1,43 @@ +prepare( + "UPDATE users SET reset_code=? WHERE email=?" + ); + $stmt->bind_param("ss", $code, $email); + if ($stmt->execute()) { + setMsg("msg_notify", "Please check your email to verify your account", "warning"); + $message = "Hi! You requested account verification. You need to click here to activate your account."; + send_mail([ + "to" => $email, + "message" => $message, + "subject" => "Account Verification Request", + ]); + } + } else { + $data = [ + "email" => $email, + ]; + setMsg("form_data", $data); + setMsg("errors", $errors); + } +} diff --git a/clientarea/controllers/reset_password.php b/clientarea/controllers/reset_password.php new file mode 100644 index 0000000..e935f62 --- /dev/null +++ b/clientarea/controllers/reset_password.php @@ -0,0 +1,63 @@ + 20 || strlen($password) < 5) { + $errors["password_err"] = "Password min limit is 5 & max is 20 characters"; + } + if (empty($confirm_password)) { + $errors["confirm_password_err"] = "The password is empty."; + } elseif ($password != $confirm_password) { + $errors["confirm_password_err"] = "The password does not match."; + } + if (!count($errors)) { + $password = password_hash($password, PASSWORD_DEFAULT); + $stmt = $objDB->prepare( + "UPDATE users SET reset_code= '', is_active=1, password=? WHERE reset_code=?" + ); + $stmt->bind_param("ss", $password, $reset_code); + if ($stmt->execute()) { + setMsg("msg_notify", "Your account password has been reset, you can login now."); + redirect("clientarea", "login"); + } + } else { + $data = [ + "password" => $password, + "confirm_password" => $confirm_password, + ]; + setMsg("form_data", $data); + setMsg("errors", $errors); + redirect("clientarea", "reset_password", ["reset_code" => $reset_code]); + } +} diff --git a/clientarea/controllers/tickets.php b/clientarea/controllers/tickets.php new file mode 100644 index 0000000..0ba42b0 --- /dev/null +++ b/clientarea/controllers/tickets.php @@ -0,0 +1,39 @@ + 10, + "pages" => 4, + "page" => 1, + "list" => [ + [ + "date" => "Saturday, August 11th, 2018 (04:50)", + "department" => "Saturday, August 11th, 2018 (04:50)", + "subject" => "Invoice Payment Confirmation", + "status" => "", + "lastupdated" => "" + ], + [ + "date" => "Friday, August 10th, 2018 (12:00)", + "department" => "Friday, August 10th, 2018 (12:00)", + "subject" => "Customer Invoice", + "status" => "", + "lastupdated" => "" + ], + [ + "date" => "Tuesday, April 3rd, 2018 (00:51)", + "department" => "Tuesday, April 3rd, 2018 (00:51)", + "subject" => "Your password has been reset", + "status" => "", + "lastupdated" => "" + ] + ] +]; diff --git a/clientarea/data/config.php b/clientarea/data/config.php new file mode 100644 index 0000000..85460d6 --- /dev/null +++ b/clientarea/data/config.php @@ -0,0 +1,26 @@ +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 G=Kl+m8UADd literal 0 HcmV?d00001 diff --git a/clientarea/images/114625Mc-01560891624.jpg b/clientarea/images/114625Mc-01560891624.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fb56ad3f7f0feea0f088b53a33d638795f30b859 GIT binary patch literal 14592 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 = false; + $this->smtp_port = $smtp_port; + $this->relay_host = $relay_host; + $this->time_out = 30; // is used in fsockopen() + $this->auth = $auth; // auth + $this->user = $user; + $this->pass = $pass; + $this->host_name = "localhost"; //is used in HELO command + $this->log_file = ""; + $this->sock = false; + } + + public function sendmail($to, $totitle = "", $from, $fromtitle = "", $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "") + { + $mail_from = $this->get_address($this->strip_comment($from)); + $body = preg_replace("/(^|(\r\n))(\.)/", "\1.\3", $body); + $header = "MIME-Version:1.0\r\n"; + if ($mailtype == "HTML") { + $header .= 'Content-Type: text/html; charset="utf-8"' . "\r\n"; + } + if (!empty($totitle)) { + $header .= "To: =?utf-8?B?" . base64_encode($totitle) . "?= <{$to}>\r\n"; + } else { + $header .= "To: {$to} <{$to}>\r\n"; + } + if (!empty($cc)) { + $header .= "Cc: {$cc}\r\n"; + } + if (!empty($fromtitle)) { + $header .= "From: =?utf-8?B?" . base64_encode($fromtitle) . "?= <{$from}>\r\n"; + } else { + $header .= "From: {$from} <{$from}>\r\n"; + } + $header .= "Subject: =?utf-8?B?" . base64_encode($subject) . "?=\r\n"; + $header .= $additional_headers; + $header .= "Date: " . date("r") . "\r\n"; + $header .= "X-Mailer: By UIISC (PHP/" . phpversion() . ")\r\n"; + list($msec, $sec) = explode(" ", microtime()); + $header .= "Message-ID: <" . date("YmdHis", $sec) . "." . ($msec * 1000000) . "." . $mail_from . ">\r\n"; + $TO = explode(",", $this->strip_comment($to)); + if ($cc != "") { + $TO = array_merge($TO, explode(",", $this->strip_comment($cc))); + } + if ($bcc != "") { + $TO = array_merge($TO, explode(",", $this->strip_comment($bcc))); + } + $sent = true; + foreach ($TO as $rcpt_to) { + $rcpt_to = $this->get_address($rcpt_to); + if (!$this->smtp_sockopen($rcpt_to)) { + $this->log_write("Error: Cannot send email to " . $rcpt_to . "\n"); + $sent = false; + continue; + } + if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body)) { + $this->log_write("E-mail has been sent to <" . $rcpt_to . ">\n"); + } else { + $this->log_write("Error: Cannot send email to <" . $rcpt_to . ">\n"); + $sent = false; + } + fclose($this->sock); + $this->log_write("Disconnected from remote host\n"); + } + return $sent; + } + + /* Private Functions */ + public function smtp_send($helo, $from, $to, $header, $body = "") + { + if (!$this->smtp_putcmd("HELO", $helo)) { + return $this->smtp_error("sending HELO command"); + } + if ($this->auth) { + if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user))) { + return $this->smtp_error("sending HELO command"); + } + if (!$this->smtp_putcmd("", base64_encode($this->pass))) { + return $this->smtp_error("sending HELO command"); + } + } + if (!$this->smtp_putcmd("MAIL", "FROM:<" . $from . ">")) { + return $this->smtp_error("sending MAIL FROM command"); + } + if (!$this->smtp_putcmd("RCPT", "TO:<" . $to . ">")) { + return $this->smtp_error("sending RCPT TO command"); + } + if (!$this->smtp_putcmd("DATA")) { + return $this->smtp_error("sending DATA command"); + } + if (!$this->smtp_message($header, $body)) { + return $this->smtp_error("sending message"); + } + if (!$this->smtp_eom()) { + return $this->smtp_error("sending . [EOM]"); + } + if (!$this->smtp_putcmd("QUIT")) { + return $this->smtp_error("sending QUIT command"); + } + return true; + } + + public function smtp_sockopen($address) + { + if ($this->relay_host == "") { + return $this->smtp_sockopen_mx($address); + } else { + return $this->smtp_sockopen_relay(); + } + } + + public function smtp_sockopen_relay() + { + $this->log_write("Trying to " . $this->relay_host . ":" . $this->smtp_port . "\n"); + $this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out); + if (!($this->sock && $this->smtp_ok())) { + $this->log_write("Error: Cannot connenct to relay host " . $this->relay_host . "\n"); + $this->log_write("Error: " . $errstr . " (" . $errno . ")\n"); + return false; + } + $this->log_write("Connected to relay host " . $this->relay_host . "\n"); + return true; + } + + public function smtp_sockopen_mx($address) + { + $domain = ereg_replace("^.+@([^@]+)$", "\1", $address); + if (!@getmxrr($domain, $MXHOSTS)) { + $this->log_write("Error: Cannot resolve MX \"" . $domain . "\"\n"); + return false; + } + foreach ($MXHOSTS as $host) { + $this->log_write("Trying to " . $host . ":" . $this->smtp_port . "\n"); + $this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out); + if (!($this->sock && $this->smtp_ok())) { + $this->log_write("Warning: Cannot connect to mx host " . $host . "\n"); + $this->log_write("Error: " . $errstr . " (" . $errno . ")\n"); + continue; + } + $this->log_write("Connected to mx host " . $host . "\n"); + return true; + } + $this->log_write("Error: Cannot connect to any mx hosts (" . implode(", ", $MXHOSTS) . ")\n"); + return false; + } + + public function smtp_message($header, $body) + { + fputs($this->sock, $header . "\r\n" . $body); + $this->smtp_debug("> " . str_replace("\r\n", "\n" . "> ", $header . "\n> " . $body . "\n> ")); + return true; + } + + public function smtp_eom() + { + fputs($this->sock, "\r\n.\r\n"); + $this->smtp_debug(". [EOM]\n"); + return $this->smtp_ok(); + } + + public function smtp_ok() + { + $response = str_replace("\r\n", "", fgets($this->sock, 512)); + $this->smtp_debug($response . "\n"); + if (!preg_match("/^[23]/", $response)) { + fputs($this->sock, "QUIT\r\n"); + fgets($this->sock, 512); + $this->log_write("Error: Remote host returned \"" . $response . "\"\n"); + return false; + } + return true; + } + + public function smtp_putcmd($cmd, $arg = "") + { + if ($arg != "") { + if ($cmd == "") { + $cmd = $arg; + } else { + $cmd = $cmd . " " . $arg; + } + } + fputs($this->sock, $cmd . "\r\n"); + $this->smtp_debug("> " . $cmd . "\n"); + return $this->smtp_ok(); + } + + public function smtp_error($string) + { + $this->log_write("Error: Error occurred while " . $string . ".\n"); + return false; + } + + public function log_write($message) + { + $this->smtp_debug($message); + if ($this->log_file == "") { + return true; + } + $message = date("M d H:i:s ") . get_current_user() . "[" . getmypid() . "]: " . $message; + if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a"))) { + $this->smtp_debug("Warning: Cannot open log file \"" . $this->log_file . "\"\n"); + return false; + } + flock($fp, LOCK_EX); + fputs($fp, $message); + fclose($fp); + return true; + } + + public function strip_comment($address) + { + $comment = "/\([^()]*\)/"; + while (preg_match($comment, $address)) { + $address = ereg_replace($comment, "", $address); + } + return $address; + } + + public function get_address($address) + { + $address = preg_replace("/([ \t\r\n])+/", "", $address); + $address = preg_replace("/^.*<(.+)>.*$/", "\1", $address); + return $address; + } + + public function smtp_debug($message) + { + if ($this->debug) { + echo $message; + } + } +} diff --git a/clientarea/library/functions.php b/clientarea/library/functions.php new file mode 100644 index 0000000..b1abbf3 --- /dev/null +++ b/clientarea/library/functions.php @@ -0,0 +1,217 @@ +connect_error) { + die("Connection not established"); + } + return $objDB; +} + +function upload_image($image) +{ + + if (!is_dir(APPROOT . "/images")) { + mkdir(APPROOT . "/images"); + } + + if ($image["error"] == 4) { + die("image file not uploaded"); + } + + if ($image["type"] != "image/png") { + die("Only, png image files are allowed"); + } + + $image_info = pathinfo($image["name"]); + extract($image_info); + $image_convention = $filename . time() . ".$extension"; + + if (move_uploaded_file($image["tmp_name"], APPROOT . "/images/" . $imageConvention)) { + return $image_convention; + } else { + return false; + } +} + +function cTime($timestamp) +{ + return date("Y-m-d H:i:s", $timestamp); +} + +function checkUserByEmail($email) +{ + + $objDB = objDB(); + $stmt = $objDB->prepare( + "SELECT * FROM users WHERE email=?" + ); + + $stmt->bind_param("s", $email); + $stmt->execute(); + $stmt->store_result(); + return $stmt->num_rows; +} + +function checkUserByUsername($username) +{ + + $objDB = objDB(); + $stmt = $objDB->prepare( + "SELECT * FROM users WHERE username=?" + ); + $stmt->bind_param("s", $username); + $stmt->execute(); + $stmt->store_result(); + return $stmt->num_rows; +} + +function checkUserActivation($username) +{ + + $objDB = objDB(); + $stmt = $objDB->prepare( + "SELECT * FROM users WHERE username=? AND is_active=1" + ); + $stmt->bind_param("s", $username); + $stmt->execute(); + $stmt->store_result(); + return $stmt->num_rows; +} + +function setMsg($name, $value, $class = "success") +{ + if (is_array($value)) { + $_SESSION[$name] = $value; + } else { + $_SESSION[$name] = "

$value
"; + } +} + +function getMsg($name) +{ + if (isset($_SESSION[$name])) { + $session = $_SESSION[$name]; + unset($_SESSION[$name]); + return $session; + } +} + +function getUserById($user_id) +{ + + $objDB = objDB(); + $stmt = $objDB->prepare( + "SELECT * FROM users WHERE id=?" + ); + $stmt->bind_param("i", $user_id); + $stmt->execute(); + $result = $stmt->get_result(); + return $result->fetch_object(); +} + +function verifyUserAccount($code) +{ + + $objDB = objDB(); + $stmt = $objDB->prepare( + "UPDATE users SET is_active = 1 , reset_code = '' WHERE reset_code = ?" + ); + $stmt->bind_param("s", $code); + $stmt->execute(); + $stmt->store_result(); + return $stmt->affected_rows; +} + +function checkUserByCode($code) +{ + $objDB = objDB(); + $stmt = $objDB->prepare( + "SELECT * FROM users WHERE reset_code = ?" + ); + $stmt->bind_param("s", $code); + $stmt->execute(); + $stmt->store_result(); + return $stmt->num_rows; +} + +function isUserLoggedIn() +{ + if (isset($_SESSION["user"]) || isset($_COOKIE["user"])) { + return true; + } else { + return false; + } +} + +function get_userinfo() +{ + return isUserLoggedIn() ? isset($_COOKIE["user"]) ? unserialize($_COOKIE["user"]) : $_SESSION["user"] : ""; +} + +function send_mail($detail = array()) +{ + if (!empty($detail["to"]) && !empty($detail["message"]) && !empty($detail["subject"])) { + $to = $detail["to"]; + $totitle = isset($detail["totitle"]) ? $detail["totitle"] : ""; + $from = SMTP_MAILADDR; + $fromtitle = isset($detail["fromtitle"]) ? $detail["fromtitle"] : ""; + $subject = $detail["subject"]; + $body = $detail["message"]; + $mailtype = "HTML"; // HTML/TXT + + $smtp = new MailSMTP(SMTP_SERVER, SMTP_PORT, true, SMTP_USERNAME, SMTP_PASSWORD); + $smtp->debug = false; + $res = $smtp->sendmail($to, $totitle, $from, $fromtitle, $subject, $body, $mailtype); + if (!$res) { + return false; + } else { + return true; + } + } else { + die("Your Mail Handler requires four main paramters"); + } +} + +/** + * redirect to functions URL + */ +function redirect($module, $section = "", $param = []) +{ + $url = $param ? setRouter($module, $section) . "&" . http_build_query($param) : setRouter($module, $section); + // $param = $param ? http_build_query($param) : ""; + // $url = $section ? setRouter($module, $section) . "&" . $param : setRouter($module) . "?" . $param; + header("Location: {$url}"); + exit; +} + +/** make router URL + * @param mixed $module + * @param mixed $section + * @return string + */ +function setRouter($module, $section = "") +{ + return empty($section) ? "{$module}.php" : "{$module}.php?s=$section"; +} + +/** make a full path http URL + * @param mixed $module + * @param mixed $section + * @return string + */ +function setURL($module, $section = "") +{ + return empty($section) ? URLROOT . "/{$module}.php" : URLROOT . "/{$module}.php?s=$section"; +} + +/** Determine if a variable is an email address + * + * @param string $email + * @return bool + */ +function isemail($email = "") +{ + return preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/", $email); +} diff --git a/clientarea/views/account_deactivation.php b/clientarea/views/account_deactivation.php new file mode 100644 index 0000000..3dc498a --- /dev/null +++ b/clientarea/views/account_deactivation.php @@ -0,0 +1,25 @@ + + +
+
+
+
+
+

Account Deactivation

+
+
+ +
+ +
+
+
+
diff --git a/clientarea/views/account_verify.php b/clientarea/views/account_verify.php new file mode 100644 index 0000000..537da15 --- /dev/null +++ b/clientarea/views/account_verify.php @@ -0,0 +1,25 @@ + + +
+
+
+
+
+

Account Verify

+
+
+ +
+ +
+
+
+
diff --git a/clientarea/views/change_password.php b/clientarea/views/change_password.php new file mode 100644 index 0000000..04cf67f --- /dev/null +++ b/clientarea/views/change_password.php @@ -0,0 +1,46 @@ + + +
+
+
+ +
+
+

Change Password

+
+
+

Please fill in credentials to Change Password.

+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/clientarea/views/details.php b/clientarea/views/details.php new file mode 100644 index 0000000..e9fb257 --- /dev/null +++ b/clientarea/views/details.php @@ -0,0 +1,71 @@ + + +
+
+
+ +
+
+

Account Details

+
+
+
+ +
+
+
+ + name); ?> +
+
+ + email); ?> +
+
+ + username); ?> +
+
+ + website); ?> +
+
+
+ + +
+
+ +
+
+
+
+ + diff --git a/clientarea/views/edit_details.php b/clientarea/views/edit_details.php new file mode 100644 index 0000000..d2c4d14 --- /dev/null +++ b/clientarea/views/edit_details.php @@ -0,0 +1,60 @@ + + +
+
+
+ +
+
+

Edit Account Details

+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+ +
+ + + +
+
+ +
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/clientarea/views/emails.php b/clientarea/views/emails.php new file mode 100644 index 0000000..7c7ee97 --- /dev/null +++ b/clientarea/views/emails.php @@ -0,0 +1,55 @@ + + +
+
+
+ +
+
+

Email History

+
+
+
+ + + + + + + + + + + $value) { ?> + + + + + + + + + + + + +
IDDate SentMessage SubjectOperate
+ +
No Records Found
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/clientarea/views/footer.php b/clientarea/views/footer.php new file mode 100644 index 0000000..1381d23 --- /dev/null +++ b/clientarea/views/footer.php @@ -0,0 +1,32 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/clientarea/views/forget_password.php b/clientarea/views/forget_password.php new file mode 100644 index 0000000..387f2b1 --- /dev/null +++ b/clientarea/views/forget_password.php @@ -0,0 +1,37 @@ + + +
+
+
+ +
+
+

Forget Password

+
+
+

If you have forgotten your password, you can reset it here. When you fill in your registered email address, you will be sent instructions on how to reset your password.

+

Please fill in credentials to get a link to reset password.

+
+
+ + + +
+
+ +
+
+
+ +
+
+
+
diff --git a/clientarea/views/header.php b/clientarea/views/header.php new file mode 100644 index 0000000..a877645 --- /dev/null +++ b/clientarea/views/header.php @@ -0,0 +1,29 @@ + + + + + + + + + + + Client Area + + + + + + + + + diff --git a/clientarea/views/index.php b/clientarea/views/index.php new file mode 100644 index 0000000..a3de1d1 --- /dev/null +++ b/clientarea/views/index.php @@ -0,0 +1,2 @@ + + +
+
+
+ +
+
+

Login

+
+
+

Please fill in credentials to log in.

+
+
+ + + +
+
+ + + +
+
+ + +
+
+
+ +
+
+
+
diff --git a/clientarea/views/logout.php b/clientarea/views/logout.php new file mode 100644 index 0000000..f1e0183 --- /dev/null +++ b/clientarea/views/logout.php @@ -0,0 +1,26 @@ + +
+
+
+ +
+
+

Logout

+
+
+

What do you want to do.

+

+ Login + Register +

+
+
+
+
+
\ No newline at end of file diff --git a/clientarea/views/main.php b/clientarea/views/main.php new file mode 100644 index 0000000..0428063 --- /dev/null +++ b/clientarea/views/main.php @@ -0,0 +1,52 @@ + + +
+

Client Area

+
+
+ +
+
+

Client Area

+
+
+

Please fill in credentials to log in.

+
+ +
+
+
+
+ +
+
+

Project Client Area Features

+

Create the complete login and register form

+
+
+
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/clientarea/views/navbar.php b/clientarea/views/navbar.php new file mode 100644 index 0000000..6409737 --- /dev/null +++ b/clientarea/views/navbar.php @@ -0,0 +1,75 @@ + + + \ No newline at end of file diff --git a/clientarea/views/register.php b/clientarea/views/register.php new file mode 100644 index 0000000..97ef9c6 --- /dev/null +++ b/clientarea/views/register.php @@ -0,0 +1,61 @@ + + +
+
+
+ +
+
+

Account Register

+
+
+

Please fill in credentials to Sign Up.

+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+
+ +
+
+
+
diff --git a/clientarea/views/request-account-activate.php b/clientarea/views/request-account-activate.php new file mode 100644 index 0000000..e4c6b04 --- /dev/null +++ b/clientarea/views/request-account-activate.php @@ -0,0 +1,35 @@ + + +
+
+
+ +
+
+

Activate Account Request

+
+
+
+
+ + + +
+
+ +
+
+
+ +
+
+
+
diff --git a/clientarea/views/reset_password.php b/clientarea/views/reset_password.php new file mode 100644 index 0000000..b975374 --- /dev/null +++ b/clientarea/views/reset_password.php @@ -0,0 +1,43 @@ + + +
+
+
+ +
+
+

Reset Password

+
+
+

Please fill in credentials to Reset Password.

+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+
+
+
+
+
diff --git a/clientarea/views/tickets.php b/clientarea/views/tickets.php new file mode 100644 index 0000000..b26a4be --- /dev/null +++ b/clientarea/views/tickets.php @@ -0,0 +1,56 @@ + + +
+
+
+ +
+
+ Support Tickets + New Ticket +
+
+
+ + + + + + + + + + + + $value) { ?> + + + + + + + + + + + + + +
DateDepartmentSubjectStatusLast Updated
No Records Found
+
+
+ +
+
+
+
\ No newline at end of file