+ ajax-delete comments via front end (if logged in with super admin priviledges)
This commit is contained in:
parent
b4ab9a5111
commit
905c04937c
|
@ -2,9 +2,9 @@ function escapeRegExp(str) {
|
||||||
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
|
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
|
||||||
}
|
}
|
||||||
jQuery(document).ready(function () {
|
jQuery(document).ready(function () {
|
||||||
var commentForm = $(document).find('.comments-form');
|
var commentForm = $('#comments-form'); //$(document).find('.comments-form').first();
|
||||||
var commentSection = $(document).find('.comments').first();
|
var commentSection = $('#comments-section'); //$(document).find('.comments').first();
|
||||||
var commentAlert = $(document).find('.alert').first();
|
var commentAlert = $('#comments-alert'); //$(document).find('.alert').first();
|
||||||
|
|
||||||
//hide form, show link
|
//hide form, show link
|
||||||
commentForm.hide();
|
commentForm.hide();
|
||||||
|
@ -13,20 +13,78 @@ jQuery(document).ready(function () {
|
||||||
//show comment form above comments section (new comment thread)
|
//show comment form above comments section (new comment thread)
|
||||||
$('body').on('click', '.comment-add-new', function (e) {
|
$('body').on('click', '.comment-add-new', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
//commentForm.hide(1000);
|
if ($(this).prev().filter('#comments-form').length > 0) {
|
||||||
|
//form is already in the right place.
|
||||||
|
//just make sure it is visible.
|
||||||
|
commentForm.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
commentForm.hide(); //hide it to make sure that it is not shown after move to make "show" transition work.
|
||||||
$(this).before(commentForm);
|
$(this).before(commentForm);
|
||||||
commentForm.show('slow');
|
commentForm.show('slow');
|
||||||
commentAlert.slideUp();
|
commentAlert.empty().slideUp();
|
||||||
});
|
});
|
||||||
|
|
||||||
//show comment form below selected comment (reply to existing comment)
|
//show comment form below selected comment (reply to existing comment)
|
||||||
$('body').on('click', '.comment-add-reply', function (e) {
|
$('body').on('click', '.comment-add-reply', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var media = $(this).closest('.comment');
|
var comment = $(this).closest('.comment');
|
||||||
|
if (comment.find('#comments-form').length > 0) {
|
||||||
|
//form is already in the right place.
|
||||||
|
//just make sure it is visible.
|
||||||
|
commentForm.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
commentForm.hide();
|
commentForm.hide();
|
||||||
media.find('>.comment-body>.comment-text').after(commentForm);
|
comment.find('.comment-body').last().append(commentForm);
|
||||||
commentForm.show('slow');
|
commentForm.show('slow');
|
||||||
commentAlert.slideUp();
|
commentAlert.empty().slideUp();
|
||||||
|
});
|
||||||
|
|
||||||
|
//delete comment (authorized user only)
|
||||||
|
$('body').on('click', '.comment-delete', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var comment = $(this).closest('.comment');
|
||||||
|
var id = parseInt(comment.attr('data-id'), 10);
|
||||||
|
var level = parseInt(comment.attr('data-level'), 10);
|
||||||
|
var nonce = commentForm.find("input[name='form-nonce']").val();
|
||||||
|
if (comment.next().filter(".comment[data-level='" + (level + 1) + "']").length > 0) {
|
||||||
|
alert('Deletion not allowed. There are replies to this comment. Please delete them first.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var url = commentForm.attr( "action" );
|
||||||
|
var posting = $.post(url, { action: 'delete', id: id, nonce: nonce}, null, 'json');
|
||||||
|
// Register events to ajax call
|
||||||
|
posting.done(function (response) {
|
||||||
|
|
||||||
|
//make sure that commentForm is definitely not within the deleted DOM part.
|
||||||
|
//hide
|
||||||
|
//temporary move it outside the comment selected for deletion. (this definitely exists, not taking any chances here)
|
||||||
|
//finally move back to start of commentSection. (preferred target)
|
||||||
|
//Hint: Don't forget commentAlert as it is not inside the form.
|
||||||
|
commentAlert.empty().hide();
|
||||||
|
commentForm.hide();
|
||||||
|
comment.before(commentForm);
|
||||||
|
comment.before(commentAlert);
|
||||||
|
commentSection.prepend(commentAlert);
|
||||||
|
commentSection.prepend(commentForm);
|
||||||
|
//remove the comment and all content from DOM.
|
||||||
|
//detach would be a soft delete but as there is no reason to reuse the deleted comment, means should not be provided.
|
||||||
|
comment.remove();
|
||||||
|
});
|
||||||
|
posting.fail(function (status, error, title) {
|
||||||
|
//alert('error');
|
||||||
|
//console.log("Response Data (fail)", JSON.parse(JSON.stringify(status)));
|
||||||
|
commentForm.after(commentAlert);
|
||||||
|
commentAlert.show();
|
||||||
|
commentAlert.empty().append("<p>Error: </p>");
|
||||||
|
commentAlert.append("<p>" + JSON.stringify(status) + "</p>");
|
||||||
|
commentAlert.append("<p>" + JSON.stringify(error) + "</p>");
|
||||||
|
commentAlert.append("<p>" + JSON.stringify(title) + "</p>");
|
||||||
|
});
|
||||||
|
posting.always(function () {
|
||||||
|
//alert("finished, be it successful or not");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Attach a submit handler to the form
|
// Attach a submit handler to the form
|
||||||
|
@ -65,14 +123,12 @@ jQuery(document).ready(function () {
|
||||||
commentAlert.css('color', 'green').empty().append(document.createTextNode( response.message )).fadeIn(30);
|
commentAlert.css('color', 'green').empty().append(document.createTextNode( response.message )).fadeIn(30);
|
||||||
var newMedia = "<div class='comment comment-level-{{comment.level|e}} comment-flag-new' data-level='{{comment.level}}' data-id='{{comment.id}}' >" +
|
var newMedia = "<div class='comment comment-level-{{comment.level|e}} comment-flag-new' data-level='{{comment.level}}' data-id='{{comment.id}}' >" +
|
||||||
"<div class='comment-left'>" +
|
"<div class='comment-left'>" +
|
||||||
"<a href='#'>" +
|
|
||||||
"<img class='comment-object' src='https://www.gravatar.com/avatar/{{comment.email|trim|lower|md5}}?d=identicon' alt='user icon'>" +
|
"<img class='comment-object' src='https://www.gravatar.com/avatar/{{comment.email|trim|lower|md5}}?d=identicon' alt='user icon'>" +
|
||||||
"</a>" +
|
|
||||||
"</div>" +
|
"</div>" +
|
||||||
"<div class='comment-body'>" +
|
"<div class='comment-body'>" +
|
||||||
"<div class='comment-heading'>" +
|
"<div class='comment-heading'>" +
|
||||||
"<div class='comment-title'><h4>{{comment.title}}</h4></div>" +
|
"<div class='comment-title'><h4>{{comment.title}}</h4></div>" +
|
||||||
"<div class='comment-reply'><a class='comment-add-reply' href='#'><i class='fa fa-reply' title='{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}'></i> {{'PLUGIN_COMMENTS.ADD_REPLY'|t}}</a></div>" +
|
"<div class='comment-reply'><a class='comment-add-reply' href='#'><i class='fa fa-reply' title='{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}'></i> {{'PLUGIN_COMMENTS.REPLY'|t}}</a></div>" +
|
||||||
"<div class='comment-meta'>{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}} {{comment.date|e}} {{'PLUGIN_COMMENTS.BY'|t}} {{comment.author}}</div>" +
|
"<div class='comment-meta'>{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}} {{comment.date|e}} {{'PLUGIN_COMMENTS.BY'|t}} {{comment.author}}</div>" +
|
||||||
"</div>" +
|
"</div>" +
|
||||||
"<div class='comment-text' >" +
|
"<div class='comment-text' >" +
|
||||||
|
@ -92,6 +148,7 @@ jQuery(document).ready(function () {
|
||||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.date|e}}"), 'g'), response.data.date);
|
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.date|e}}"), 'g'), response.data.date);
|
||||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{nested}}"), 'g'), '');
|
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{nested}}"), 'g'), '');
|
||||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}"), 'g'), response.data.ADD_REPLY);
|
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}"), 'g'), response.data.ADD_REPLY);
|
||||||
|
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.REPLY'|t}}"), 'g'), response.data.REPLY);
|
||||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}}"), 'g'), response.data.WRITTEN_ON);
|
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}}"), 'g'), response.data.WRITTEN_ON);
|
||||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.BY'|t}}"), 'g'), response.data.BY);
|
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.BY'|t}}"), 'g'), response.data.BY);
|
||||||
if ($( "div[data-id='" + response.data.parent_id + "']" ).length > 0) {
|
if ($( "div[data-id='" + response.data.parent_id + "']" ).length > 0) {
|
||||||
|
@ -101,7 +158,7 @@ jQuery(document).ready(function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
commentForm.hide(2000);
|
commentForm.slideUp();
|
||||||
commentAlert.fadeOut(5000);
|
commentAlert.fadeOut(5000);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
});
|
});
|
||||||
|
@ -109,10 +166,11 @@ jQuery(document).ready(function () {
|
||||||
//alert('error');
|
//alert('error');
|
||||||
//console.log("Response Data (fail)", JSON.parse(JSON.stringify(status)));
|
//console.log("Response Data (fail)", JSON.parse(JSON.stringify(status)));
|
||||||
commentForm.after(commentAlert);
|
commentForm.after(commentAlert);
|
||||||
commentAlert.empty().append("<p>TEST</p>");
|
commentAlert.show();
|
||||||
commentAlert.append("<p>" + status + "</p>");
|
commentAlert.empty().append("<p>Error: </p>");
|
||||||
commentAlert.append("<p>" + error + "</p>");
|
commentAlert.append("<p>" + JSON.stringify(status) + "</p>");
|
||||||
commentAlert.append("<p>" + title + "</p>");
|
commentAlert.append("<p>" + JSON.stringify(error) + "</p>");
|
||||||
|
commentAlert.append("<p>" + JSON.stringify(title) + "</p>");
|
||||||
});
|
});
|
||||||
posting.always(function () {
|
posting.always(function () {
|
||||||
//alert("finished, be it successful or not");
|
//alert("finished, be it successful or not");
|
||||||
|
|
183
comments.php
183
comments.php
|
@ -180,22 +180,71 @@ class CommentsPlugin extends Plugin
|
||||||
// $this->only_full_stars = $this->config->get('plugins.star-ratings.only_full_stars');
|
// $this->only_full_stars = $this->config->get('plugins.star-ratings.only_full_stars');
|
||||||
$callback = $this->config->get('plugins.comments.ajax_callback');
|
$callback = $this->config->get('plugins.comments.ajax_callback');
|
||||||
// Process comment if required
|
// Process comment if required
|
||||||
if ($is_ajax || $callback === $this->grav['uri']->path()) {
|
if ($is_ajax) {// || $callback === $this->grav['uri']->path()
|
||||||
|
$action = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_STRING);
|
||||||
|
switch ($action) {
|
||||||
|
case 'addComment':
|
||||||
|
case '':
|
||||||
|
case null:
|
||||||
// try to add the comment
|
// try to add the comment
|
||||||
$result = $this->addComment(true);
|
$result = $this->addComment(true);
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
'status' => $result[0],
|
'status' => $result[0],
|
||||||
'message' => $result[1],
|
'message' => $result[1],
|
||||||
'data' => $result[2],
|
'data' => $result[2],
|
||||||
// 'data' => [
|
|
||||||
// 'score' => $result[2][0],
|
|
||||||
// 'count' => $result[2][1]
|
|
||||||
// ]
|
|
||||||
]);
|
]);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
// try to delete the comment
|
||||||
|
$result = $this->deleteComment(true);
|
||||||
|
echo json_encode([
|
||||||
|
'status' => $result[0],
|
||||||
|
'message' => $result[1],
|
||||||
|
'data' => $result[2],
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//request unknown, present error page
|
||||||
|
//Set a 400 (bad request) response code.
|
||||||
|
http_response_code(400);
|
||||||
|
echo 'request malformed - action unknown';
|
||||||
|
break;
|
||||||
|
}
|
||||||
exit(); //prevents the page frontend from beeing displayed.
|
exit(); //prevents the page frontend from beeing displayed.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteComment()
|
||||||
|
{
|
||||||
|
$language = $this->grav['language'];
|
||||||
|
if (!$this->grav['user']->authorize('admin.super')) {
|
||||||
|
http_response_code(403);
|
||||||
|
return [false, 'access forbidden', [0, 0]];
|
||||||
|
}
|
||||||
|
$id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
|
||||||
|
$nonce = filter_input(INPUT_POST, 'nonce', FILTER_SANITIZE_STRING);
|
||||||
|
// ensure both values are sent
|
||||||
|
if (is_null($id) || is_null($nonce)) {
|
||||||
|
// Set a 400 (bad request) response code and exit.
|
||||||
|
http_response_code(400);
|
||||||
|
return [false, 'request malformed - missing parameter(s)', [0, 0]];
|
||||||
|
}
|
||||||
|
if (!Utils::verifyNonce($nonce, 'comments')) {
|
||||||
|
http_response_code(403);
|
||||||
|
return [false, 'Invalid security nonce', [0, $nonce]];
|
||||||
|
}
|
||||||
|
$lang = $this->grav['language']->getLanguage();
|
||||||
|
$path = $this->grav['page']->path();
|
||||||
|
$route = $this->grav['page']->route();
|
||||||
|
$data = $this->removeComment($route, $path, $id, $lang);
|
||||||
|
if ($data[0]) {
|
||||||
|
return [true, $language->translate('PLUGIN_COMMENTS.DELETE_SUCCESS'), $data[1]];
|
||||||
|
} else {
|
||||||
|
http_response_code(403); //forbidden
|
||||||
|
return [false, $language->translate('PLUGIN_COMMENTS.DELETE_FAIL'), $data[1]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function addComment($is_ajax = false)
|
public function addComment($is_ajax = false)
|
||||||
{
|
{
|
||||||
if($is_ajax) {
|
if($is_ajax) {
|
||||||
|
@ -254,6 +303,7 @@ class CommentsPlugin extends Plugin
|
||||||
'level' => 0,
|
'level' => 0,
|
||||||
'hash' => md5(strtolower(trim($comment['email']))),
|
'hash' => md5(strtolower(trim($comment['email']))),
|
||||||
'ADD_REPLY' => $language->translate('PLUGIN_COMMENTS.ADD_REPLY'),
|
'ADD_REPLY' => $language->translate('PLUGIN_COMMENTS.ADD_REPLY'),
|
||||||
|
'REPLY' => $language->translate('PLUGIN_COMMENTS.REPLY'),
|
||||||
'WRITTEN_ON' => $language->translate('PLUGIN_COMMENTS.WRITTEN_ON'),
|
'WRITTEN_ON' => $language->translate('PLUGIN_COMMENTS.WRITTEN_ON'),
|
||||||
'BY' => $language->translate('PLUGIN_COMMENTS.BY'),
|
'BY' => $language->translate('PLUGIN_COMMENTS.BY'),
|
||||||
);
|
);
|
||||||
|
@ -265,6 +315,123 @@ class CommentsPlugin extends Plugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle form processing instructions.
|
||||||
|
*
|
||||||
|
* @param Event $event
|
||||||
|
*/
|
||||||
|
public function removeComment($route, $path, $id, $lang)
|
||||||
|
{
|
||||||
|
$entry_removed = false;
|
||||||
|
$message = '';
|
||||||
|
$date = time();//date('D, d M Y H:i:s', time());
|
||||||
|
|
||||||
|
/******************************/
|
||||||
|
/** store comments with page **/
|
||||||
|
/******************************/
|
||||||
|
$localfilename = $path . '/comments.yaml';
|
||||||
|
$localfile = CompiledYamlFile::instance($localfilename);
|
||||||
|
if (file_exists($localfilename)) {
|
||||||
|
$data = $localfile->content();
|
||||||
|
if(isset($data['comments']) && is_array($data['comments'])) {
|
||||||
|
foreach($data['comments'] as $key => $comment) {
|
||||||
|
if(!empty($comment['parent_id']) && $comment['parent_id'] == $id) {
|
||||||
|
//hit an existing comment that is a reply to comment selected for deletion.
|
||||||
|
//deletion of "parent" comment not allowed to preserve integrity of nested comments.
|
||||||
|
//TODO: Alternatively allow it to mark parent comments as deleted
|
||||||
|
// and make sure (via Comment class / setCommentLevels) that children are
|
||||||
|
// filtered out from fetch regardless of their own deletion state.
|
||||||
|
$data['comments'][$key] = array_merge(array('deleted' => ''), $comment);
|
||||||
|
//set date after merge
|
||||||
|
//reason: could be possible that "deleted" already exists (e.g. false or '') in $comment which would overwrite the first (newly added) occurence
|
||||||
|
$data['comments'][$key]['deleted'] = $date;
|
||||||
|
//no need to look further as ids are supposed to be unique.
|
||||||
|
$localfile->save($data);
|
||||||
|
$entry_removed = false;
|
||||||
|
$reply_id = empty($comment['id']) ? '' : $comment['id'];
|
||||||
|
$message = "Found active reply ($reply_id) for selected comment ($id).";
|
||||||
|
return [$entry_removed, $message];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach($data['comments'] as $key => $comment) {
|
||||||
|
if(!empty($comment['id']) && $comment['id'] == $id) {
|
||||||
|
//add deleted as first item in array (better readability in file)
|
||||||
|
$data['comments'][$key] = array_merge(array('deleted' => ''), $comment);
|
||||||
|
//set date after merge
|
||||||
|
//reason: could be possible that "deleted" already exists (e.g. false or '') in $comment which would overwrite the first (newly added) occurence
|
||||||
|
$data['comments'][$key]['deleted'] = $date;
|
||||||
|
//no need to look further as ids are supposed to be unique.
|
||||||
|
$localfile->save($data);
|
||||||
|
$entry_removed = true;
|
||||||
|
$message = "Deleted comment ($id) via path ($path)";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//nothing
|
||||||
|
}
|
||||||
|
/**********************************/
|
||||||
|
/** store comments in index file **/
|
||||||
|
/**********************************/
|
||||||
|
$indexfilename = DATA_DIR . 'comments/index.yaml';
|
||||||
|
$indexfile = CompiledYamlFile::instance($indexfilename);
|
||||||
|
if (file_exists($indexfilename)) {
|
||||||
|
$dataIndex = $indexfile->content();
|
||||||
|
if(isset($dataIndex['comments']) && is_array($dataIndex['comments'])) {
|
||||||
|
foreach($dataIndex['comments'] as $key => $comment) {
|
||||||
|
if(!empty($comment['page']) && !empty($comment['id']) && $comment['page'] == $route && $comment['id'] == $id) {
|
||||||
|
//add deleted as first item in array (better readability in file)
|
||||||
|
$dataIndex['comments'][$key] = array_merge(array('deleted' => ''), $comment);
|
||||||
|
//set date after merge
|
||||||
|
//reason: could be possible that "deleted" already exists (e.g. false or '') in $comment which would overwrite the first (newly added) occurence
|
||||||
|
$dataIndex['comments'][$key]['deleted'] = $date;
|
||||||
|
//no need to look further as ids are supposed to be unique.
|
||||||
|
$indexfile->save($dataIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//nothing
|
||||||
|
}
|
||||||
|
/**************************************/
|
||||||
|
/** store comments in old data files **/
|
||||||
|
/** TODO: remove as soon as admin **/
|
||||||
|
/** panel uses new index file **/
|
||||||
|
/**************************************/
|
||||||
|
$filename = DATA_DIR . 'comments';
|
||||||
|
$filename .= ($lang ? '/' . $lang : '');
|
||||||
|
$filename .= $path . '.yaml';
|
||||||
|
$file = CompiledYamlFile::instance($filename);
|
||||||
|
|
||||||
|
if (file_exists($filename)) {
|
||||||
|
$dataLegacy = $file->content();
|
||||||
|
if(isset($dataLegacy['comments']) && is_array($dataLegacy['comments'])) {
|
||||||
|
foreach($dataLegacy['comments'] as $key => $comment) {
|
||||||
|
if(!empty($comment['id']) && $comment['id'] == $id) {
|
||||||
|
//add deleted as first item in array (better readability in file)
|
||||||
|
$dataLegacy['comments'][$key] = array_merge(array('deleted' => ''), $comment);
|
||||||
|
//set date after merge
|
||||||
|
//reason: could be possible that "deleted" already exists (e.g. false or '') in $comment which would overwrite the first (newly added) occurence
|
||||||
|
$dataLegacy['comments'][$key]['deleted'] = $date;
|
||||||
|
//no need to look further as ids are supposed to be unique.
|
||||||
|
$file->save($dataLegacy);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
//clear cache
|
||||||
|
$this->grav['cache']->delete($this->comments_cache_id);
|
||||||
|
|
||||||
|
return [$entry_removed, $message];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle form processing instructions.
|
* Handle form processing instructions.
|
||||||
*
|
*
|
||||||
|
@ -532,9 +699,15 @@ class CommentsPlugin extends Plugin
|
||||||
}
|
}
|
||||||
$levelsflat = array();
|
$levelsflat = array();
|
||||||
foreach($comments as $key => $comment) {
|
foreach($comments as $key => $comment) {
|
||||||
|
if(!empty($comment['deleted'])) {
|
||||||
|
//if field "deleted" exists and is filled with a true value then ignore the comment completely.
|
||||||
|
//TODO: This only works on this position as long as it is forbidden to delete comments that have active replies (children).
|
||||||
|
// Otherwise implement that children get the deleted flag recursively or are ignored via Comment class.
|
||||||
|
} else {
|
||||||
$levelsflat[$comment['id']]['parent'] = $comment['parent'];
|
$levelsflat[$comment['id']]['parent'] = $comment['parent'];
|
||||||
$levelsflat[$comment['id']]['class'] = new Comment($comment['id'], $comments[$key]);
|
$levelsflat[$comment['id']]['class'] = new Comment($comment['id'], $comments[$key]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//get starting points (entries without valid parent = root element)
|
//get starting points (entries without valid parent = root element)
|
||||||
$leveltree = array();
|
$leveltree = array();
|
||||||
foreach($levelsflat as $id => $parent) {
|
foreach($levelsflat as $id => $parent) {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
de:
|
de:
|
||||||
PLUGIN_COMMENTS:
|
PLUGIN_COMMENTS:
|
||||||
ADD_NEW: Kommentar hinzufügen
|
ADD_NEW: Kommentar hinzufügen
|
||||||
ADD_REPLY: Antworten
|
ADD_REPLY: Auf Kommentar antworten
|
||||||
ADD_COMMENT: Kommentar hinzufügen
|
ADD_COMMENT: Kommentar hinzufügen
|
||||||
DELETE_COMMENT: Kommentar löschen
|
DELETE_COMMENT: Kommentar löschen
|
||||||
SUCCESS: Der Kommentar wurde erfolgreich gespeichert.
|
REPLY: Antworten
|
||||||
|
DELETE: Löschen
|
||||||
|
SUCCESS: "Der Kommentar wurde erfolgreich gespeichert."
|
||||||
COMMENTS: Kommentare
|
COMMENTS: Kommentare
|
||||||
EMAIL_NOT_CONFIGURED: Email nicht konfiguriert
|
EMAIL_NOT_CONFIGURED: Email nicht konfiguriert
|
||||||
NEW_COMMENT_EMAIL_SUBJECT: 'Neuer Kommentar für %1$s'
|
NEW_COMMENT_EMAIL_SUBJECT: 'Neuer Kommentar für %1$s'
|
||||||
|
@ -27,10 +29,12 @@ de:
|
||||||
en:
|
en:
|
||||||
PLUGIN_COMMENTS:
|
PLUGIN_COMMENTS:
|
||||||
ADD_NEW: Add a comment
|
ADD_NEW: Add a comment
|
||||||
ADD_REPLY: Reply
|
ADD_REPLY: Reply to comment
|
||||||
ADD_COMMENT: Add a comment
|
ADD_COMMENT: Add a comment
|
||||||
DELETE_COMMENT: Delete comment
|
DELETE_COMMENT: Delete comment
|
||||||
SUCCESS: Comment has been saved successfully.
|
REPLY: Reply
|
||||||
|
DELETE: Delete
|
||||||
|
SUCCESS: "Comment has been saved successfully."
|
||||||
COMMENTS: Comments
|
COMMENTS: Comments
|
||||||
EMAIL_NOT_CONFIGURED: Email not configured
|
EMAIL_NOT_CONFIGURED: Email not configured
|
||||||
NEW_COMMENT_EMAIL_SUBJECT: 'New comment on %1$s'
|
NEW_COMMENT_EMAIL_SUBJECT: 'New comment on %1$s'
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<h3>{{'PLUGIN_COMMENTS.ADD_COMMENT'|t}}</h3>
|
<form id="comments-form" name="{{ grav.config.plugins.comments.form.name }}" class="comments-form"
|
||||||
<form name="{{ grav.config.plugins.comments.form.name }}" class="comments-form"
|
|
||||||
action="{{ grav.config.plugins.comments.form.action ? base_url ~ grav.config.plugins.comments.form.action : page.url }}"
|
action="{{ grav.config.plugins.comments.form.action ? base_url ~ grav.config.plugins.comments.form.action : page.url }}"
|
||||||
method="{{ grav.config.plugins.comments.form.method|upper|default('POST') }}">
|
method="{{ grav.config.plugins.comments.form.method|upper|default('POST') }}">
|
||||||
|
|
||||||
|
@ -35,4 +34,4 @@
|
||||||
{{ nonce_field('comments', 'form-nonce')|raw }}
|
{{ nonce_field('comments', 'form-nonce')|raw }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="alert">{{ form.message }}</div>
|
<div id="comments-alert" class="alert">{{ form.message }}</div>
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
{% if grav.twig.enable_comments_plugin %}
|
{% if grav.twig.enable_comments_plugin %}
|
||||||
{% set scope = scope ?: 'data.' %}
|
{% set scope = scope ?: 'data.' %}
|
||||||
|
<section id="comments-section">
|
||||||
|
<h2>{{'PLUGIN_COMMENTS.COMMENTS'|t}}</h3>
|
||||||
|
<!-- <h2>{{ 'COMMENTS'|t }}</h2> -->
|
||||||
|
|
||||||
{% include 'partials/comments.form.html.twig' %}
|
{% include 'partials/comments.form.html.twig' %}
|
||||||
|
|
||||||
{% if grav.twig.comments|length %}
|
{% if grav.twig.comments|length %}
|
||||||
|
|
||||||
<h3>{{'PLUGIN_COMMENTS.COMMENTS'|t}}</h3>
|
|
||||||
<a class="comment-add-new" href="#"><i class="fa fa-plus" title="{{'PLUGIN_COMMENTS.ADD_NEW'|t}}"></i> {{'PLUGIN_COMMENTS.ADD_NEW'|t}}</a>
|
<a class="comment-add-new" href="#"><i class="fa fa-plus" title="{{'PLUGIN_COMMENTS.ADD_NEW'|t}}"></i> {{'PLUGIN_COMMENTS.ADD_NEW'|t}}</a>
|
||||||
<div class="row comments">
|
<div class="row comments">
|
||||||
{% for comment in grav.twig.comments %}
|
{% for comment in grav.twig.comments %}
|
||||||
<div class="comment comment-level-{{comment.level|e}}" data-level="{{comment.level}}" data-id="{{comment.id}}" >
|
<div class="comment comment-level-{{comment.level|e}}" data-level="{{comment.level}}" data-id="{{comment.id}}" >
|
||||||
<div class="comment-left">
|
<div class="comment-left">
|
||||||
<a href="#">
|
|
||||||
<img class="comment-object" src="https://www.gravatar.com/avatar/{{comment.email|trim|lower|md5}}?d=identicon" alt="user icon">
|
<img class="comment-object" src="https://www.gravatar.com/avatar/{{comment.email|trim|lower|md5}}?d=identicon" alt="user icon">
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="comment-body">
|
<div class="comment-body">
|
||||||
<div class="comment-heading">
|
<div class="comment-heading">
|
||||||
<div class="comment-title"><h4>{{comment.title}}</h4></div>
|
<div class="comment-title"><h4>{{comment.title}}</h4></div>
|
||||||
<div class="comment-reply">
|
<div class="comment-reply">
|
||||||
<a class="comment-add-reply" href="#"><i class="fa fa-reply" title="{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}"></i> {{'PLUGIN_COMMENTS.ADD_REPLY'|t}}</a>
|
<a class="comment-add-reply" href="#"><i class="fa fa-reply" title="{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}"></i> {{'PLUGIN_COMMENTS.REPLY'|t}}</a>
|
||||||
{% if grav.user.access.admin.super %}
|
{% if grav.user.access.admin.super %}
|
||||||
<a class="comment-delete" href="#"><i class="fa fa-trash" title="{{'PLUGIN_COMMENTS.DELETE'|t}}"></i> {{'PLUGIN_COMMENTS.DELETE'|t}}</a>
|
<a class="comment-delete" href="#"><i class="fa fa-trash" title="{{'PLUGIN_COMMENTS.DELETE_COMMENT'|t}}"></i> {{'PLUGIN_COMMENTS.DELETE'|t}}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="comment-meta">{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}} {{comment.date|e}} {{'PLUGIN_COMMENTS.BY'|t}} {{comment.author}}</div>
|
<div class="comment-meta">{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}} {{comment.date|e}} {{'PLUGIN_COMMENTS.BY'|t}} {{comment.author}}</div>
|
||||||
|
@ -36,6 +36,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue