+ ajax-delete comments via front end (if logged in with super admin priviledges)
This commit is contained in:
		
							parent
							
								
									b4ab9a5111
								
							
						
					
					
						commit
						905c04937c
					
				
					 5 changed files with 278 additions and 43 deletions
				
			
		| 
						 | 
					@ -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");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										201
									
								
								comments.php
									
										
									
									
									
								
							
							
						
						
									
										201
									
								
								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()
 | 
				
			||||||
            // try to add the comment
 | 
								$action = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_STRING);
 | 
				
			||||||
            $result = $this->addComment(true);
 | 
								switch ($action) {
 | 
				
			||||||
            echo json_encode([
 | 
									case 'addComment':
 | 
				
			||||||
				'status' => $result[0],
 | 
									case '':
 | 
				
			||||||
				'message' => $result[1],
 | 
									case null:
 | 
				
			||||||
				'data' => $result[2],
 | 
										// try to add the comment
 | 
				
			||||||
//				'data' => [
 | 
										$result = $this->addComment(true);
 | 
				
			||||||
//					'score' => $result[2][0],
 | 
										echo json_encode([
 | 
				
			||||||
//					'count' => $result[2][1]
 | 
											'status' => $result[0],
 | 
				
			||||||
//				]
 | 
											'message' => $result[1],
 | 
				
			||||||
			]);
 | 
											'data' => $result[2],
 | 
				
			||||||
 | 
										]);
 | 
				
			||||||
 | 
										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,8 +699,14 @@ class CommentsPlugin extends Plugin
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		$levelsflat = array();
 | 
							$levelsflat = array();
 | 
				
			||||||
		foreach($comments as $key => $comment) {
 | 
							foreach($comments as $key => $comment) {
 | 
				
			||||||
			$levelsflat[$comment['id']]['parent'] = $comment['parent'];
 | 
								if(!empty($comment['deleted'])) {
 | 
				
			||||||
			$levelsflat[$comment['id']]['class'] = new Comment($comment['id'], $comments[$key]);
 | 
									//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']]['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();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue