]> BookStack Code Mirror - bookstack/commitdiff
Comments: Added back-end content reference handling
authorDan Brown <redacted>
Fri, 18 Apr 2025 20:13:49 +0000 (21:13 +0100)
committerDan Brown <redacted>
Fri, 18 Apr 2025 20:13:49 +0000 (21:13 +0100)
Also added archived property, to be added.

app/Activity/CommentRepo.php
app/Activity/Controllers/CommentController.php
app/Activity/Models/Comment.php
database/factories/Activity/Models/CommentFactory.php
database/migrations/2025_04_18_215145_add_content_refs_and_archived_to_comments.php [new file with mode: 0644]
resources/js/components/page-comments.ts
tests/Entity/CommentTest.php

index 3336e17e98831a21ca02dd255182c4c706e458d3..c488350ca24aadf13e6e006961d1953089b92793 100644 (file)
@@ -20,7 +20,7 @@ class CommentRepo
     /**
      * Create a new comment on an entity.
      */
     /**
      * Create a new comment on an entity.
      */
-    public function create(Entity $entity, string $html, ?int $parent_id): Comment
+    public function create(Entity $entity, string $html, ?int $parent_id, string $content_ref): Comment
     {
         $userId = user()->id;
         $comment = new Comment();
     {
         $userId = user()->id;
         $comment = new Comment();
@@ -30,6 +30,7 @@ class CommentRepo
         $comment->updated_by = $userId;
         $comment->local_id = $this->getNextLocalId($entity);
         $comment->parent_id = $parent_id;
         $comment->updated_by = $userId;
         $comment->local_id = $this->getNextLocalId($entity);
         $comment->parent_id = $parent_id;
+        $comment->content_ref = preg_match('/^bkmrk-(.*?):\d+:(\d*-\d*)?$/', $content_ref) === 1 ? $content_ref : '';
 
         $entity->comments()->save($comment);
         ActivityService::add(ActivityType::COMMENT_CREATE, $comment);
 
         $entity->comments()->save($comment);
         ActivityService::add(ActivityType::COMMENT_CREATE, $comment);
index 52ccc823864e9e6e3221580b080aa0019968eb40..2620800678406b5b0607a3cd551849cee1b74d8a 100644 (file)
@@ -26,6 +26,7 @@ class CommentController extends Controller
         $input = $this->validate($request, [
             'html'      => ['required', 'string'],
             'parent_id' => ['nullable', 'integer'],
         $input = $this->validate($request, [
             'html'      => ['required', 'string'],
             'parent_id' => ['nullable', 'integer'],
+            'content_ref' => ['string'],
         ]);
 
         $page = $this->pageQueries->findVisibleById($pageId);
         ]);
 
         $page = $this->pageQueries->findVisibleById($pageId);
@@ -40,7 +41,7 @@ class CommentController extends Controller
 
         // Create a new comment.
         $this->checkPermission('comment-create-all');
 
         // Create a new comment.
         $this->checkPermission('comment-create-all');
-        $comment = $this->commentRepo->create($page, $input['html'], $input['parent_id'] ?? null);
+        $comment = $this->commentRepo->create($page, $input['html'], $input['parent_id'] ?? null, $input['content_ref']);
 
         return view('comments.comment-branch', [
             'readOnly' => false,
 
         return view('comments.comment-branch', [
             'readOnly' => false,
index d0385d3962f63f3766f88a4855cf738194796cd6..91cea4fe0e3b62526ed5cfa982e869ef6a4ef551 100644 (file)
@@ -19,6 +19,8 @@ use Illuminate\Database\Eloquent\Relations\MorphTo;
  * @property int      $entity_id
  * @property int      $created_by
  * @property int      $updated_by
  * @property int      $entity_id
  * @property int      $created_by
  * @property int      $updated_by
+ * @property string   $content_ref
+ * @property bool     $archived
  */
 class Comment extends Model implements Loggable
 {
  */
 class Comment extends Model implements Loggable
 {
index efbd183b31d8cd75dd4a18281e3948f7353878b9..844bc39938188bbe3d2e54d5c7932266862f5e84 100644 (file)
@@ -27,6 +27,8 @@ class CommentFactory extends Factory
             'html'      => $html,
             'parent_id' => null,
             'local_id'  => 1,
             'html'      => $html,
             'parent_id' => null,
             'local_id'  => 1,
+            'content_ref' => '',
+            'archived' => false,
         ];
     }
 }
         ];
     }
 }
diff --git a/database/migrations/2025_04_18_215145_add_content_refs_and_archived_to_comments.php b/database/migrations/2025_04_18_215145_add_content_refs_and_archived_to_comments.php
new file mode 100644 (file)
index 0000000..794201d
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('comments', function (Blueprint $table) {
+            $table->string('content_ref');
+            $table->boolean('archived')->index();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('comments', function (Blueprint $table) {
+            $table->dropColumn('content_ref');
+            $table->dropColumn('archived');
+        });
+    }
+};
index a19d2c7d4b128d4deeae63cd36bffaa2e6c89c40..45f8d6a9f6d192494560386899ac1066e366002c 100644 (file)
@@ -95,7 +95,7 @@ export class PageComments extends Component {
         const reqData = {
             html: this.wysiwygEditor.getContent(),
             parent_id: this.parentId || null,
         const reqData = {
             html: this.wysiwygEditor.getContent(),
             parent_id: this.parentId || null,
-            content_reference: this.contentReference || '',
+            content_ref: this.contentReference || '',
         };
 
         window.$http.post(`/comment/${this.pageId}`, reqData).then(resp => {
         };
 
         window.$http.post(`/comment/${this.pageId}`, reqData).then(resp => {
index 9e019e3d1485d99f6924422cd30a25bc130461c7..973b2b81d8d301ecf840770e22d7ff8f22a8da86 100644 (file)
@@ -33,6 +33,32 @@ class CommentTest extends TestCase
 
         $this->assertActivityExists(ActivityType::COMMENT_CREATE);
     }
 
         $this->assertActivityExists(ActivityType::COMMENT_CREATE);
     }
+    public function test_add_comment_stores_content_reference_only_if_format_valid()
+    {
+        $validityByRefs = [
+            'bkmrk-my-title:4589284922:4-3' => true,
+            'bkmrk-my-title:4589284922:' => true,
+            'bkmrk-my-title:4589284922:abc' => false,
+            'my-title:4589284922:' => false,
+            'bkmrk-my-title-4589284922:' => false,
+        ];
+
+        $page = $this->entities->page();
+
+        foreach ($validityByRefs as $ref => $valid) {
+            $this->asAdmin()->postJson("/comment/$page->id", [
+                'html' => '<p>My comment</p>',
+                'parent_id' => null,
+                'content_ref' => $ref,
+            ]);
+
+            if ($valid) {
+                $this->assertDatabaseHas('comments', ['entity_id' => $page->id, 'content_ref' => $ref]);
+            } else {
+                $this->assertDatabaseMissing('comments', ['entity_id' => $page->id, 'content_ref' => $ref]);
+            }
+        }
+    }
 
     public function test_comment_edit()
     {
 
     public function test_comment_edit()
     {