]> BookStack Code Mirror - bookstack/blob - app/Entities/Queries/PageQueries.php
f821ee86a5889e0bcc1d59fc825ff7b4be73becf
[bookstack] / app / Entities / Queries / PageQueries.php
1 <?php
2
3 namespace BookStack\Entities\Queries;
4
5 use BookStack\Entities\Models\Page;
6 use BookStack\Exceptions\NotFoundException;
7 use Illuminate\Database\Eloquent\Builder;
8
9 class PageQueries implements ProvidesEntityQueries
10 {
11     protected static array $contentAttributes = [
12         'name', 'id', 'slug', 'book_id', 'chapter_id', 'draft',
13         'template', 'html', 'text', 'created_at', 'updated_at', 'priority',
14         'created_by', 'updated_by', 'owned_by',
15     ];
16     protected static array $listAttributes = [
17         'name', 'id', 'slug', 'book_id', 'chapter_id', 'draft',
18         'template', 'text', 'created_at', 'updated_at', 'priority', 'owned_by',
19     ];
20
21     public function start(): Builder
22     {
23         return Page::query();
24     }
25
26     public function findVisibleById(int $id): ?Page
27     {
28         return $this->start()->scopes('visible')->find($id);
29     }
30
31     public function findVisibleByIdOrFail(int $id): Page
32     {
33         $page = $this->findVisibleById($id);
34
35         if (is_null($page)) {
36             throw new NotFoundException(trans('errors.page_not_found'));
37         }
38
39         return $page;
40     }
41
42     public function findVisibleBySlugsOrFail(string $bookSlug, string $pageSlug): Page
43     {
44         /** @var ?Page $page */
45         $page = $this->start()->with('book')
46             ->scopes('visible')
47             ->whereHas('book', function (Builder $query) use ($bookSlug) {
48                 $query->where('slug', '=', $bookSlug);
49             })
50             ->where('slug', '=', $pageSlug)
51             ->first();
52
53         if (is_null($page)) {
54             throw new NotFoundException(trans('errors.page_not_found'));
55         }
56
57         return $page;
58     }
59
60     public function usingSlugs(string $bookSlug, string $pageSlug): Builder
61     {
62         return $this->start()
63             ->where('slug', '=', $pageSlug)
64             ->whereHas('book', function (Builder $query) use ($bookSlug) {
65                 $query->where('slug', '=', $bookSlug);
66             });
67     }
68
69     /**
70      * @return Builder<Page>
71      */
72     public function visibleForList(): Builder
73     {
74         return $this->start()
75             ->scopes('visible')
76             ->select($this->mergeBookSlugForSelect(static::$listAttributes));
77     }
78
79     public function visibleForChapterList(int $chapterId): Builder
80     {
81         return $this->visibleForList()
82             ->where('chapter_id', '=', $chapterId)
83             ->orderBy('draft', 'desc')
84             ->orderBy('priority', 'asc');
85     }
86
87     public function visibleWithContents(): Builder
88     {
89         return $this->start()
90             ->scopes('visible')
91             ->select($this->mergeBookSlugForSelect(static::$contentAttributes));
92     }
93
94     public function currentUserDraftsForList(): Builder
95     {
96         return $this->visibleForList()
97             ->where('draft', '=', true)
98             ->where('created_by', '=', user()->id);
99     }
100
101     public function visibleTemplates(): Builder
102     {
103         return $this->visibleForList()
104             ->where('template', '=', true);
105     }
106
107     protected function mergeBookSlugForSelect(array $columns): array
108     {
109         return array_merge($columns, ['book_slug' => function ($builder) {
110             $builder->select('slug')
111                 ->from('books')
112                 ->whereColumn('books.id', '=', 'pages.book_id');
113         }]);
114     }
115 }