implemented admin control panel with the ability to delete articles/users in bulk, and open user panels with the standard options to reset passwords, change email/usernames, or delete. additionally, updated SQL schema, created dummy data, and fixed some bugs.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require 'db_functions.php';
|
||||
require_once 'db_functions.php';
|
||||
|
||||
function user_id_exists($user_id)
|
||||
{
|
||||
@@ -220,6 +220,7 @@ function reset_pw_form()
|
||||
<span class="modal_close">×</span>
|
||||
<form method="post">
|
||||
<input type="hidden" name="form_id" value="reset_pw_form">
|
||||
<input type="hidden" name="user_id" value="' . $_GET['user_id'] . '">
|
||||
|
||||
<label for="new_pw">New Password</label>
|
||||
<input id="new_pw" name="new_pw" type="password" required>
|
||||
@@ -260,6 +261,7 @@ function update_email_form()
|
||||
<span class="modal_close">×</span>
|
||||
<form method="post">
|
||||
<input type="hidden" name="form_id" value="update_email_form">
|
||||
<input type="hidden" name="user_id" value="' . $_GET['user_id'] . '">
|
||||
|
||||
<label for="new_email">New Email</label>
|
||||
<input id="new_email" name="new_email" required>
|
||||
@@ -299,6 +301,7 @@ function update_username_form()
|
||||
<span class="modal_close">×</span>
|
||||
<form method="post">
|
||||
<input type="hidden" name="form_id" value="update_username_form">
|
||||
<input type="hidden" name="user_id" value="' . $_GET['user_id'] . '">
|
||||
|
||||
<label for="new_username">New Username</label>
|
||||
<input id="new_username" name="new_username" required>
|
||||
@@ -387,6 +390,7 @@ function delete_account_form()
|
||||
<span class="modal_close">×</span>
|
||||
<form method="post">
|
||||
<input type="hidden" name="form_id" value="delete_account_form">
|
||||
<input type="hidden" name="user_id" value="' . $_GET['user_id'] . '">
|
||||
|
||||
<label for="delete_password">Password</label>
|
||||
<input id="delete_password" name="delete_password" type="password" required>
|
||||
@@ -402,7 +406,7 @@ function delete_account_form()
|
||||
return $form;
|
||||
}
|
||||
|
||||
function delete_account($user_id, $password, $verify_password)
|
||||
function delete_account($user_id, $password = null, $verify_password = null)
|
||||
{
|
||||
if ($user_id == 2025) {
|
||||
$error_msg = '
|
||||
@@ -424,23 +428,43 @@ function delete_account($user_id, $password, $verify_password)
|
||||
return $error_msg;
|
||||
}
|
||||
|
||||
$password_hash = hash('sha256', $password);
|
||||
$query = 'SELECT user_id FROM user WHERE user_id = ' . $user_id . ' AND password_hash = "' . $password_hash . '";';
|
||||
$user = query_one_result($query);
|
||||
if ($password && $verify_password) {
|
||||
$password_hash = hash('sha256', $password);
|
||||
$query = 'SELECT user_id, profile_picture FROM user WHERE user_id = ' . $user_id . ' AND password_hash = "' . $password_hash . '";';
|
||||
$user = query_one_result($query);
|
||||
|
||||
if ($user == null) {
|
||||
$error_msg = '
|
||||
if ($user == null) {
|
||||
$error_msg = '
|
||||
<div class="error">
|
||||
Username and/or Password are invalid!
|
||||
</div>
|
||||
';
|
||||
|
||||
return $error_msg;
|
||||
}
|
||||
return $error_msg;
|
||||
}
|
||||
|
||||
$stmt = 'DELETE FROM user WHERE user_id = ' . $user_id . ';';
|
||||
exec_statement($stmt, 1);
|
||||
logout();
|
||||
delete_file($_ENV['PROFILE_IMAGES_FQ_PATH'] . $user['profile_picture']);
|
||||
$stmt = 'DELETE FROM user WHERE user_id = ' . $user_id . ';';
|
||||
exec_statement($stmt, 1);
|
||||
logout();
|
||||
} else if ($_COOKIE['role_id'] < 3) {
|
||||
$query = 'SELECT user_id FROM user WHERE user_id = ' . $user_id . ';';
|
||||
$user = query_one_result($query);
|
||||
|
||||
if ($user['user_id'] == 2025) {
|
||||
$error_msg = '
|
||||
<div class="error">
|
||||
Cannot delete the owner!
|
||||
</div>
|
||||
';
|
||||
|
||||
return $error_msg;
|
||||
}
|
||||
|
||||
delete_file($_ENV['PROFILE_IMAGES_FQ_PATH'] . $user['profile_picture']);
|
||||
$stmt = 'DELETE FROM user WHERE user_id = ' . $user_id . ';';
|
||||
exec_statement($stmt, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function user_view($user_id)
|
||||
@@ -492,9 +516,3 @@ function user_view($user_id)
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
function admin_user_view($user_id)
|
||||
{
|
||||
$query = 'SELECT user_id, username, email, role_id, created_at, last_active, is_active, profile_picture FROM user WHERE user_id = ' . $user_id . ';';
|
||||
$user = query_one_result($query);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
require_once 'db_functions.php';
|
||||
require_once 'account_functions.php';
|
||||
require_once 'article_functions.php';
|
||||
|
||||
function admin_article_view()
|
||||
{
|
||||
$display = '
|
||||
<div class="view_card">
|
||||
<div class="row">
|
||||
<h3>Articles</h3>
|
||||
<a href="admin.php?view=users">View Users</a>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="form_id" value="articles">
|
||||
<div class="row">
|
||||
<label for="delete" class="form_checkbox_container">Delete
|
||||
<input type="radio" class="button" name="action" id="delete" value="delete">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
<input type="submit" class="button narrow" value="Commit">
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Select</th>
|
||||
<th>Article ID</th>
|
||||
<th>Author</th>
|
||||
<th>Title</th>
|
||||
<th>Created</th>
|
||||
<th>Updated</th>
|
||||
<th>Published</th>
|
||||
<th>Read Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
';
|
||||
$query = 'SELECT article_id, username, title, read_count, article.created_at, updated_at, published_at, excerpt FROM article INNER JOIN user ON article.author_id = user.user_id;';
|
||||
|
||||
$results = query_one_or_more_results($query);
|
||||
|
||||
foreach ($results as $key => $result) {
|
||||
$display .= '
|
||||
<tr>
|
||||
<td>
|
||||
<label class="form_checkbox_container">
|
||||
<input name="selected_articles[]" value="' . $result['article_id'] . '" type="checkbox">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td>' . $result['article_id'] . '</td>
|
||||
<td>' . $result['username'] . '</td>
|
||||
<td>' . $result['title'] . '</td>
|
||||
<td>' . $result['created_at'] . '</td>
|
||||
<td>' . $result['updated_at'] . '</td>
|
||||
<td>' . $result['published_at'] . '</td>
|
||||
<td>' . $result['read_count'] . '</td>
|
||||
</tr>
|
||||
';
|
||||
}
|
||||
|
||||
$display .= '
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
';
|
||||
|
||||
return $display;
|
||||
}
|
||||
function admin_user_view()
|
||||
{
|
||||
$display = '
|
||||
<div class="view_card">
|
||||
<div class="row">
|
||||
<h3>Users</h3>
|
||||
<a href="admin.php?view=articles">View Articles</a>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="form_id" value="users">
|
||||
<div class="row">
|
||||
<label for="delete" class="form_checkbox_container">Delete
|
||||
<input type="radio" class="button" name="action" id="delete" value="delete">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
<input type="submit" class="button narrow" value="Commit">
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Select</th>
|
||||
<th>User ID</th>
|
||||
<th>Username</th>
|
||||
<th>Email</th>
|
||||
<th>Role</th>
|
||||
<th>Created</th>
|
||||
<th>Last Active</th>
|
||||
<th>Active</th>
|
||||
<th>Profile Picture</th>
|
||||
</tr>
|
||||
';
|
||||
$query = 'SELECT user_id, username, email, last_active, role, created_at, is_active, profile_picture FROM user INNER JOIN roles ON user.role_id = roles.role_id;';
|
||||
|
||||
$results = query_one_or_more_results($query);
|
||||
|
||||
foreach ($results as $key => $result) {
|
||||
$display .= '
|
||||
<tr>
|
||||
<td>
|
||||
<label class="form_checkbox_container">
|
||||
<input name="selected_users[]" value="' . $result['user_id'] . '" type="checkbox">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td>' . $result['user_id'] . '</td>
|
||||
<td>' . $result['username'] . '</td>
|
||||
<td>' . $result['email'] . '</td>
|
||||
<td>' . ucwords($result['role']) . '</td>
|
||||
<td>' . $result['created_at'] . '</td>
|
||||
<td>' . $result['last_active'] . '</td>
|
||||
<td>' . $result['is_active'] . '</td>
|
||||
<td><img src="' . $_ENV['PROFILE_IMAGES_PQ_PATH'] . $result['profile_picture'] . '" class="card_profile_picture"></td>
|
||||
</tr>
|
||||
';
|
||||
}
|
||||
|
||||
$display .= '
|
||||
</table>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
';
|
||||
|
||||
return $display;
|
||||
}
|
||||
|
||||
function delete_users($ids)
|
||||
{
|
||||
foreach ($ids as $id) {
|
||||
delete_account($id);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require 'db_functions.php';
|
||||
require_once 'db_functions.php';
|
||||
|
||||
function article_ids_by_recency()
|
||||
{
|
||||
@@ -14,6 +14,19 @@ function article_ids_by_recency()
|
||||
return $ids;
|
||||
}
|
||||
|
||||
function articles_ids_by_author($author_id)
|
||||
{
|
||||
$query = 'SELECT article_id FROM article ORDER BY published_at DESC WHERE author_id = ' . $author_id . ';';
|
||||
$results = query_one_or_more_results($query);
|
||||
|
||||
$ids = [];
|
||||
|
||||
while ($row = mysqli_fetch_array($results))
|
||||
$ids[] = $row['article_id'];
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
function article_tags()
|
||||
{
|
||||
$query = 'SELECT * FROM tags;';
|
||||
@@ -63,7 +76,7 @@ function article_page_from_markdown($article_id)
|
||||
<p>Published on ' . $article['published_at'] . '</p>
|
||||
</div>
|
||||
<div class="card_pic_box">
|
||||
<img src="' . $_ENV['PROFILE_IMAGES_PQ_PATH'] . '"' . $author['profile_picture'] . '" class="card_profile_picture" />
|
||||
<img src="' . $_ENV['PROFILE_IMAGES_PQ_PATH'] . $author['profile_picture'] . '" class="card_profile_picture" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="line" style="margin-bottom: 15px;"></div>
|
||||
@@ -129,8 +142,10 @@ function create_article($author_id, $title, $excerpt, $tags, $markdown_file_cont
|
||||
$stmt = 'INSERT INTO article (author_id, title, excerpt, published_at) VALUES (' . $author_id . ', "' . $title . '", "' . $excerpt . '", CURRENT_TIMESTAMP);';
|
||||
$id = exec_statement($stmt, 0);
|
||||
|
||||
$path = $_ENV['ARTICLES_PQ_PATH'] . $id . '/';
|
||||
$path = $_ENV['ARTICLES_FQ_PATH'] . $id . '/';
|
||||
mkdir($path);
|
||||
echo '<p>created ' . $path . '</p>';
|
||||
|
||||
$fs = fopen($path . 'article.md', 'a');
|
||||
fwrite($fs, $markdown_file_contents);
|
||||
fclose($fs);
|
||||
@@ -146,8 +161,6 @@ function create_article($author_id, $title, $excerpt, $tags, $markdown_file_cont
|
||||
$stmt .= ';';
|
||||
}
|
||||
|
||||
echo $stmt;
|
||||
pretty_dump($tags);
|
||||
if (count($tags) > 0)
|
||||
exec_statement($stmt, 0);
|
||||
|
||||
@@ -156,8 +169,13 @@ function create_article($author_id, $title, $excerpt, $tags, $markdown_file_cont
|
||||
|
||||
function delete_article($article_id)
|
||||
{
|
||||
$stmt = 'DELETE FROM article_tags WHERE article_id = ' . $article_id . ';';
|
||||
exec_statement($stmt, 1);
|
||||
|
||||
$stmt = 'DELETE FROM article WHERE article_id = ' . $article_id . ';';
|
||||
return exec_statement($stmt, 1);
|
||||
exec_statement($stmt, 1);
|
||||
|
||||
delete_dir($_ENV['ARTICLES_FQ_PATH'] . $article_id . '/');
|
||||
}
|
||||
|
||||
function delete_articles_by_author($author_id)
|
||||
@@ -165,3 +183,9 @@ function delete_articles_by_author($author_id)
|
||||
$stmt = 'DELETE FROM article WHERE author_id = "' . $author_id . '";';
|
||||
return exec_statement($stmt, 1);
|
||||
}
|
||||
|
||||
function increment_read_counter($article_id)
|
||||
{
|
||||
$stmt = 'UPDATE article SET read_count = read_count + 1 WHERE article_id = ' . $article_id . ';';
|
||||
return exec_statement($stmt, 1);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
<?php
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
||||
$dotenv->safeLoad();
|
||||
|
||||
// Use environment variables for the database password and IP address.
|
||||
$db_user = $_ENV['DATABASE_USER'];
|
||||
$db_pass = $_ENV['DATABASE_PASSWORD'];
|
||||
|
||||
@@ -9,6 +9,30 @@ if (!empty($_FILES['upload'])) {
|
||||
upload($_FILES['upload'], $_ENV['UPLOAD_TMP_FQ_PATH'], isset($_POST['filename']) ? $_POST['filename'] : null);
|
||||
}
|
||||
|
||||
function delete_dir($dir)
|
||||
{
|
||||
if (!is_dir($dir)) return false;
|
||||
|
||||
if (substr($dir, strlen($dir) - 1, 1) != '/') {
|
||||
$dir .= '/';
|
||||
}
|
||||
$files = glob($dir . '*', GLOB_MARK);
|
||||
foreach ($files as $file) {
|
||||
if (is_dir($file))
|
||||
delete_dir($file);
|
||||
else
|
||||
delete_file($file);
|
||||
}
|
||||
rmdir($dir);
|
||||
}
|
||||
|
||||
function delete_file($file)
|
||||
{
|
||||
if (!file_exists($file)) return false;
|
||||
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
function upload($input, $dest_dir, $filename = null)
|
||||
{
|
||||
$filetype = strtolower(pathinfo($input['name'], PATHINFO_EXTENSION));
|
||||
|
||||
@@ -3,6 +3,7 @@ session_start();
|
||||
|
||||
// Initialize Composer.
|
||||
require_once 'vendor/autoload.php';
|
||||
require_once 'db_functions.php';
|
||||
|
||||
// Load environment variables.
|
||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
||||
@@ -18,3 +19,6 @@ if ($_SESSION['initialized'] && isset($_POST['theme'])) {
|
||||
$_SESSION['theme'] = $_POST['theme'];
|
||||
unset($_POST['theme']);
|
||||
}
|
||||
|
||||
if (isset($_COOKIE['user_id']))
|
||||
exec_statement('UPDATE user SET is_active = true WHERE user_id = ' . $_COOKIE['user_id'] . ';', 1);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 MiB |
Reference in New Issue
Block a user