3 namespace BookStack\Activity\Tools;
5 use BookStack\Activity\Models\Comment;
6 use BookStack\Entities\Models\Page;
11 * The built nested tree structure array.
12 * @var CommentTreeNode[]
14 protected array $tree;
15 protected array $comments;
17 public function __construct(
20 $this->comments = $this->loadComments();
21 $this->tree = $this->createTree($this->comments);
24 public function enabled(): bool
26 return !setting('app-disable-comments');
29 public function empty(): bool
31 return count($this->getActive()) === 0;
34 public function count(): int
36 return count($this->comments);
39 public function getActive(): array
41 return array_filter($this->tree, fn (CommentTreeNode $node) => !$node->comment->archived);
44 public function activeThreadCount(): int
46 return count($this->getActive());
49 public function getArchived(): array
51 return array_filter($this->tree, fn (CommentTreeNode $node) => $node->comment->archived);
54 public function archivedThreadCount(): int
56 return count($this->getArchived());
59 public function getCommentNodeForId(int $commentId): ?CommentTreeNode
61 foreach ($this->tree as $node) {
62 if ($node->comment->id === $commentId) {
70 public function canUpdateAny(): bool
72 foreach ($this->comments as $comment) {
73 if (userCan('comment-update', $comment)) {
82 * @param Comment[] $comments
83 * @return CommentTreeNode[]
85 protected function createTree(array $comments): array
88 foreach ($comments as $comment) {
89 $byId[$comment->local_id] = $comment;
93 foreach ($comments as $comment) {
94 $parent = $comment->parent_id;
95 if (is_null($parent) || !isset($byId[$parent])) {
99 if (!isset($childMap[$parent])) {
100 $childMap[$parent] = [];
102 $childMap[$parent][] = $comment->local_id;
106 foreach ($childMap[0] ?? [] as $childId) {
107 $tree[] = $this->createTreeNodeForId($childId, 0, $byId, $childMap);
113 protected function createTreeNodeForId(int $id, int $depth, array &$byId, array &$childMap): CommentTreeNode
115 $childIds = $childMap[$id] ?? [];
118 foreach ($childIds as $childId) {
119 $children[] = $this->createTreeNodeForId($childId, $depth + 1, $byId, $childMap);
122 return new CommentTreeNode($byId[$id], $depth, $children);
125 protected function loadComments(): array
127 if (!$this->enabled()) {
131 return $this->page->comments()