]> BookStack Code Mirror - bookstack/blob - app/Entities/Models/Page.php
Refactored search runner a little to be neater
[bookstack] / app / Entities / Models / Page.php
1 <?php
2
3 namespace BookStack\Entities\Models;
4
5 use BookStack\Entities\Tools\PageContent;
6 use BookStack\Uploads\Attachment;
7 use Illuminate\Database\Eloquent\Builder;
8 use Illuminate\Database\Eloquent\Collection;
9 use Illuminate\Database\Eloquent\Factories\HasFactory;
10 use Illuminate\Database\Eloquent\Relations\BelongsTo;
11 use Illuminate\Database\Eloquent\Relations\HasMany;
12 use Permissions;
13
14 /**
15  * Class Page.
16  *
17  * @property int        $chapter_id
18  * @property string     $html
19  * @property string     $markdown
20  * @property string     $text
21  * @property bool       $template
22  * @property bool       $draft
23  * @property int        $revision_count
24  * @property Chapter    $chapter
25  * @property Collection $attachments
26  */
27 class Page extends BookChild
28 {
29     use HasFactory;
30
31     public static $listAttributes = ['name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'text', 'created_at', 'updated_at', 'priority'];
32     public static $contentAttributes = ['name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'html', 'text', 'created_at', 'updated_at', 'priority'];
33
34     protected $fillable = ['name', 'priority'];
35
36     public $textField = 'text';
37
38     protected $hidden = ['html', 'markdown', 'text', 'restricted', 'pivot', 'deleted_at'];
39
40     protected $casts = [
41         'draft'    => 'boolean',
42         'template' => 'boolean',
43     ];
44
45     /**
46      * Get the entities that are visible to the current user.
47      */
48     public function scopeVisible(Builder $query): Builder
49     {
50         $query = Permissions::enforceDraftVisibilityOnQuery($query);
51
52         return parent::scopeVisible($query);
53     }
54
55     /**
56      * Get the chapter that this page is in, If applicable.
57      *
58      * @return BelongsTo
59      */
60     public function chapter()
61     {
62         return $this->belongsTo(Chapter::class);
63     }
64
65     /**
66      * Check if this page has a chapter.
67      *
68      * @return bool
69      */
70     public function hasChapter()
71     {
72         return $this->chapter()->count() > 0;
73     }
74
75     /**
76      * Get the associated page revisions, ordered by created date.
77      * Only provides actual saved page revision instances, Not drafts.
78      */
79     public function revisions(): HasMany
80     {
81         return $this->allRevisions()
82             ->where('type', '=', 'version')
83             ->orderBy('created_at', 'desc')
84             ->orderBy('id', 'desc');
85     }
86
87     /**
88      * Get all revision instances assigned to this page.
89      * Includes all types of revisions.
90      */
91     public function allRevisions(): HasMany
92     {
93         return $this->hasMany(PageRevision::class);
94     }
95
96     /**
97      * Get the attachments assigned to this page.
98      *
99      * @return HasMany
100      */
101     public function attachments()
102     {
103         return $this->hasMany(Attachment::class, 'uploaded_to')->orderBy('order', 'asc');
104     }
105
106     /**
107      * Get the url of this page.
108      */
109     public function getUrl(string $path = ''): string
110     {
111         $parts = [
112             'books',
113             urlencode($this->book_slug ?? $this->book->slug),
114             $this->draft ? 'draft' : 'page',
115             $this->draft ? $this->id : urlencode($this->slug),
116             trim($path, '/'),
117         ];
118
119         return url('/' . implode('/', $parts));
120     }
121
122     /**
123      * Get the current revision for the page if existing.
124      *
125      * @return PageRevision|null
126      */
127     public function getCurrentRevision()
128     {
129         return $this->revisions()->first();
130     }
131
132     /**
133      * Get this page for JSON display.
134      */
135     public function forJsonDisplay(): self
136     {
137         $refreshed = $this->refresh()->unsetRelations()->load(['tags', 'createdBy', 'updatedBy', 'ownedBy']);
138         $refreshed->setHidden(array_diff($refreshed->getHidden(), ['html', 'markdown']));
139         $refreshed->html = (new PageContent($refreshed))->render();
140
141         return $refreshed;
142     }
143 }