diff --git a/app/Activity/CommentRepo.php b/app/Activity/CommentRepo.php index 3336e17e9..c488350ca 100644 --- a/app/Activity/CommentRepo.php +++ b/app/Activity/CommentRepo.php @@ -20,7 +20,7 @@ class CommentRepo /** * 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(); @@ -30,6 +30,7 @@ class CommentRepo $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); diff --git a/app/Activity/Controllers/CommentController.php b/app/Activity/Controllers/CommentController.php index 52ccc8238..262080067 100644 --- a/app/Activity/Controllers/CommentController.php +++ b/app/Activity/Controllers/CommentController.php @@ -26,6 +26,7 @@ class CommentController extends Controller $input = $this->validate($request, [ 'html' => ['required', 'string'], 'parent_id' => ['nullable', 'integer'], + 'content_ref' => ['string'], ]); $page = $this->pageQueries->findVisibleById($pageId); @@ -40,7 +41,7 @@ class CommentController extends Controller // 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, diff --git a/app/Activity/Models/Comment.php b/app/Activity/Models/Comment.php index d0385d396..91cea4fe0 100644 --- a/app/Activity/Models/Comment.php +++ b/app/Activity/Models/Comment.php @@ -19,6 +19,8 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; * @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 { diff --git a/database/factories/Activity/Models/CommentFactory.php b/database/factories/Activity/Models/CommentFactory.php index efbd183b3..844bc3993 100644 --- a/database/factories/Activity/Models/CommentFactory.php +++ b/database/factories/Activity/Models/CommentFactory.php @@ -27,6 +27,8 @@ class CommentFactory extends Factory '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 index 000000000..794201dec --- /dev/null +++ b/database/migrations/2025_04_18_215145_add_content_refs_and_archived_to_comments.php @@ -0,0 +1,30 @@ +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'); + }); + } +}; diff --git a/resources/js/components/page-comments.ts b/resources/js/components/page-comments.ts index a19d2c7d4..45f8d6a9f 100644 --- a/resources/js/components/page-comments.ts +++ b/resources/js/components/page-comments.ts @@ -95,7 +95,7 @@ export class PageComments extends Component { 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 => { diff --git a/tests/Entity/CommentTest.php b/tests/Entity/CommentTest.php index 9e019e3d1..973b2b81d 100644 --- a/tests/Entity/CommentTest.php +++ b/tests/Entity/CommentTest.php @@ -33,6 +33,32 @@ class CommentTest extends TestCase $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' => '
My comment
', + '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() {