diff options
-rwxr-xr-x | create_thread.php | 33 | ||||
-rw-r--r-- | includes/form/CreateThreadForm.php | 45 | ||||
-rw-r--r-- | includes/form/Form.php | 45 | ||||
-rw-r--r-- | includes/form/RegisterForm.php | 56 | ||||
-rw-r--r-- | includes/form/SignInForm.php | 32 | ||||
-rwxr-xr-x | includes/model/User.php | 17 | ||||
-rwxr-xr-x | register.php | 116 | ||||
-rwxr-xr-x | signin.php | 61 |
8 files changed, 254 insertions, 151 deletions
diff --git a/create_thread.php b/create_thread.php index d01eb26..11b278c 100755 --- a/create_thread.php +++ b/create_thread.php @@ -42,36 +42,23 @@ if (!Session::get()->is_signed_in()) { <input type="submit" name="submit">
</form>
<?php
+include_once './includes/form/CreateThreadForm.php';
include_once './includes/model/Post.php';
include_once './includes/model/Thread.php';
include_once './includes/error.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- $post_content = filter_input(INPUT_POST, 'post_content', FILTER_SANITIZE_STRING);
- $thread_subject = filter_input(INPUT_POST, 'thread_subject', FILTER_SANITIZE_STRING);
- $thread_cat = filter_input(INPUT_POST, 'thread_cat', FILTER_SANITIZE_NUMBER_INT);
+ $form = new CreateThreadForm();
+ $post_content = $form->validate_post_content($_POST['post_content']);
+ $thread_subject = $form->validate_thread_subject($_POST['thread_subject']);
+ $thread_category = $form->validate_thread_category($_POST['thread_cat']);
- $errors = array();
- if (empty($thread_subject) or !$thread_subject) {
- $errors[] = 'Thread subject cannot be empty';
- }
- if (empty($post_content) or !$post_content) {
- $errors[] = 'Thread body cannot be empty';
- }
+ $form->on_success(function () use ($post_content, $thread_subject, $thread_category) {
+ $thread_id = Thread::create($thread_subject, $thread_category);
+ Post::create($post_content, $thread_id, $thread_category);
- if (!empty($errors)) {
- $errstr = 'Please check the following problems: <ul>';
- foreach ($errors as $err) {
- $errstr .= '<li>' . $err . '</li>';
- }
- $errstr .= '</ul>';
- trigger_error($errstr);
- } else {
- $thread_id = Thread::create($thread_subject, $thread_cat);
- Post::create($post_content, $thread_id, $thread_cat);
-
- header("Location: viewthread.php?id=" . $thread_id);
- }
+ header("Location: /viewthread.php?id=" . $thread_id);
+ });
}
?>
</body>
diff --git a/includes/form/CreateThreadForm.php b/includes/form/CreateThreadForm.php new file mode 100644 index 0000000..3774f6a --- /dev/null +++ b/includes/form/CreateThreadForm.php @@ -0,0 +1,45 @@ +<?php + +include_once './includes/form/Form.php'; + +class CreateThreadForm extends Form +{ + public function validate_post_content($post_content): ?string + { + $result = null; + + if (empty($post_content)) { + $this->report_error("Post content cannot be empty"); + } else { + $result = filter_var($post_content, FILTER_SANITIZE_STRING); + } + + return $result; + } + + public function validate_thread_subject($thread_subject): ?string + { + $result = null; + + if (empty($thread_subject)) { + $this->report_error("Thread subject cannot be empty"); + } else { + $result = filter_var($thread_subject, FILTER_SANITIZE_STRING); + } + + return $result; + } + + public function validate_thread_category($thread_category): ?int + { + $result = null; + + if (empty($thread_category)) { + $this->report_error("Invalid thread category"); + } else { + $result = filter_var($thread_category, FILTER_SANITIZE_NUMBER_INT); + } + + return $result; + } +}
\ No newline at end of file diff --git a/includes/form/Form.php b/includes/form/Form.php new file mode 100644 index 0000000..3f1bd62 --- /dev/null +++ b/includes/form/Form.php @@ -0,0 +1,45 @@ +<?php + +abstract class Form +{ + private $errors = array(); + private $success = true; + + protected function report_error($error_string) + { + $this->errors[] = $error_string; + $this->success = false; + } + + public function success(): bool + { + return $this->success; + } + + public function html_error_list(): string + { + if ($this->success) + return ""; + + if (count($this->errors) > 1) { + $result = '<ul>'; + foreach ($this->errors as $err) { + $result .= '<li>' . $err . '</li>'; + } + $result .= '</ul>'; + return $result; + } else { + return $this->errors[0]; + } + } + + public function on_success(Closure $param) + { + if ($this->success()) { + $param(); + } else { + echo '<p>Please check the following problems:</p>'; + trigger_error($this->html_error_list()); + } + } +}
\ No newline at end of file diff --git a/includes/form/RegisterForm.php b/includes/form/RegisterForm.php new file mode 100644 index 0000000..4967048 --- /dev/null +++ b/includes/form/RegisterForm.php @@ -0,0 +1,56 @@ +<?php + +include_once './includes/form/Form.php'; +include_once './includes/model/User.php'; + +class RegisterForm extends Form +{ + const USERNAME_REGEX = "/^[a-zA-Z0-9_]*$/"; + const PASSWORD_REGEX = "/^[a-zA-Z0-9\W]*$/"; + + public function validate_username($username): ?string + { + $result = null; + + if (empty($username)) { + $this->report_error("You must provide a username."); + } else { + $result = filter_var($username, FILTER_SANITIZE_STRING); + + if (!preg_match(self::USERNAME_REGEX, $result)) { + $this->report_error("Username can only contain letters, numbers and underscores."); + } + + if (strlen($result) > 30) { + $this->report_error("Your username must be 30 characters or less."); + } + + if (User::username_exists($result)) { + $this->report_error("The username '" . $result . "' has already been taken by another user."); + } + } + return $result; + } + + public function validate_password($password, $password_check): ?string + { + $result = null; + + if (empty($password)) { + $this->report_error("You must provide a password."); + } else { + $result = filter_var($password, FILTER_SANITIZE_STRING); + $pass_check = filter_var($password_check, FILTER_SANITIZE_STRING); + + if (preg_match(self::PASSWORD_REGEX, $result) === false) { + $this->report_error("Password contains invalid characters!"); + } + + if ($result !== $pass_check) { + $this->report_error("The two passwords do not match."); + } + } + + return $result; + } +} diff --git a/includes/form/SignInForm.php b/includes/form/SignInForm.php new file mode 100644 index 0000000..3735029 --- /dev/null +++ b/includes/form/SignInForm.php @@ -0,0 +1,32 @@ +<?php + +include_once './includes/form/Form.php'; + +class SignInForm extends Form +{ + public function validate_username($username): ?string + { + $result = null; + + if (empty($username)) { + $this->report_error('Please provide a username.'); + } else { + $result = filter_var($username, FILTER_SANITIZE_STRING); + } + + return $result; + } + + public function validate_password($password): ?string + { + $result = null; + + if (empty($password)) { + $this->report_error('Please provide a password.'); + } else { + $result = filter_var($password, FILTER_SANITIZE_STRING); + } + + return $result; + } +}
\ No newline at end of file diff --git a/includes/model/User.php b/includes/model/User.php index ba475c7..785b847 100755 --- a/includes/model/User.php +++ b/includes/model/User.php @@ -56,9 +56,10 @@ class User return $this->has_value;
}
- public static function register(string $username, string $pass_hash)
+ public static function register(string $username, string $password)
{
$sql = "INSERT INTO users(user_name, user_pass, user_date, user_level) VALUES(?, ?, NOW(), 0);";
+ $pass_hash = password_hash($password, PASSWORD_DEFAULT);
Database::get()->query($sql, "ss", $username, $pass_hash);
}
@@ -92,12 +93,12 @@ class User return $threads;
}
-}
-function username_exists(string $username): bool
-{
- $sql = "SELECT * FROM users WHERE user_name = ?;";
- $result = Database::get()->query($sql, "s", $username);
+ public static function username_exists(string $username): bool
+ {
+ $sql = "SELECT * FROM users WHERE user_name = ?;";
+ $result = Database::get()->query($sql, "s", $username);
- return !empty($result);
-}
\ No newline at end of file + return !empty($result);
+ }
+}
diff --git a/register.php b/register.php index 5128f10..34e43a0 100755 --- a/register.php +++ b/register.php @@ -1,78 +1,38 @@ -<?php session_start() ?>
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <title>Register an account - cflip.net forum</title>
-<?php include_once 'includes/templates/head.php'; ?>
-</head>
-<body>
-<?php include './includes/templates/header.php' ?>
- <h2>Register an account</h2>
- <form action="register.php" method="post">
- <label for="user_name">Username: </label><br>
- <input type="text" name="user_name"><br>
- <label for="user_pass">Password: </label><br>
- <input type="password" name="user_pass"><br>
- <label for="user_pass_check">Re-enter password: </label><br>
- <input type="password" name="user_pass_check"><br>
- <input type="submit" name="submit">
- </form>
- <br>
-<?php
-include_once './includes/model/User.php';
-include_once './includes/error.php';
-
-if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- $errors = array();
-
- $user_name = "";
- $user_pass = "";
-
- if (empty($_POST['user_name'])) {
- $errors[] = "You must provide a username.";
- } else {
- $user_name = $_POST['user_name'];
- if (!preg_match("/^[a-zA-Z0-9_]*$/", $user_name)) {
- $errors[] = "Username can only contain letters, numbers and underscores.";
- }
-
- if (strlen($user_name) > 30) {
- $errors[] = "Your username must be 30 characters or less.";
- }
-
- if (username_exists($user_name) !== false) {
- $errors[] = "The username '" . $user_name . "' has already been taken by another user.";
- }
- }
-
- if (empty($_POST['user_pass'])) {
- $errors[] = "You must provide a password.";
- } else {
- $user_pass = $_POST['user_pass'];
- $pass_check = $_POST['user_pass_check'];
-
- if (preg_match("/^[a-zA-Z0-9\W]*$/", $user_pass) === false) {
- $errors[] = "Password contains invalid characters!";
- }
-
- if ($user_pass !== $pass_check) {
- $errors[] = "The two passwords do not match.";
- }
- }
-
- if (!empty($errors)) {
- $errstr = 'Please check the following problems: <ul>';
- foreach ($errors as $err) {
- $errstr .= '<li>' . $err . '</li>';
- }
- $errstr .= '</ul>';
- trigger_error($errstr);
- } else {
- $pass_hash = password_hash($user_pass, PASSWORD_DEFAULT);
- User::register($user_name, $pass_hash);
- echo '<p class="success">Account successfully registered! You can now <a href="signin.php">sign in</a></p>';
- }
-}
-?>
-</body>
-</html>
+<?php session_start() ?> +<!DOCTYPE html> +<html lang="en"> +<head> + <title>Register an account - cflip.net forum</title> +<?php include_once 'includes/templates/head.php'; ?> +</head> +<body> +<?php include './includes/templates/header.php' ?> + <h2>Register an account</h2> + <form action="register.php" method="post"> + <label for="user_name">Username: </label><br> + <input type="text" name="user_name"><br> + <label for="user_pass">Password: </label><br> + <input type="password" name="user_pass"><br> + <label for="user_pass_check">Re-enter password: </label><br> + <input type="password" name="user_pass_check"><br> + <input type="submit" name="submit"> + </form> + <br> +<?php +include_once './includes/form/RegisterForm.php'; +include_once './includes/model/User.php'; +include_once './includes/error.php'; + +if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $form = new RegisterForm(); + $username = $form->validate_username($_POST['user_pass']); + $password = $form->validate_password($_POST['user_pass'], $_POST['user_pass_check']); + + $form->on_success(function () use ($username, $password) { + User::register($username, $password); + echo '<p class="success">Account successfully registered! You can now <a href="/signin.php">sign in</a></p>'; + }); +} +?> +</body> +</html> @@ -16,52 +16,29 @@ <input type="submit" name="submit">
</form>
<?php
-include_once 'includes/error.php';
-
-function validate($data): string
-{
- $data = trim($data);
- $data = stripslashes($data);
- return htmlspecialchars($data);
-}
+include_once './includes/form/SignInForm.php';
+include_once './includes/error.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- $errors = array();
-
- if (empty($_POST['user_name'])) {
- $errors[] = 'Please provide a username.';
- } else {
- $user_name = validate($_POST['user_name']);
- }
-
- if (empty($_POST['user_pass'])) {
- $errors[] = 'Please provide a password.';
- } else {
- $user_pass = $_POST['user_pass'];
- }
+ $form = new SignInForm();
+ $username = $form->validate_username($_POST['user_name']);
+ $password = $form->validate_password($_POST['user_pass']);
- if (!empty($errors)) {
- $errstr = 'Please check the following problems: <ul>';
- foreach ($errors as $err) {
- $errstr .= '<li>' . $err . '</li>';
- }
- $errstr .= '</ul>';
- trigger_error($errstr);
- } else {
- $user = new User();
- $user->get_by_name($user_name);
+ $form->on_success(function () use ($username, $password) {
+ $user = new User();
+ $user->get_by_name($username);
- if (!$user->has_value()) {
- trigger_error('There is no user with that name. Did you mean to <a href="register.php">create a new account?</a>');
- } else {
- if (!password_verify($user_pass, $user->password)) {
- echo 'Password does not match!';
- } else {
- Session::get()->sign_in($user);
- header("Location: index.php");
- }
- }
- }
+ if (!$user->has_value()) {
+ trigger_error('There is no user with that name. Did you mean to <a href="register.php">create a new account?</a>');
+ } else {
+ if (!password_verify($password, $user->password)) {
+ echo 'Password does not match!';
+ } else {
+ Session::get()->sign_in($user);
+ header("Location: /");
+ }
+ }
+ });
}
?>
</body>
|