]> BookStack Code Mirror - bookstack/blob - app/Entities/Repos/BookRepo.php
Dependancies: Updated PHP deps via composer
[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         $this->updateBookDefaultTemplate($book, intval($input['default_template_id'] ?? null));
90         Activity::add(ActivityType::BOOK_CREATE, $book);
91
92         return $book;
93     }
94
95     /**
96      * Update the given book.
97      */
98     public function update(Book $book, array $input): Book
99     {
100         $this->baseRepo->update($book, $input);
101
102         if (array_key_exists('default_template_id', $input)) {
103             $this->updateBookDefaultTemplate($book, intval($input['default_template_id']));
104         }
105
106         if (array_key_exists('image', $input)) {
107             $this->baseRepo->updateCoverImage($book, $input['image'], $input['image'] === null);
108         }
109
110         Activity::add(ActivityType::BOOK_UPDATE, $book);
111
112         return $book;
113     }
114
115     /**
116      * Update the default page template used for this book.
117      * Checks that, if changing, the provided value is a valid template and the user
118      * has visibility of the provided page template id.
119      */
120     protected function updateBookDefaultTemplate(Book $book, int $templateId): void
121     {
122         $changing = $templateId !== intval($book->default_template_id);
123         if (!$changing) {
124             return;
125         }
126
127         if ($templateId === 0) {
128             $book->default_template_id = null;
129             $book->save();
130             return;
131         }
132
133         $templateExists = Page::query()->visible()
134             ->where('template', '=', true)
135             ->where('id', '=', $templateId)
136             ->exists();
137
138         $book->default_template_id = $templateExists ? $templateId : null;
139         $book->save();
140     }
141
142     /**
143      * Update the given book's cover image, or clear it.
144      *
145      * @throws ImageUploadException
146      * @throws Exception
147      */
148     public function updateCoverImage(Book $book, ?UploadedFile $coverImage, bool $removeImage = false)
149     {
150         $this->baseRepo->updateCoverImage($book, $coverImage, $removeImage);
151     }
152
153     /**
154      * Remove a book from the system.
155      *
156      * @throws Exception
157      */
158     public function destroy(Book $book)
159     {
160         $trashCan = new TrashCan();
161         $trashCan->softDestroyBook($book);
162         Activity::add(ActivityType::BOOK_DELETE, $book);
163
164         $trashCan->autoClearOld();
165     }
166 }