Added basic post deletion (no AJAX or topic deletion yet).
This commit is contained in:
parent
624cba9d32
commit
364cc75b68
8 changed files with 445 additions and 18 deletions
18
assets/less/classes/forum/confirm.less
Normal file
18
assets/less/classes/forum/confirm.less
Normal file
|
@ -0,0 +1,18 @@
|
|||
.forum__confirm {
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
|
||||
&__message {
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
&__buttons {
|
||||
display: flex;
|
||||
padding: 5px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__button {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
|
@ -166,6 +166,7 @@ html {
|
|||
@import "classes/forum/actions";
|
||||
@import "classes/forum/categories";
|
||||
@import "classes/forum/category";
|
||||
@import "classes/forum/confirm";
|
||||
@import "classes/forum/post";
|
||||
@import "classes/forum/topic";
|
||||
@import "classes/forum/topics";
|
||||
|
|
247
public/forum/post.php
Normal file
247
public/forum/post.php
Normal file
|
@ -0,0 +1,247 @@
|
|||
<?php
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
$postId = (int)($_GET['p'] ?? 0);
|
||||
$postMode = (string)($_GET['m'] ?? '');
|
||||
|
||||
// basing whether or not this is an xhr request on whether a referrer header is present
|
||||
// this page is never directy accessed, under normal circumstances
|
||||
$redirect = !empty($_SERVER['HTTP_REFERER']) && empty($_SERVER['HTTP_X_MISUZU_XHR']) ? $_SERVER['HTTP_REFERER'] : '';
|
||||
$isXHR = !$redirect;
|
||||
|
||||
if ($isXHR) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
} elseif (!is_local_url($redirect)) {
|
||||
echo render_info('Possible request forgery detected.', 403);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($_REQUEST['csrf'])) {
|
||||
$postRequestVerified = csrf_verify('forum_post', $_REQUEST['csrf'] ?? '');
|
||||
} elseif (!empty($_SERVER['HTTP_X_MISUZU_CSRF'])) {
|
||||
$postRequestVerified = csrf_verify('forum_post', csrf_http_header_parse($_SERVER['HTTP_X_MISUZU_CSRF'])['token']);
|
||||
} else {
|
||||
$postRequestVerified = false;
|
||||
}
|
||||
|
||||
if (!empty($postMode) && !user_session_active()) {
|
||||
echo render_info_or_json($isXHR, 'You must be logged in to manage posts.', 401);
|
||||
return;
|
||||
}
|
||||
|
||||
$currentUserId = (int)user_session_current('user_id', 0);
|
||||
|
||||
if (user_warning_check_expiration($currentUserId, MSZ_WARN_BAN) > 0) {
|
||||
echo render_info_or_json($isXHR, 'You have been banned, check your profile for more information.', 403);
|
||||
return;
|
||||
}
|
||||
if (user_warning_check_expiration($currentUserId, MSZ_WARN_SILENCE) > 0) {
|
||||
echo render_info_or_json($isXHR, 'You have been silenced, check your profile for more information.', 403);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($isXHR) {
|
||||
if (!$postRequestVerified) {
|
||||
http_response_code(403);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Possible request forgery detected.',
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
header(csrf_http_header('forum_post'));
|
||||
}
|
||||
|
||||
$postInfo = forum_post_get($postId, true);
|
||||
$perms = empty($postInfo) ? 0 : forum_perms_get_user(MSZ_FORUM_PERMS_GENERAL, $postInfo['forum_id'], $currentUserId);
|
||||
|
||||
switch ($postMode) {
|
||||
case 'delete':
|
||||
$canDelete = forum_post_can_delete($postInfo, $currentUserId);
|
||||
$canDeleteMsg = '';
|
||||
$responseCode = 200;
|
||||
|
||||
switch ($canDelete) {
|
||||
case MSZ_E_FORUM_POST_DELETE_USER: // i don't think this is ever reached but we may as well have it
|
||||
$responseCode = 401;
|
||||
$canDeleteMsg = 'You must be logged in to delete posts.';
|
||||
break;
|
||||
case MSZ_E_FORUM_POST_DELETE_POST:
|
||||
$responseCode = 404;
|
||||
$canDeleteMsg = "This post doesn't exist.";
|
||||
break;
|
||||
case MSZ_E_FORUM_POST_DELETE_DELETED:
|
||||
$responseCode = 404;
|
||||
$canDeleteMsg = 'This post has already been marked as deleted.';
|
||||
break;
|
||||
case MSZ_E_FORUM_POST_DELETE_OWNER:
|
||||
$responseCode = 403;
|
||||
$canDeleteMsg = 'You can only delete your own posts.';
|
||||
break;
|
||||
case MSZ_E_FORUM_POST_DELETE_OLD:
|
||||
$responseCode = 401;
|
||||
$canDeleteMsg = 'This post has existed for too long, ask a moderator to remove if it absolutely necessary.';
|
||||
break;
|
||||
case MSZ_E_FORUM_POST_DELETE_PERM:
|
||||
$responseCode = 401;
|
||||
$canDeleteMsg = 'You are not allowed to delete posts.';
|
||||
break;
|
||||
case MSZ_E_FORUM_POST_DELETE_OP:
|
||||
$responseCode = 403;
|
||||
$canDeleteMsg = 'This is the opening post of a topic, it may not be deleted without deleting the entire topic as well.';
|
||||
break;
|
||||
case MSZ_E_FORUM_POST_DELETE_OK:
|
||||
break;
|
||||
default:
|
||||
$responseCode = 500;
|
||||
$canDeleteMsg = sprintf('Unknown error \'%d\'', $canDelete);
|
||||
}
|
||||
|
||||
if ($canDelete !== MSZ_E_FORUM_POST_DELETE_OK) {
|
||||
if ($isXHR) {
|
||||
http_response_code($responseCode);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'post_id' => $postInfo['post_id'],
|
||||
'code' => $canDelete,
|
||||
'message' => $canDeleteMsg,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
echo render_info($canDeleteMsg, $responseCode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$isXHR) {
|
||||
if ($postRequestVerified && isset($_GET['confirm']) && $_GET['confirm'] !== '1') {
|
||||
header("Location: /forum/topic.php?p={$postInfo['post_id']}#p{$postInfo['post_id']}");
|
||||
break;
|
||||
} elseif (!$postRequestVerified) {
|
||||
echo tpl_render('forum.confirm', [
|
||||
'title' => 'Confirm post deletion',
|
||||
'class' => 'far fa-trash-alt',
|
||||
'mode' => 'delete',
|
||||
'message' => sprintf('You are about to delete post #%d. Are you sure about that?', $postInfo['post_id']),
|
||||
'post' => $postInfo,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$deletePost = forum_post_delete($postInfo['post_id']);
|
||||
|
||||
if ($isXHR) {
|
||||
echo json_encode([
|
||||
'success' => $deletePost,
|
||||
'post_id' => $postInfo['post_id'],
|
||||
'message' => $deletePost ? 'Post deleted!' : 'Failed to delete post.',
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$deletePost) {
|
||||
echo render_error(500);
|
||||
break;
|
||||
}
|
||||
|
||||
header('Location: /forum/topic.php?t=' . $postInfo['topic_id']);
|
||||
break;
|
||||
|
||||
case 'nuke':
|
||||
if (!perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST)) {
|
||||
echo render_error(403);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$isXHR) {
|
||||
if ($postRequestVerified && isset($_GET['confirm']) && $_GET['confirm'] !== '1') {
|
||||
header("Location: /forum/topic.php?p={$postInfo['post_id']}#p{$postInfo['post_id']}");
|
||||
break;
|
||||
} elseif (!$postRequestVerified) {
|
||||
echo tpl_render('forum.confirm', [
|
||||
'title' => 'Confirm post nuke',
|
||||
'class' => 'fas fa-radiation',
|
||||
'mode' => 'nuke',
|
||||
'message' => sprintf('You are about to PERMANENTLY DELETE post #%d. Are you sure about that?', $postInfo['post_id']),
|
||||
'post' => $postInfo,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$nukePost = forum_post_nuke($postInfo['post_id']);
|
||||
|
||||
if (!$nukePost) {
|
||||
echo render_error(500);
|
||||
break;
|
||||
}
|
||||
|
||||
http_response_code(204);
|
||||
|
||||
if (!$isXHR) {
|
||||
header('Location: /forum/topic.php?t=' . $postInfo['topic_id']);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'restore':
|
||||
if (!perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST)) {
|
||||
echo render_error(403);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$isXHR) {
|
||||
if ($postRequestVerified && isset($_GET['confirm']) && $_GET['confirm'] !== '1') {
|
||||
header("Location: /forum/topic.php?p={$postInfo['post_id']}#p{$postInfo['post_id']}");
|
||||
break;
|
||||
} elseif (!$postRequestVerified) {
|
||||
echo tpl_render('forum.confirm', [
|
||||
'title' => 'Confirm post restore',
|
||||
'class' => 'fas fa-magic',
|
||||
'mode' => 'restore',
|
||||
'message' => sprintf('You are about to restore post #%d. Are you sure about that?', $postInfo['post_id']),
|
||||
'post' => $postInfo,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$restorePost = forum_post_restore($postInfo['post_id']);
|
||||
|
||||
if (!$restorePost) {
|
||||
echo render_error(500);
|
||||
break;
|
||||
}
|
||||
|
||||
http_response_code(204);
|
||||
|
||||
if (!$isXHR) {
|
||||
header('Location: /forum/topic.php?t=' . $postInfo['topic_id']);
|
||||
}
|
||||
break;
|
||||
|
||||
default: // function as an alt for topic.php?p= by default
|
||||
if (!empty($postInfo['post_deleted']) && !perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST)) {
|
||||
echo render_error(404);
|
||||
break;
|
||||
}
|
||||
|
||||
$postFind = forum_post_find($postInfo['post_id'], user_session_current('user_id', 0));
|
||||
|
||||
if (empty($postFind)) {
|
||||
echo render_error(404);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($isXHR) {
|
||||
unset($postFind['can_view_deleted']);
|
||||
echo json_encode($postFind);
|
||||
break;
|
||||
}
|
||||
|
||||
header('Location: ' . url_construct('/forum/topic.php', [
|
||||
't' => $postFind['topic_id'],
|
||||
'p' => floor($postFind['preceeding_post_count'] / MSZ_FORUM_POSTS_PER_PAGE) + 1,
|
||||
]));
|
||||
}
|
|
@ -12,8 +12,7 @@ if (user_warning_check_restriction(user_session_current('user_id', 0))) {
|
|||
}
|
||||
|
||||
$forumPostingModes = [
|
||||
'create', 'edit', 'quote',
|
||||
'delete', 'restore', 'nuke',
|
||||
'create', 'edit', 'quote',
|
||||
];
|
||||
|
||||
if (!empty($_POST)) {
|
||||
|
|
|
@ -86,7 +86,7 @@ function forum_post_get(int $postId, bool $allowDeleted = false): array
|
|||
'
|
||||
SELECT
|
||||
p.`post_id`, p.`post_text`, p.`post_created`, p.`post_parse`,
|
||||
p.`topic_id`, p.`post_deleted`, p.`post_edited`,
|
||||
p.`topic_id`, p.`post_deleted`, p.`post_edited`, p.`topic_id`, p.`forum_id`,
|
||||
INET6_NTOA(p.`post_ip`) AS `post_ip`,
|
||||
u.`user_id` AS `poster_id`,
|
||||
u.`username` AS `poster_name`,
|
||||
|
@ -166,3 +166,118 @@ function forum_post_listing(int $topicId, int $offset = 0, int $take = 0, bool $
|
|||
|
||||
return db_fetch_all($getPosts);
|
||||
}
|
||||
|
||||
define('MSZ_E_FORUM_POST_DELETE_OK', 0); // deleting is fine
|
||||
define('MSZ_E_FORUM_POST_DELETE_USER', 1); // invalid user
|
||||
define('MSZ_E_FORUM_POST_DELETE_POST', 2); // post doesn't exist
|
||||
define('MSZ_E_FORUM_POST_DELETE_DELETED', 3); // post is already marked as deleted
|
||||
define('MSZ_E_FORUM_POST_DELETE_OWNER', 4); // you may only delete your own posts
|
||||
define('MSZ_E_FORUM_POST_DELETE_OLD', 5); // posts has existed for too long to be deleted
|
||||
define('MSZ_E_FORUM_POST_DELETE_PERM', 6); // you aren't allowed to delete posts
|
||||
define('MSZ_E_FORUM_POST_DELETE_OP', 7); // this is the opening post of a topic
|
||||
|
||||
// only allow posts made within a week of posting to be deleted by normal users
|
||||
define('MSZ_FORUM_POST_DELETE_LIMIT', 60 * 60 * 24 * 7);
|
||||
|
||||
// set $userId to null for system request, make sure this is NEVER EVER null on user request
|
||||
// $postId can also be a the return value of forum_post_get if you already grabbed it once before
|
||||
function forum_post_can_delete($postId, ?int $userId = null): int
|
||||
{
|
||||
if (($userId !== null && $userId < 1) || $postId < 1) {
|
||||
return MSZ_E_FORUM_POST_DELETE_USER;
|
||||
}
|
||||
|
||||
if (is_array($postId)) {
|
||||
$post = $postId;
|
||||
} else {
|
||||
$post = forum_post_get((int)$postId, true);
|
||||
}
|
||||
|
||||
if (empty($post)) {
|
||||
return MSZ_E_FORUM_POST_DELETE_POST;
|
||||
}
|
||||
|
||||
$isSystemReq = $userId === null;
|
||||
$perms = $isSystemReq ? 0 : forum_perms_get_user(MSZ_FORUM_PERMS_GENERAL, $post['forum_id'], $userId);
|
||||
$canDeleteAny = $isSystemReq ? true : perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST);
|
||||
$canViewPost = $isSystemReq ? true : perms_check($perms, MSZ_FORUM_PERM_VIEW_FORUM);
|
||||
$postIsDeleted = !empty($post['post_deleted']);
|
||||
|
||||
if (!$canViewPost) {
|
||||
return MSZ_E_FORUM_POST_DELETE_POST;
|
||||
}
|
||||
|
||||
if ($post['is_opening_post']) {
|
||||
return MSZ_E_FORUM_POST_DELETE_OP;
|
||||
}
|
||||
|
||||
if ($postIsDeleted) {
|
||||
return $canDeleteAny ? MSZ_E_FORUM_POST_DELETE_DELETED : MSZ_E_FORUM_POST_DELETE_POST;
|
||||
}
|
||||
|
||||
if ($isSystemReq) {
|
||||
return MSZ_E_FORUM_POST_DELETE_OK;
|
||||
}
|
||||
|
||||
if (!$canDeleteAny) {
|
||||
if (!perms_check($perms, MSZ_FORUM_PERM_DELETE_POST)) {
|
||||
return MSZ_E_FORUM_POST_DELETE_PERM;
|
||||
}
|
||||
|
||||
if ($post['poster_id'] !== $userId) {
|
||||
return MSZ_E_FORUM_POST_DELETE_OWNER;
|
||||
}
|
||||
|
||||
if (strtotime($post['post_created']) <= time() - MSZ_FORUM_POST_DELETE_LIMIT) {
|
||||
return MSZ_E_FORUM_POST_DELETE_OLD;
|
||||
}
|
||||
}
|
||||
|
||||
return MSZ_E_FORUM_POST_DELETE_OK;
|
||||
}
|
||||
|
||||
function forum_post_delete(int $postId): bool
|
||||
{
|
||||
if ($postId < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$markDeleted = db_prepare('
|
||||
UPDATE `msz_forum_posts`
|
||||
SET `post_deleted` = NOW()
|
||||
WHERE `post_id` = :post
|
||||
AND `post_deleted` IS NULL
|
||||
');
|
||||
$markDeleted->bindValue('post', $postId);
|
||||
return $markDeleted->execute();
|
||||
}
|
||||
|
||||
function forum_post_restore(int $postId): bool
|
||||
{
|
||||
if ($postId < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$markDeleted = db_prepare('
|
||||
UPDATE `msz_forum_posts`
|
||||
SET `post_deleted` = NULL
|
||||
WHERE `post_id` = :post
|
||||
AND `post_deleted` IS NOT NULL
|
||||
');
|
||||
$markDeleted->bindValue('post', $postId);
|
||||
return $markDeleted->execute();
|
||||
}
|
||||
|
||||
function forum_post_nuke(int $postId): bool
|
||||
{
|
||||
if ($postId < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$markDeleted = db_prepare('
|
||||
DELETE FROM `msz_forum_posts`
|
||||
WHERE `post_id` = :post
|
||||
');
|
||||
$markDeleted->bindValue('post', $postId);
|
||||
return $markDeleted->execute();
|
||||
}
|
||||
|
|
16
src/csrf.php
16
src/csrf.php
|
@ -120,6 +120,22 @@ function csrf_http_header(string $realm, string $name = 'X-Misuzu-CSRF'): string
|
|||
return "{$name}: {$realm};" . csrf_token($realm);
|
||||
}
|
||||
|
||||
function csrf_http_header_parse(string $header): array
|
||||
{
|
||||
$split = explode(';', $header, 2);
|
||||
$realm = $split[0] ?? '';
|
||||
$token = $split[1] ?? '';
|
||||
|
||||
if (empty($realm) || empty($token)) {
|
||||
[$realm, $token] = ['', ''];
|
||||
}
|
||||
|
||||
return [
|
||||
'realm' => $realm,
|
||||
'token' => $token,
|
||||
];
|
||||
}
|
||||
|
||||
function csrf_get_list(): array
|
||||
{
|
||||
$list = [];
|
||||
|
|
24
templates/forum/confirm.twig
Normal file
24
templates/forum/confirm.twig
Normal file
|
@ -0,0 +1,24 @@
|
|||
{% extends 'forum/master.twig' %}
|
||||
{% from 'forum/macros.twig' import forum_category_listing, forum_topic_listing, forum_category_buttons, forum_header, forum_category_tools %}
|
||||
{% from 'macros.twig' import container_title %}
|
||||
{% from '_layout/input.twig' import input_csrf %}
|
||||
|
||||
{% set title = title|default('Confirm your action') %}
|
||||
|
||||
{% block content %}
|
||||
<form action="" method="get" class="container forum__confirm">
|
||||
{{ container_title('<i class="' ~ class|default('fas fa-exclamation-circle') ~ ' fa-fw"></i> ' ~ title) }}
|
||||
{{ input_csrf('forum_post') }}
|
||||
<input type="hidden" name="p" value="{{ post.post_id|default(0) }}">
|
||||
<input type="hidden" name="m" value="{{ mode|default('') }}">
|
||||
|
||||
<div class="forum__confirm__message">
|
||||
{{ message|default('Are you sure you w') }}
|
||||
</div>
|
||||
|
||||
<div class="forum__confirm__buttons">
|
||||
<button name="confirm" value="1" class="input__button forum__confirm__button">Yes</button>
|
||||
<button name="confirm" value="0" class="input__button forum__confirm__button">No</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -350,17 +350,24 @@
|
|||
{% from _self import forum_post_entry %}
|
||||
|
||||
{% for post in posts %}
|
||||
{{ forum_post_entry(
|
||||
post,
|
||||
perms|perms_check(constant('MSZ_FORUM_PERM_CREATE_POST')),
|
||||
perms|perms_check(constant(user_id == post.poster_id ? 'MSZ_FORUM_PERM_EDIT_POST' : 'MSZ_FORUM_PERM_EDIT_ANY_POST')),
|
||||
perms|perms_check(constant(user_id == post.poster_id ? 'MSZ_FORUM_PERM_DELETE_POST' : 'MSZ_FORUM_PERM_DELETE_ANY_POST'))
|
||||
) }}
|
||||
{{ forum_post_entry(post, user_id, perms) }}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro forum_post_entry(post, can_post, can_edit, can_delete) %}
|
||||
{% set is_deleted = post.post_deleted is not null %}
|
||||
{% macro forum_post_entry(post, user_id, perms) %}
|
||||
{% set is_deleted = post.post_deleted is not null %}
|
||||
{% set can_post = perms|perms_check(constant('MSZ_FORUM_PERM_CREATE_POST')) %}
|
||||
{% set can_edit = perms|perms_check(constant('MSZ_FORUM_PERM_EDIT_ANY_POST')) or (
|
||||
user_id == post.poster_id
|
||||
and perms|perms_check(constant('MSZ_FORUM_PERM_EDIT_POST'))
|
||||
) %}
|
||||
{% set can_delete = not post.is_opening_post and (
|
||||
perms|perms_check(constant('MSZ_FORUM_PERM_DELETE_ANY_POST')) or (
|
||||
user_id == post.poster_id
|
||||
and perms|perms_check(constant('MSZ_FORUM_PERM_DELETE_POST'))
|
||||
and post.post_created|date('U') > ''|date('U') - constant('MSZ_FORUM_POST_DELETE_LIMIT')
|
||||
)
|
||||
) %}
|
||||
|
||||
<div class="container forum__post{% if is_deleted %} forum__post--deleted{% endif %}" id="p{{ post.post_id }}" style="{{ post.poster_colour|html_colour('--accent-colour') }}">
|
||||
<div class="forum__post__info">
|
||||
|
@ -409,18 +416,18 @@
|
|||
{% if can_post or can_edit or can_delete %}
|
||||
<div class="forum__post__actions">
|
||||
{% if is_deleted %}
|
||||
<a href="/forum/posting.php?p={{ post.post_id }}&m=restore" class="forum__post__action"><i class="fas fa-magic fa-fw"></i> Restore</a>
|
||||
<a href="/forum/posting.php?p={{ post.post_id }}&m=nuke" class="forum__post__action"><i class="fas fa-radiation-alt fa-fw"></i> Permanently Delete</a>
|
||||
<a href="/forum/post.php?p={{ post.post_id }}&m=restore" class="forum__post__action forum__post__action--restore"><i class="fas fa-magic fa-fw"></i> Restore</a>
|
||||
<a href="/forum/post.php?p={{ post.post_id }}&m=nuke" class="forum__post__action forum__post__action--nuke"><i class="fas fa-radiation-alt fa-fw"></i> Permanently Delete</a>
|
||||
{% else %}
|
||||
{# if can_post %}
|
||||
<a href="/forum/posting.php?p={{ post.post_id }}&m=quote" class="forum__post__action"><i class="fas fa-quote-left fa-fw"></i> Quote</a>
|
||||
<a href="/forum/posting.php?p={{ post.post_id }}&m=quote" class="forum__post__action forum__post__action--quote"><i class="fas fa-quote-left fa-fw"></i> Quote</a>
|
||||
{% endif #}
|
||||
{% if can_edit %}
|
||||
<a href="/forum/posting.php?p={{ post.post_id }}&m=edit" class="forum__post__action"><i class="fas fa-edit fa-fw"></i> Edit</a>
|
||||
<a href="/forum/posting.php?p={{ post.post_id }}&m=edit" class="forum__post__action forum__post__action--edit"><i class="fas fa-edit fa-fw"></i> Edit</a>
|
||||
{% endif %}
|
||||
{% if can_delete %}
|
||||
<a href="/forum/post.php?p={{ post.post_id }}&m=delete" class="forum__post__action forum__post__action--delete"><i class="far fa-trash-alt fa-fw"></i> Delete</a>
|
||||
{% endif %}
|
||||
{# if can_delete %}
|
||||
<a href="/forum/posting.php?p={{ post.post_id }}&m=delete" class="forum__post__action"><i class="far fa-trash-alt fa-fw"></i> Delete</a>
|
||||
{% endif #}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
Loading…
Add table
Reference in a new issue