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:
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'functions/init.php';
|
||||||
|
require_once 'functions/functions.php';
|
||||||
|
|
||||||
|
include_once 'components/head.php';
|
||||||
|
|
||||||
|
if (!isset($_COOKIE['role_id']))
|
||||||
|
header('Location: user.php');
|
||||||
|
else if ($_COOKIE['role_id'] >= 3)
|
||||||
|
header('Location: user.php?action=view&user_id=' . $_COOKIE['user_id']);
|
||||||
|
|
||||||
|
include_once 'functions/admin_functions.php';
|
||||||
|
|
||||||
|
if (isset($_POST['action']) && isset($_POST['form_id'])) {
|
||||||
|
switch ($_POST['action']) {
|
||||||
|
case 'delete':
|
||||||
|
if ($_POST['form_id'] == 'users')
|
||||||
|
foreach ($_POST['selected_users'] as $id)
|
||||||
|
delete_account($id);
|
||||||
|
else if ($_POST['form_id'] == 'articles')
|
||||||
|
foreach ($_POST['selected_articles'] as $id)
|
||||||
|
delete_article($id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'view':
|
||||||
|
header('Location: user.php?action=view&user_id=' . $_POST['selected_users'][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_GET['view'])) {
|
||||||
|
switch ($_GET['view']) {
|
||||||
|
case 'users':
|
||||||
|
echo admin_user_view();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'articles':
|
||||||
|
echo admin_article_view();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo admin_article_view();
|
||||||
|
}
|
||||||
|
|
||||||
|
include_once 'components/foot.php';
|
||||||
+9
-5
@@ -9,20 +9,24 @@ include_once 'functions/article_functions.php';
|
|||||||
// TODO: Move to a grid, where the left hand column is either a search and filtering system, or...Table of Contents?
|
// TODO: Move to a grid, where the left hand column is either a search and filtering system, or...Table of Contents?
|
||||||
|
|
||||||
// Default view, it'll show articles by recency
|
// Default view, it'll show articles by recency
|
||||||
if (!isset($_GET['article_id']) && !isset($_GET['tag'])) {
|
if (!isset($_GET['article_id']) && !isset($_GET['tag']) && !isset($_GET['author_id'])) {
|
||||||
$ids = article_ids_by_recency();
|
$ids = article_ids_by_recency();
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id)
|
||||||
echo article_card($id);
|
echo article_card($id);
|
||||||
}
|
|
||||||
} else if (isset($_GET['article_id'])) {
|
} else if (isset($_GET['article_id'])) {
|
||||||
|
increment_read_counter($_GET['article_id']);
|
||||||
echo article_page_from_markdown($_GET['article_id']);
|
echo article_page_from_markdown($_GET['article_id']);
|
||||||
|
} else if (isset($_GET['author_id'])) {
|
||||||
|
$ids = articles_ids_by_author($_GET['author_id']);
|
||||||
|
|
||||||
|
foreach ($ids as $id)
|
||||||
|
echo article_card($id);
|
||||||
} else if (isset($_GET['tag'])) {
|
} else if (isset($_GET['tag'])) {
|
||||||
$ids = article_ids_by_tag($_GET['tag']);
|
$ids = article_ids_by_tag($_GET['tag']);
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id)
|
||||||
echo article_card($id);
|
echo article_card($id);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
include_once 'components/foot.php';
|
include_once 'components/foot.php';
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
if (isset($args['action'])) {
|
if (isset($args['action'])) {
|
||||||
if ($args['action'] == 'signup') {
|
if ($args['action'] == 'signup') {
|
||||||
echo '
|
echo '
|
||||||
<script src="js/cropper.js"></script>
|
|
||||||
<script src="js/profile_picture_cropper_modal.js"></script>
|
<script src="js/profile_picture_cropper_modal.js"></script>
|
||||||
<script src="js/upload.js"></script>
|
<script src="js/upload.js"></script>
|
||||||
';
|
';
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ $nav = '
|
|||||||
<li><a href="/articles.php"' . ($current_page == '/articles.php' ? ' class="underline"' : '') . '>Articles</a></li>
|
<li><a href="/articles.php"' . ($current_page == '/articles.php' ? ' class="underline"' : '') . '>Articles</a></li>
|
||||||
';
|
';
|
||||||
|
|
||||||
|
if (isset($_COOKIE['role_id']) && $_COOKIE['role_id'] <= 2) {
|
||||||
|
$nav .= '
|
||||||
|
<li><a href="/admin.php"' . ($current_page == '/admin.php' ? ' class="underline"' : '') . '>Admin</a></li>
|
||||||
|
';
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($_COOKIE['user_id'])) {
|
if (isset($_COOKIE['user_id'])) {
|
||||||
$nav .= '
|
$nav .= '
|
||||||
<li><a href="/user.php?action=view&user_id=' . $_COOKIE['user_id'] . '"' . ($current_page == '/user.php' ? ' class="underline"' : '') . '>Account</a></li>
|
<li><a href="/user.php?action=view&user_id=' . $_COOKIE['user_id'] . '"' . ($current_page == '/user.php' ? ' class="underline"' : '') . '>Account</a></li>
|
||||||
|
|||||||
+4
-1
@@ -4,10 +4,13 @@ require_once 'functions/functions.php';
|
|||||||
include_once 'functions/article_functions.php';
|
include_once 'functions/article_functions.php';
|
||||||
|
|
||||||
if (!empty($_POST)) {
|
if (!empty($_POST)) {
|
||||||
$id = create_article(2025, $_POST['title'], $_POST['excerpt'], $_POST['tags'], $_POST['markdown']);
|
$id = create_article($_COOKIE['user_id'], $_POST['title'], $_POST['excerpt'], $_POST['tags'], $_POST['markdown']);
|
||||||
header('Location: articles.php?article_id=' . $id);
|
header('Location: articles.php?article_id=' . $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isset($_COOKIE['role_id']) || $_COOKIE['role_id'] == 4)
|
||||||
|
header('Location: articles.php');
|
||||||
|
|
||||||
include_once 'components/head.php';
|
include_once 'components/head.php';
|
||||||
|
|
||||||
echo form();
|
echo form();
|
||||||
|
|||||||
+59
-3
@@ -25,7 +25,9 @@ label,
|
|||||||
input,
|
input,
|
||||||
textarea,
|
textarea,
|
||||||
a,
|
a,
|
||||||
.modal_button {
|
.modal_button,
|
||||||
|
th,
|
||||||
|
td {
|
||||||
font-family: 'HackNerdFontMono', Hack, sans-serif;
|
font-family: 'HackNerdFontMono', Hack, sans-serif;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -165,7 +167,8 @@ code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.article_card,
|
.article_card,
|
||||||
.form_card {
|
.form_card,
|
||||||
|
.view_card {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
@@ -189,6 +192,36 @@ code {
|
|||||||
width: 80%;
|
width: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.view_card form {
|
||||||
|
width: 95%;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form table {
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr {
|
||||||
|
transition-duration: 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:hover {
|
||||||
|
outline: solid 3px orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr td {
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px 0px 15px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr td label {
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
.card_info_box {
|
.card_info_box {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@@ -218,6 +251,14 @@ code {
|
|||||||
border: 3px solid orange;
|
border: 3px solid orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(255, 165, 0, 0.3), 0 3px 8px 0 rgba(255, 165, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.narrow {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
margin: 15px;
|
margin: 15px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
@@ -226,6 +267,10 @@ code {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag:hover {
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(255, 165, 0, 0.3), 0 3px 8px 0 rgba(255, 165, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
.tag_row {}
|
.tag_row {}
|
||||||
|
|
||||||
.tag_box {
|
.tag_box {
|
||||||
@@ -295,6 +340,7 @@ textarea:focus,
|
|||||||
input:hover,
|
input:hover,
|
||||||
textarea:hover {
|
textarea:hover {
|
||||||
border: 3px solid orange;
|
border: 3px solid orange;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(255, 165, 0, 0.3), 0 3px 8px 0 rgba(255, 165, 0, 0.7);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +351,10 @@ textarea {
|
|||||||
|
|
||||||
.checkboxes {}
|
.checkboxes {}
|
||||||
|
|
||||||
|
input[type="radio"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.form_checkbox_container {
|
.form_checkbox_container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -414,7 +464,9 @@ input[type="file"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form_card h3,
|
.form_card h3,
|
||||||
.form_card h5 {
|
.form_card h5,
|
||||||
|
.view_card h3,
|
||||||
|
.view_card h5 {
|
||||||
padding-bottom: 15px;
|
padding-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,3 +585,7 @@ input[type="file"] {
|
|||||||
right: -5px;
|
right: -5px;
|
||||||
cursor: se-resize;
|
cursor: se-resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-href] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|||||||
+6
-1
@@ -40,11 +40,16 @@ code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.article_card,
|
.article_card,
|
||||||
.form_card {
|
.form_card,
|
||||||
|
.view_card {
|
||||||
border: 5px solid white;
|
border: 5px solid white;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table tr {
|
||||||
|
outline: solid 3px white;
|
||||||
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -40,11 +40,16 @@ code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.article_card,
|
.article_card,
|
||||||
.form_card {
|
.form_card,
|
||||||
|
.view_card {
|
||||||
border: 5px solid black;
|
border: 5px solid black;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table tr {
|
||||||
|
outline: solid 3px black;
|
||||||
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
require 'db_functions.php';
|
require_once 'db_functions.php';
|
||||||
|
|
||||||
function user_id_exists($user_id)
|
function user_id_exists($user_id)
|
||||||
{
|
{
|
||||||
@@ -220,6 +220,7 @@ function reset_pw_form()
|
|||||||
<span class="modal_close">×</span>
|
<span class="modal_close">×</span>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="form_id" value="reset_pw_form">
|
<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>
|
<label for="new_pw">New Password</label>
|
||||||
<input id="new_pw" name="new_pw" type="password" required>
|
<input id="new_pw" name="new_pw" type="password" required>
|
||||||
@@ -260,6 +261,7 @@ function update_email_form()
|
|||||||
<span class="modal_close">×</span>
|
<span class="modal_close">×</span>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="form_id" value="update_email_form">
|
<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>
|
<label for="new_email">New Email</label>
|
||||||
<input id="new_email" name="new_email" required>
|
<input id="new_email" name="new_email" required>
|
||||||
@@ -299,6 +301,7 @@ function update_username_form()
|
|||||||
<span class="modal_close">×</span>
|
<span class="modal_close">×</span>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="form_id" value="update_username_form">
|
<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>
|
<label for="new_username">New Username</label>
|
||||||
<input id="new_username" name="new_username" required>
|
<input id="new_username" name="new_username" required>
|
||||||
@@ -387,6 +390,7 @@ function delete_account_form()
|
|||||||
<span class="modal_close">×</span>
|
<span class="modal_close">×</span>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="form_id" value="delete_account_form">
|
<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>
|
<label for="delete_password">Password</label>
|
||||||
<input id="delete_password" name="delete_password" type="password" required>
|
<input id="delete_password" name="delete_password" type="password" required>
|
||||||
@@ -402,7 +406,7 @@ function delete_account_form()
|
|||||||
return $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) {
|
if ($user_id == 2025) {
|
||||||
$error_msg = '
|
$error_msg = '
|
||||||
@@ -424,8 +428,9 @@ function delete_account($user_id, $password, $verify_password)
|
|||||||
return $error_msg;
|
return $error_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($password && $verify_password) {
|
||||||
$password_hash = hash('sha256', $password);
|
$password_hash = hash('sha256', $password);
|
||||||
$query = 'SELECT user_id FROM user WHERE user_id = ' . $user_id . ' AND password_hash = "' . $password_hash . '";';
|
$query = 'SELECT user_id, profile_picture FROM user WHERE user_id = ' . $user_id . ' AND password_hash = "' . $password_hash . '";';
|
||||||
$user = query_one_result($query);
|
$user = query_one_result($query);
|
||||||
|
|
||||||
if ($user == null) {
|
if ($user == null) {
|
||||||
@@ -438,9 +443,28 @@ function delete_account($user_id, $password, $verify_password)
|
|||||||
return $error_msg;
|
return $error_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete_file($_ENV['PROFILE_IMAGES_FQ_PATH'] . $user['profile_picture']);
|
||||||
$stmt = 'DELETE FROM user WHERE user_id = ' . $user_id . ';';
|
$stmt = 'DELETE FROM user WHERE user_id = ' . $user_id . ';';
|
||||||
exec_statement($stmt, 1);
|
exec_statement($stmt, 1);
|
||||||
logout();
|
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)
|
function user_view($user_id)
|
||||||
@@ -492,9 +516,3 @@ function user_view($user_id)
|
|||||||
|
|
||||||
return $view;
|
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
|
<?php
|
||||||
require 'db_functions.php';
|
require_once 'db_functions.php';
|
||||||
|
|
||||||
function article_ids_by_recency()
|
function article_ids_by_recency()
|
||||||
{
|
{
|
||||||
@@ -14,6 +14,19 @@ function article_ids_by_recency()
|
|||||||
return $ids;
|
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()
|
function article_tags()
|
||||||
{
|
{
|
||||||
$query = 'SELECT * FROM tags;';
|
$query = 'SELECT * FROM tags;';
|
||||||
@@ -63,7 +76,7 @@ function article_page_from_markdown($article_id)
|
|||||||
<p>Published on ' . $article['published_at'] . '</p>
|
<p>Published on ' . $article['published_at'] . '</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card_pic_box">
|
<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>
|
</div>
|
||||||
<div class="line" style="margin-bottom: 15px;"></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);';
|
$stmt = 'INSERT INTO article (author_id, title, excerpt, published_at) VALUES (' . $author_id . ', "' . $title . '", "' . $excerpt . '", CURRENT_TIMESTAMP);';
|
||||||
$id = exec_statement($stmt, 0);
|
$id = exec_statement($stmt, 0);
|
||||||
|
|
||||||
$path = $_ENV['ARTICLES_PQ_PATH'] . $id . '/';
|
$path = $_ENV['ARTICLES_FQ_PATH'] . $id . '/';
|
||||||
mkdir($path);
|
mkdir($path);
|
||||||
|
echo '<p>created ' . $path . '</p>';
|
||||||
|
|
||||||
$fs = fopen($path . 'article.md', 'a');
|
$fs = fopen($path . 'article.md', 'a');
|
||||||
fwrite($fs, $markdown_file_contents);
|
fwrite($fs, $markdown_file_contents);
|
||||||
fclose($fs);
|
fclose($fs);
|
||||||
@@ -146,8 +161,6 @@ function create_article($author_id, $title, $excerpt, $tags, $markdown_file_cont
|
|||||||
$stmt .= ';';
|
$stmt .= ';';
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $stmt;
|
|
||||||
pretty_dump($tags);
|
|
||||||
if (count($tags) > 0)
|
if (count($tags) > 0)
|
||||||
exec_statement($stmt, 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)
|
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 . ';';
|
$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)
|
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 . '";';
|
$stmt = 'DELETE FROM article WHERE author_id = "' . $author_id . '";';
|
||||||
return exec_statement($stmt, 1);
|
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
|
<?php
|
||||||
|
|
||||||
|
require_once 'vendor/autoload.php';
|
||||||
|
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
||||||
|
$dotenv->safeLoad();
|
||||||
|
|
||||||
// Use environment variables for the database password and IP address.
|
// Use environment variables for the database password and IP address.
|
||||||
$db_user = $_ENV['DATABASE_USER'];
|
$db_user = $_ENV['DATABASE_USER'];
|
||||||
$db_pass = $_ENV['DATABASE_PASSWORD'];
|
$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);
|
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)
|
function upload($input, $dest_dir, $filename = null)
|
||||||
{
|
{
|
||||||
$filetype = strtolower(pathinfo($input['name'], PATHINFO_EXTENSION));
|
$filetype = strtolower(pathinfo($input['name'], PATHINFO_EXTENSION));
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ session_start();
|
|||||||
|
|
||||||
// Initialize Composer.
|
// Initialize Composer.
|
||||||
require_once 'vendor/autoload.php';
|
require_once 'vendor/autoload.php';
|
||||||
|
require_once 'db_functions.php';
|
||||||
|
|
||||||
// Load environment variables.
|
// Load environment variables.
|
||||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
||||||
@@ -18,3 +19,6 @@ if ($_SESSION['initialized'] && isset($_POST['theme'])) {
|
|||||||
$_SESSION['theme'] = $_POST['theme'];
|
$_SESSION['theme'] = $_POST['theme'];
|
||||||
unset($_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 |
@@ -0,0 +1,14 @@
|
|||||||
|
USE vintagecoding;
|
||||||
|
|
||||||
|
INSERT INTO user (user_id, username, email, password_hash, role_id, profile_picture)
|
||||||
|
VALUES (5749248, 'jsmith', 'jsmith@email.com', 'f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b', 4, '2025.jpg'),
|
||||||
|
(5789203, 'dummy', 'dummy@iamdumb.com', 'f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b', 4, '2025.jpg'),
|
||||||
|
(5723948, 'writer', 'writer@something.com', 'f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b', 3, '5723948.jpg')
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO article (author_id, title, excerpt, published_at)
|
||||||
|
VALUES (2025, 'Testing vintagecoding.net', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas a mauris sit amet dui pellentesque sodales. Pellentesque non viverra leo, et congue metus.', CURRENT_TIMESTAMP),
|
||||||
|
(5723948, 'Something Else', 'Here goes some random crap. Lorem ipsum akdfljskjlag IDK what to put here. I am just filling the space requirement. Blah blah blah blah, what does this look like? Is vintagecoding.net cool?', CURRENT_TIMESTAMP)
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO article_tags (article_id, tag_id) VALUES (21, 2), (21, 6);
|
||||||
+2
-6
@@ -53,13 +53,9 @@ INSERT INTO tags (tag)
|
|||||||
VALUES ('linux'), ('web-dev'), ('raspberry-pi'), ('self-hosting'), ('devlog'), ('testing');
|
VALUES ('linux'), ('web-dev'), ('raspberry-pi'), ('self-hosting'), ('devlog'), ('testing');
|
||||||
|
|
||||||
INSERT INTO user (user_id, username, email, password_hash, role_id, profile_picture)
|
INSERT INTO user (user_id, username, email, password_hash, role_id, profile_picture)
|
||||||
VALUES (2025, 'quaxlyqueen', 'me@joshashton.dev', 'changeme', 1, '2025.jpg');
|
VALUES (2025, 'quaxlyqueen', 'me@joshashton.dev', '057ba03d6c44104863dc7361fe4578965d1887360f90a0895882e58a6248fc86', 1, '2025.jpg');
|
||||||
|
|
||||||
INSERT INTO article (author_id, title, excerpt, published_at)
|
INSERT INTO article (author_id, title, excerpt, published_at)
|
||||||
VALUES (2025, 'Building vintagecoding.net', 'This site is intended to be a platform for exposing, celebrating, and sharing the style of Vintage Coding. Topics from hardware to software and kernel to web, this site aims to cover it all.', CURRENT_TIMESTAMP);
|
VALUES (2025, 'Building vintagecoding.net', 'A devlog of the creation of vintagecoding.net and a test at the formatting of article cards and articles. Let the great experiment begin!', CURRENT_TIMESTAMP);
|
||||||
|
|
||||||
INSERT INTO article (author_id, title, excerpt, published_at)
|
|
||||||
VALUES (2025, 'Testing vintagecoding.net', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas a mauris sit amet dui pellentesque sodales. Pellentesque non viverra leo, et congue metus.', CURRENT_TIMESTAMP);
|
|
||||||
|
|
||||||
INSERT INTO article_tags (article_id, tag_id) VALUES (1, 2), (1, 4), (1, 5);
|
INSERT INTO article_tags (article_id, tag_id) VALUES (1, 2), (1, 4), (1, 5);
|
||||||
INSERT INTO article_tags (article_id, tag_id) VALUES (2, 2), (2, 6);
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ if (isset($_POST['form_id'])) {
|
|||||||
|
|
||||||
case 'reset_pw_form':
|
case 'reset_pw_form':
|
||||||
$msg = reset_password(
|
$msg = reset_password(
|
||||||
$_COOKIE['user_id'],
|
($_COOKIE['role_id'] <= 2 && $_COOKIE['user_id'] != $_POST['user_id'] ? $_POST['user_id'] : $_COOKIE['user_id']),
|
||||||
$_POST['new_pw'],
|
$_POST['new_pw'],
|
||||||
$_POST['verify_new_pw']
|
$_POST['verify_new_pw']
|
||||||
);
|
);
|
||||||
@@ -53,7 +53,7 @@ if (isset($_POST['form_id'])) {
|
|||||||
|
|
||||||
case 'update_email_form':
|
case 'update_email_form':
|
||||||
$msg = update_email(
|
$msg = update_email(
|
||||||
$_COOKIE['user_id'],
|
($_COOKIE['role_id'] <= 2 && $_COOKIE['user_id'] != $_POST['user_id'] ? $_POST['user_id'] : $_COOKIE['user_id']),
|
||||||
$_POST['new_email'],
|
$_POST['new_email'],
|
||||||
$_POST['verify_new_email']
|
$_POST['verify_new_email']
|
||||||
);
|
);
|
||||||
@@ -64,7 +64,7 @@ if (isset($_POST['form_id'])) {
|
|||||||
|
|
||||||
case 'update_username_form':
|
case 'update_username_form':
|
||||||
$msg = update_username(
|
$msg = update_username(
|
||||||
$_COOKIE['user_id'],
|
($_COOKIE['role_id'] <= 2 && $_COOKIE['user_id'] != $_POST['user_id'] ? $_POST['user_id'] : $_COOKIE['user_id']),
|
||||||
$_POST['new_username'],
|
$_POST['new_username'],
|
||||||
$_POST['verify_new_username']
|
$_POST['verify_new_username']
|
||||||
);
|
);
|
||||||
@@ -75,7 +75,7 @@ if (isset($_POST['form_id'])) {
|
|||||||
|
|
||||||
case 'delete_account_form':
|
case 'delete_account_form':
|
||||||
$msg = delete_account(
|
$msg = delete_account(
|
||||||
$_COOKIE['user_id'],
|
($_COOKIE['role_id'] <= 2 && $_COOKIE['user_id'] != $_POST['user_id'] ? $_POST['user_id'] : $_COOKIE['user_id']),
|
||||||
$_POST['delete_password'],
|
$_POST['delete_password'],
|
||||||
$_POST['delete_verify_password']
|
$_POST['delete_verify_password']
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user