]> BookStack Code Mirror - bookstack/blob - app/Repos/ChapterRepo.php
Added in restriction queries for most lists
[bookstack] / app / Repos / ChapterRepo.php
1 <?php namespace BookStack\Repos;
2
3
4 use Activity;
5 use BookStack\Services\RestrictionService;
6 use Illuminate\Support\Str;
7 use BookStack\Chapter;
8
9 class ChapterRepo
10 {
11
12     protected $chapter;
13     protected $restrictionService;
14
15     /**
16      * ChapterRepo constructor.
17      * @param Chapter $chapter
18      * @param RestrictionService $restrictionService
19      */
20     public function __construct(Chapter $chapter, RestrictionService $restrictionService)
21     {
22         $this->chapter = $chapter;
23         $this->restrictionService = $restrictionService;
24     }
25
26     /**
27      * Base query for getting chapters, Takes restrictions into account.
28      * @return mixed
29      */
30     private function chapterQuery()
31     {
32         return $this->restrictionService->enforceChapterRestrictions($this->chapter, 'view');
33     }
34
35     /**
36      * Check if an id exists.
37      * @param $id
38      * @return bool
39      */
40     public function idExists($id)
41     {
42         return $this->chapterQuery()->where('id', '=', $id)->count() > 0;
43     }
44
45     /**
46      * Get a chapter by a specific id.
47      * @param $id
48      * @return mixed
49      */
50     public function getById($id)
51     {
52         return $this->chapterQuery()->findOrFail($id);
53     }
54
55     /**
56      * Get all chapters.
57      * @return \Illuminate\Database\Eloquent\Collection|static[]
58      */
59     public function getAll()
60     {
61         return $this->chapterQuery()->all();
62     }
63
64     /**
65      * Get a chapter that has the given slug within the given book.
66      * @param $slug
67      * @param $bookId
68      * @return mixed
69      */
70     public function getBySlug($slug, $bookId)
71     {
72         $chapter = $this->chapterQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
73         if ($chapter === null) abort(404);
74         return $chapter;
75     }
76
77     /**
78      * Create a new chapter from request input.
79      * @param $input
80      * @return $this
81      */
82     public function newFromInput($input)
83     {
84         return $this->chapter->fill($input);
85     }
86
87     /**
88      * Destroy a chapter and its relations by providing its slug.
89      * @param Chapter $chapter
90      */
91     public function destroy(Chapter $chapter)
92     {
93         if (count($chapter->pages) > 0) {
94             foreach ($chapter->pages as $page) {
95                 $page->chapter_id = 0;
96                 $page->save();
97             }
98         }
99         Activity::removeEntity($chapter);
100         $chapter->views()->delete();
101         $chapter->delete();
102     }
103
104     /**
105      * Check if a chapter's slug exists.
106      * @param            $slug
107      * @param            $bookId
108      * @param bool|false $currentId
109      * @return bool
110      */
111     public function doesSlugExist($slug, $bookId, $currentId = false)
112     {
113         $query = $this->chapter->where('slug', '=', $slug)->where('book_id', '=', $bookId);
114         if ($currentId) {
115             $query = $query->where('id', '!=', $currentId);
116         }
117         return $query->count() > 0;
118     }
119
120     /**
121      * Finds a suitable slug for the provided name.
122      * Checks database to prevent duplicate slugs.
123      * @param            $name
124      * @param            $bookId
125      * @param bool|false $currentId
126      * @return string
127      */
128     public function findSuitableSlug($name, $bookId, $currentId = false)
129     {
130         $slug = Str::slug($name);
131         while ($this->doesSlugExist($slug, $bookId, $currentId)) {
132             $slug .= '-' . substr(md5(rand(1, 500)), 0, 3);
133         }
134         return $slug;
135     }
136
137     /**
138      * Get chapters by the given search term.
139      * @param       $term
140      * @param array $whereTerms
141      * @param int $count
142      * @param array $paginationAppends
143      * @return mixed
144      */
145     public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
146     {
147         $terms = explode(' ', $term);
148         $chapters = $this->restrictionService->enforceChapterRestrictions($this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms))
149             ->paginate($count)->appends($paginationAppends);
150         $words = join('|', explode(' ', preg_quote(trim($term), '/')));
151         foreach ($chapters as $chapter) {
152             //highlight
153             $result = preg_replace('#' . $words . '#iu', "<span class=\"highlight\">\$0</span>", $chapter->getExcerpt(100));
154             $chapter->searchSnippet = $result;
155         }
156         return $chapters;
157     }
158
159     /**
160      * Changes the book relation of this chapter.
161      * @param         $bookId
162      * @param Chapter $chapter
163      * @return Chapter
164      */
165     public function changeBook($bookId, Chapter $chapter)
166     {
167         $chapter->book_id = $bookId;
168         foreach ($chapter->activity as $activity) {
169             $activity->book_id = $bookId;
170             $activity->save();
171         }
172         $chapter->slug = $this->findSuitableSlug($chapter->name, $bookId, $chapter->id);
173         $chapter->save();
174         return $chapter;
175     }
176
177     /**
178      * Updates pages restrictions from a request
179      * @param $request
180      * @param $chapter
181      */
182     public function updateRestrictionsFromRequest($request, $chapter)
183     {
184         // TODO - extract into shared repo
185         $chapter->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
186         $chapter->restrictions()->delete();
187         if ($request->has('restrictions')) {
188             foreach($request->get('restrictions') as $roleId => $restrictions) {
189                 foreach ($restrictions as $action => $value) {
190                     $chapter->restrictions()->create([
191                         'role_id' => $roleId,
192                         'action'  => strtolower($action)
193                     ]);
194                 }
195             }
196         }
197         $chapter->save();
198     }
199
200 }