summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcflip <36554078+cflip@users.noreply.github.com>2021-05-08 17:30:08 -0600
committerGitHub <noreply@github.com>2021-05-08 17:30:08 -0600
commit87b1dfd1f77b08915ee5e905da45e316ba2c0e7d (patch)
treef6c0f8d09454b6e887df0f66ca37c1ce9efb30d0
parent0b045d57b2164b5ce003955d79627ae506a153eb (diff)
parenta09d9f377f5c055e42e5f21b5cdea64c2e2ca896 (diff)
Merge pull request #14 from cflip/refactor
Huge refactor
-rw-r--r--.gitignore2
-rw-r--r--README.md3
-rw-r--r--TODO17
-rw-r--r--change_passw.php69
-rw-r--r--create_thread.php69
-rw-r--r--includes/Database.php82
-rw-r--r--includes/Session.php57
-rw-r--r--includes/db_inc.php14
-rw-r--r--includes/functions_category.php17
-rw-r--r--includes/functions_display.php110
-rw-r--r--includes/functions_insert.php35
-rw-r--r--includes/functions_post.php159
-rw-r--r--includes/functions_thread.php67
-rw-r--r--includes/functions_user.php31
-rw-r--r--includes/model/Category.php56
-rw-r--r--includes/model/Post.php36
-rw-r--r--includes/model/Thread.php65
-rw-r--r--includes/model/User.php43
-rw-r--r--includes/reply_inc.php31
-rw-r--r--includes/signout_inc.php6
-rw-r--r--includes/templates/404.php (renamed from templates/404.php)0
-rw-r--r--includes/templates/header.php (renamed from templates/header.php)8
-rw-r--r--index.php94
-rw-r--r--manage_post.php113
-rw-r--r--model/Category.php103
-rw-r--r--model/Post.php121
-rw-r--r--model/Thread.php111
-rw-r--r--model/User.php57
-rw-r--r--moderate.php24
-rw-r--r--register.php63
-rw-r--r--search.php115
-rw-r--r--signin.php56
-rw-r--r--signout.php16
-rw-r--r--styles/style.css23
-rw-r--r--viewcategory.php86
-rw-r--r--viewthread.php79
-rw-r--r--viewuser.php17
37 files changed, 1000 insertions, 1055 deletions
diff --git a/.gitignore b/.gitignore
index 394de92..f2ca6e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
.vscode
+.idea
+
config.ini \ No newline at end of file
diff --git a/README.md b/README.md
index 2255372..80c9d54 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,9 @@
# cflip.net forums
The source code to my first PHP project, a forum system.
+## Requirements
+This project requires PHP 7.0 or newer
+
## Setup
- Create a `config.ini` file and put your MySQL credentials in (see `config.example.ini`)
- `setup.sql` has the SQL script to set up your database.
diff --git a/TODO b/TODO
deleted file mode 100644
index 879a858..0000000
--- a/TODO
+++ /dev/null
@@ -1,17 +0,0 @@
-IMPROVE EXISTING CODE
-[v] Object-oriented code
-[ ] Clean up table printing code
-[v] Fix thread create page
-[ ] Clean up links
-[ ] Create 404 pages
-
-CREATE NEW PAGES
-[ ] Come up with designs for each page
-[ ] Create search page (all posts, threads, users + search)
-[ ] User profile picture + description
-[ ] Scrolling banners for each category
-
-CLEAN UP PAGES
-[ ] Create .htaccess for all pages/directories
- - block off all .php files
-[ ] Create CSS style \ No newline at end of file
diff --git a/change_passw.php b/change_passw.php
index aa8de88..31e0e0d 100644
--- a/change_passw.php
+++ b/change_passw.php
@@ -1,28 +1,11 @@
-<?php include_once 'header.php';?>
-
-<section>
<?php
- // FIXME
- if (!isset($_SESSION) or empty($_SESSION['signed_in']) or !$_SESSION['signed_in']) {
- echo '<h2>You must be logged in to change your password.</h2>';
- } else {
- echo '
- <h2>Change your password</h2>
- <form action="change_passw.php" method="post">
- <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>';
- }
-?>
+include_once './includes/Session.php';
+include_once './includes/model/User.php';
+include_once './includes/functions_user.php';
-<?php
-include_once 'includes/db_inc.php';
+session_start();
-if ($_SERVER['REQUEST_METHOD'] == 'POST' and $_SESSION['signed_in']) {
+if ($_SERVER['REQUEST_METHOD'] == 'POST' and Session::get()->is_signed_in()) {
$errors = array();
$user_pass = "";
@@ -48,24 +31,36 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST' and $_SESSION['signed_in']) {
}
echo '</ul>';
} else {
- $sql = "UPDATE users SET user_pass = ? WHERE user_id = ?;";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- die('Could not create account due to internal error: ' . mysqli_error($dbc));
- }
-
$pass_hash = password_hash($user_pass, PASSWORD_DEFAULT);
-
- mysqli_stmt_bind_param($stmt, "ss", $pass_hash, $_SESSION['user_id']);
- mysqli_stmt_execute($stmt);
- mysqli_stmt_close($stmt);
-
+ change_password(Session::get()->get_current_user(), $pass_hash);
echo 'Password successfully changed!';
}
}
?>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Change your password - cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
+</head>
+<body>
+<?php
+include_once './includes/templates/header.php';
-</section>
-
-<?php include_once 'footer.php';?>
+if (!Session::get()->is_signed_in()) {
+ echo '<h2>You must be logged in to change your password.</h2>';
+} else {
+ echo '
+ <h2>Change your password</h2>
+ <form action="change_passw.php" method="post">
+ <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>';
+}
+?>
+</body>
+</html>
diff --git a/create_thread.php b/create_thread.php
index 4598ce2..6fb7df9 100644
--- a/create_thread.php
+++ b/create_thread.php
@@ -1,63 +1,60 @@
-<?php session_start()?>
+<?php session_start() ?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title>Create a thread - cflip.net forum</title>
- <link rel="stylesheet" href="styles/style.css">
+ <title>Create a thread - cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
</head>
<body>
-<?php include_once 'templates/header.php' ?>
+<?php include_once 'includes/templates/header.php' ?>
<h2>Create a new thread</h2>
<?php
-if (!isset($_SESSION['signed_in'])) {
- die('You must be <a href="signin.php">signed in</a> to create a thread.');
-}
+include_once 'includes/Session.php';
+if (!Session::get()->is_signed_in()) {
+ trigger_error('You must be <a href="signin.php">signed in</a> to create a thread.');
+ exit();
+}
?>
-<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
- <label for="thread_subject">Subject: </label><br>
- <input type="text" name="thread_subject"><br>
- <label for="thread_cat">Category: </label><br>
+<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
+ <label for="thread_subject">Subject: </label><br>
+ <input type="text" name="thread_subject"><br>
+ <label for="thread_cat">Category: </label><br>
<?php
- include_once 'includes/db_inc.php';
- include_once 'model/Category.php';
+ include_once './includes/functions_category.php';
+ include_once './includes/model/Category.php';
- $categories = get_all_categories($dbc);
+ $categories = get_all_categories();
- if (count($categories) == 0) {
- echo 'There are no categories to post to!';
- } else {
- echo '<select name="thread_cat">';
+ if (count($categories) == 0) {
+ echo 'There are no categories to post to!';
+ } else {
+ echo '<select name="thread_cat">';
- foreach ($categories as $category) {
- echo '<option value="' . $category->id . '">' . $category->name . '</option>';
- }
-
- echo '</select><br>';
+ foreach ($categories as $category) {
+ echo '<option value="' . $category->id . '">' . $category->name . '</option>';
}
+
+ echo '</select><br>';
+ }
?>
- <label for="post_content">Write your post: </label><br>
- <textarea name="post_content"></textarea><br>
- <input type="submit" name="submit">
+ <label for="post_content">Write your post: </label><br>
+ <textarea name="post_content"></textarea><br>
+ <input type="submit" name="submit">
</form>
<?php
-include_once 'includes/db_inc.php';
-include_once 'includes/functions_insert.php';
+include_once 'includes/functions_post.php';
+include_once 'includes/functions_thread.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);
- $user_id = filter_var($_SESSION['user_id'], FILTER_SANITIZE_NUMBER_INT);
if (empty($thread_subject) or !$thread_subject) {
echo 'Thread subject cannot be empty';
} else {
- insert_thread($dbc, $thread_subject, $thread_cat, $user_id);
- $thread_id = mysqli_insert_id($dbc);
- insert_post($dbc, $post_content, $thread_id, $user_id, $thread_cat);
-
- $sql = "UPDATE categories SET `cat_thread_count` = `cat_thread_count` + '1' WHERE cat_id = " . $thread_cat . ";";
- mysqli_query($dbc, $sql);
+ $thread_id = create_thread($thread_subject, $thread_cat);
+ create_post($post_content, $thread_id, $thread_cat);
header("Location: viewthread.php?id=" . $thread_id);
}
diff --git a/includes/Database.php b/includes/Database.php
new file mode 100644
index 0000000..4950ae3
--- /dev/null
+++ b/includes/Database.php
@@ -0,0 +1,82 @@
+<?php
+
+class Database
+{
+ private static $instance = null;
+ private $sql_connection;
+
+ private function __construct()
+ {
+ $config = parse_ini_file('config.ini', true)['mysql_credentials'];
+
+ $db_server = $config['server'];
+ $db_user = $config['user'];
+ $db_pass = $config['password'];
+ $db_database = $config['database'];
+
+ $this->sql_connection = mysqli_connect($db_server, $db_user, $db_pass, $db_database);
+
+ if (!$this->sql_connection) {
+ trigger_error("Database connection error: " . mysqli_connect_error());
+ }
+ }
+
+ public static function get()
+ {
+ if (self::$instance == null) {
+ self::$instance = new Database();
+ }
+
+ return self::$instance;
+ }
+
+ public function query(string $sql, string $types = "", ...$vars): array
+ {
+ $result = array();
+
+ if ($types == "") {
+ // No types were provided, preparing a statement is not necessary
+ $db_result = mysqli_query($this->sql_connection, $sql);
+ } else {
+ $stmt = mysqli_stmt_init($this->sql_connection);
+
+ if (!mysqli_stmt_prepare($stmt, $sql)) {
+ trigger_error('Internal error: ' . mysqli_error($this->sql_connection));
+ return $result;
+ }
+
+ mysqli_stmt_bind_param($stmt, $types, ...$vars);
+ mysqli_stmt_execute($stmt);
+
+ $db_result = mysqli_stmt_get_result($stmt);
+
+ mysqli_stmt_close($stmt);
+ }
+
+ if (!$db_result) {
+ return $result;
+ }
+
+ if (mysqli_num_rows($db_result) > 0) {
+ while ($row = mysqli_fetch_assoc($db_result)) {
+ array_push($result, $row);
+ }
+ }
+
+ mysqli_free_result($db_result);
+
+ return $result;
+ }
+
+ /**
+ * Returns the auto generated ID of the last query.
+ * This function is just a wrapper for mysqli_insert_id.
+ * In the future, it might be better to return different
+ * values in the query function depending on the type of
+ * SQL query.
+ */
+ public function get_last_id()
+ {
+ return mysqli_insert_id($this->sql_connection);
+ }
+} \ No newline at end of file
diff --git a/includes/Session.php b/includes/Session.php
new file mode 100644
index 0000000..7951d70
--- /dev/null
+++ b/includes/Session.php
@@ -0,0 +1,57 @@
+<?php
+
+class Session
+{
+ private static $instance = null;
+
+ private function __construct()
+ {
+ if (session_status() == PHP_SESSION_NONE)
+ session_start();
+ }
+
+ public static function get()
+ {
+ if (self::$instance == null) {
+ self::$instance = new Session();
+ }
+
+ return self::$instance;
+ }
+
+ public function sign_in(User $user)
+ {
+ $_SESSION['signed_in'] = true;
+ $_SESSION['user_id'] = $user->id;
+ $_SESSION['user_name'] = $user->name;
+ }
+
+ public function sign_out()
+ {
+ session_unset();
+ session_destroy();
+ }
+
+ public function is_signed_in(): bool
+ {
+ return isset($_SESSION['signed_in']);
+ }
+
+ public function get_current_user()
+ {
+ // There is no current user
+ if (!$this->is_signed_in()) {
+ return null;
+ }
+
+ $result = new User();
+
+ if (isset($_SESSION['user_id'])) {
+ $result->get_by_id($_SESSION['user_id']);
+ } else {
+ $result = null;
+ }
+
+ return $result;
+ }
+} \ No newline at end of file
diff --git a/includes/db_inc.php b/includes/db_inc.php
deleted file mode 100644
index b7c361d..0000000
--- a/includes/db_inc.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-$cfg_ini = parse_ini_file('config.ini', true);
-$dbcfg = $cfg_ini['mysql_credentials'];
-
-$db_server = $dbcfg['server'];
-$db_user = $dbcfg['user'];
-$db_pass = $dbcfg['password'];
-$db_database = $dbcfg['database'];
-
-$dbc = mysqli_connect($db_server, $db_user, $db_pass, $db_database);
-
-if (!$dbc) {
- die("Database connection error: " . mysqli_connect_error());
-}
diff --git a/includes/functions_category.php b/includes/functions_category.php
new file mode 100644
index 0000000..808708c
--- /dev/null
+++ b/includes/functions_category.php
@@ -0,0 +1,17 @@
+<?php
+
+function get_all_categories(): array
+{
+ $sql = "SELECT cat_id FROM categories ORDER BY cat_id;";
+ $result = Database::get()->query($sql);
+
+ $categories = array();
+
+ foreach ($result as $row) {
+ $category = new Category();
+ $category->get_from_database($row['cat_id']);
+ array_push($categories, $category);
+ }
+
+ return $categories;
+} \ No newline at end of file
diff --git a/includes/functions_display.php b/includes/functions_display.php
deleted file mode 100644
index bf9ed64..0000000
--- a/includes/functions_display.php
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-
-function display_navbar($dbc) {
-
-}
-
-function display_categories($dbc, $sql_result) {
- $sql = "SELECT thread_id, thread_subject, thread_date, user_id, user_name FROM threads JOIN users ON thread_author = user_id WHERE thread_cat = ? ORDER BY thread_id DESC LIMIT 1";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- die('Could not create thread due to internal error: ' . mysqli_error($dbc));
- }
-
- while ($row = mysqli_fetch_assoc($sql_result)) {
- mysqli_stmt_bind_param($stmt, "i", $row['cat_id']);
- mysqli_stmt_execute($stmt);
-
- $thread_res = mysqli_stmt_get_result($stmt);
- $thread = mysqli_fetch_assoc($thread_res);
-
- echo '<tr><td class="left">';
- echo '<h4><a href="category.php?id=' . $row['cat_id'] . '">' . $row['cat_name'] . '</a></h4>';
- echo $row['cat_description'];
- if ($thread) {
- echo '</td><td class="right">' . $thread['thread_subject'] . '<br>';
- echo '<small>by <b><a href="user.php?id=' . $thread['user_id'] . '">' . $thread['user_name'] . '</a></b></small></td></tr>';
- } else {
- $no_threads_msg = 'There are no threads in this category yet.';
- echo '</td><td class="right"><small>'. $no_threads_msg .'</small></td>';
- }
- }
-
- mysqli_stmt_close($stmt);
- mysqli_free_result($thread_res);
-}
-
-function display_threads($dbc, $sql_result, $show_category = false) {
- $sql = "SELECT post_id, post_date, user_id, user_name FROM posts JOIN users ON post_author = user_id WHERE post_thread = ? ORDER BY post_id DESC LIMIT 1";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- die('Could not create thread due to internal error: ' . mysqli_error($dbc));
- }
-
- while ($row = mysqli_fetch_assoc($sql_result)) {
- mysqli_stmt_bind_param($stmt, "i", $row['thread_id']);
- mysqli_stmt_execute($stmt);
-
- $thread_res = mysqli_stmt_get_result($stmt);
- $thread = mysqli_fetch_assoc($thread_res);
-
- echo '<tr><td class="left">';
- echo '<h4><a href="thread.php?id=' . $row['thread_id'] . '">' . $row['thread_subject'] . '</a></h4>';
- echo '<small>by <b><a href="user.php?id=' . $row['user_id'] . '">' . $row['user_name'] . '</a></b> ';
- if ($show_category) {
- echo 'in <b><a href="category.php?id=' . $row['cat_id'] . '">' . $row['cat_name'] . '</a></b> ';
- }
- echo 'on ' . date('M d, Y', strtotime($row['thread_date'])) . '</small>';
- echo '</td><td class="right">by <b><a href="user.php?id=' . $thread['user_id'] . '">' . $thread['user_name'] . '</a></b><br>';
- echo '<small>' . date('m/d/Y g:ia', strtotime($thread['post_date'])) . '</small></td></tr>';
- }
-
- mysqli_stmt_close($stmt);
-}
-
-function add_quote($dbc, $thread_id, $matches) {
- foreach ($matches as $match) {
- $id = (int) filter_var($match, FILTER_SANITIZE_NUMBER_INT) - 1;
- $sql = "SELECT post_content, post_author, user_name FROM posts LEFT JOIN users ON post_author = user_id WHERE post_thread = " . $thread_id . " LIMIT 1 OFFSET " . $id;
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- return '<blockquote></blockquote>';
- }
-
- $reply = mysqli_fetch_assoc($result);
-
- if (empty($reply)) {
- return '<blockquote>Invalid quote!</blockquote>';
- }
-
- $id = $id + 1;
-
- return '<blockquote><a href="#' . $id .'">Quote from ' . $reply['user_name'] . '</a><br>' . $reply['post_content'] . '</blockquote>';
- }
-}
-
-function display_posts($dbc, $thread_id, $sql_result) {
- while ($row = mysqli_fetch_assoc($sql_result)) {
- echo '#' . $row['post_id'] . ' Posted by <a href="user.php?id='. $row['user_id'] .'">' . $row['user_name'] . '</a> on ' . date('m/d/Y g:ia', strtotime($row['post_date'])) . '<br>';
-
- $post_content = $row['post_content'];
-
- $post_content = preg_replace_callback('/>#\d+/', function($matches) use($thread_id, $dbc) {
- return add_quote($dbc, $thread_id, $matches);
- }, $post_content);
-
- // Replace YouTube URLs with embedded YouTube videos.
- $post_content = preg_replace(
- "/\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i",
- '<br><iframe class="youtube-embed" src="//www.youtube.com/embed/$2" allowfullscreen></iframe>', $post_content);
- // Replace Image URLs with embedded images.
- $post_content = preg_replace('@\b(http(s)?://)([^\s]*?(?:\.[a-z\d?=/_-]+)+(?:\.jpg|\.png|\.gif))(?![^<]*?(?:</\w+>|/?>))@i', '<img class="image-embed" src="http$2://$3" alt="http$2://$3" />', $post_content);
- // Replace other URLs with links.
- $post_content = preg_replace('@\b(http(s)?://)([^\s]*?(?:\.[a-z\d?=/_-]+)+)(?![^<]*?(?:</\w+>|/?>))@i', '<a href="http$2://$3">$0</a>', $post_content);
-
- echo $post_content;
- }
-} \ No newline at end of file
diff --git a/includes/functions_insert.php b/includes/functions_insert.php
deleted file mode 100644
index 4f60701..0000000
--- a/includes/functions_insert.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-// This file may be replaced by a MVC controller later on
-
-function insert_thread($dbc, $thread_subject, $thread_cat, $thread_author) {
- $sql = "INSERT INTO threads(thread_subject, thread_date_created, thread_date_lastpost, thread_category, thread_author) VALUES (?, CONVERT_TZ(NOW(), 'SYSTEM', '+00:00'), CONVERT_TZ(NOW(), 'SYSTEM', '+00:00'), ?, ?);";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- die('Could not create thread due to internal error: ' . mysqli_error($dbc));
- }
-
- mysqli_stmt_bind_param($stmt, "sii", $thread_subject, $thread_cat, $thread_author);
- mysqli_stmt_execute($stmt);
- mysqli_stmt_close($stmt);
-}
-
-function insert_post($dbc, $post_content, $post_thread, $post_author, $post_category) {
- $sql = "INSERT INTO posts(post_content, post_date_created, post_thread, post_author) VALUES (?, CONVERT_TZ(NOW(), 'SYSTEM', '+00:00'), ?, ?);";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- die('Could not create post due to internal error: ' . mysqli_error($dbc));
- }
-
- mysqli_stmt_bind_param($stmt, "sii", $post_content, $post_thread, $post_author);
- mysqli_stmt_execute($stmt);
- mysqli_stmt_close($stmt);
-
- $sql = "UPDATE categories SET `cat_post_count` = `cat_post_count` + '1' WHERE cat_id = " . $post_category . ";";
- mysqli_query($dbc, $sql);
-
- $sql = "UPDATE threads SET thread_date_lastpost = CONVERT_TZ(NOW(), 'SYSTEM', '+00:00') WHERE thread_id = " . $post_thread . ";";
- mysqli_query($dbc, $sql);
-}
diff --git a/includes/functions_post.php b/includes/functions_post.php
new file mode 100644
index 0000000..97fc622
--- /dev/null
+++ b/includes/functions_post.php
@@ -0,0 +1,159 @@
+<?php
+include_once './includes/Session.php';
+include_once './includes/Database.php';
+include_once './includes/model/User.php';
+
+function get_all_posts(): array
+{
+ $sql = "SELECT post_id FROM posts";
+ $result = Database::get()->query($sql);
+
+ $posts = array();
+
+ foreach ($result as $row) {
+ $post = new Post();
+ $post->get_from_database($row['post_id']);
+ array_push($posts, $post);
+ }
+
+ return $posts;
+}
+
+function create_post($post_content, $post_thread, $post_category)
+{
+ // User must be signed in
+ if (!Session::get()->is_signed_in()) {
+ trigger_error('You must be signed in to create a post');
+ return;
+ }
+
+ $user = Session::get()->get_current_user();
+
+ // Insert the post into the database
+ $sql = "INSERT INTO posts(post_content, post_date_created, post_thread, post_author) VALUES (?, CONVERT_TZ(NOW(), 'SYSTEM', '+00:00'), ?, ?);";
+ Database::get()->query($sql, "sii", $post_content, $post_thread, $user->id);
+
+ // Increment the category's post count
+ $sql = "UPDATE categories SET `cat_post_count` = `cat_post_count` + '1' WHERE cat_id = ?;";
+ Database::get()->query($sql, "i", $post_category);
+
+ // Set the last post date of the parent thread
+ $sql = "UPDATE threads SET thread_date_lastpost = CONVERT_TZ(NOW(), 'SYSTEM', '+00:00') WHERE thread_id = ?;";
+ Database::get()->query($sql, "i", $post_thread);
+}
+
+function create_quote(int $id): string
+{
+ $sql = "SELECT post_content, post_author, post_thread, user_name FROM posts LEFT JOIN users ON post_author = user_id WHERE post_id = ?;";
+ $result = Database::get()->query($sql, "i", $id);
+
+ $reply = $result[0];
+
+ if (empty($reply)) {
+ return '<blockquote><span style="color:red;">This post has been deleted</span></blockquote>';
+ }
+
+ return '<blockquote><a href="/viewthread.php?id=' . $reply['post_thread'] . '#p' . $id . '">Quote from ' . $reply['user_name'] . '</a><br>' . $reply['post_content'] . '</blockquote>';
+}
+
+function format_post_content(string $post_content)
+{
+ $post_content = preg_replace_callback('/>#\d+/', function ($matches) {
+ $result = "";
+ foreach ($matches as $match) {
+ $id = (int) filter_var($match, FILTER_SANITIZE_NUMBER_INT);
+ $result .= create_quote($id);
+ }
+ return $result;
+ }, $post_content);
+
+ $result = $post_content;
+
+ // Replace newline characters with HTML <br> tags
+ $result = nl2br($result);
+
+ // Replace YouTube URLs with embedded YouTube videos.
+ $result = preg_replace(
+ "/\s*[a-zA-Z\/:]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/*-_?&;%=.]*)/i",
+ '<br><iframe class="youtube-embed" src="//www.youtube.com/embed/$2" allowfullscreen></iframe>', $result);
+
+ // Replace Image URLs with embedded images.
+ $result = preg_replace('@\b(http(s)?://)([^\s]*?(?:\.[a-z\d?=/_-]+)+(?:\.jpg|\.png|\.gif))(?![^<]*?(?:</\w+>|/?>))@i', '<img class="image-embed" src="http$2://$3" alt="http$2://$3" />', $result);
+
+ // Replace other URLs with links.
+ return preg_replace('@\b(http(s)?://)([^\s]*?(?:\.[a-z\d?=/_-]+)+)(?![^<]*?(?:</\w+>|/?>))@i', '<a href="http$2://$3">$0</a>', $result);
+}
+
+/**
+ * Get the post content from the database and return it as a string ready for HTML display
+ */
+function get_post_content(Post $post): string
+{
+ // Build the header
+ $result = '<div class="header" id="p' . $post->id . '"><b>#' . $post->id . '</b>';
+ $result .= ' Posted by <a href="viewuser.php?id=' . $post->author->id . '">' . $post->author->name . '</a>';
+ $result .= ' on ' . date('m/d/Y g:ia', strtotime($post->date_created));
+
+ // If the post has a edit date, display it
+ if (!is_null($post->date_edited)) {
+ $result .= ' <small>edited ' . date('m/d/Y g:ia', strtotime($post->date_edited)) . '</small>';
+ }
+
+ // Append a manage post button if the user is signed in and is the post's creator
+ if (Session::get()->is_signed_in() && Session::get()->get_current_user()->id == $post->author->id) {
+ $result .= '<span style="float:right;">';
+ $result .= '[<a href="manage_post.php?id=' . $post->id . '">Edit/Delete</a>]';
+ $result .= '</span>';
+ }
+ $result .= '</div>';
+
+ // Append the formatted post content
+ $result .= '<span class="post-content">' . format_post_content($post->content) . '</span>';
+
+ return $result;
+}
+
+function edit_post(Post $post, string $post_content)
+{
+ // User must be signed in
+ if (!Session::get()->is_signed_in()) {
+ trigger_error('You must be signed in to edit this post!');
+ return;
+ }
+
+ // User must have permission to edit the post
+ $current_user = Session::get()->get_current_user();
+ if ($current_user->id != $post->author->id) {
+ trigger_error("You don't have sufficient permissions to edit this post.");
+ return;
+ }
+
+ // Set the post content and the post edit date
+ $sql = "UPDATE posts SET post_content = ?, post_date_edited = CONVERT_TZ(NOW(), 'SYSTEM', '+00:00') WHERE post_id = ?;";
+ Database::get()->query($sql, "si", $post_content, $post->id);
+}
+
+function delete_post(Post $post)
+{
+ // User must be signed in
+ if (!Session::get()->is_signed_in()) {
+ trigger_error('You must be signed in to delete a post!');
+ return;
+ }
+
+ // User must have permission to delete the post
+ $current_user = Session::get()->get_current_user();
+ if ($current_user->id != $post->author->id || $current_user->level != USER_LEVEL_MODERATOR) {
+ trigger_error("You don't have sufficient permissions to delete this post.");
+ return;
+ }
+
+ // TODO: The post must not be locked
+ // TODO: The post must have not been around for a certain amount of time
+
+ // Delete the post from the database
+ Database::get()->query("DELETE FROM posts WHERE post_id = ?", "i", $post->id);
+
+ // Decrement the post count of the category
+ Database::get()->query("UPDATE categories SET `cat_post_count` = `cat_post_count` - '1' WHERE cat_id = ?", "i", $post->thread->category->id);
+}
diff --git a/includes/functions_thread.php b/includes/functions_thread.php
new file mode 100644
index 0000000..61b8e59
--- /dev/null
+++ b/includes/functions_thread.php
@@ -0,0 +1,67 @@
+<?php
+include_once './includes/Database.php';
+include_once './includes/Session.php';
+
+function get_all_threads(): array
+{
+ $sql = "SELECT thread_id FROM threads";
+ $result = Database::get()->query($sql);
+
+ $threads = array();
+
+ foreach ($result as $row) {
+ $thread = new Thread();
+ $thread->get_from_database($row['thread_id']);
+ array_push($threads, $thread);
+ }
+
+ return $threads;
+}
+
+function create_thread($subject, $category)
+{
+ if (!Session::get()->is_signed_in()) {
+ trigger_error('You must be signed in to create a thread');
+ return 0;
+ }
+
+ $user = Session::get()->get_current_user();
+
+ // Insert the new thread into the database
+ $sql = "INSERT INTO threads(thread_subject, thread_date_created, thread_date_lastpost, thread_category, thread_author) VALUES (?, CONVERT_TZ(NOW(), 'SYSTEM', '+00:00'), CONVERT_TZ(NOW(), 'SYSTEM', '+00:00'), ?, ?);";
+ Database::get()->query($sql, "sii", $subject, $category, $user->id);
+
+ // Get the ID of the thread we just created
+ $thread_id = Database::get()->get_last_id();
+
+ // Increment the category's thread count
+ $sql = "UPDATE categories SET `cat_thread_count` = `cat_thread_count` + '1' WHERE cat_id = ?;";
+ Database::get()->query($sql, "i", $category);
+
+ return $thread_id;
+}
+
+function delete_thread($thread)
+{
+ // User must be signed in
+ if (!Session::get()->is_signed_in()) {
+ trigger_error('You must be signed in to delete a thread.');
+ return;
+ }
+
+ // User must be a moderator to delete a thread
+ $current_user = Session::get()->get_current_user();
+ if ($current_user->level != USER_LEVEL_MODERATOR) {
+ trigger_error("You must be a moderator to delete this post.");
+ return;
+ }
+
+ // TODO: The post must not be locked
+ // TODO: The post must have not been around for a certain amount of time
+
+ // Delete the thread from the database
+ Database::get()->query("DELETE FROM threads WHERE thread_id = ?", "i", $thread->id);
+
+ // Decrement the thread count of the category
+ Database::get()->query("UPDATE categories SET `cat_thread_count` = `cat_thread_count` - '1' WHERE cat_id = ?", "i", $thread->category->id);
+} \ No newline at end of file
diff --git a/includes/functions_user.php b/includes/functions_user.php
new file mode 100644
index 0000000..690350a
--- /dev/null
+++ b/includes/functions_user.php
@@ -0,0 +1,31 @@
+<?php
+
+function username_exists(string $username): bool
+{
+ $sql = "SELECT * FROM users WHERE user_name = ?;";
+ $result = Database::get()->query($sql, "s", $username);
+
+ return !empty($result);
+}
+
+function register_user(string $username, string $pass_hash)
+{
+ $sql = "INSERT INTO users(user_name, user_pass, user_date, user_level) VALUES(?, ?, NOW(), 0);";
+ Database::get()->query($sql, "ss", $username, $pass_hash);
+}
+
+function change_password(User $user, string $pass_hash)
+{
+ if (!Session::get()->is_signed_in()) {
+ trigger_error('You are not signed in.');
+ return;
+ }
+
+ if (Session::get()->get_current_user()->id != $user->id) {
+ trigger_error("You can't change another user's password.");
+ return;
+ }
+
+ $sql = "UPDATE users SET user_pass = ? WHERE user_id = ?;";
+ Database::get()->query($sql, "si", $pass_hash, $user->id);
+} \ No newline at end of file
diff --git a/includes/model/Category.php b/includes/model/Category.php
new file mode 100644
index 0000000..ed53bdc
--- /dev/null
+++ b/includes/model/Category.php
@@ -0,0 +1,56 @@
+<?php
+
+include_once 'Thread.php';
+
+class Category
+{
+ public $id = 0;
+ public $name = 'Unknown';
+ public $description = 'This category does not exist';
+ public $thread_count = 0;
+ public $post_count = 0;
+
+ function get_from_database($id): bool
+ {
+ $sql = "SELECT cat_name, cat_description, cat_thread_count, cat_post_count FROM categories WHERE cat_id = ?;";
+ $result = Database::get()->query($sql, "i", $id);
+
+ if (empty($result)) {
+ return false;
+ }
+
+ $this->id = $id;
+ $this->name = $result[0]['cat_name'];
+ $this->description = $result[0]['cat_description'];
+ $this->thread_count = $result[0]['cat_thread_count'];
+ $this->post_count = $result[0]['cat_post_count'];
+
+ return true;
+ }
+
+ function get_threads(): array
+ {
+ $sql = "SELECT thread_id FROM threads WHERE thread_category = ? ORDER BY thread_date_lastpost DESC";
+ $result = Database::get()->query($sql, "i", $this->id);
+ $threads = array();
+
+ foreach ($result as $row) {
+ $thread = new Thread();
+ $thread->get_from_database($row['thread_id']);
+ array_push($threads, $thread);
+ }
+
+ return $threads;
+ }
+
+ function get_latest_thread(): Thread
+ {
+ $sql = "SELECT thread_id FROM threads WHERE thread_category = ? ORDER BY thread_date_lastpost DESC LIMIT 1";
+ $result = Database::get()->query($sql, "i", $this->id);
+
+ $thread = new Thread();
+ $thread->get_from_database($result[0]['thread_id']);
+
+ return $thread;
+ }
+}
diff --git a/includes/model/Post.php b/includes/model/Post.php
new file mode 100644
index 0000000..67c7e4a
--- /dev/null
+++ b/includes/model/Post.php
@@ -0,0 +1,36 @@
+<?php
+
+include_once 'Thread.php';
+
+class Post
+{
+ public $id;
+ public $content;
+ public $date_created;
+ public $date_edited;
+ public $thread;
+ public $author;
+
+ function get_from_database($id): bool
+ {
+ $sql = "SELECT post_content, post_date_created, post_date_edited, post_thread, post_author FROM posts WHERE post_id = ?;";
+ $result = Database::get()->query($sql, "i", $id);
+
+ if (empty($result)) {
+ return false;
+ }
+
+ $this->id = $id;
+ $this->content = $result[0]['post_content'];
+ $this->date_created = $result[0]['post_date_created'];
+ $this->date_edited = $result[0]['post_date_edited'];
+
+ $this->thread = new Thread();
+ $this->thread->get_from_database($result[0]['post_thread']);
+
+ $this->author = new User();
+ $this->author->get_by_id($result[0]['post_author']);
+
+ return true;
+ }
+}
diff --git a/includes/model/Thread.php b/includes/model/Thread.php
new file mode 100644
index 0000000..cfe10d6
--- /dev/null
+++ b/includes/model/Thread.php
@@ -0,0 +1,65 @@
+<?php
+
+include_once 'Category.php';
+include_once 'User.php';
+include_once 'Post.php';
+
+class Thread
+{
+ public $id = 0;
+ public $subject = 'Unknown thread';
+ public $date_created = 0;
+ public $date_lastpost = 0;
+ public $category;
+ public $author;
+
+ function get_from_database($id): bool
+ {
+ $sql = "SELECT thread_subject, thread_date_created, thread_date_lastpost, thread_category, thread_author FROM threads WHERE thread_id = ?;";
+ $result = Database::get()->query($sql, "i", $id);
+
+ if (empty($result)) {
+ return false;
+ }
+
+ $this->id = $id;
+ $this->subject = $result[0]['thread_subject'];
+ $this->date_created = $result[0]['thread_date_created'];
+ $this->date_lastpost = $result[0]['thread_date_lastpost'];
+
+ $this->category = new Category();
+ $this->category->get_from_database($result[0]['thread_category']);
+
+ $this->author = new User();
+ $this->author->get_by_id($result[0]['thread_author']);
+
+ return true;
+ }
+
+ function get_posts(): array
+ {
+ $sql = "SELECT post_id FROM posts WHERE post_thread = ?";
+ $result = Database::get()->query($sql, "i", $this->id);
+
+ $posts = array();
+
+ foreach ($result as $row) {
+ $post = new Post();
+ $post->get_from_database($row['post_id']);
+ array_push($posts, $post);
+ }
+
+ return $posts;
+ }
+
+ function get_latest_post(): Post
+ {
+ $sql = "SELECT post_id FROM posts WHERE post_thread = ? ORDER BY post_date_created DESC LIMIT 1";
+ $result = Database::get()->query($sql, "i", $this->id);
+
+ $post = new Post();
+ $post->get_from_database($result[0]['post_id']);
+
+ return $post;
+ }
+}
diff --git a/includes/model/User.php b/includes/model/User.php
new file mode 100644
index 0000000..f2bd23d
--- /dev/null
+++ b/includes/model/User.php
@@ -0,0 +1,43 @@
+<?php
+include_once './includes/Database.php';
+
+const USER_LEVEL_MODERATOR = 1;
+
+class User
+{
+ public $id;
+ public $name = 'Unknown';
+ public $password;
+ public $date = 0;
+ public $level = 0;
+
+ function get_by_name($name): bool
+ {
+ $sql = "SELECT user_id, user_date, user_level, user_pass FROM users WHERE user_name = ?";
+ $result = Database::get()->query($sql, "s", $name);
+
+ if (empty($result)) {
+ return false;
+ }
+
+ $this->id = $result[0]['user_id'];
+ $this->name = $name;
+ $this->password = $result[0]['user_pass'];
+ $this->date = $result[0]['user_date'];
+ $this->level = $result[0]['user_level'];
+
+ return true;
+ }
+
+ function get_by_id($id)
+ {
+ $sql = "SELECT user_name, user_date, user_level, user_pass FROM users WHERE user_id = ?;";
+ $result = Database::get()->query($sql, "i", $id);
+
+ $this->id = $id;
+ $this->name = $result[0]['user_name'];
+ $this->password = $result[0]['user_pass'];
+ $this->date = $result[0]['user_date'];
+ $this->level = $result[0]['user_level'];
+ }
+} \ No newline at end of file
diff --git a/includes/reply_inc.php b/includes/reply_inc.php
deleted file mode 100644
index cf7a839..0000000
--- a/includes/reply_inc.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-session_start();
-
-include_once 'db_inc.php';
-include_once 'functions_inc.php';
-
-if ($_SERVER['REQUEST_METHOD'] != 'POST') {
- die('This file cannot be called directly.');
-}
-
-if (!isset($_SESSION['signed_in'])) {
- die('You must be signed in to reply to a thread.');
-}
-
-$reply_content = filter_var($_POST['reply_content'], FILTER_SANITIZE_STRING);
-$reply_to = $_GET['reply_to'];
-$post_author = $_SESSION['user_id'];
-
-$sql = "INSERT INTO posts(post_content, post_date, post_thread, post_author) VALUES(?, NOW(), ?, ?)";
-$stmt = mysqli_stmt_init($dbc);
-
-if (!mysqli_stmt_prepare($stmt, $sql)) {
- die('Failed to process statement: ' . mysqli_error($dbc));
-}
-
-mysqli_stmt_bind_param($stmt, "sii", $reply_content, $reply_to, $post_author);
-mysqli_stmt_execute($stmt);
-mysqli_stmt_close($stmt);
-
-header("Location: ../thread.php?id=" . $_GET['reply_to']); \ No newline at end of file
diff --git a/includes/signout_inc.php b/includes/signout_inc.php
deleted file mode 100644
index 7859c4f..0000000
--- a/includes/signout_inc.php
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-session_start();
-session_unset();
-session_destroy();
-header("Location: ../index.php"); \ No newline at end of file
diff --git a/templates/404.php b/includes/templates/404.php
index d4d5128..d4d5128 100644
--- a/templates/404.php
+++ b/includes/templates/404.php
diff --git a/templates/header.php b/includes/templates/header.php
index 4eb17e3..1db9cda 100644
--- a/templates/header.php
+++ b/includes/templates/header.php
@@ -5,8 +5,12 @@
[<a href="/create_thread.php">Create a thread</a>]
<span style="float:right;">
<?php
- if (isset($_SESSION['signed_in'])) {
- echo '[<a href="viewuser.php?id='. $_SESSION['user_id'] .'">' . $_SESSION['user_name'] . '\'s Profile</a>] [<a href="includes/signout_inc.php">Log out</a>]';
+ include_once './includes/Session.php';
+ include_once './includes/model/User.php';
+
+ if (Session::get()->is_signed_in()) {
+ $user = Session::get()->get_current_user();
+ echo '[<a href="viewuser.php?id=' . $user->id . '">' . $user->name . '\'s Profile</a>] [<a href="signout.php">Log out</a>]';
} else {
echo '[<a href="signin.php">Sign in</a>] or [<a href="register.php">Register an account</a>]';
}
diff --git a/index.php b/index.php
index 7dd0fe4..9d62f52 100644
--- a/index.php
+++ b/index.php
@@ -1,62 +1,56 @@
-<?php session_start()?>
+<?php session_start() ?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title>cflip.net forum</title>
- <link rel="stylesheet" href="styles/style.css">
+ <title>cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
</head>
<body>
- <?php include_once 'templates/header.php'; ?>
- <h2>Welcome to the cflip.net forum!</h2>
- <p>
- This is the beta test of the forum website, so there are lots of features missing. Since there are no moderation features built into the website,
- <i>for the most part</i> I don't care that much about what is posted here. Some links and buttons may not have any functionality either!
- </p>
- <p>
- If you notice a problem or have an idea for a feature that is missing, <a href="http://51.195.90.7/forum/thread.php?id=40">reply to this thread!</a>
- </p>
- <h2>Categories</h2>
- <table>
- <tr>
- <th>Category</th>
- <th>Threads</th>
- <th>Posts</th>
- <th>Latest Thread</th>
- </tr>
+<?php include('includes/templates/header.php'); ?>
+<h2>Welcome to the cflip.net forum!</h2>
+<p>
+ This is the beta test of the forum website, so there are lots of features missing. Since there are no moderation
+ features built into the website,
+ <i>for the most part</i> I don't care that much about what is posted here. Some links and buttons may not have any
+ functionality either!
+</p>
+<p>
+ If you notice a problem or have an idea for a feature that is missing, <a
+ href="http://51.195.90.7/forum/thread.php?id=40">reply to this thread!</a>
+</p>
+<h2>Categories</h2>
+<table>
+ <tr>
+ <th>Category</th>
+ <th>Threads</th>
+ <th>Posts</th>
+ <th>Latest Thread</th>
+ </tr>
<?php
- include_once 'includes/db_inc.php';
- include_once 'model/Category.php';
+ include_once './includes/functions_category.php';
+ include_once './includes/model/Category.php';
- // TODO: The get_all_categories function should return them in the right order
- function cmp($a, $b) {
- if ($a->id == $b->id) {
- return 0;
- }
- return ($a->id < $b->id) ? -1 : 1;
- }
-
- $categories = get_all_categories($dbc);
- usort($categories, "cmp");
+ $categories = get_all_categories();
- foreach ($categories as $category) {
- $latest_thread = $category->get_latest_thread($dbc);
+ foreach ($categories as $category) {
+ $latest_thread = $category->get_latest_thread();
- echo '<tr>';
- echo '<td>';
- echo '<b><a href="viewcategory.php?id=' . $category->id . '">' . $category->name . '</a></b>';
- echo '<br><small>' . $category->description . '</small>';
- echo '</td>';
- echo '<td>' . $category->thread_count . '</td>';
- echo '<td>' . $category->post_count . '</td>';
- if (!is_null($latest_thread)) {
- echo '<td><b><a href="viewthread.php?id=' . $latest_thread->id . '">' . $latest_thread->subject . '</a></b><br>';
- echo '<small>by <b><a href="viewuser.php?id=' . $latest_thread->author->id . '">' . $latest_thread->author->name . '</a></b>, ' . $latest_thread->date_created . '</small></td>';
- } else {
- echo '<td>No threads yet!</td>';
- }
- echo '</tr>';
+ echo '<tr>';
+ echo '<td>';
+ echo '<b><a href="viewcategory.php?id=' . $category->id . '">' . $category->name . '</a></b>';
+ echo '<br><small>' . $category->description . '</small>';
+ echo '</td>';
+ echo '<td>' . $category->thread_count . '</td>';
+ echo '<td>' . $category->post_count . '</td>';
+ if (!is_null($latest_thread)) {
+ echo '<td><b><a href="viewthread.php?id=' . $latest_thread->id . '">' . $latest_thread->subject . '</a></b><br>';
+ echo '<small>by <b><a href="viewuser.php?id=' . $latest_thread->author->id . '">' . $latest_thread->author->name . '</a></b>, ' . $latest_thread->date_created . '</small></td>';
+ } else {
+ echo '<td>No threads yet!</td>';
}
+ echo '</tr>';
+ }
?>
- </table>
+</table>
</body>
</html>
diff --git a/manage_post.php b/manage_post.php
index 8c6129b..99f0ad4 100644
--- a/manage_post.php
+++ b/manage_post.php
@@ -1,15 +1,6 @@
<?php
-
-include_once 'includes/db_inc.php';
-include_once 'model/Post.php';
-
-function delete_post($dbc, $post) {
- $sql = "DELETE FROM posts WHERE post_id = $post->id";
- mysqli_query($dbc, $sql);
-
- $sql = "UPDATE categories SET `cat_post_count` = `cat_post_count` - '1' WHERE cat_id = " . $post->thread->category->id . ";";
- mysqli_query($dbc, $sql);
-}
+include_once './includes/functions_post.php';
+include_once './includes/model/Post.php';
session_start();
@@ -18,13 +9,13 @@ if ($_SERVER['REQUEST_METHOD'] == 'GET') {
if (!isset($_GET['id']) || !filter_var($_GET['id'], FILTER_VALIDATE_INT)) {
http_response_code(404);
- include_once 'templates/404.php';
+ include_once './includes/templates/404.php';
die();
} else {
- $result = $current->get_from_database($_GET['id'], $dbc);
+ $result = $current->get_from_database($_GET['id']);
if ($result == 0) {
http_response_code(404);
- include_once 'templates/404.php';
+ include_once './includes/templates/404.php';
die();
}
}
@@ -34,80 +25,56 @@ if ($_SERVER['REQUEST_METHOD'] == 'GET') {
$post_content = filter_input(INPUT_POST, 'post_content', FILTER_SANITIZE_STRING);
$post = new Post();
- $post->get_from_database($id, $dbc);
-
- if (!isset($_SESSION['signed_in'])) {
- echo 'You must be <a href="signin.php">signed in</a> to manage a post.';
- goto end;
- }
-
-
- if ($_SESSION['user_id'] != $post->author->id) {
- echo "You can't manage another user's post!";
- goto end;
- }
+ $post->get_from_database($id);
if (strcasecmp($delete, "on") == 0) {
- delete_post($dbc, $post);
+ delete_post($post);
} else {
- $sql = "UPDATE posts SET post_content = ?, post_date_edited = CONVERT_TZ(NOW(), 'SYSTEM', '+00:00') WHERE post_id = ?;";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- die('Could not create post due to internal error: ' . mysqli_error($dbc));
- }
-
- mysqli_stmt_bind_param($stmt, "si", $post_content, $id);
- mysqli_stmt_execute($stmt);
- mysqli_stmt_close($stmt);
+ edit_post($post, $post_content);
}
- end:
header("Location: /viewthread.php?id=" . $post->thread->id);
}
?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title>Manage a post - cflip.net forum</title>
- <link rel="stylesheet" href="/styles/style.css">
+ <title>Manage a post - cflip.net forum</title>
+ <link rel="stylesheet" href="/styles/style.css">
</head>
<body>
- <?php include_once 'templates/header.php' ?>
- <h1>Manage a post</h1>
- <?php
- $current->display_content($dbc);
- echo '<hr>';
-
- $id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
+<?php include('includes/templates/header.php'); ?>
+<h1>Manage a post</h1>
+<?php
+echo get_post_content($current);
+echo '<hr>';
- if (!isset($_SESSION['signed_in'])) {
- echo 'You must be <a href="signin.php">signed in</a> to manage a post.';
- return;
- }
+$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
- $current_user = new User();
- $current_user->get_by_id($_SESSION['user_id'], $dbc);
+if (!Session::get()->is_signed_in()) {
+ echo '<p class="error">You must be <a href="signin.php">signed in</a> to manage a post.</p>';
+ return;
+}
- // Admin users should be able to delete posts, but they should not be able to edit them
- // Or should they??
- if ($current_user->id != $current->author->id/* && $current_user->level < 1*/) {
- echo "You can't manage another user's post!";
- return;
- }
+// Admin users should be able to delete posts, but they should not be able to edit them
+// Or should they??
+if (Session::get()->get_current_user()->id != $current->author->id) {
+ echo '<p class="error">You can\'t manage another user\'s post!</p>';
+ return;
+}
- // TODO: Disallow editing/deleting posts if they have been around for a while
- ?>
- <form action="manage_post.php" method="post">
- <h3>Edit post</h3>
- <input type="hidden" name="id" value="<?= $current->id ?>">
- <textarea name="post_content" rows="10" cols="50"><?= $current->content; ?></textarea>
- <p>Edited posts will show a timestamp above the post showing when the last edit was made.</p>
- <p>
- <input type="checkbox" id="delete" name="delete">
- <label for="delete">Delete this post</label>
- </p>
- <input type="submit" value="Apply Changes">
- </form>
+// TODO: Disallow editing/deleting posts if they have been around for a while
+?>
+<form action="manage_post.php" method="post">
+ <h3>Edit post</h3>
+ <input type="hidden" name="id" value="<?= $current->id ?>">
+ <textarea name="post_content" rows="10" cols="50"><?= $current->content; ?></textarea>
+ <p>Edited posts will show a timestamp above the post showing when the last edit was made.</p>
+ <p>
+ <input type="checkbox" id="delete" name="delete">
+ <label for="delete">Delete this post</label>
+ </p>
+ <input type="submit" value="Apply Changes">
+</form>
</body>
</html>
diff --git a/model/Category.php b/model/Category.php
deleted file mode 100644
index 1b699fb..0000000
--- a/model/Category.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-include_once 'Thread.php';
-
-class Category {
- public $id = 0;
- public $name = 'Unknown';
- public $description = 'This category does not exist';
- public $thread_count = 0;
- public $post_count = 0;
-
- function get_from_database($id, $dbc) {
- $sql = "SELECT cat_name, cat_description, cat_thread_count, cat_post_count FROM categories WHERE cat_id = " . mysqli_real_escape_string($dbc, $id);
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Failed to get category: ' . mysqli_error($dbc);
- }
-
- if (mysqli_num_rows($result) == 0) {
- return 0;
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $this->id = $id;
- $this->name = $row['cat_name'];
- $this->description = $row['cat_description'];
- $this->thread_count = $row['cat_thread_count'];
- $this->post_count = $row['cat_post_count'];
- }
- }
-
- mysqli_free_result($result);
- return 1;
- }
-
- function get_threads($dbc) {
- $sql = "SELECT thread_id FROM threads WHERE thread_category = " . $this->id . " ORDER BY thread_date_lastpost";
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Could not get threads from category: ' . mysqli_error($dbc);
- }
-
- $threads = array();
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $thread = new Thread();
- $thread->get_from_database($row['thread_id'], $dbc);
- array_push($threads, $thread);
- }
- }
-
- mysqli_free_result($result);
- return $threads;
- }
-
- function get_latest_thread($dbc) {
- $sql = "SELECT thread_id FROM threads WHERE thread_category = " . $this->id . " ORDER BY thread_date_lastpost DESC LIMIT 1";
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Could not get thread from category: ' . mysqli_error($dbc);
- }
-
- $thread = null;
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $thread = new Thread();
- $thread->get_from_database($row['thread_id'], $dbc);
- }
- }
-
- mysqli_free_result($result);
- return $thread;
- }
-}
-
-function get_all_categories($dbc) {
- $sql = "SELECT cat_id FROM categories";
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Failed to get categories: ' . mysqli_error($dbc);
- }
-
- $categories = array();
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $category = new Category();
- $category->get_from_database($row['cat_id'], $dbc);
- array_push($categories, $category);
- }
- }
-
- mysqli_free_result($result);
- return $categories;
-} \ No newline at end of file
diff --git a/model/Post.php b/model/Post.php
deleted file mode 100644
index 34d6a79..0000000
--- a/model/Post.php
+++ /dev/null
@@ -1,121 +0,0 @@
-<?php
-
-include_once 'Thread.php';
-
-function add_quote($dbc, $thread_id, $matches) {
- foreach ($matches as $match) {
- $id = (int) filter_var($match, FILTER_SANITIZE_NUMBER_INT);
- $sql = "SELECT post_content, post_author, post_thread, user_name FROM posts LEFT JOIN users ON post_author = user_id WHERE post_id = " . $id;
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- return '<blockquote></blockquote>';
- }
-
- $reply = mysqli_fetch_assoc($result);
-
- if (empty($reply)) {
- return '<blockquote><span style="color:red;">This post has been deleted</span></blockquote>';
- }
-
- return '<blockquote><a href="/viewthread.php?id=' . $reply['post_thread'] . '#p' . $id .'">Quote from ' . $reply['user_name'] . '</a><br>' . $reply['post_content'] . '</blockquote>';
- }
-}
-
-class Post {
- public $id;
- public $content;
- public $date_created;
- public $date_edited;
- public $thread;
- public $author;
-
- function get_from_database($id, $dbc) {
- // TODO: Potential SQL injection risk?
- $sql = "SELECT post_content, post_date_created, post_date_edited, post_thread, post_author FROM posts WHERE post_id = " . mysqli_real_escape_string($dbc, $id);
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Failed to get post: ' . mysqli_error($dbc);
- }
-
- if (mysqli_num_rows($result) == 0) {
- return 0;
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $this->id = $id;
- $this->content = $row['post_content'];
- $this->date_created = $row['post_date_created'];
- $this->date_edited = $row['post_date_edited'];
-
- $this->thread = new Thread();
- $this->thread->get_from_database($row['post_thread'], $dbc);
-
- $this->author = new User();
- $this->author->get_by_id($row['post_author'], $dbc);
- }
- }
-
- mysqli_free_result($result);
- return 1;
- }
-
- function display_content($dbc) {
- echo '<div class="header" id="p' . $this->id . '"><b>#' . $this->id . '</b>';
- echo ' Posted by <a href="viewuser.php?id='. $this->author->id . '">' . $this->author->name . '</a>';
- echo ' on ' . date('m/d/Y g:ia', strtotime($this->date_created));
- if (!is_null($this->date_edited)) {
- echo ' <small>edited ' . date('m/d/Y g:ia', strtotime($this->date_edited)) . '</small>';
- }
- if (isset($_SESSION['signed_in']) && $_SESSION['user_id'] == $this->author->id) {
- echo '<span style="float:right;">';
- echo '[<a href="manage_post.php?id=' . $this->id . '">Edit/Delete</a>] ';
- echo'</span>';
- }
- echo '</div>';
-
- $post_content = $this->content;
- $thread_id = $this->id;
-
- $post_content = preg_replace_callback('/>#\d+/', function($matches) use($thread_id, $dbc) {
- return add_quote($dbc, $thread_id, $matches);
- }, $post_content);
-
- // Replace newline characters with HTML <br> tags
- $post_content = nl2br($post_content);
-
- // Replace YouTube URLs with embedded YouTube videos.
- $post_content = preg_replace(
- "/\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i",
- '<br><iframe class="youtube-embed" src="//www.youtube.com/embed/$2" allowfullscreen></iframe>', $post_content);
- // Replace Image URLs with embedded images.
- $post_content = preg_replace('@\b(http(s)?://)([^\s]*?(?:\.[a-z\d?=/_-]+)+(?:\.jpg|\.png|\.gif))(?![^<]*?(?:</\w+>|/?>))@i', '<img class="image-embed" src="http$2://$3" alt="http$2://$3" />', $post_content);
- // Replace other URLs with links.
- $post_content = preg_replace('@\b(http(s)?://)([^\s]*?(?:\.[a-z\d?=/_-]+)+)(?![^<]*?(?:</\w+>|/?>))@i', '<a href="http$2://$3">$0</a>', $post_content);
-
- echo '<span class="post-content">' . $post_content . '</span>';
- }
-}
-
-function get_all_posts($dbc) {
- $sql = "SELECT post_id FROM posts";
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Failed to get posts: ' . mysqli_error($dbc);
- }
-
- $posts = array();
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $post = new Post();
- $post->get_from_database($row['post_id'], $dbc);
- array_push($posts, $post);
- }
- }
-
- mysqli_free_result($result);
- return $posts;
-}
diff --git a/model/Thread.php b/model/Thread.php
deleted file mode 100644
index a9dc690..0000000
--- a/model/Thread.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-
-include_once 'Category.php';
-include_once 'User.php';
-include_once 'Post.php';
-
-class Thread {
- public $id = 0;
- public $subject = 'Unknown thread';
- public $date_created = 0;
- public $date_lastpost = 0;
- public $category;
- public $author;
-
- function get_from_database($id, $dbc) {
- $sql = "SELECT thread_subject, thread_date_created, thread_date_lastpost, thread_category, thread_author FROM threads WHERE thread_id = " . mysqli_real_escape_string($dbc, $id);
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- die('Error trying to display thread page: ' . mysqli_error($dbc));
- }
-
- if (mysqli_num_rows($result) == 0) {
- return 0;
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $this->id = $id;
- $this->subject = $row['thread_subject'];
- $this->date_created = $row['thread_date_created'];
- $this->date_lastpost = $row['thread_date_lastpost'];
-
- $this->category = new Category();
- $this->category->get_from_database($row['thread_category'], $dbc);
-
- $this->author = new User();
- $this->author->get_by_id($row['thread_author'], $dbc);
- }
- }
-
- mysqli_free_result($result);
- return 1;
- }
-
- function get_posts($dbc) {
- $sql = "SELECT post_id FROM posts WHERE post_thread = " . $this->id;
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Could not get posts from thread: ' . mysqli_error($dbc);
- }
-
- $posts = array();
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $post = new Post();
- $post->get_from_database($row['post_id'], $dbc);
- array_push($posts, $post);
- }
- }
-
- mysqli_free_result($result);
- return $posts;
- }
-
- function get_latest_post($dbc) {
- $sql = "SELECT post_id FROM posts WHERE post_thread = " . $this->id . " ORDER BY post_date_created DESC LIMIT 1";
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Could not get post from category: ' . mysqli_error($dbc);
- }
-
- $post = null;
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $post = new Post();
- $post->get_from_database($row['post_id'], $dbc);
- }
- }
-
- mysqli_free_result($result);
- return $post;
- }
-}
-
-function get_all_threads($dbc) {
- $sql = "SELECT thread_id FROM threads";
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Failed to get threads: ' . mysqli_error($dbc);
- }
-
- $threads = array();
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $thread = new Thread();
- $thread->get_from_database($row['thread_id'], $dbc);
- array_push($threads, $thread);
- }
- }
-
- mysqli_free_result($result);
- return $threads;
-}
diff --git a/model/User.php b/model/User.php
deleted file mode 100644
index 469a9a1..0000000
--- a/model/User.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-class User {
- public $id;
- public $name = 'Unknown';
- public $date = 0;
- public $level = 0;
-
- function get_by_name($name, $dbc) {
- $sql = "SELECT user_id, user_date, user_level FROM users WHERE user_name = ?";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- echo 'Failed to get user: ' . mysqli_error($dbc);
- }
-
- mysqli_stmt_bind_param($stmt, "s", $name);
- mysqli_stmt_execute($stmt);
-
- $result = mysqli_stmt_get_result($stmt);
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $this->id = $row['user_id'];
- $this->name = $name;
- $this->date = $row['user_date'];
- $this->level = $row['user_level'];
- }
- }
-
- mysqli_free_result($result);
- mysqli_stmt_close($stmt);
- }
-
- function get_by_id($id, $dbc) {
- $sql = "SELECT user_name, user_date, user_level FROM users WHERE user_id = " . mysqli_real_escape_string($dbc, $id);
- $result = mysqli_query($dbc, $sql);
-
- if (!$result) {
- echo 'Failed to get user: ' . mysqli_error($dbc);
- }
-
- if (mysqli_num_rows($result) == 0) {
- } else {
- while ($row = mysqli_fetch_assoc($result)) {
- $this->id = $id;
- $this->name = $row['user_name'];
- $this->date = $row['user_date'];
- $this->level = $row['user_level'];
- }
- }
-
- mysqli_free_result($result);
- }
-
-} \ No newline at end of file
diff --git a/moderate.php b/moderate.php
index afeefa1..68bf1b9 100644
--- a/moderate.php
+++ b/moderate.php
@@ -1,25 +1,21 @@
<?php
-
-include_once 'includes/db_inc.php';
-include_once 'model/User.php';
+include_once './includes/functions_thread.php';
+include_once './includes/Session.php';
+include_once './includes/model/User.php';
session_start();
-function delete_thread($dbc, $thread_id) {
- $sql = "DELETE FROM threads WHERE thread_id = $thread_id;";
- mysqli_query($dbc, $sql);
-}
-
-if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_SESSION['signed_in'])) {
+if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$thread_id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
$delete = filter_input(INPUT_POST, "delete", FILTER_SANITIZE_STRING);
-
- $user = new User();
- $user->get_by_id($_SESSION['user_id'], $dbc);
- if ($user->level > 0) {
+ $user = Session::get()->get_current_user();
+
+ if ($user->level == USER_LEVEL_MODERATOR) {
if (strcasecmp($delete, "on") == 0) {
- delete_thread($dbc, $thread_id);
+ $thread = new Thread();
+ $thread->get_from_database($thread_id);
+ delete_thread($thread);
header("Location: /");
exit();
diff --git a/register.php b/register.php
index cd72a37..02fbe58 100644
--- a/register.php
+++ b/register.php
@@ -1,48 +1,26 @@
+<?php session_start() ?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title>Register an account - cflip.net forum</title>
- <link rel="stylesheet" href="styles/style.css">
+ <title>Register an account - cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
</head>
<body>
-<?php include_once 'templates/header.php'?>
+<?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">
+ <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/db_inc.php';
-
-function username_exists($dbc, $user_name) {
- $sql = "SELECT * FROM users WHERE user_name = ?;";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- die("Error: " . mysqli_error($dbc));
- }
-
- mysqli_stmt_bind_param($stmt, "s", $user_name);
- mysqli_stmt_execute($stmt);
-
- $result = mysqli_stmt_get_result($stmt);
-
- if ($row = mysqli_fetch_assoc($result)) {
- return $row;
- } else {
- $result = false;
- return $result;
- }
-
- mysqli_stmt_close($stmt);
-}
+include_once './includes/functions_user.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$errors = array();
@@ -62,7 +40,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$errors[] = "Your username must be 30 characters or less.";
}
- if (username_exists($dbc, $user_name) !== false) {
+ if (username_exists($user_name) !== false) {
$errors[] = "The username '" . $user_name . "' has already been taken by another user.";
}
}
@@ -89,19 +67,8 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
}
echo '</ul>';
} else {
- $sql = "INSERT INTO users(user_name, user_pass, user_date) VALUES(?, ?, NOW());";
- $stmt = mysqli_stmt_init($dbc);
-
- if (!mysqli_stmt_prepare($stmt, $sql)) {
- die('Could not create account due to internal error: ' . mysqli_error($dbc));
- }
-
$pass_hash = password_hash($user_pass, PASSWORD_DEFAULT);
-
- mysqli_stmt_bind_param($stmt, "ss", $user_name, $pass_hash);
- mysqli_stmt_execute($stmt);
- mysqli_stmt_close($stmt);
-
+ register_user($user_name, $pass_hash);
echo 'Account successfully registered! You can now <a href="signin.php">sign in</a>';
}
}
diff --git a/search.php b/search.php
index c09ae53..e5ef9db 100644
--- a/search.php
+++ b/search.php
@@ -1,65 +1,66 @@
-<?php session_start()?>
+<?php session_start() ?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title>Search - cflip.net forum</title>
- <link rel="stylesheet" href="styles/style.css">
+ <title>Search - cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
</head>
<body>
- <?php include_once 'templates/header.php'; ?>
- <h2>Search cflip.net forum</h2>
- <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="get">
- Type:
- <select name="type">
- <option value="thread">Thread</option>
- <option value="post">Post</option>
- <option value="user">User</option>
- </select>
- Sort By:
- <select name="sort">
- <option value="lr">Last Reply</option>
- <option value="cd">Creation Date</option>
- <option value="rc">Reply Count</option>
- </select>
- With Name:
- <input type="text" name="query">
- <input type="submit" value="Search!">
- </form>
- <hr>
- <?php
- include_once 'includes/db_inc.php';
- include_once 'model/Thread.php';
- include_once 'model/Post.php';
+<?php include_once './includes/templates/header.php'; ?>
+<h2>Search cflip.net forum</h2>
+<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="get">
+ <label for="type">Type:</label>
+ <select id="type" name="type">
+ <option value="thread">Thread</option>
+ <option value="post">Post</option>
+ <option value="user">User</option>
+ </select>
+ <label for="sort">Sort By:</label>
+ <select id="sort" name="sort">
+ <option value="lr">Last Reply</option>
+ <option value="cd">Creation Date</option>
+ <option value="rc">Reply Count</option>
+ </select>
+ <label for="text">With Name:</label>
+ <input id="text" type="text" name="query">
+ <input type="submit" value="Search!">
+</form>
+<hr>
+<?php
+include_once './includes/functions_thread.php';
+include_once './includes/functions_post.php';
+include_once './includes/model/Thread.php';
+include_once './includes/model/Post.php';
- if (!isset($_GET['type'])) {
- echo 'Specify a type to search.';
- } else {
- switch ($_GET['type']) {
- case 'thread':
- $threads = get_all_threads($dbc);
- foreach ($threads as $thread) {
- echo '<p>';
- echo '<td><b><a href="viewthread.php?id=' . $thread->id . '">' . $thread->subject . '</a></b>';
- echo '<small> created by <b><a href="viewuser.php?id=' . $thread->author->id . '">' . $thread->author->name . '</a></b> on ' . date('M d, Y', strtotime($thread->date_created)) . '</small></td>';
- echo '</p>';
- }
- break;
- case 'post':
- $posts = get_all_posts($dbc);
-
- foreach ($posts as $post) {
- echo '<h3>From <a href="viewthread.php?id=' . $post->thread->id . '">' . $post->thread->subject . '</a></h3>';
- $post->display_content($dbc);
- echo '<hr>';
- }
- break;
- case 'user':
- break;
- default:
- echo '<h3>Could not search: Invalid type!</h3>';
- break;
+if (!isset($_GET['type'])) {
+ echo 'Specify a type to search.';
+} else {
+ switch ($_GET['type']) {
+ case 'thread':
+ $threads = get_all_threads();
+ foreach ($threads as $thread) {
+ echo '<p>';
+ echo '<td><b><a href="viewthread.php?id=' . $thread->id . '">' . $thread->subject . '</a></b>';
+ echo '<small> created by <b><a href="viewuser.php?id=' . $thread->author->id . '">' . $thread->author->name . '</a></b> on ' . date('M d, Y', strtotime($thread->date_created)) . '</small></td>';
+ echo '</p>';
}
- }
- ?>
+ break;
+ case 'post':
+ $posts = get_all_posts();
+
+ foreach ($posts as $post) {
+ echo '<h3>From <a href="viewthread.php?id=' . $post->thread->id . '">' . $post->thread->subject . '</a></h3>';
+ echo get_post_content($post);
+ echo '<hr>';
+ }
+ break;
+ case 'user':
+ break;
+ default:
+ echo '<h3>Could not search: Invalid type!</h3>';
+ break;
+ }
+}
+?>
</body>
</html>
diff --git a/signin.php b/signin.php
index e559614..2c43309 100644
--- a/signin.php
+++ b/signin.php
@@ -1,26 +1,25 @@
-<?php session_start()?>
+<?php session_start() ?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title>Sign in - cflip.net forum</title>
- <link rel="stylesheet" href="styles/style.css">
+ <title>Sign in - cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
</head>
<body>
- <?php include_once 'templates/header.php'?>
- <h2>Sign in</h2>
- <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" 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>
- <input type="submit" name="submit">
- </form>
+<?php include_once './includes/templates/header.php' ?>
+<h2>Sign in</h2>
+<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" 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>
+ <input type="submit" name="submit">
+</form>
<?php
-include_once 'includes/db_inc.php';
-
-function validate($data) {
+function validate($data)
+{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
@@ -29,7 +28,7 @@ function validate($data) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$errors = array();
-
+
if (empty($_POST['user_name'])) {
$errors[] = 'Please provide a username.';
} else {
@@ -49,26 +48,17 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
}
echo '</ul>';
} else {
- $sql = "SELECT user_id, user_name, user_pass FROM users WHERE user_name = '" . $user_name . "';";
- $result = mysqli_query($dbc, $sql);
+ $user = new User();
+ $result = $user->get_by_name($user_name);
if (!$result) {
- echo 'An error occurred while signing in: ' . mysqli_error($dbc);
+ echo 'There is no user with that name. Did you mean to <a href="register.php">create a new account?</a>';
} else {
- if (mysqli_num_rows($result) == 0) {
- echo 'There is no user with that name. Did you mean to <a href="register.php">create a new account?</a>';
+ if (!password_verify($user_pass, $user->password)) {
+ echo 'Password does not match!';
} else {
- while ($row = mysqli_fetch_assoc($result)) {
- if (!password_verify($user_pass, $row['user_pass'])) {
- echo 'Password does not match!';
- } else {
- $_SESSION['signed_in'] = true;
- $_SESSION['user_id'] = $row['user_id'];
- $_SESSION['user_name'] = $row['user_name'];
-
- header("Location: index.php");
- }
- }
+ Session::get()->sign_in($user);
+ header("Location: index.php");
}
}
}
diff --git a/signout.php b/signout.php
new file mode 100644
index 0000000..035877b
--- /dev/null
+++ b/signout.php
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Sign out - cflip.net forums</title>
+ <link rel="stylesheet" href="styles/style.css">
+</head>
+<body>
+<?php
+include_once './includes/Session.php';
+Session::get()->sign_out();
+
+include_once './includes/templates/header.php';
+echo '<p class="success">You have now been signed out</p>';
+?>
+</body>
+</html> \ No newline at end of file
diff --git a/styles/style.css b/styles/style.css
index 92090c0..95d3a94 100644
--- a/styles/style.css
+++ b/styles/style.css
@@ -1,7 +1,8 @@
body {
font-family: Arial, sans-serif;
font-size: 10pt;
- margin: 10px 40px;
+ margin: auto;
+ width: 980px;
}
a {
@@ -14,7 +15,25 @@ small {
}
.header > small {
- color: #bde;
+ color: #dde;
+}
+
+.success {
+ background-color: #efe;
+ margin: 8px 40px 14px 18px;
+ padding: 12px;
+ border: 1px solid #aea;
+ overflow: hidden;
+ border-radius: 5px;
+}
+
+.error {
+ background-color: #fee;
+ margin: 8px 40px 14px 18px;
+ padding: 12px;
+ border: 1px solid #eaa;
+ overflow: hidden;
+ border-radius: 5px;
}
a:hover {
diff --git a/viewcategory.php b/viewcategory.php
index a10afce..852148b 100644
--- a/viewcategory.php
+++ b/viewcategory.php
@@ -1,6 +1,6 @@
<?php
-include_once 'includes/db_inc.php';
-include_once 'model/Category.php';
+
+include_once 'includes/model/Category.php';
session_start();
@@ -8,65 +8,53 @@ $current = new Category();
if (!isset($_GET['id']) || !filter_var($_GET['id'], FILTER_VALIDATE_INT)) {
http_response_code(404);
- include_once 'templates/404.php';
+ include('includes/templates/404.php');
die();
} else {
- $result = $current->get_from_database($_GET['id'], $dbc);
- if ($result == 0) {
+ $result = $current->get_from_database($_GET['id']);
+ if (!$result) {
http_response_code(404);
- include_once 'templates/404.php';
+ include('includes/templates/404.php');
die();
}
}
?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title><?= $current->name; ?> - cflip.net forum</title>
- <link rel="stylesheet" href="styles/style.css">
+ <title><?= $current->name; ?> - cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
</head>
<body>
-<?php include_once 'templates/header.php';?>
- <h1><?= $current->name; ?></h1>
- <p><?= $current->description; ?></p>
- <span class="info">
- <?= $current->thread_count . ' threads, ' . $current->post_count . ' posts'; ?>
- </span>
- <h2>Threads</h2>
- <table width="100%">
- <tr>
- <th>Thread Name</th>
- <th>Latest Post</th>
- </tr>
- <?php
- function cmp($a, $b) {
- $da = strtotime($a->date_lastpost);
- $db = strtotime($b->date_lastpost);
-
- if ($da == $db) return 0;
-
- return ($da > $db) ? -1 : 1;
+<?php include('includes/templates/header.php'); ?>
+<h1><?= $current->name; ?></h1>
+<p><?= $current->description; ?></p>
+<span class="info"><?= $current->thread_count . ' threads, ' . $current->post_count . ' posts'; ?></span>
+<h2>Threads</h2>
+<table>
+ <tr>
+ <th>Thread Name</th>
+ <th>Latest Post</th>
+ </tr>
+ <?php
+ $threads = $current->get_threads();
+
+ foreach ($threads as $thread) {
+ $latest_post = $thread->get_latest_post();
+
+ echo '<tr>';
+ echo '<td><b><a href="viewthread.php?id=' . $thread->id . '">' . $thread->subject . '</a></b>';
+ echo '<small> by <b><a href="viewuser.php?id=' . $thread->author->id . '">' . $thread->author->name . '</a></b> on ' . date('M d, Y', strtotime($thread->date_created)) . '</small></td>';
+
+ if (!is_null($latest_post)) {
+ echo '<td>by <b><a href="viewuser.php?id=' . $latest_post->author->id . '">' . $latest_post->author->name . '</a></b><small> on ' . $latest_post->date_created . '</small></td>';
+ } else {
+ echo '<td>No posts yet!</td>';
}
-
- $threads = $current->get_threads($dbc);
- usort($threads, "cmp");
-
- foreach ($threads as $thread) {
- $latest_post = $thread->get_latest_post($dbc);
- echo '<tr>';
- echo '<td><b><a href="viewthread.php?id=' . $thread->id . '">' . $thread->subject . '</a></b>';
- echo '<small> by <b><a href="viewuser.php?id=' . $thread->author->id . '">' . $thread->author->name . '</a></b> on ' . date('M d, Y', strtotime($thread->date_created)) . '</small></td>';
-
- if (!is_null($latest_post)) {
- echo '<td>by <b><a href="viewuser.php?id=' . $latest_post->author->id . '">' . $latest_post->author->name . '</a></b><small> on ' . $latest_post->date_created . '</small></td>';
- } else {
- echo '<td>No posts yet!</td>';
- }
-
- echo '</tr>';
- }
- ?>
- </table>
+ echo '</tr>';
+ }
+ ?>
+</table>
</body>
</html>
diff --git a/viewthread.php b/viewthread.php
index d41fb9b..e8eda06 100644
--- a/viewthread.php
+++ b/viewthread.php
@@ -1,6 +1,5 @@
<?php
-include_once 'includes/db_inc.php';
-include_once 'model/Thread.php';
+include_once 'includes/model/Thread.php';
session_start();
@@ -8,37 +7,37 @@ $current = new Thread();
if (!isset($_GET['id']) || !filter_var($_GET['id'], FILTER_VALIDATE_INT)) {
http_response_code(404);
- include_once 'templates/404.php';
+ include('includes/templates/404.php');
die();
} else {
- $result = $current->get_from_database($_GET['id'], $dbc);
- if ($result == 0) {
+ $result = $current->get_from_database($_GET['id']);
+
+ if (!$result) {
http_response_code(404);
- include_once 'templates/404.php';
+ include('includes/templates/404.php');
die();
}
}
?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title><?= $current->subject; ?> - cflip.net forum</title>
- <link rel="stylesheet" href="styles/style.css">
+ <title><?= $current->subject; ?> - cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
</head>
<body>
- <?php include_once 'templates/header.php';?>
- <h1><?= $current->subject; ?></h1>
- created by <b><?= $current->author->name; ?></b>
- in <b><?= $current->category->name; ?></b>
- <abbr title="<?= date('M d, Y g:ia', strtotime($current->date_created));?>">3 days ago</abbr>
+<?php include('includes/templates/header.php'); ?>
+<h1><?= $current->subject; ?></h1>
+created by <b><?= $current->author->name; ?></b>
+in <b><?= $current->category->name; ?></b>
+<abbr title="<?= date('M d, Y g:ia', strtotime($current->date_created)); ?>">3 days ago</abbr>
<?php
-include_once 'model/User.php';
+include_once('includes/model/User.php');
-if (isset($_SESSION['signed_in'])) {
- $user = new User();
- $user->get_by_id($_SESSION['user_id'], $dbc);
+if (Session::get()->is_signed_in()) {
+ $user = Session::get()->get_current_user();
- if ($user->level > 0) {
+ if ($user->level == USER_LEVEL_MODERATOR) {
echo '
<form action="moderate.php" method="post">
<p>
@@ -57,41 +56,41 @@ if (isset($_SESSION['signed_in'])) {
}
}
?>
- <hr>
- <?php
- $posts = $current->get_posts($dbc);
+<hr>
+<?php
+include './includes/functions_post.php';
- foreach ($posts as $post) {
- $post->display_content($dbc);
- }
- ?>
- <hr>
- <h2>Reply to this thread</h2>
- <form method="post">
- <textarea name="post_content" rows="10" cols="50"></textarea>
- <br>
- <input type="submit" name="submit">
- </form>
+$posts = $current->get_posts();
+
+foreach ($posts as $post) {
+ echo get_post_content($post);
+}
+?>
+<hr>
+<h2>Reply to this thread</h2>
+<form method="post">
+ <textarea name="post_content" rows="10" cols="50"></textarea>
+ <br>
+ <input type="submit" name="submit">
+</form>
</body>
</html>
<?php
-include_once 'includes/db_inc.php';
-include_once 'includes/functions_insert.php';
+include_once 'includes/functions_post.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- if (!isset($_SESSION['signed_in'])) {
+ if (!Session::get()->is_signed_in()) {
echo 'You must be <a href="signin.php">signed in</a> to reply to this thread.';
return;
- }
+ }
$post_content = filter_input(INPUT_POST, 'post_content', FILTER_SANITIZE_STRING);
- $user_id = filter_var($_SESSION['user_id'], FILTER_SANITIZE_NUMBER_INT);
if (empty($post_content) or !$post_content) {
echo 'Thread subject cannot be empty';
} else {
- insert_post($dbc, $post_content, $current->id, $user_id, $current->category->id);
+ create_post($post_content, $current->id, $current->category->id);
+ header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $current->id);
}
}
-
?>
diff --git a/viewuser.php b/viewuser.php
index 3a33de0..45f557a 100644
--- a/viewuser.php
+++ b/viewuser.php
@@ -1,6 +1,5 @@
<?php
-include_once 'includes/db_inc.php';
-include_once 'model/User.php';
+include_once './includes/model/User.php';
session_start();
@@ -8,18 +7,18 @@ $current = new User();
if (!isset($_GET['id'])) {
} else {
- $current->get_by_id($_GET['id'], $dbc);
+ $current->get_by_id($_GET['id']);
}
?>
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
- <title><?= $current->name; ?>'s Profile - cflip.net forum</title>
- <link rel="stylesheet" href="styles/style.css">
+ <title><?= $current->name; ?>'s Profile - cflip.net forum</title>
+ <link rel="stylesheet" href="styles/style.css">
</head>
<body>
- <?php include_once "templates/header.php" ?>
- <h1><?= $current->name; ?></h1>
- member since <?= date('M d, Y', strtotime($current->date)); ?>
+<?php include_once "includes/templates/header.php" ?>
+<h1><?= $current->name; ?></h1>
+member since <?= date('M d, Y', strtotime($current->date)); ?>
</body>
</html>