]> BookStack Code Mirror - bookstack/blob - app/Repos/BookRepo.php.orig
Merge branch 'custom_role_system'
[bookstack] / app / Repos / BookRepo.php.orig
1 <?php namespace BookStack\Repos;
2
3 use Activity;
4 use BookStack\Exceptions\NotFoundException;
5 use BookStack\Services\RestrictionService;
6 use Illuminate\Support\Str;
7 use BookStack\Book;
8 use Views;
9
10 class BookRepo
11 {
12
13     protected $book;
14     protected $pageRepo;
15     protected $chapterRepo;
16     protected $restrictionService;
17
18     /**
19      * BookRepo constructor.
20      * @param Book $book
21      * @param PageRepo $pageRepo
22      * @param ChapterRepo $chapterRepo
23      * @param RestrictionService $restrictionService
24      */
25     public function __construct(Book $book, PageRepo $pageRepo, ChapterRepo $chapterRepo, RestrictionService $restrictionService)
26     {
27         $this->book = $book;
28         $this->pageRepo = $pageRepo;
29         $this->chapterRepo = $chapterRepo;
30         $this->restrictionService = $restrictionService;
31     }
32
33     /**
34      * Base query for getting books.
35      * Takes into account any restrictions.
36      * @return mixed
37      */
38     private function bookQuery()
39     {
40         return $this->restrictionService->enforceBookRestrictions($this->book, 'view');
41     }
42
43     /**
44      * Get the book that has the given id.
45      * @param $id
46      * @return mixed
47      */
48     public function getById($id)
49     {
50         return $this->bookQuery()->findOrFail($id);
51     }
52
53     /**
54      * Get all books, Limited by count.
55      * @param int $count
56      * @return mixed
57      */
58     public function getAll($count = 10)
59     {
60         $bookQuery = $this->bookQuery()->orderBy('name', 'asc');
61         if (!$count) return $bookQuery->get();
62         return $bookQuery->take($count)->get();
63     }
64
65     /**
66      * Get all books paginated.
67      * @param int $count
68      * @return mixed
69      */
70     public function getAllPaginated($count = 10)
71     {
72         return $this->bookQuery()
73             ->orderBy('name', 'asc')->paginate($count);
74     }
75
76
77     /**
78      * Get the latest books.
79      * @param int $count
80      * @return mixed
81      */
82     public function getLatest($count = 10)
83     {
84         return $this->bookQuery()->orderBy('created_at', 'desc')->take($count)->get();
85     }
86
87     /**
88      * Gets the most recently viewed for a user.
89      * @param int $count
90      * @param int $page
91      * @return mixed
92      */
93     public function getRecentlyViewed($count = 10, $page = 0)
94     {
95         // TODO restrict
96         return Views::getUserRecentlyViewed($count, $page, $this->book);
97     }
98
99     /**
100      * Gets the most viewed books.
101      * @param int $count
102      * @param int $page
103      * @return mixed
104      */
105     public function getPopular($count = 10, $page = 0)
106     {
107         // TODO - Restrict
108         return Views::getPopular($count, $page, $this->book);
109     }
110
111     /**
112      * Get a book by slug
113      * @param $slug
114      * @return mixed
115      * @throws NotFoundException
116      */
117     public function getBySlug($slug)
118     {
119         $book = $this->bookQuery()->where('slug', '=', $slug)->first();
120         if ($book === null) throw new NotFoundException('Book not found');
121         return $book;
122     }
123
124     /**
125      * Checks if a book exists.
126      * @param $id
127      * @return bool
128      */
129     public function exists($id)
130     {
131         return $this->bookQuery()->where('id', '=', $id)->exists();
132     }
133
134     /**
135      * Get a new book instance from request input.
136      * @param $input
137      * @return Book
138      */
139     public function newFromInput($input)
140     {
141         return $this->book->newInstance($input);
142     }
143
144     /**
145      * Destroy a book identified by the given slug.
146      * @param $bookSlug
147      */
148     public function destroyBySlug($bookSlug)
149     {
150         $book = $this->getBySlug($bookSlug);
151         foreach ($book->pages as $page) {
152             $this->pageRepo->destroy($page);
153         }
154         foreach ($book->chapters as $chapter) {
155             $this->chapterRepo->destroy($chapter);
156         }
157         $book->views()->delete();
158         $book->restrictions()->delete();
159         $book->delete();
160     }
161
162     /**
163      * Get the next child element priority.
164      * @param Book $book
165      * @return int
166      */
167     public function getNewPriority($book)
168     {
169         $lastElem = $this->getChildren($book)->pop();
170         return $lastElem ? $lastElem->priority + 1 : 0;
171     }
172
173     /**
174      * @param string $slug
175      * @param bool|false $currentId
176      * @return bool
177      */
178     public function doesSlugExist($slug, $currentId = false)
179     {
180         $query = $this->book->where('slug', '=', $slug);
181         if ($currentId) {
182             $query = $query->where('id', '!=', $currentId);
183         }
184         return $query->count() > 0;
185     }
186
187     /**
188      * Provides a suitable slug for the given book name.
189      * Ensures the returned slug is unique in the system.
190      * @param string $name
191      * @param bool|false $currentId
192      * @return string
193      */
194     public function findSuitableSlug($name, $currentId = false)
195     {
196         $originalSlug = Str::slug($name);
197         $slug = $originalSlug;
198         $count = 2;
199         while ($this->doesSlugExist($slug, $currentId)) {
200             $slug = $originalSlug . '-' . $count;
201             $count++;
202         }
203         return $slug;
204     }
205
206     /**
207      * Get all child objects of a book.
208      * Returns a sorted collection of Pages and Chapters.
209      * Loads the bookslug onto child elements to prevent access database access for getting the slug.
210      * @param Book $book
211      * @return mixed
212      */
213     public function getChildren(Book $book)
214     {
215         $pageQuery = $book->pages()->where('chapter_id', '=', 0);
216         $pageQuery = $this->restrictionService->enforcePageRestrictions($pageQuery, 'view');
217         $pages = $pageQuery->get();
218
219         $chapterQuery = $book->chapters()->with(['pages' => function($query) {
220             $this->restrictionService->enforcePageRestrictions($query, 'view');
221         }]);
222         $chapterQuery = $this->restrictionService->enforceChapterRestrictions($chapterQuery, 'view');
223         $chapters = $chapterQuery->get();
224         $children = $pages->merge($chapters);
225         $bookSlug = $book->slug;
226         $children->each(function ($child) use ($bookSlug) {
227             $child->setAttribute('bookSlug', $bookSlug);
228             if ($child->isA('chapter')) {
229                 $child->pages->each(function ($page) use ($bookSlug) {
230                     $page->setAttribute('bookSlug', $bookSlug);
231                 });
232             }
233         });
234         return $children->sortBy('priority');
235     }
236
237     /**
238      * Get books by search term.
239      * @param $term
240      * @param int $count
241      * @param array $paginationAppends
242      * @return mixed
243      */
244     public function getBySearch($term, $count = 20, $paginationAppends = [])
245     {
246 <<<<<<< HEAD
247         preg_match_all('/"(.*?)"/', $term, $matches);
248         if (count($matches[1]) > 0) {
249             $terms = $matches[1];
250             $term = trim(preg_replace('/"(.*?)"/', '', $term));
251         } else {
252             $terms = [];
253         }
254         if (!empty($term)) {
255             $terms = array_merge($terms, explode(' ', $term));
256         }
257         $books = $this->book->fullTextSearchQuery(['name', 'description'], $terms)
258 =======
259         $terms = explode(' ', $term);
260         $books = $this->restrictionService->enforceBookRestrictions($this->book->fullTextSearchQuery(['name', 'description'], $terms))
261 >>>>>>> custom_role_system
262             ->paginate($count)->appends($paginationAppends);
263         $words = join('|', explode(' ', preg_quote(trim($term), '/')));
264         foreach ($books as $book) {
265             //highlight
266             $result = preg_replace('#' . $words . '#iu', "<span class=\"highlight\">\$0</span>", $book->getExcerpt(100));
267             $book->searchSnippet = $result;
268         }
269         return $books;
270     }
271
272     /**
273      * Updates books restrictions from a request
274      * @param $request
275      * @param $book
276      */
277     public function updateRestrictionsFromRequest($request, $book)
278     {
279         // TODO - extract into shared repo
280         $book->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
281         $book->restrictions()->delete();
282         if ($request->has('restrictions')) {
283             foreach ($request->get('restrictions') as $roleId => $restrictions) {
284                 foreach ($restrictions as $action => $value) {
285                     $book->restrictions()->create([
286                         'role_id' => $roleId,
287                         'action' => strtolower($action)
288                     ]);
289                 }
290             }
291         }
292         $book->save();
293     }
294
295 }