]> BookStack Code Mirror - bookstack/blob - app/Activity/CommentRepo.php
API: Started building comments API endpoints
[bookstack] / app / Activity / CommentRepo.php
1 <?php
2
3 namespace BookStack\Activity;
4
5 use BookStack\Activity\Models\Comment;
6 use BookStack\Entities\Models\Entity;
7 use BookStack\Exceptions\NotifyException;
8 use BookStack\Facades\Activity as ActivityService;
9 use BookStack\Util\HtmlDescriptionFilter;
10 use Illuminate\Database\Eloquent\Builder;
11
12 class CommentRepo
13 {
14     /**
15      * Get a comment by ID.
16      */
17     public function getById(int $id): Comment
18     {
19         return Comment::query()->findOrFail($id);
20     }
21
22     /**
23      * Start a query for comments visible to the user.
24      */
25     public function getQueryForVisible(): Builder
26     {
27         return Comment::query()->scopes('visible');
28     }
29
30     /**
31      * Create a new comment on an entity.
32      */
33     public function create(Entity $entity, string $html, ?int $parentId, string $contentRef): Comment
34     {
35         $userId = user()->id;
36         $comment = new Comment();
37
38         $comment->html = HtmlDescriptionFilter::filterFromString($html);
39         $comment->created_by = $userId;
40         $comment->updated_by = $userId;
41         $comment->local_id = $this->getNextLocalId($entity);
42         $comment->parent_id = $parentId;
43         $comment->content_ref = preg_match('/^bkmrk-(.*?):\d+:(\d*-\d*)?$/', $contentRef) === 1 ? $contentRef : '';
44
45         $entity->comments()->save($comment);
46         ActivityService::add(ActivityType::COMMENT_CREATE, $comment);
47         ActivityService::add(ActivityType::COMMENTED_ON, $entity);
48
49         return $comment;
50     }
51
52     /**
53      * Update an existing comment.
54      */
55     public function update(Comment $comment, string $html): Comment
56     {
57         $comment->updated_by = user()->id;
58         $comment->html = HtmlDescriptionFilter::filterFromString($html);
59         $comment->save();
60
61         ActivityService::add(ActivityType::COMMENT_UPDATE, $comment);
62
63         return $comment;
64     }
65
66
67     /**
68      * Archive an existing comment.
69      */
70     public function archive(Comment $comment): Comment
71     {
72         if ($comment->parent_id) {
73             throw new NotifyException('Only top-level comments can be archived.', '/', 400);
74         }
75
76         $comment->archived = true;
77         $comment->save();
78
79         ActivityService::add(ActivityType::COMMENT_UPDATE, $comment);
80
81         return $comment;
82     }
83
84     /**
85      * Un-archive an existing comment.
86      */
87     public function unarchive(Comment $comment): Comment
88     {
89         if ($comment->parent_id) {
90             throw new NotifyException('Only top-level comments can be un-archived.', '/', 400);
91         }
92
93         $comment->archived = false;
94         $comment->save();
95
96         ActivityService::add(ActivityType::COMMENT_UPDATE, $comment);
97
98         return $comment;
99     }
100
101     /**
102      * Delete a comment from the system.
103      */
104     public function delete(Comment $comment): void
105     {
106         $comment->delete();
107
108         ActivityService::add(ActivityType::COMMENT_DELETE, $comment);
109     }
110
111     /**
112      * Get the next local ID relative to the linked entity.
113      */
114     protected function getNextLocalId(Entity $entity): int
115     {
116         $currentMaxId = $entity->comments()->max('local_id');
117
118         return $currentMaxId + 1;
119     }
120 }