]> BookStack Code Mirror - bookstack/blob - app/Entities/Repos/BookRepo.php
Default templates: Added page picker and working forms
[bookstack] / app / Entities / Repos / BookRepo.php
1 <?php
2
3 namespace BookStack\Entities\Repos;
4
5 use BookStack\Activity\ActivityType;
6 use BookStack\Activity\TagRepo;
7 use BookStack\Entities\Models\Book;
8 use BookStack\Entities\Models\Page;
9 use BookStack\Entities\Tools\TrashCan;
10 use BookStack\Exceptions\ImageUploadException;
11 use BookStack\Exceptions\NotFoundException;
12 use BookStack\Facades\Activity;
13 use BookStack\Uploads\ImageRepo;
14 use Exception;
15 use Illuminate\Contracts\Pagination\LengthAwarePaginator;
16 use Illuminate\Http\UploadedFile;
17 use Illuminate\Support\Collection;
18
19 class BookRepo
20 {
21     public function __construct(
22         protected BaseRepo $baseRepo,
23         protected TagRepo $tagRepo,
24         protected ImageRepo $imageRepo
25     ) {
26     }
27
28     /**
29      * Get all books in a paginated format.
30      */
31     public function getAllPaginated(int $count = 20, string $sort = 'name', string $order = 'asc'): LengthAwarePaginator
32     {
33         return Book::visible()->with('cover')->orderBy($sort, $order)->paginate($count);
34     }
35
36     /**
37      * Get the books that were most recently viewed by this user.
38      */
39     public function getRecentlyViewed(int $count = 20): Collection
40     {
41         return Book::visible()->withLastView()
42             ->having('last_viewed_at', '>', 0)
43             ->orderBy('last_viewed_at', 'desc')
44             ->take($count)->get();
45     }
46
47     /**
48      * Get the most popular books in the system.
49      */
50     public function getPopular(int $count = 20): Collection
51     {
52         return Book::visible()->withViewCount()
53             ->having('view_count', '>', 0)
54             ->orderBy('view_count', 'desc')
55             ->take($count)->get();
56     }
57
58     /**
59      * Get the most recently created books from the system.
60      */
61     public function getRecentlyCreated(int $count = 20): Collection
62     {
63         return Book::visible()->orderBy('created_at', 'desc')
64             ->take($count)->get();
65     }
66
67     /**
68      * Get a book by its slug.
69      */
70     public function getBySlug(string $slug): Book
71     {
72         $book = Book::visible()->where('slug', '=', $slug)->first();
73
74         if ($book === null) {
75             throw new NotFoundException(trans('errors.book_not_found'));
76         }
77
78         return $book;
79     }
80
81     /**
82      * Create a new book in the system.
83      */
84     public function create(array $input): Book
85     {
86         $book = new Book();
87         $this->baseRepo->create($book, $input);
88         $this->baseRepo->updateCoverImage($book, $input['image'] ?? null);
89         Activity::add(ActivityType::BOOK_CREATE, $book);
90
91         return $book;
92     }
93
94     /**
95      * Update the given book.
96      */
97     public function update(Book $book, array $input): Book
98     {
99         $this->baseRepo->update($book, $input);
100
101         if (array_key_exists('default_template', $input)) {
102             $this->updateBookDefaultTemplate($book, intval($input['default_template']));
103         }
104
105         if (array_key_exists('image', $input)) {
106             $this->baseRepo->updateCoverImage($book, $input['image'], $input['image'] === null);
107         }
108
109         Activity::add(ActivityType::BOOK_UPDATE, $book);
110
111         return $book;
112     }
113
114     /**
115      * Update the default page template used for this book.
116      * Checks that, if changing, the provided value is a valid template and the user
117      * has visibility of the provided page template id.
118      */
119     protected function updateBookDefaultTemplate(Book $book, int $templateId): void
120     {
121         $changing = $templateId !== intval($book->default_template);
122         if (!$changing) {
123             return;
124         }
125
126         if ($templateId === 0) {
127             $book->default_template = null;
128             $book->save();
129             return;
130         }
131
132         $templateExists = Page::query()->visible()
133             ->where('template', '=', true)
134             ->where('id', '=', $templateId)
135             ->exists();
136
137         $book->default_template = $templateExists ? $templateId : null;
138         $book->save();
139     }
140
141     /**
142      * Update the given book's cover image, or clear it.
143      *
144      * @throws ImageUploadException
145      * @throws Exception
146      */
147     public function updateCoverImage(Book $book, ?UploadedFile $coverImage, bool $removeImage = false)
148     {
149         $this->baseRepo->updateCoverImage($book, $coverImage, $removeImage);
150     }
151
152     /**
153      * Remove a book from the system.
154      *
155      * @throws Exception
156      */
157     public function destroy(Book $book)
158     {
159         $trashCan = new TrashCan();
160         $trashCan->softDestroyBook($book);
161         Activity::add(ActivityType::BOOK_DELETE, $book);
162
163         $trashCan->autoClearOld();
164     }
165 }