From 69dbba2a3d82193d64c2f817b7768ea0cb077575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Gonz=C3=A1lez?= Date: Sat, 14 Jan 2023 21:22:26 +0000 Subject: [PATCH] Add a new form to Update a comment authored by the user --- client/src/legacy/CommentsInterface.js | 123 +++++++++++++++++- lang/en.yml | 1 + lang/es.yml | 2 + src/Controllers/CommentingController.php | 34 +++++ src/Forms/CommentForm.php | 24 +++- src/Model/Comment.php | 30 +++++ .../CommentsInterface_singlecomment.ss | 12 +- 7 files changed, 219 insertions(+), 7 deletions(-) diff --git a/client/src/legacy/CommentsInterface.js b/client/src/legacy/CommentsInterface.js index d3a8fc0..1df565d 100755 --- a/client/src/legacy/CommentsInterface.js +++ b/client/src/legacy/CommentsInterface.js @@ -123,8 +123,121 @@ } }); - e.preventDefault(); - return false; - }); - }); -}(jQuery)); + /** + * Hide comment reply forms by default (unless visiting via permalink) + */ + $(".comment") + .children('.info') + .not(window.document.location.hash) + .nextAll(".comment-replies-container") + .children(".comment-reply-form-holder") + .hide(); + + /** + * Hide comment update forms by default + */ + $(".comment") + .children(".comment-update-form-holder") + .hide(); + + /** + * Toggle on/off reply form + */ + $('.comments-holder').on('click', '.comment-reply-link', function(e) { + var allForms = $('.comment-reply-form-holder'); + var formID = '#' + $(this).attr('aria-controls'); + var form = $(formID).closest('.comment-reply-form-holder'); + + $(this).attr('aria-expanded', function (i, attr) { + return attr == 'true' ? 'false' : 'true' + }); + + // Prevent focus + e.preventDefault(); + + if(form.is(':visible')) { + allForms.slideUp(); + } else { + allForms.not(form).slideUp(); + form.slideDown(); + } + }); + + /** + * Toggle on/off update form + */ + $('.comments-holder').on('click', '.comment-update-link', function(e) { + var allForms = $('.comment-update-form-holder'); + var formID = '#' + $(this).attr('aria-controls'); + var form = $(formID).closest('.comment-update-form-holder'); + + $(this).attr('aria-expanded', function (i, attr) { + return attr == 'true' ? 'false' : 'true' + }); + + // Prevent focus + e.preventDefault(); + + if(form.is(':visible')) { + allForms.slideUp(); + } else { + allForms.not(form).slideUp(); + form.slideDown(); + } + }); + + /** + * Clicking one of the metalinks performs the operation via ajax + * this inclues the spam and approve links + */ + $('.comments-holder .comments-list').on('click', 'div.comment-moderation-options a', function(e) { + e.stopPropagation(); + + var link = $(this); + if (link.hasClass('delete')) { + var confirmationMsg = ss.i18n._t('CommentsInterface_singlecomment_ss.DELETE_CONFIRMATION'); + var confirmation = window.confirm(confirmationMsg); + if (!confirmation) { + e.preventDefault(); + return false; + } + } + var comment = link.parents('.comment:first'); + + $.ajax({ + url: $(this).attr('href'), + cache: false, + success: function(html){ + if(link.hasClass('ham')) { + // comment has been marked as not spam + comment.html(html); + comment.removeClass('spam'); + } + else if(link.hasClass('approve')) { + // comment has been approved + comment.html(html); + comment.removeClass('unmoderated'); + } + else if(link.hasClass('delete')) { + comment.fadeOut(1000, function() { + comment.remove(); + + if($('.comments-holder .comments-list').children().length === 0) { + $('.no-comments-yet').show(); + } + }); + } + else if(link.hasClass('spam')) { + comment.html(html).addClass('spam'); + } + }, + failure: function(html) { + var errorMsg = ss.i18n._t('CommentsInterface_singlecomment_ss.AJAX_ERROR'); + alert(errorMsg); + } + }); + + e.preventDefault(); + }); + }); +})(jQuery); diff --git a/lang/en.yml b/lang/en.yml index 47235e5..113af2a 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -22,6 +22,7 @@ en: ISNTSPAM: 'Not spam' ISSPAM: 'Spam it' REMCOM: 'Reject it' + UPDCOM: 'Update it' REPLYTO: 'Reply to' CommentsInterface_ss: AWAITINGMODERATION: 'Your comment has been submitted and is now awaiting moderation.' diff --git a/lang/es.yml b/lang/es.yml index 4f88b04..e36d505 100644 --- a/lang/es.yml +++ b/lang/es.yml @@ -11,6 +11,8 @@ es: YOURNAME_MESSAGE_REQUIRED: 'Por favor, ingrese su nombre' CommentsInterface_pendingcomment_ss: AWAITINGMODERATION: 'Se envió su comentario y ahora está esperando la moderación.' + CommentsInterface_singlecomment_ss: + UPDCOM: 'Actualizarlo' CommentsInterface_ss: AWAITINGMODERATION: 'Se envió su comentario y ahora está esperando la moderación.' COMMENTLOGINERROR: 'Ud no puede comentar hasta que haya iniciado sesión' diff --git a/src/Controllers/CommentingController.php b/src/Controllers/CommentingController.php index 3246c3b..7041ab4 100644 --- a/src/Controllers/CommentingController.php +++ b/src/Controllers/CommentingController.php @@ -20,6 +20,7 @@ use SilverStripe\ORM\FieldType\DBHTMLText; use SilverStripe\ORM\PaginatedList; use SilverStripe\Security\Security; use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware; +use SilverStripe\Forms\HiddenField; /** * @package comments @@ -37,6 +38,7 @@ class CommentingController extends Controller 'rss', 'CommentsForm', 'reply', + 'updateComment', 'doPostComment', 'doPreviewComment', ]; @@ -46,6 +48,7 @@ class CommentingController extends Controller */ private static $url_handlers = [ 'reply/$ParentCommentID//$ID/$OtherID' => 'reply', + 'updateComment/$ParentCommentID//$ID/$OtherID' => 'updateComment', ]; /** @@ -456,6 +459,24 @@ class CommentingController extends Controller return $form; } + public function UpdateForm($comment) + { + $form = $this->CommentsForm(); + $form->setName('UpdateForm_' . $comment->ID); + $form->setHTMLID(null); + $form->addExtraClass('update-form'); + + $form->Fields()->push(HiddenField::create('CommentId', '', $comment->ID)); + $form->loadDataFrom($comment); + + // Customise action + $form->setFormAction($this->Link('updateComment', $comment->ID)); + + $this->extend('updateUpdateForm', $form); + + return $form; + } + /** * Request handler for reply form. @@ -478,6 +499,19 @@ class CommentingController extends Controller return $this->httpError(404); } + public function updateComment(HTTPRequest $request) + { + if ($commentID = $request->param('ParentCommentID')) { + /** @var Comment $comment */ + $comment = DataObject::get_by_id(Comment::class, $commentID, true); + if ($comment) { + return $this->UpdateForm($comment); + } + } + + return $this->httpError(404); + } + /** * Post a comment form * diff --git a/src/Forms/CommentForm.php b/src/Forms/CommentForm.php index 50a2e9e..4ac3627 100644 --- a/src/Forms/CommentForm.php +++ b/src/Forms/CommentForm.php @@ -236,7 +236,29 @@ class CommentForm extends Form break; } - $comment = Comment::create(); + // Updating comment + $existingCommentId = $data["CommentId"] ?? null; + + if ($existingCommentId) { + $comment = Comment::get()->byID($existingCommentId); + + if (!$comment) { + return $this->getRequestHandler()->httpError(404); + } + + if (!$comment->canUpdate()) { + return Security::permissionFailure( + $this->controller, + _t( + 'SilverStripe\\Comments\\Controllers\\CommentingController.PERMISSIONFAILURE', + "You're not able to update this comment. Please ensure you are logged in and have an " + . 'appropriate permission level.' + ) + ); + } + } else { + $comment = Comment::create(); + } $form->saveInto($comment); $comment->ParentID = $data['ParentID']; diff --git a/src/Model/Comment.php b/src/Model/Comment.php index a9d1391..a2a1469 100755 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -381,6 +381,15 @@ class Comment extends DataObject return false; } + public function canUpdate($member = null) + { + $member = $this->getMember($member); + $memberID = $member->ID ?? null; + $authorID = $this->Author()->ID; + + return $memberID === $authorID; + } + /** * Checks if the comment can be deleted. * @@ -880,6 +889,27 @@ class Comment extends DataObject return $controller->ReplyForm($this); } + public function UpdateForm() + { + if (!$this->canUpdate()) { + return null; + } + // Check parent is available + $parent = $this->Parent(); + + if (!$parent || !$parent->exists()) { + return null; + } + + // Build update controller + $controller = CommentingController::create(); + $controller->setOwnerRecord($parent); + $controller->setParentClass($parent->ClassName); + $controller->setOwnerController(Controller::curr()); + + return $controller->UpdateForm($this); + } + /** * @return string */ diff --git a/templates/Includes/CommentsInterface_singlecomment.ss b/templates/Includes/CommentsInterface_singlecomment.ss index 73f644f..243531d 100755 --- a/templates/Includes/CommentsInterface_singlecomment.ss +++ b/templates/Includes/CommentsInterface_singlecomment.ss @@ -14,9 +14,14 @@

$EscapedComment

+<% if $UpdateForm %> +
+ $UpdateForm +
+<% end_if %> <% if not $isPreview %> - <% if $ApproveLink || $SpamLink || $HamLink || $DeleteLink || $RepliesEnabled %> + <% if $ApproveLink || $SpamLink || $HamLink || $DeleteLink || $UpdateForm || $RepliesEnabled %>