Post editing feature
This commit is contained in:
parent
8211c01d84
commit
e7213d9749
@ -496,6 +496,8 @@
|
||||
$config['allow_delete'] = true;
|
||||
// How long after posting should you have to wait before being able to delete that post? (In seconds.)
|
||||
$config['delete_time'] = 10;
|
||||
// Allow users to delete their own posts?
|
||||
$config['allow_edit'] = false;
|
||||
// Reply limit (stops bumping thread when this is reached).
|
||||
$config['reply_limit'] = 250;
|
||||
|
||||
@ -1029,6 +1031,7 @@
|
||||
// $config['additional_javascript'][] = 'js/auto-reload.js';
|
||||
// $config['additional_javascript'][] = 'js/post-hover.js';
|
||||
// $config['additional_javascript'][] = 'js/style-select.js';
|
||||
// $config['additional_javascript'][] = 'js/history.js'; // Post editing JS, not required and needs jQuery
|
||||
|
||||
// Where these script files are located on the web. Defaults to $config['root'].
|
||||
// $config['additional_javascript_url'] = 'http://static.example.org/tinyboard-javascript-stuff/';
|
||||
|
||||
@ -2862,3 +2862,13 @@ function strategy_first($fun, $array) {
|
||||
return array('defer');
|
||||
}
|
||||
}
|
||||
|
||||
function ids_from_postdata($post, $prefix='delete') {
|
||||
$ids = array();
|
||||
foreach ($_POST as $post => $value) {
|
||||
if (preg_match('/^'.$prefix.'_(\d+)$/', $post, $m)) {
|
||||
$ids[] = (int)$m[1];
|
||||
}
|
||||
}
|
||||
return array_unique($ids);
|
||||
}
|
||||
8
js/history.js
Executable file
8
js/history.js
Executable file
@ -0,0 +1,8 @@
|
||||
$(document).ready(function(){
|
||||
$('.history_item').hide();
|
||||
$('.edit_history').prepend('This post was edited by the user. <a href="#" class="view_history">Click here to toggle the edit history.</a> ');
|
||||
$('.view_history').click(function(element) {
|
||||
$(this).parent().find('.history_item').toggle();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
113
post.php
113
post.php
@ -197,14 +197,9 @@ if (isset($_POST['delete'])) {
|
||||
|
||||
if ($password == '')
|
||||
error($config['error']['invalidpassword']);
|
||||
|
||||
$delete = array();
|
||||
foreach ($_POST as $post => $value) {
|
||||
if (preg_match('/^delete_(\d+)$/', $post, $m)) {
|
||||
$delete[] = (int)$m[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$delete = ids_from_postdata($_POST);
|
||||
|
||||
checkDNSBL();
|
||||
|
||||
// Check if board exists
|
||||
@ -276,6 +271,108 @@ if (isset($_POST['delete'])) {
|
||||
@fastcgi_finish_request();
|
||||
|
||||
rebuildThemes('post-delete', $board['uri']);
|
||||
} else if (isset($_POST['edit'])) {
|
||||
if (!$config['allow_edit'])
|
||||
error('Post editing is not allowed!');
|
||||
|
||||
checkDNSBL();
|
||||
|
||||
// Check if board exists
|
||||
if (!openBoard($_POST['board']))
|
||||
error($config['error']['noboard']);
|
||||
|
||||
// Check if banned
|
||||
checkBan($board['uri']);
|
||||
|
||||
// Check if password is empty
|
||||
$password = &$_POST['password'];
|
||||
if ($password == '')
|
||||
error($config['error']['invalidpassword']);
|
||||
|
||||
// Check if user is coming from edit template
|
||||
$view_base = isset($_POST['body']);
|
||||
|
||||
if (!$view_base) {
|
||||
// Fetch id list from $_POST
|
||||
$ids = ids_from_postdata($_POST);
|
||||
if (count($ids) == 0) {
|
||||
error('You must select one post to edit.');
|
||||
} else if (count($ids) > 1) {
|
||||
error('You must select only one post to edit.');
|
||||
}
|
||||
// First and only id from ids array
|
||||
$id = $ids[0];
|
||||
} else {
|
||||
$id = (int)$_POST['id'];
|
||||
}
|
||||
|
||||
$query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `id` = :id", $board['uri']));
|
||||
$query->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$query->execute() or error(db_error($query));
|
||||
|
||||
if ($post = $query->fetch(PDO::FETCH_ASSOC)) {
|
||||
if ($post['password'] != $password) {
|
||||
error($config['error']['invalidpassword']);
|
||||
}
|
||||
|
||||
if (!$view_base) {
|
||||
// Removes modifiers for showing
|
||||
$post['body_nomarkup'] = remove_modifiers($post['body_nomarkup']);
|
||||
|
||||
echo Element('page.html', array(
|
||||
'config' => $config,
|
||||
'mod' => false,
|
||||
'title' => 'Edit post',
|
||||
'subtitle' => '',
|
||||
'boardlist' => array(),
|
||||
'body' => Element('edit_post_form.html',
|
||||
array_merge(
|
||||
array('config' => $config, 'mod' => false),
|
||||
array('post' => array_merge($post, array('board' => $board['uri'])))
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// Remove any modifiers they may have put in
|
||||
$_POST['body'] = remove_modifiers($_POST['body']);
|
||||
|
||||
// Add back modifiers from the original post
|
||||
$modifiers = extract_modifiers($post['body_nomarkup']);
|
||||
|
||||
// If post was previously edited, it should have a history modifier
|
||||
// then, we want to add the actual post to it.
|
||||
$history_html = Element('post/history_item.html', array(
|
||||
'post' => $post,
|
||||
'config' => $config,
|
||||
'edited_at' => time()
|
||||
));
|
||||
if (isset($modifiers['history'])) {
|
||||
$modifiers['history'] = $history_html.$modifiers['history'];
|
||||
} else {
|
||||
$modifiers['history'] = $history_html;
|
||||
}
|
||||
|
||||
foreach ($modifiers as $key => $value) {
|
||||
$_POST['body'] .= "<tinyboard $key>$value</tinyboard>";
|
||||
};
|
||||
|
||||
$query = prepare(sprintf('UPDATE ``posts_%s`` SET `body_nomarkup` = :body_nomarkup WHERE `id` = :id', $board['uri']));
|
||||
$query->bindValue(':id', $id);
|
||||
$query->bindValue(':body_nomarkup', $_POST['body']);
|
||||
$query->execute() or error(db_error($query));
|
||||
|
||||
rebuildPost($id);
|
||||
|
||||
buildIndex();
|
||||
rebuildThemes('post', $board['uri']);
|
||||
|
||||
header('Location: ' . $config['root'] . $board['dir'] . $config['file_index'], true, $config['redirect_http']);
|
||||
}
|
||||
} else {
|
||||
// Invalid post
|
||||
error($config['error']['404']);
|
||||
}
|
||||
|
||||
} elseif (isset($_POST['report'])) {
|
||||
if (!isset($_POST['board'], $_POST['reason']))
|
||||
|
||||
@ -254,3 +254,9 @@ table.board-list-table .board-tags .board-cell:hover {
|
||||
table.board-list-table tr:nth-of-type( even ) .board-tags .board-cell {
|
||||
background: #333333;
|
||||
}
|
||||
|
||||
/* Post editing style */
|
||||
.edit_history {
|
||||
color: #000;
|
||||
padding: 5px;
|
||||
}
|
||||
@ -1923,3 +1923,19 @@ div.mix {
|
||||
footer {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
/* Post editing style */
|
||||
.edit_history {
|
||||
color: #000;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.history_item {
|
||||
padding: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.history_date {
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
}
|
||||
42
templates/edit_post_form.html
Executable file
42
templates/edit_post_form.html
Executable file
@ -0,0 +1,42 @@
|
||||
<form action="" method="post">
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>
|
||||
{% trans %}Name{% endtrans %}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="name" size="25" maxlength="35" autocomplete="off" value="{{ post.name|e }}" disabled>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{% trans %}Email{% endtrans %}
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="email" size="25" maxlength="40" autocomplete="off" value="{{ post.email|e }}" disabled>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{% trans %}Subject{% endtrans %}
|
||||
</th>
|
||||
<td>
|
||||
<input style="float:left;" type="text" name="subject" size="25" maxlength="100" autocomplete="off" value="{{ post.subject|e }}" disabled>
|
||||
<input accesskey="s" style="margin-left:2px;" type="submit" name="post" value="{% trans %}Update{% endtrans %}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
{% trans %}Comment{% endtrans %}
|
||||
</th>
|
||||
<td>
|
||||
<textarea name="body" id="body" rows="8" cols="35">{{ post.body_nomarkup|e }}</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="hidden" name="password" size="25" maxlength="40" autocomplete="off" value="{{ post.password|e }}">
|
||||
<input type="hidden" name="board" size="25" maxlength="40" autocomplete="off" value="{{ post.board|e }}">
|
||||
<input type="hidden" name="id" size="25" maxlength="40" autocomplete="off" value="{{ post.id }}">
|
||||
<input type="hidden" name="edit" value="on">
|
||||
</form>
|
||||
5
templates/post/history.html
Executable file
5
templates/post/history.html
Executable file
@ -0,0 +1,5 @@
|
||||
{% if post.modifiers.history %}
|
||||
<div class="edit_history">
|
||||
{{post.modifiers.history}}
|
||||
</div>
|
||||
{% endif %}
|
||||
6
templates/post/history_item.html
Executable file
6
templates/post/history_item.html
Executable file
@ -0,0 +1,6 @@
|
||||
<div class="history_item">
|
||||
<span class="history_date">Edited at {{edited_at|date(config.post_date)}}. Previous comment:</span>
|
||||
<div class="history_comment">
|
||||
{{post.body}}
|
||||
</div>
|
||||
</div>
|
||||
3
templates/post_reply.html
Normal file → Executable file
3
templates/post_reply.html
Normal file → Executable file
@ -24,6 +24,9 @@
|
||||
{% if post.modifiers['ban message'] %}
|
||||
{{ config.mod.ban_message|sprintf(post.modifiers['ban message']) }}
|
||||
{% endif %}
|
||||
{% if post.modifiers['history'] %}
|
||||
{% include 'post/history.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
3
templates/post_thread.html
Normal file → Executable file
3
templates/post_thread.html
Normal file → Executable file
@ -61,6 +61,9 @@
|
||||
{% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %}
|
||||
{% if post.modifiers['ban message'] %}
|
||||
{{ config.mod.ban_message|sprintf(post.modifiers['ban message']) }}
|
||||
{% endif %}
|
||||
{% if post.modifiers['history'] %}
|
||||
{% include 'post/history.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if post.omitted or post.omitted_images %}
|
||||
|
||||
11
templates/report_delete.html
Normal file → Executable file
11
templates/report_delete.html
Normal file → Executable file
@ -5,8 +5,17 @@
|
||||
<label for="delete_file">{% trans %}File{% endtrans %}</label>] <label for="password">{% trans %}Password{% endtrans %}</label>
|
||||
<input id="password" type="password" name="password" size="12" maxlength="18" />
|
||||
<input type="submit" name="delete" value="{% trans %}Delete{% endtrans %}" />
|
||||
{% if config.allow_edit %}
|
||||
<input type="submit" name="edit" value="{% trans %}Edit{% endtrans %}" />
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% elseif config.allow_edit %}
|
||||
<div id="edit-fields">
|
||||
<label for="password">{% trans %}Password{% endtrans %}</label>
|
||||
<input id="password" type="password" name="password" size="12" maxlength="18" />
|
||||
<input type="submit" name="edit" value="{% trans %}Edit{% endtrans %}" />
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="report-fields">
|
||||
<label for="reason">{% trans %}Reason{% endtrans %}</label>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user