Dan Brown

Finished refactor of entity repos

Removed entity-specific repos and standardised
the majority of repo calls to be applicable to
all entity types
...@@ -18,11 +18,12 @@ class Chapter extends Entity ...@@ -18,11 +18,12 @@ class Chapter extends Entity
18 18
19 /** 19 /**
20 * Get the pages that this chapter contains. 20 * Get the pages that this chapter contains.
21 + * @param string $dir
21 * @return mixed 22 * @return mixed
22 */ 23 */
23 - public function pages() 24 + public function pages($dir = 'ASC')
24 { 25 {
25 - return $this->hasMany(Page::class)->orderBy('priority', 'ASC'); 26 + return $this->hasMany(Page::class)->orderBy('priority', $dir);
26 } 27 }
27 28
28 /** 29 /**
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
3 use BookStack\Exceptions\FileUploadException; 3 use BookStack\Exceptions\FileUploadException;
4 use BookStack\Attachment; 4 use BookStack\Attachment;
5 use BookStack\Repos\EntityRepo; 5 use BookStack\Repos\EntityRepo;
6 -use BookStack\Repos\PageRepo;
7 use BookStack\Services\AttachmentService; 6 use BookStack\Services\AttachmentService;
8 use Illuminate\Http\Request; 7 use Illuminate\Http\Request;
9 8
...@@ -11,21 +10,18 @@ class AttachmentController extends Controller ...@@ -11,21 +10,18 @@ class AttachmentController extends Controller
11 { 10 {
12 protected $attachmentService; 11 protected $attachmentService;
13 protected $attachment; 12 protected $attachment;
14 - protected $pageRepo;
15 protected $entityRepo; 13 protected $entityRepo;
16 14
17 /** 15 /**
18 * AttachmentController constructor. 16 * AttachmentController constructor.
19 * @param AttachmentService $attachmentService 17 * @param AttachmentService $attachmentService
20 * @param Attachment $attachment 18 * @param Attachment $attachment
21 - * @param PageRepo $pageRepo 19 + * @param EntityRepo $entityRepo
22 */ 20 */
23 - public function __construct(AttachmentService $attachmentService, Attachment $attachment, EntityRepo $entityRepo, PageRepo $pageRepo) 21 + public function __construct(AttachmentService $attachmentService, Attachment $attachment, EntityRepo $entityRepo)
24 { 22 {
25 $this->attachmentService = $attachmentService; 23 $this->attachmentService = $attachmentService;
26 $this->attachment = $attachment; 24 $this->attachment = $attachment;
27 - // TODO - Remove this
28 - $this->pageRepo = $pageRepo;
29 $this->entityRepo = $entityRepo; 25 $this->entityRepo = $entityRepo;
30 parent::__construct(); 26 parent::__construct();
31 } 27 }
......
...@@ -4,10 +4,6 @@ use Activity; ...@@ -4,10 +4,6 @@ use Activity;
4 use BookStack\Repos\EntityRepo; 4 use BookStack\Repos\EntityRepo;
5 use BookStack\Repos\UserRepo; 5 use BookStack\Repos\UserRepo;
6 use Illuminate\Http\Request; 6 use Illuminate\Http\Request;
7 -use BookStack\Http\Requests;
8 -use BookStack\Repos\BookRepo;
9 -use BookStack\Repos\ChapterRepo;
10 -use BookStack\Repos\PageRepo;
11 use Illuminate\Http\Response; 7 use Illuminate\Http\Response;
12 use Views; 8 use Views;
13 9
...@@ -15,26 +11,16 @@ class BookController extends Controller ...@@ -15,26 +11,16 @@ class BookController extends Controller
15 { 11 {
16 12
17 protected $entityRepo; 13 protected $entityRepo;
18 - protected $bookRepo;
19 - protected $pageRepo;
20 - protected $chapterRepo;
21 protected $userRepo; 14 protected $userRepo;
22 15
23 /** 16 /**
24 * BookController constructor. 17 * BookController constructor.
25 * @param EntityRepo $entityRepo 18 * @param EntityRepo $entityRepo
26 - * @param BookRepo $bookRepo
27 - * @param PageRepo $pageRepo
28 - * @param ChapterRepo $chapterRepo
29 * @param UserRepo $userRepo 19 * @param UserRepo $userRepo
30 */ 20 */
31 - public function __construct(EntityRepo $entityRepo, BookRepo $bookRepo, PageRepo $pageRepo, ChapterRepo $chapterRepo, UserRepo $userRepo) 21 + public function __construct(EntityRepo $entityRepo, UserRepo $userRepo)
32 { 22 {
33 $this->entityRepo = $entityRepo; 23 $this->entityRepo = $entityRepo;
34 - // TODO - Remove below
35 - $this->bookRepo = $bookRepo;
36 - $this->pageRepo = $pageRepo;
37 - $this->chapterRepo = $chapterRepo;
38 $this->userRepo = $userRepo; 24 $this->userRepo = $userRepo;
39 parent::__construct(); 25 parent::__construct();
40 } 26 }
...@@ -76,7 +62,7 @@ class BookController extends Controller ...@@ -76,7 +62,7 @@ class BookController extends Controller
76 'name' => 'required|string|max:255', 62 'name' => 'required|string|max:255',
77 'description' => 'string|max:1000' 63 'description' => 'string|max:1000'
78 ]); 64 ]);
79 - $book = $this->bookRepo->createFromInput($request->all()); 65 + $book = $this->entityRepo->createFromInput('book', $request->all());
80 Activity::add($book, 'book_create', $book->id); 66 Activity::add($book, 'book_create', $book->id);
81 return redirect($book->getUrl()); 67 return redirect($book->getUrl());
82 } 68 }
...@@ -90,7 +76,7 @@ class BookController extends Controller ...@@ -90,7 +76,7 @@ class BookController extends Controller
90 { 76 {
91 $book = $this->entityRepo->getBySlug('book', $slug); 77 $book = $this->entityRepo->getBySlug('book', $slug);
92 $this->checkOwnablePermission('book-view', $book); 78 $this->checkOwnablePermission('book-view', $book);
93 - $bookChildren = $this->bookRepo->getChildren($book); 79 + $bookChildren = $this->entityRepo->getBookChildren($book);
94 Views::add($book); 80 Views::add($book);
95 $this->setPageTitle($book->getShortName()); 81 $this->setPageTitle($book->getShortName());
96 return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]); 82 return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]);
...@@ -123,7 +109,7 @@ class BookController extends Controller ...@@ -123,7 +109,7 @@ class BookController extends Controller
123 'name' => 'required|string|max:255', 109 'name' => 'required|string|max:255',
124 'description' => 'string|max:1000' 110 'description' => 'string|max:1000'
125 ]); 111 ]);
126 - $book = $this->bookRepo->updateFromInput($book, $request->all()); 112 + $book = $this->entityRepo->updateFromInput('book', $book, $request->all());
127 Activity::add($book, 'book_update', $book->id); 113 Activity::add($book, 'book_update', $book->id);
128 return redirect($book->getUrl()); 114 return redirect($book->getUrl());
129 } 115 }
...@@ -150,7 +136,7 @@ class BookController extends Controller ...@@ -150,7 +136,7 @@ class BookController extends Controller
150 { 136 {
151 $book = $this->entityRepo->getBySlug('book', $bookSlug); 137 $book = $this->entityRepo->getBySlug('book', $bookSlug);
152 $this->checkOwnablePermission('book-update', $book); 138 $this->checkOwnablePermission('book-update', $book);
153 - $bookChildren = $this->bookRepo->getChildren($book, true); 139 + $bookChildren = $this->entityRepo->getBookChildren($book, true);
154 $books = $this->entityRepo->getAll('book', false); 140 $books = $this->entityRepo->getAll('book', false);
155 $this->setPageTitle(trans('entities.books_sort_named', ['bookName'=>$book->getShortName()])); 141 $this->setPageTitle(trans('entities.books_sort_named', ['bookName'=>$book->getShortName()]));
156 return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]); 142 return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]);
...@@ -165,7 +151,7 @@ class BookController extends Controller ...@@ -165,7 +151,7 @@ class BookController extends Controller
165 public function getSortItem($bookSlug) 151 public function getSortItem($bookSlug)
166 { 152 {
167 $book = $this->entityRepo->getBySlug('book', $bookSlug); 153 $book = $this->entityRepo->getBySlug('book', $bookSlug);
168 - $bookChildren = $this->bookRepo->getChildren($book); 154 + $bookChildren = $this->entityRepo->getBookChildren($book);
169 return view('books/sort-box', ['book' => $book, 'bookChildren' => $bookChildren]); 155 return view('books/sort-box', ['book' => $book, 'bookChildren' => $bookChildren]);
170 } 156 }
171 157
...@@ -202,7 +188,7 @@ class BookController extends Controller ...@@ -202,7 +188,7 @@ class BookController extends Controller
202 188
203 // Update models only if there's a change in parent chain or ordering. 189 // Update models only if there's a change in parent chain or ordering.
204 if ($model->priority !== $priority || $model->book_id !== $bookId || ($isPage && $model->chapter_id !== $chapterId)) { 190 if ($model->priority !== $priority || $model->book_id !== $bookId || ($isPage && $model->chapter_id !== $chapterId)) {
205 - $isPage ? $this->pageRepo->changeBook($bookId, $model) : $this->chapterRepo->changeBook($bookId, $model); 191 + $this->entityRepo->changeBook($isPage?'page':'chapter', $bookId, $model);
206 $model->priority = $priority; 192 $model->priority = $priority;
207 if ($isPage) $model->chapter_id = $chapterId; 193 if ($isPage) $model->chapter_id = $chapterId;
208 $model->save(); 194 $model->save();
...@@ -222,7 +208,7 @@ class BookController extends Controller ...@@ -222,7 +208,7 @@ class BookController extends Controller
222 } 208 }
223 209
224 // Update permissions on changed models 210 // Update permissions on changed models
225 - $this->bookRepo->buildJointPermissions($updatedModels); 211 + $this->entityRepo->buildJointPermissions($updatedModels);
226 212
227 return redirect($book->getUrl()); 213 return redirect($book->getUrl());
228 } 214 }
...@@ -237,8 +223,7 @@ class BookController extends Controller ...@@ -237,8 +223,7 @@ class BookController extends Controller
237 $book = $this->entityRepo->getBySlug('book', $bookSlug); 223 $book = $this->entityRepo->getBySlug('book', $bookSlug);
238 $this->checkOwnablePermission('book-delete', $book); 224 $this->checkOwnablePermission('book-delete', $book);
239 Activity::addMessage('book_delete', 0, $book->name); 225 Activity::addMessage('book_delete', 0, $book->name);
240 - Activity::removeEntity($book); 226 + $this->entityRepo->destroyBook($book);
241 - $this->bookRepo->destroy($book);
242 return redirect('/books'); 227 return redirect('/books');
243 } 228 }
244 229
...@@ -269,7 +254,7 @@ class BookController extends Controller ...@@ -269,7 +254,7 @@ class BookController extends Controller
269 { 254 {
270 $book = $this->entityRepo->getBySlug('book', $bookSlug); 255 $book = $this->entityRepo->getBySlug('book', $bookSlug);
271 $this->checkOwnablePermission('restrictions-manage', $book); 256 $this->checkOwnablePermission('restrictions-manage', $book);
272 - $this->bookRepo->updateEntityPermissionsFromRequest($request, $book); 257 + $this->entityRepo->updateEntityPermissionsFromRequest($request, $book);
273 session()->flash('success', trans('entities.books_permissions_updated')); 258 session()->flash('success', trans('entities.books_permissions_updated'));
274 return redirect($book->getUrl()); 259 return redirect($book->getUrl());
275 } 260 }
......
...@@ -4,32 +4,23 @@ use Activity; ...@@ -4,32 +4,23 @@ use Activity;
4 use BookStack\Repos\EntityRepo; 4 use BookStack\Repos\EntityRepo;
5 use BookStack\Repos\UserRepo; 5 use BookStack\Repos\UserRepo;
6 use Illuminate\Http\Request; 6 use Illuminate\Http\Request;
7 -use BookStack\Repos\BookRepo;
8 -use BookStack\Repos\ChapterRepo;
9 use Illuminate\Http\Response; 7 use Illuminate\Http\Response;
10 use Views; 8 use Views;
11 9
12 class ChapterController extends Controller 10 class ChapterController extends Controller
13 { 11 {
14 12
15 - protected $bookRepo;
16 - protected $chapterRepo;
17 protected $userRepo; 13 protected $userRepo;
18 protected $entityRepo; 14 protected $entityRepo;
19 15
20 /** 16 /**
21 * ChapterController constructor. 17 * ChapterController constructor.
22 * @param EntityRepo $entityRepo 18 * @param EntityRepo $entityRepo
23 - * @param BookRepo $bookRepo
24 - * @param ChapterRepo $chapterRepo
25 * @param UserRepo $userRepo 19 * @param UserRepo $userRepo
26 */ 20 */
27 - public function __construct(EntityRepo $entityRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo, UserRepo $userRepo) 21 + public function __construct(EntityRepo $entityRepo, UserRepo $userRepo)
28 { 22 {
29 $this->entityRepo = $entityRepo; 23 $this->entityRepo = $entityRepo;
30 - // TODO - Remove below
31 - $this->bookRepo = $bookRepo;
32 - $this->chapterRepo = $chapterRepo;
33 $this->userRepo = $userRepo; 24 $this->userRepo = $userRepo;
34 parent::__construct(); 25 parent::__construct();
35 } 26 }
...@@ -63,8 +54,8 @@ class ChapterController extends Controller ...@@ -63,8 +54,8 @@ class ChapterController extends Controller
63 $this->checkOwnablePermission('chapter-create', $book); 54 $this->checkOwnablePermission('chapter-create', $book);
64 55
65 $input = $request->all(); 56 $input = $request->all();
66 - $input['priority'] = $this->bookRepo->getNewPriority($book); 57 + $input['priority'] = $this->entityRepo->getNewBookPriority($book);
67 - $chapter = $this->chapterRepo->createFromInput($input, $book); 58 + $chapter = $this->entityRepo->createFromInput('chapter', $input, $book);
68 Activity::add($chapter, 'chapter_create', $book->id); 59 Activity::add($chapter, 'chapter_create', $book->id);
69 return redirect($chapter->getUrl()); 60 return redirect($chapter->getUrl());
70 } 61 }
...@@ -79,10 +70,10 @@ class ChapterController extends Controller ...@@ -79,10 +70,10 @@ class ChapterController extends Controller
79 { 70 {
80 $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); 71 $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
81 $this->checkOwnablePermission('chapter-view', $chapter); 72 $this->checkOwnablePermission('chapter-view', $chapter);
82 - $sidebarTree = $this->bookRepo->getChildren($chapter->book); 73 + $sidebarTree = $this->entityRepo->getBookChildren($chapter->book);
83 Views::add($chapter); 74 Views::add($chapter);
84 $this->setPageTitle($chapter->getShortName()); 75 $this->setPageTitle($chapter->getShortName());
85 - $pages = $this->chapterRepo->getChildren($chapter); 76 + $pages = $this->entityRepo->getChapterChildren($chapter);
86 return view('chapters/show', [ 77 return view('chapters/show', [
87 'book' => $chapter->book, 78 'book' => $chapter->book,
88 'chapter' => $chapter, 79 'chapter' => $chapter,
...@@ -153,7 +144,7 @@ class ChapterController extends Controller ...@@ -153,7 +144,7 @@ class ChapterController extends Controller
153 $book = $chapter->book; 144 $book = $chapter->book;
154 $this->checkOwnablePermission('chapter-delete', $chapter); 145 $this->checkOwnablePermission('chapter-delete', $chapter);
155 Activity::addMessage('chapter_delete', $book->id, $chapter->name); 146 Activity::addMessage('chapter_delete', $book->id, $chapter->name);
156 - $this->chapterRepo->destroy($chapter); 147 + $this->entityRepo->destroyChapter($chapter);
157 return redirect($book->getUrl()); 148 return redirect($book->getUrl());
158 } 149 }
159 150
...@@ -206,7 +197,7 @@ class ChapterController extends Controller ...@@ -206,7 +197,7 @@ class ChapterController extends Controller
206 return redirect()->back(); 197 return redirect()->back();
207 } 198 }
208 199
209 - $this->chapterRepo->changeBook($parent->id, $chapter, true); 200 + $this->entityRepo->changeBook('chapter', $parent->id, $chapter, true);
210 Activity::add($chapter, 'chapter_move', $chapter->book->id); 201 Activity::add($chapter, 'chapter_move', $chapter->book->id);
211 session()->flash('success', trans('entities.chapter_move_success', ['bookName' => $parent->name])); 202 session()->flash('success', trans('entities.chapter_move_success', ['bookName' => $parent->name]));
212 203
...@@ -241,7 +232,7 @@ class ChapterController extends Controller ...@@ -241,7 +232,7 @@ class ChapterController extends Controller
241 { 232 {
242 $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); 233 $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
243 $this->checkOwnablePermission('restrictions-manage', $chapter); 234 $this->checkOwnablePermission('restrictions-manage', $chapter);
244 - $this->chapterRepo->updateEntityPermissionsFromRequest($request, $chapter); 235 + $this->entityRepo->updateEntityPermissionsFromRequest($request, $chapter);
245 session()->flash('success', trans('entities.chapters_permissions_success')); 236 session()->flash('success', trans('entities.chapters_permissions_success'));
246 return redirect($chapter->getUrl()); 237 return redirect($chapter->getUrl());
247 } 238 }
......
1 <?php namespace BookStack\Http\Controllers; 1 <?php namespace BookStack\Http\Controllers;
2 2
3 use BookStack\Exceptions\ImageUploadException; 3 use BookStack\Exceptions\ImageUploadException;
4 +use BookStack\Repos\EntityRepo;
4 use BookStack\Repos\ImageRepo; 5 use BookStack\Repos\ImageRepo;
5 use Illuminate\Filesystem\Filesystem as File; 6 use Illuminate\Filesystem\Filesystem as File;
6 use Illuminate\Http\Request; 7 use Illuminate\Http\Request;
...@@ -150,12 +151,12 @@ class ImageController extends Controller ...@@ -150,12 +151,12 @@ class ImageController extends Controller
150 151
151 /** 152 /**
152 * Deletes an image and all thumbnail/image files 153 * Deletes an image and all thumbnail/image files
153 - * @param PageRepo $pageRepo 154 + * @param EntityRepo $entityRepo
154 * @param Request $request 155 * @param Request $request
155 * @param int $id 156 * @param int $id
156 * @return \Illuminate\Http\JsonResponse 157 * @return \Illuminate\Http\JsonResponse
157 */ 158 */
158 - public function destroy(PageRepo $pageRepo, Request $request, $id) 159 + public function destroy(EntityRepo $entityRepo, Request $request, $id)
159 { 160 {
160 $image = $this->imageRepo->getById($id); 161 $image = $this->imageRepo->getById($id);
161 $this->checkOwnablePermission('image-delete', $image); 162 $this->checkOwnablePermission('image-delete', $image);
...@@ -163,7 +164,7 @@ class ImageController extends Controller ...@@ -163,7 +164,7 @@ class ImageController extends Controller
163 // Check if this image is used on any pages 164 // Check if this image is used on any pages
164 $isForced = ($request->has('force') && ($request->get('force') === 'true') || $request->get('force') === true); 165 $isForced = ($request->has('force') && ($request->get('force') === 'true') || $request->get('force') === true);
165 if (!$isForced) { 166 if (!$isForced) {
166 - $pageSearch = $pageRepo->searchForImage($image->url); 167 + $pageSearch = $entityRepo->searchForImage($image->url);
167 if ($pageSearch !== false) { 168 if ($pageSearch !== false) {
168 return response()->json($pageSearch, 400); 169 return response()->json($pageSearch, 400);
169 } 170 }
......
...@@ -7,9 +7,6 @@ use BookStack\Repos\UserRepo; ...@@ -7,9 +7,6 @@ use BookStack\Repos\UserRepo;
7 use BookStack\Services\ExportService; 7 use BookStack\Services\ExportService;
8 use Carbon\Carbon; 8 use Carbon\Carbon;
9 use Illuminate\Http\Request; 9 use Illuminate\Http\Request;
10 -use BookStack\Repos\BookRepo;
11 -use BookStack\Repos\ChapterRepo;
12 -use BookStack\Repos\PageRepo;
13 use Illuminate\Http\Response; 10 use Illuminate\Http\Response;
14 use Views; 11 use Views;
15 use GatherContent\Htmldiff\Htmldiff; 12 use GatherContent\Htmldiff\Htmldiff;
...@@ -18,28 +15,18 @@ class PageController extends Controller ...@@ -18,28 +15,18 @@ class PageController extends Controller
18 { 15 {
19 16
20 protected $entityRepo; 17 protected $entityRepo;
21 - protected $pageRepo;
22 - protected $bookRepo;
23 - protected $chapterRepo;
24 protected $exportService; 18 protected $exportService;
25 protected $userRepo; 19 protected $userRepo;
26 20
27 /** 21 /**
28 * PageController constructor. 22 * PageController constructor.
29 * @param EntityRepo $entityRepo 23 * @param EntityRepo $entityRepo
30 - * @param PageRepo $pageRepo
31 - * @param BookRepo $bookRepo
32 - * @param ChapterRepo $chapterRepo
33 * @param ExportService $exportService 24 * @param ExportService $exportService
34 * @param UserRepo $userRepo 25 * @param UserRepo $userRepo
35 */ 26 */
36 - public function __construct(EntityRepo $entityRepo, PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo, ExportService $exportService, UserRepo $userRepo) 27 + public function __construct(EntityRepo $entityRepo, ExportService $exportService, UserRepo $userRepo)
37 { 28 {
38 $this->entityRepo = $entityRepo; 29 $this->entityRepo = $entityRepo;
39 - // TODO - remove below;
40 - $this->pageRepo = $pageRepo;
41 - $this->bookRepo = $bookRepo;
42 - $this->chapterRepo = $chapterRepo;
43 $this->exportService = $exportService; 30 $this->exportService = $exportService;
44 $this->userRepo = $userRepo; 31 $this->userRepo = $userRepo;
45 parent::__construct(); 32 parent::__construct();
...@@ -61,7 +48,7 @@ class PageController extends Controller ...@@ -61,7 +48,7 @@ class PageController extends Controller
61 48
62 // Redirect to draft edit screen if signed in 49 // Redirect to draft edit screen if signed in
63 if ($this->signedIn) { 50 if ($this->signedIn) {
64 - $draft = $this->pageRepo->getDraftPage($book, $chapter); 51 + $draft = $this->entityRepo->getDraftPage($book, $chapter);
65 return redirect($draft->getUrl()); 52 return redirect($draft->getUrl());
66 } 53 }
67 54
...@@ -89,8 +76,8 @@ class PageController extends Controller ...@@ -89,8 +76,8 @@ class PageController extends Controller
89 $parent = $chapter ? $chapter : $book; 76 $parent = $chapter ? $chapter : $book;
90 $this->checkOwnablePermission('page-create', $parent); 77 $this->checkOwnablePermission('page-create', $parent);
91 78
92 - $page = $this->pageRepo->getDraftPage($book, $chapter); 79 + $page = $this->entityRepo->getDraftPage($book, $chapter);
93 - $this->pageRepo->publishDraft($page, [ 80 + $this->entityRepo->publishPageDraft($page, [
94 'name' => $request->get('name'), 81 'name' => $request->get('name'),
95 'html' => '' 82 'html' => ''
96 ]); 83 ]);
...@@ -141,12 +128,12 @@ class PageController extends Controller ...@@ -141,12 +128,12 @@ class PageController extends Controller
141 $this->checkOwnablePermission('page-create', $parent); 128 $this->checkOwnablePermission('page-create', $parent);
142 129
143 if ($parent->isA('chapter')) { 130 if ($parent->isA('chapter')) {
144 - $input['priority'] = $this->chapterRepo->getNewPriority($parent); 131 + $input['priority'] = $this->entityRepo->getNewChapterPriority($parent);
145 } else { 132 } else {
146 - $input['priority'] = $this->bookRepo->getNewPriority($parent); 133 + $input['priority'] = $this->entityRepo->getNewBookPriority($parent);
147 } 134 }
148 135
149 - $page = $this->pageRepo->publishDraft($draftPage, $input); 136 + $page = $this->entityRepo->publishPageDraft($draftPage, $input);
150 137
151 Activity::add($page, 'page_create', $book->id); 138 Activity::add($page, 'page_create', $book->id);
152 return redirect($page->getUrl()); 139 return redirect($page->getUrl());
...@@ -164,15 +151,15 @@ class PageController extends Controller ...@@ -164,15 +151,15 @@ class PageController extends Controller
164 try { 151 try {
165 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); 152 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
166 } catch (NotFoundException $e) { 153 } catch (NotFoundException $e) {
167 - $page = $this->pageRepo->findPageUsingOldSlug($pageSlug, $bookSlug); 154 + $page = $this->entityRepo->getPageByOldSlug($pageSlug, $bookSlug);
168 if ($page === null) abort(404); 155 if ($page === null) abort(404);
169 return redirect($page->getUrl()); 156 return redirect($page->getUrl());
170 } 157 }
171 158
172 $this->checkOwnablePermission('page-view', $page); 159 $this->checkOwnablePermission('page-view', $page);
173 160
174 - $sidebarTree = $this->bookRepo->getChildren($page->book); 161 + $sidebarTree = $this->entityRepo->getBookChildren($page->book);
175 - $pageNav = $this->pageRepo->getPageNav($page); 162 + $pageNav = $this->entityRepo->getPageNav($page);
176 163
177 Views::add($page); 164 Views::add($page);
178 $this->setPageTitle($page->getShortName()); 165 $this->setPageTitle($page->getShortName());
...@@ -206,18 +193,18 @@ class PageController extends Controller ...@@ -206,18 +193,18 @@ class PageController extends Controller
206 193
207 // Check for active editing 194 // Check for active editing
208 $warnings = []; 195 $warnings = [];
209 - if ($this->pageRepo->isPageEditingActive($page, 60)) { 196 + if ($this->entityRepo->isPageEditingActive($page, 60)) {
210 - $warnings[] = $this->pageRepo->getPageEditingActiveMessage($page, 60); 197 + $warnings[] = $this->entityRepo->getPageEditingActiveMessage($page, 60);
211 } 198 }
212 199
213 // Check for a current draft version for this user 200 // Check for a current draft version for this user
214 - if ($this->pageRepo->hasUserGotPageDraft($page, $this->currentUser->id)) { 201 + if ($this->entityRepo->hasUserGotPageDraft($page, $this->currentUser->id)) {
215 - $draft = $this->pageRepo->getUserPageDraft($page, $this->currentUser->id); 202 + $draft = $this->entityRepo->getUserPageDraft($page, $this->currentUser->id);
216 $page->name = $draft->name; 203 $page->name = $draft->name;
217 $page->html = $draft->html; 204 $page->html = $draft->html;
218 $page->markdown = $draft->markdown; 205 $page->markdown = $draft->markdown;
219 $page->isDraft = true; 206 $page->isDraft = true;
220 - $warnings [] = $this->pageRepo->getUserPageDraftMessage($draft); 207 + $warnings [] = $this->entityRepo->getUserPageDraftMessage($draft);
221 } 208 }
222 209
223 if (count($warnings) > 0) session()->flash('warning', implode("\n", $warnings)); 210 if (count($warnings) > 0) session()->flash('warning', implode("\n", $warnings));
...@@ -245,7 +232,7 @@ class PageController extends Controller ...@@ -245,7 +232,7 @@ class PageController extends Controller
245 ]); 232 ]);
246 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); 233 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
247 $this->checkOwnablePermission('page-update', $page); 234 $this->checkOwnablePermission('page-update', $page);
248 - $this->pageRepo->updatePage($page, $page->book->id, $request->all()); 235 + $this->entityRepo->updatePage($page, $page->book->id, $request->all());
249 Activity::add($page, 'page_update', $page->book->id); 236 Activity::add($page, 'page_update', $page->book->id);
250 return redirect($page->getUrl()); 237 return redirect($page->getUrl());
251 } 238 }
...@@ -268,11 +255,7 @@ class PageController extends Controller ...@@ -268,11 +255,7 @@ class PageController extends Controller
268 ], 500); 255 ], 500);
269 } 256 }
270 257
271 - if ($page->draft) { 258 + $draft = $this->entityRepo->updatePageDraft($page, $request->only(['name', 'html', 'markdown']));
272 - $draft = $this->pageRepo->updateDraftPage($page, $request->only(['name', 'html', 'markdown']));
273 - } else {
274 - $draft = $this->pageRepo->saveUpdateDraft($page, $request->only(['name', 'html', 'markdown']));
275 - }
276 259
277 $updateTime = $draft->updated_at->timestamp; 260 $updateTime = $draft->updated_at->timestamp;
278 $utcUpdateTimestamp = $updateTime + Carbon::createFromTimestamp(0)->offset; 261 $utcUpdateTimestamp = $updateTime + Carbon::createFromTimestamp(0)->offset;
...@@ -339,7 +322,7 @@ class PageController extends Controller ...@@ -339,7 +322,7 @@ class PageController extends Controller
339 $this->checkOwnablePermission('page-delete', $page); 322 $this->checkOwnablePermission('page-delete', $page);
340 Activity::addMessage('page_delete', $book->id, $page->name); 323 Activity::addMessage('page_delete', $book->id, $page->name);
341 session()->flash('success', trans('entities.pages_delete_success')); 324 session()->flash('success', trans('entities.pages_delete_success'));
342 - $this->pageRepo->destroy($page); 325 + $this->entityRepo->destroyPage($page);
343 return redirect($book->getUrl()); 326 return redirect($book->getUrl());
344 } 327 }
345 328
...@@ -356,7 +339,7 @@ class PageController extends Controller ...@@ -356,7 +339,7 @@ class PageController extends Controller
356 $book = $page->book; 339 $book = $page->book;
357 $this->checkOwnablePermission('page-update', $page); 340 $this->checkOwnablePermission('page-update', $page);
358 session()->flash('success', trans('entities.pages_delete_draft_success')); 341 session()->flash('success', trans('entities.pages_delete_draft_success'));
359 - $this->pageRepo->destroy($page); 342 + $this->entityRepo->destroyPage($page);
360 return redirect($book->getUrl()); 343 return redirect($book->getUrl());
361 } 344 }
362 345
...@@ -383,7 +366,7 @@ class PageController extends Controller ...@@ -383,7 +366,7 @@ class PageController extends Controller
383 public function showRevision($bookSlug, $pageSlug, $revisionId) 366 public function showRevision($bookSlug, $pageSlug, $revisionId)
384 { 367 {
385 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); 368 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
386 - $revision = $this->pageRepo->getRevisionById($revisionId); 369 + $revision = $this->entityRepo->getById('page_revision', $revisionId, false);
387 370
388 $page->fill($revision->toArray()); 371 $page->fill($revision->toArray());
389 $this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()])); 372 $this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()]));
...@@ -404,7 +387,7 @@ class PageController extends Controller ...@@ -404,7 +387,7 @@ class PageController extends Controller
404 public function showRevisionChanges($bookSlug, $pageSlug, $revisionId) 387 public function showRevisionChanges($bookSlug, $pageSlug, $revisionId)
405 { 388 {
406 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); 389 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
407 - $revision = $this->pageRepo->getRevisionById($revisionId); 390 + $revision = $this->entityRepo->getById('page_revision', $revisionId);
408 391
409 $prev = $revision->getPrevious(); 392 $prev = $revision->getPrevious();
410 $prevContent = ($prev === null) ? '' : $prev->html; 393 $prevContent = ($prev === null) ? '' : $prev->html;
...@@ -431,7 +414,7 @@ class PageController extends Controller ...@@ -431,7 +414,7 @@ class PageController extends Controller
431 { 414 {
432 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); 415 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
433 $this->checkOwnablePermission('page-update', $page); 416 $this->checkOwnablePermission('page-update', $page);
434 - $page = $this->pageRepo->restoreRevision($page, $page->book, $revisionId); 417 + $page = $this->entityRepo->restorePageRevision($page, $page->book, $revisionId);
435 Activity::add($page, 'page_restore', $page->book->id); 418 Activity::add($page, 'page_restore', $page->book->id);
436 return redirect($page->getUrl()); 419 return redirect($page->getUrl());
437 } 420 }
...@@ -491,7 +474,7 @@ class PageController extends Controller ...@@ -491,7 +474,7 @@ class PageController extends Controller
491 */ 474 */
492 public function showRecentlyCreated() 475 public function showRecentlyCreated()
493 { 476 {
494 - $pages = $this->pageRepo->getRecentlyCreatedPaginated(20)->setPath(baseUrl('/pages/recently-created')); 477 + $pages = $this->entityRepo->getRecentlyCreatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-created'));
495 return view('pages/detailed-listing', [ 478 return view('pages/detailed-listing', [
496 'title' => trans('entities.recently_created_pages'), 479 'title' => trans('entities.recently_created_pages'),
497 'pages' => $pages 480 'pages' => $pages
...@@ -504,7 +487,7 @@ class PageController extends Controller ...@@ -504,7 +487,7 @@ class PageController extends Controller
504 */ 487 */
505 public function showRecentlyUpdated() 488 public function showRecentlyUpdated()
506 { 489 {
507 - $pages = $this->pageRepo->getRecentlyUpdatedPaginated(20)->setPath(baseUrl('/pages/recently-updated')); 490 + $pages = $this->entityRepo->getRecentlyUpdatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-updated'));
508 return view('pages/detailed-listing', [ 491 return view('pages/detailed-listing', [
509 'title' => trans('entities.recently_updated_pages'), 492 'title' => trans('entities.recently_updated_pages'),
510 'pages' => $pages 493 'pages' => $pages
...@@ -575,7 +558,7 @@ class PageController extends Controller ...@@ -575,7 +558,7 @@ class PageController extends Controller
575 return redirect()->back(); 558 return redirect()->back();
576 } 559 }
577 560
578 - $this->pageRepo->changePageParent($page, $parent); 561 + $this->entityRepo->changePageParent($page, $parent);
579 Activity::add($page, 'page_move', $page->book->id); 562 Activity::add($page, 'page_move', $page->book->id);
580 session()->flash('success', trans('entities.pages_move_success', ['parentName' => $parent->name])); 563 session()->flash('success', trans('entities.pages_move_success', ['parentName' => $parent->name]));
581 564
...@@ -593,7 +576,7 @@ class PageController extends Controller ...@@ -593,7 +576,7 @@ class PageController extends Controller
593 { 576 {
594 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); 577 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
595 $this->checkOwnablePermission('restrictions-manage', $page); 578 $this->checkOwnablePermission('restrictions-manage', $page);
596 - $this->pageRepo->updateEntityPermissionsFromRequest($request, $page); 579 + $this->entityRepo->updateEntityPermissionsFromRequest($request, $page);
597 session()->flash('success', trans('entities.pages_permissions_success')); 580 session()->flash('success', trans('entities.pages_permissions_success'));
598 return redirect($page->getUrl()); 581 return redirect($page->getUrl());
599 } 582 }
......
1 -<?php namespace BookStack\Repos;
2 -
3 -use BookStack\Book;
4 -
5 -class BookRepo extends EntityRepo
6 -{
7 - protected $pageRepo;
8 - protected $chapterRepo;
9 -
10 - /**
11 - * BookRepo constructor.
12 - * @param PageRepo $pageRepo
13 - * @param ChapterRepo $chapterRepo
14 - */
15 - public function __construct(PageRepo $pageRepo, ChapterRepo $chapterRepo)
16 - {
17 - $this->pageRepo = $pageRepo;
18 - $this->chapterRepo = $chapterRepo;
19 - parent::__construct();
20 - }
21 -
22 - /**
23 - * Get a new book instance from request input.
24 - * @param array $input
25 - * @return Book
26 - */
27 - public function createFromInput($input)
28 - {
29 - $book = $this->book->newInstance($input);
30 - $book->slug = $this->findSuitableSlug('book', $book->name);
31 - $book->created_by = user()->id;
32 - $book->updated_by = user()->id;
33 - $book->save();
34 - $this->permissionService->buildJointPermissionsForEntity($book);
35 - return $book;
36 - }
37 -
38 - /**
39 - * Update the given book from user input.
40 - * @param Book $book
41 - * @param $input
42 - * @return Book
43 - */
44 - public function updateFromInput(Book $book, $input)
45 - {
46 - if ($book->name !== $input['name']) {
47 - $book->slug = $this->findSuitableSlug('book', $input['name'], $book->id);
48 - }
49 - $book->fill($input);
50 - $book->updated_by = user()->id;
51 - $book->save();
52 - $this->permissionService->buildJointPermissionsForEntity($book);
53 - return $book;
54 - }
55 -
56 - /**
57 - * Destroy the given book.
58 - * @param Book $book
59 - * @throws \Exception
60 - */
61 - public function destroy(Book $book)
62 - {
63 - foreach ($book->pages as $page) {
64 - $this->pageRepo->destroy($page);
65 - }
66 - foreach ($book->chapters as $chapter) {
67 - $this->chapterRepo->destroy($chapter);
68 - }
69 - $book->views()->delete();
70 - $book->permissions()->delete();
71 - $this->permissionService->deleteJointPermissionsForEntity($book);
72 - $book->delete();
73 - }
74 -
75 - /**
76 - * Get the next child element priority.
77 - * @param Book $book
78 - * @return int
79 - */
80 - public function getNewPriority($book)
81 - {
82 - $lastElem = $this->getChildren($book)->pop();
83 - return $lastElem ? $lastElem->priority + 1 : 0;
84 - }
85 -
86 - /**
87 - * Get all child objects of a book.
88 - * Returns a sorted collection of Pages and Chapters.
89 - * Loads the book slug onto child elements to prevent access database access for getting the slug.
90 - * @param Book $book
91 - * @param bool $filterDrafts
92 - * @return mixed
93 - */
94 - public function getChildren(Book $book, $filterDrafts = false)
95 - {
96 - $q = $this->permissionService->bookChildrenQuery($book->id, $filterDrafts);
97 - $entities = [];
98 - $parents = [];
99 - $tree = [];
100 -
101 - foreach ($q as $index => $rawEntity) {
102 - if ($rawEntity->entity_type === 'Bookstack\\Page') {
103 - $entities[$index] = $this->page->newFromBuilder($rawEntity);
104 - } else if ($rawEntity->entity_type === 'Bookstack\\Chapter') {
105 - $entities[$index] = $this->chapter->newFromBuilder($rawEntity);
106 - $key = $entities[$index]->entity_type . ':' . $entities[$index]->id;
107 - $parents[$key] = $entities[$index];
108 - $parents[$key]->setAttribute('pages', collect());
109 - }
110 - if ($entities[$index]->chapter_id === 0) $tree[] = $entities[$index];
111 - $entities[$index]->book = $book;
112 - }
113 -
114 - foreach ($entities as $entity) {
115 - if ($entity->chapter_id === 0) continue;
116 - $parentKey = 'Bookstack\\Chapter:' . $entity->chapter_id;
117 - $chapter = $parents[$parentKey];
118 - $chapter->pages->push($entity);
119 - }
120 -
121 - return collect($tree);
122 - }
123 -
124 -}
...\ No newline at end of file ...\ No newline at end of file
1 -<?php namespace BookStack\Repos;
2 -
3 -
4 -use Activity;
5 -use BookStack\Book;
6 -use BookStack\Exceptions\NotFoundException;
7 -use Illuminate\Support\Str;
8 -use BookStack\Chapter;
9 -
10 -class ChapterRepo extends EntityRepo
11 -{
12 - protected $pageRepo;
13 -
14 - /**
15 - * ChapterRepo constructor.
16 - * @param $pageRepo
17 - */
18 - public function __construct(PageRepo $pageRepo)
19 - {
20 - $this->pageRepo = $pageRepo;
21 - parent::__construct();
22 - }
23 -
24 - /**
25 - * Get the child items for a chapter
26 - * @param Chapter $chapter
27 - */
28 - public function getChildren(Chapter $chapter)
29 - {
30 - $pages = $this->permissionService->enforcePageRestrictions($chapter->pages())->get();
31 - // Sort items with drafts first then by priority.
32 - return $pages->sortBy(function ($child, $key) {
33 - $score = $child->priority;
34 - if ($child->draft) $score -= 100;
35 - return $score;
36 - });
37 - }
38 -
39 - /**
40 - * Create a new chapter from request input.
41 - * @param $input
42 - * @param Book $book
43 - * @return Chapter
44 - */
45 - public function createFromInput($input, Book $book)
46 - {
47 - $chapter = $this->chapter->newInstance($input);
48 - $chapter->slug = $this->findSuitableSlug('chapter', $chapter->name, false, $book->id);
49 - $chapter->created_by = user()->id;
50 - $chapter->updated_by = user()->id;
51 - $chapter = $book->chapters()->save($chapter);
52 - $this->permissionService->buildJointPermissionsForEntity($chapter);
53 - return $chapter;
54 - }
55 -
56 - /**
57 - * Destroy a chapter and its relations by providing its slug.
58 - * @param Chapter $chapter
59 - */
60 - public function destroy(Chapter $chapter)
61 - {
62 - if (count($chapter->pages) > 0) {
63 - foreach ($chapter->pages as $page) {
64 - $page->chapter_id = 0;
65 - $page->save();
66 - }
67 - }
68 - Activity::removeEntity($chapter);
69 - $chapter->views()->delete();
70 - $chapter->permissions()->delete();
71 - $this->permissionService->deleteJointPermissionsForEntity($chapter);
72 - $chapter->delete();
73 - }
74 -
75 -
76 - /**
77 - * Get a new priority value for a new page to be added
78 - * to the given chapter.
79 - * @param Chapter $chapter
80 - * @return int
81 - */
82 - public function getNewPriority(Chapter $chapter)
83 - {
84 - $lastPage = $chapter->pages->last();
85 - return $lastPage !== null ? $lastPage->priority + 1 : 0;
86 - }
87 -
88 - /**
89 - * Changes the book relation of this chapter.
90 - * @param $bookId
91 - * @param Chapter $chapter
92 - * @param bool $rebuildPermissions
93 - * @return Chapter
94 - */
95 - public function changeBook($bookId, Chapter $chapter, $rebuildPermissions = false)
96 - {
97 - $chapter->book_id = $bookId;
98 - // Update related activity
99 - foreach ($chapter->activity as $activity) {
100 - $activity->book_id = $bookId;
101 - $activity->save();
102 - }
103 - $chapter->slug = $this->findSuitableSlug('chapter', $chapter->name, $chapter->id, $bookId);
104 - $chapter->save();
105 - // Update all child pages
106 - foreach ($chapter->pages as $page) {
107 - $this->pageRepo->changeBook($bookId, $page);
108 - }
109 -
110 - // Update permissions if applicable
111 - if ($rebuildPermissions) {
112 - $chapter->load('book');
113 - $this->permissionService->buildJointPermissionsForEntity($chapter->book);
114 - }
115 -
116 - return $chapter;
117 - }
118 -
119 -}
...\ No newline at end of file ...\ No newline at end of file
...@@ -5,8 +5,13 @@ use BookStack\Chapter; ...@@ -5,8 +5,13 @@ use BookStack\Chapter;
5 use BookStack\Entity; 5 use BookStack\Entity;
6 use BookStack\Exceptions\NotFoundException; 6 use BookStack\Exceptions\NotFoundException;
7 use BookStack\Page; 7 use BookStack\Page;
8 +use BookStack\PageRevision;
9 +use BookStack\Services\AttachmentService;
8 use BookStack\Services\PermissionService; 10 use BookStack\Services\PermissionService;
9 use BookStack\Services\ViewService; 11 use BookStack\Services\ViewService;
12 +use Carbon\Carbon;
13 +use DOMDocument;
14 +use DOMXPath;
10 use Illuminate\Support\Collection; 15 use Illuminate\Support\Collection;
11 16
12 class EntityRepo 17 class EntityRepo
...@@ -28,6 +33,11 @@ class EntityRepo ...@@ -28,6 +33,11 @@ class EntityRepo
28 public $page; 33 public $page;
29 34
30 /** 35 /**
36 + * @var PageRevision
37 + */
38 + protected $pageRevision;
39 +
40 + /**
31 * Base entity instances keyed by type 41 * Base entity instances keyed by type
32 * @var []Entity 42 * @var []Entity
33 */ 43 */
...@@ -44,6 +54,11 @@ class EntityRepo ...@@ -44,6 +54,11 @@ class EntityRepo
44 protected $viewService; 54 protected $viewService;
45 55
46 /** 56 /**
57 + * @var TagRepo
58 + */
59 + protected $tagRepo;
60 +
61 + /**
47 * Acceptable operators to be used in a query 62 * Acceptable operators to be used in a query
48 * @var array 63 * @var array
49 */ 64 */
...@@ -51,20 +66,32 @@ class EntityRepo ...@@ -51,20 +66,32 @@ class EntityRepo
51 66
52 /** 67 /**
53 * EntityService constructor. 68 * EntityService constructor.
69 + * @param Book $book
70 + * @param Chapter $chapter
71 + * @param Page $page
72 + * @param PageRevision $pageRevision
73 + * @param ViewService $viewService
74 + * @param PermissionService $permissionService
75 + * @param TagRepo $tagRepo
54 */ 76 */
55 - public function __construct() 77 + public function __construct(
78 + Book $book, Chapter $chapter, Page $page, PageRevision $pageRevision,
79 + ViewService $viewService, PermissionService $permissionService, TagRepo $tagRepo
80 + )
56 { 81 {
57 - // TODO - Redo this to come via injection 82 + $this->book = $book;
58 - $this->book = app(Book::class); 83 + $this->chapter = $chapter;
59 - $this->chapter = app(Chapter::class); 84 + $this->page = $page;
60 - $this->page = app(Page::class); 85 + $this->pageRevision = $pageRevision;
61 $this->entities = [ 86 $this->entities = [
62 'page' => $this->page, 87 'page' => $this->page,
63 'chapter' => $this->chapter, 88 'chapter' => $this->chapter,
64 - 'book' => $this->book 89 + 'book' => $this->book,
90 + 'page_revision' => $this->pageRevision
65 ]; 91 ];
66 - $this->viewService = app(ViewService::class); 92 + $this->viewService = $viewService;
67 - $this->permissionService = app(PermissionService::class); 93 + $this->permissionService = $permissionService;
94 + $this->tagRepo = $tagRepo;
68 } 95 }
69 96
70 /** 97 /**
...@@ -139,6 +166,27 @@ class EntityRepo ...@@ -139,6 +166,27 @@ class EntityRepo
139 return $entity; 166 return $entity;
140 } 167 }
141 168
169 +
170 + /**
171 + * Search through page revisions and retrieve the last page in the
172 + * current book that has a slug equal to the one given.
173 + * @param string $pageSlug
174 + * @param string $bookSlug
175 + * @return null|Page
176 + */
177 + public function getPageByOldSlug($pageSlug, $bookSlug)
178 + {
179 + $revision = $this->pageRevision->where('slug', '=', $pageSlug)
180 + ->whereHas('page', function ($query) {
181 + $this->permissionService->enforceEntityRestrictions('page', $query);
182 + })
183 + ->where('type', '=', 'version')
184 + ->where('book_slug', '=', $bookSlug)
185 + ->orderBy('created_at', 'desc')
186 + ->with('page')->first();
187 + return $revision !== null ? $revision->page : null;
188 + }
189 +
142 /** 190 /**
143 * Get all entities of a type limited by count unless count if false. 191 * Get all entities of a type limited by count unless count if false.
144 * @param string $type 192 * @param string $type
...@@ -213,6 +261,28 @@ class EntityRepo ...@@ -213,6 +261,28 @@ class EntityRepo
213 } 261 }
214 262
215 /** 263 /**
264 + * Get the latest pages added to the system with pagination.
265 + * @param string $type
266 + * @param int $count
267 + * @return mixed
268 + */
269 + public function getRecentlyCreatedPaginated($type, $count = 20)
270 + {
271 + return $this->entityQuery($type)->orderBy('created_at', 'desc')->paginate($count);
272 + }
273 +
274 + /**
275 + * Get the latest pages added to the system with pagination.
276 + * @param string $type
277 + * @param int $count
278 + * @return mixed
279 + */
280 + public function getRecentlyUpdatedPaginated($type, $count = 20)
281 + {
282 + return $this->entityQuery($type)->orderBy('updated_at', 'desc')->paginate($count);
283 + }
284 +
285 + /**
216 * Get the most popular entities base on all views. 286 * Get the most popular entities base on all views.
217 * @param string|bool $type 287 * @param string|bool $type
218 * @param int $count 288 * @param int $count
...@@ -238,10 +308,68 @@ class EntityRepo ...@@ -238,10 +308,68 @@ class EntityRepo
238 ->skip($count * $page)->take($count)->get(); 308 ->skip($count * $page)->take($count)->get();
239 } 309 }
240 310
311 + /**
312 + * Get all child objects of a book.
313 + * Returns a sorted collection of Pages and Chapters.
314 + * Loads the book slug onto child elements to prevent access database access for getting the slug.
315 + * @param Book $book
316 + * @param bool $filterDrafts
317 + * @return mixed
318 + */
319 + public function getBookChildren(Book $book, $filterDrafts = false)
320 + {
321 + $q = $this->permissionService->bookChildrenQuery($book->id, $filterDrafts);
322 + $entities = [];
323 + $parents = [];
324 + $tree = [];
325 +
326 + foreach ($q as $index => $rawEntity) {
327 + if ($rawEntity->entity_type === 'Bookstack\\Page') {
328 + $entities[$index] = $this->page->newFromBuilder($rawEntity);
329 + } else if ($rawEntity->entity_type === 'Bookstack\\Chapter') {
330 + $entities[$index] = $this->chapter->newFromBuilder($rawEntity);
331 + $key = $entities[$index]->entity_type . ':' . $entities[$index]->id;
332 + $parents[$key] = $entities[$index];
333 + $parents[$key]->setAttribute('pages', collect());
334 + }
335 + if ($entities[$index]->chapter_id === 0) $tree[] = $entities[$index];
336 + $entities[$index]->book = $book;
337 + }
338 +
339 + foreach ($entities as $entity) {
340 + if ($entity->chapter_id === 0) continue;
341 + $parentKey = 'Bookstack\\Chapter:' . $entity->chapter_id;
342 + $chapter = $parents[$parentKey];
343 + $chapter->pages->push($entity);
344 + }
345 +
346 + return collect($tree);
347 + }
348 +
349 + /**
350 + * Get the child items for a chapter sorted by priority but
351 + * with draft items floated to the top.
352 + * @param Chapter $chapter
353 + */
354 + public function getChapterChildren(Chapter $chapter)
355 + {
356 + return $this->permissionService->enforceEntityRestrictions('page', $chapter->pages())
357 + ->orderBy('draft', 'DESC')->orderBy('priority', 'ASC')->get();
358 + }
359 +
360 + /**
361 + * Search entities of a type via a given query.
362 + * @param string $type
363 + * @param string $term
364 + * @param array $whereTerms
365 + * @param int $count
366 + * @param array $paginationAppends
367 + * @return mixed
368 + */
241 public function getBySearch($type, $term, $whereTerms = [], $count = 20, $paginationAppends = []) 369 public function getBySearch($type, $term, $whereTerms = [], $count = 20, $paginationAppends = [])
242 { 370 {
243 $terms = $this->prepareSearchTerms($term); 371 $terms = $this->prepareSearchTerms($term);
244 - $q = $this->permissionService->enforceChapterRestrictions($this->getEntity($type)->fullTextSearchQuery($terms, $whereTerms)); 372 + $q = $this->permissionService->enforceEntityRestrictions($type, $this->getEntity($type)->fullTextSearchQuery($terms, $whereTerms));
245 $q = $this->addAdvancedSearchQueries($q, $term); 373 $q = $this->addAdvancedSearchQueries($q, $term);
246 $entities = $q->paginate($count)->appends($paginationAppends); 374 $entities = $q->paginate($count)->appends($paginationAppends);
247 $words = join('|', explode(' ', preg_quote(trim($term), '/'))); 375 $words = join('|', explode(' ', preg_quote(trim($term), '/')));
...@@ -281,6 +409,28 @@ class EntityRepo ...@@ -281,6 +409,28 @@ class EntityRepo
281 } 409 }
282 410
283 /** 411 /**
412 + * Get the next sequential priority for a new child element in the given book.
413 + * @param Book $book
414 + * @return int
415 + */
416 + public function getNewBookPriority(Book $book)
417 + {
418 + $lastElem = $this->getBookChildren($book)->pop();
419 + return $lastElem ? $lastElem->priority + 1 : 0;
420 + }
421 +
422 + /**
423 + * Get a new priority for a new page to be added to the given chapter.
424 + * @param Chapter $chapter
425 + * @return int
426 + */
427 + public function getNewChapterPriority(Chapter $chapter)
428 + {
429 + $lastPage = $chapter->pages('DESC')->first();
430 + return $lastPage !== null ? $lastPage->priority + 1 : 0;
431 + }
432 +
433 + /**
284 * Find a suitable slug for an entity. 434 * Find a suitable slug for an entity.
285 * @param string $type 435 * @param string $type
286 * @param string $name 436 * @param string $name
...@@ -438,6 +588,81 @@ class EntityRepo ...@@ -438,6 +588,81 @@ class EntityRepo
438 } 588 }
439 589
440 /** 590 /**
591 + * Create a new entity from request input.
592 + * Used for books and chapters.
593 + * @param string $type
594 + * @param array $input
595 + * @param bool|Book $book
596 + * @return Entity
597 + */
598 + public function createFromInput($type, $input = [], $book = false)
599 + {
600 + $isChapter = strtolower($type) === 'chapter';
601 + $entity = $this->getEntity($type)->newInstance($input);
602 + $entity->slug = $this->findSuitableSlug($type, $entity->name, false, $isChapter ? $book->id : false);
603 + $entity->created_by = user()->id;
604 + $entity->updated_by = user()->id;
605 + $isChapter ? $book->chapters()->save($entity) : $entity->save();
606 + $this->permissionService->buildJointPermissionsForEntity($entity);
607 + return $entity;
608 + }
609 +
610 + /**
611 + * Update entity details from request input.
612 + * Use for books and chapters
613 + * @param string $type
614 + * @param Entity $entityModel
615 + * @param array $input
616 + * @return Entity
617 + */
618 + public function updateFromInput($type, Entity $entityModel, $input = [])
619 + {
620 + if ($entityModel->name !== $input['name']) {
621 + $entityModel->slug = $this->findSuitableSlug($type, $input['name'], $entityModel->id);
622 + }
623 + $entityModel->fill($input);
624 + $entityModel->updated_by = user()->id;
625 + $entityModel->save();
626 + $this->permissionService->buildJointPermissionsForEntity($entityModel);
627 + return $entityModel;
628 + }
629 +
630 + /**
631 + * Change the book that an entity belongs to.
632 + * @param string $type
633 + * @param integer $newBookId
634 + * @param Entity $entity
635 + * @param bool $rebuildPermissions
636 + * @return Entity
637 + */
638 + public function changeBook($type, $newBookId, Entity $entity, $rebuildPermissions = false)
639 + {
640 + $entity->book_id = $newBookId;
641 + // Update related activity
642 + foreach ($entity->activity as $activity) {
643 + $activity->book_id = $newBookId;
644 + $activity->save();
645 + }
646 + $entity->slug = $this->findSuitableSlug($type, $entity->name, $entity->id, $newBookId);
647 + $entity->save();
648 +
649 + // Update all child pages if a chapter
650 + if (strtolower($type) === 'chapter') {
651 + foreach ($entity->pages as $page) {
652 + $this->changeBook('page', $newBookId, $page, false);
653 + }
654 + }
655 +
656 + // Update permissions if applicable
657 + if ($rebuildPermissions) {
658 + $entity->load('book');
659 + $this->permissionService->buildJointPermissionsForEntity($entity->book);
660 + }
661 +
662 + return $entity;
663 + }
664 +
665 + /**
441 * Alias method to update the book jointPermissions in the PermissionService. 666 * Alias method to update the book jointPermissions in the PermissionService.
442 * @param Collection $collection collection on entities 667 * @param Collection $collection collection on entities
443 */ 668 */
...@@ -459,6 +684,463 @@ class EntityRepo ...@@ -459,6 +684,463 @@ class EntityRepo
459 return $slug; 684 return $slug;
460 } 685 }
461 686
687 + /**
688 + * Publish a draft page to make it a normal page.
689 + * Sets the slug and updates the content.
690 + * @param Page $draftPage
691 + * @param array $input
692 + * @return Page
693 + */
694 + public function publishPageDraft(Page $draftPage, array $input)
695 + {
696 + $draftPage->fill($input);
697 +
698 + // Save page tags if present
699 + if (isset($input['tags'])) {
700 + $this->tagRepo->saveTagsToEntity($draftPage, $input['tags']);
701 + }
702 +
703 + $draftPage->slug = $this->findSuitableSlug('page', $draftPage->name, false, $draftPage->book->id);
704 + $draftPage->html = $this->formatHtml($input['html']);
705 + $draftPage->text = strip_tags($draftPage->html);
706 + $draftPage->draft = false;
707 +
708 + $draftPage->save();
709 + $this->savePageRevision($draftPage, trans('entities.pages_initial_revision'));
710 +
711 + return $draftPage;
712 + }
713 +
714 + /**
715 + * Saves a page revision into the system.
716 + * @param Page $page
717 + * @param null|string $summary
718 + * @return PageRevision
719 + */
720 + public function savePageRevision(Page $page, $summary = null)
721 + {
722 + $revision = $this->pageRevision->newInstance($page->toArray());
723 + if (setting('app-editor') !== 'markdown') $revision->markdown = '';
724 + $revision->page_id = $page->id;
725 + $revision->slug = $page->slug;
726 + $revision->book_slug = $page->book->slug;
727 + $revision->created_by = user()->id;
728 + $revision->created_at = $page->updated_at;
729 + $revision->type = 'version';
730 + $revision->summary = $summary;
731 + $revision->save();
732 +
733 + // Clear old revisions
734 + if ($this->pageRevision->where('page_id', '=', $page->id)->count() > 50) {
735 + $this->pageRevision->where('page_id', '=', $page->id)
736 + ->orderBy('created_at', 'desc')->skip(50)->take(5)->delete();
737 + }
738 +
739 + return $revision;
740 + }
741 +
742 + /**
743 + * Formats a page's html to be tagged correctly
744 + * within the system.
745 + * @param string $htmlText
746 + * @return string
747 + */
748 + protected function formatHtml($htmlText)
749 + {
750 + if ($htmlText == '') return $htmlText;
751 + libxml_use_internal_errors(true);
752 + $doc = new DOMDocument();
753 + $doc->loadHTML(mb_convert_encoding($htmlText, 'HTML-ENTITIES', 'UTF-8'));
754 +
755 + $container = $doc->documentElement;
756 + $body = $container->childNodes->item(0);
757 + $childNodes = $body->childNodes;
758 +
759 + // Ensure no duplicate ids are used
760 + $idArray = [];
761 +
762 + foreach ($childNodes as $index => $childNode) {
763 + /** @var \DOMElement $childNode */
764 + if (get_class($childNode) !== 'DOMElement') continue;
765 +
766 + // Overwrite id if not a BookStack custom id
767 + if ($childNode->hasAttribute('id')) {
768 + $id = $childNode->getAttribute('id');
769 + if (strpos($id, 'bkmrk') === 0 && array_search($id, $idArray) === false) {
770 + $idArray[] = $id;
771 + continue;
772 + };
773 + }
774 +
775 + // Create an unique id for the element
776 + // Uses the content as a basis to ensure output is the same every time
777 + // the same content is passed through.
778 + $contentId = 'bkmrk-' . substr(strtolower(preg_replace('/\s+/', '-', trim($childNode->nodeValue))), 0, 20);
779 + $newId = urlencode($contentId);
780 + $loopIndex = 0;
781 + while (in_array($newId, $idArray)) {
782 + $newId = urlencode($contentId . '-' . $loopIndex);
783 + $loopIndex++;
784 + }
785 +
786 + $childNode->setAttribute('id', $newId);
787 + $idArray[] = $newId;
788 + }
789 +
790 + // Generate inner html as a string
791 + $html = '';
792 + foreach ($childNodes as $childNode) {
793 + $html .= $doc->saveHTML($childNode);
794 + }
795 +
796 + return $html;
797 + }
798 +
799 + /**
800 + * Get a new draft page instance.
801 + * @param Book $book
802 + * @param Chapter|bool $chapter
803 + * @return Page
804 + */
805 + public function getDraftPage(Book $book, $chapter = false)
806 + {
807 + $page = $this->page->newInstance();
808 + $page->name = trans('entities.pages_initial_name');
809 + $page->created_by = user()->id;
810 + $page->updated_by = user()->id;
811 + $page->draft = true;
812 +
813 + if ($chapter) $page->chapter_id = $chapter->id;
814 +
815 + $book->pages()->save($page);
816 + $this->permissionService->buildJointPermissionsForEntity($page);
817 + return $page;
818 + }
819 +
820 + /**
821 + * Search for image usage within page content.
822 + * @param $imageString
823 + * @return mixed
824 + */
825 + public function searchForImage($imageString)
826 + {
827 + $pages = $this->entityQuery('page')->where('html', 'like', '%' . $imageString . '%')->get();
828 + foreach ($pages as $page) {
829 + $page->url = $page->getUrl();
830 + $page->html = '';
831 + $page->text = '';
832 + }
833 + return count($pages) > 0 ? $pages : false;
834 + }
835 +
836 + /**
837 + * Parse the headers on the page to get a navigation menu
838 + * @param Page $page
839 + * @return array
840 + */
841 + public function getPageNav(Page $page)
842 + {
843 + if ($page->html == '') return null;
844 + libxml_use_internal_errors(true);
845 + $doc = new DOMDocument();
846 + $doc->loadHTML(mb_convert_encoding($page->html, 'HTML-ENTITIES', 'UTF-8'));
847 + $xPath = new DOMXPath($doc);
848 + $headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6");
849 +
850 + if (is_null($headers)) return null;
851 +
852 + $tree = [];
853 + foreach ($headers as $header) {
854 + $text = $header->nodeValue;
855 + $tree[] = [
856 + 'nodeName' => strtolower($header->nodeName),
857 + 'level' => intval(str_replace('h', '', $header->nodeName)),
858 + 'link' => '#' . $header->getAttribute('id'),
859 + 'text' => strlen($text) > 30 ? substr($text, 0, 27) . '...' : $text
860 + ];
861 + }
862 + return $tree;
863 + }
864 +
865 + /**
866 + * Updates a page with any fillable data and saves it into the database.
867 + * @param Page $page
868 + * @param int $book_id
869 + * @param array $input
870 + * @return Page
871 + */
872 + public function updatePage(Page $page, $book_id, $input)
873 + {
874 + // Hold the old details to compare later
875 + $oldHtml = $page->html;
876 + $oldName = $page->name;
877 +
878 + // Prevent slug being updated if no name change
879 + if ($page->name !== $input['name']) {
880 + $page->slug = $this->findSuitableSlug('page', $input['name'], $page->id, $book_id);
881 + }
882 +
883 + // Save page tags if present
884 + if (isset($input['tags'])) {
885 + $this->tagRepo->saveTagsToEntity($page, $input['tags']);
886 + }
887 +
888 + // Update with new details
889 + $userId = user()->id;
890 + $page->fill($input);
891 + $page->html = $this->formatHtml($input['html']);
892 + $page->text = strip_tags($page->html);
893 + if (setting('app-editor') !== 'markdown') $page->markdown = '';
894 + $page->updated_by = $userId;
895 + $page->save();
896 +
897 + // Remove all update drafts for this user & page.
898 + $this->userUpdatePageDraftsQuery($page, $userId)->delete();
899 +
900 + // Save a revision after updating
901 + if ($oldHtml !== $input['html'] || $oldName !== $input['name'] || $input['summary'] !== null) {
902 + $this->savePageRevision($page, $input['summary']);
903 + }
904 +
905 + return $page;
906 + }
907 +
908 + /**
909 + * The base query for getting user update drafts.
910 + * @param Page $page
911 + * @param $userId
912 + * @return mixed
913 + */
914 + protected function userUpdatePageDraftsQuery(Page $page, $userId)
915 + {
916 + return $this->pageRevision->where('created_by', '=', $userId)
917 + ->where('type', 'update_draft')
918 + ->where('page_id', '=', $page->id)
919 + ->orderBy('created_at', 'desc');
920 + }
921 +
922 + /**
923 + * Checks whether a user has a draft version of a particular page or not.
924 + * @param Page $page
925 + * @param $userId
926 + * @return bool
927 + */
928 + public function hasUserGotPageDraft(Page $page, $userId)
929 + {
930 + return $this->userUpdatePageDraftsQuery($page, $userId)->count() > 0;
931 + }
932 +
933 + /**
934 + * Get the latest updated draft revision for a particular page and user.
935 + * @param Page $page
936 + * @param $userId
937 + * @return mixed
938 + */
939 + public function getUserPageDraft(Page $page, $userId)
940 + {
941 + return $this->userUpdatePageDraftsQuery($page, $userId)->first();
942 + }
943 +
944 + /**
945 + * Get the notification message that informs the user that they are editing a draft page.
946 + * @param PageRevision $draft
947 + * @return string
948 + */
949 + public function getUserPageDraftMessage(PageRevision $draft)
950 + {
951 + $message = trans('entities.pages_editing_draft_notification', ['timeDiff' => $draft->updated_at->diffForHumans()]);
952 + if ($draft->page->updated_at->timestamp <= $draft->updated_at->timestamp) return $message;
953 + return $message . "\n" . trans('entities.pages_draft_edited_notification');
954 + }
955 +
956 + /**
957 + * Check if a page is being actively editing.
958 + * Checks for edits since last page updated.
959 + * Passing in a minuted range will check for edits
960 + * within the last x minutes.
961 + * @param Page $page
962 + * @param null $minRange
963 + * @return bool
964 + */
965 + public function isPageEditingActive(Page $page, $minRange = null)
966 + {
967 + $draftSearch = $this->activePageEditingQuery($page, $minRange);
968 + return $draftSearch->count() > 0;
969 + }
970 +
971 + /**
972 + * A query to check for active update drafts on a particular page.
973 + * @param Page $page
974 + * @param null $minRange
975 + * @return mixed
976 + */
977 + protected function activePageEditingQuery(Page $page, $minRange = null)
978 + {
979 + $query = $this->pageRevision->where('type', '=', 'update_draft')
980 + ->where('page_id', '=', $page->id)
981 + ->where('updated_at', '>', $page->updated_at)
982 + ->where('created_by', '!=', user()->id)
983 + ->with('createdBy');
984 +
985 + if ($minRange !== null) {
986 + $query = $query->where('updated_at', '>=', Carbon::now()->subMinutes($minRange));
987 + }
988 +
989 + return $query;
990 + }
991 +
992 + /**
993 + * Restores a revision's content back into a page.
994 + * @param Page $page
995 + * @param Book $book
996 + * @param int $revisionId
997 + * @return Page
998 + */
999 + public function restorePageRevision(Page $page, Book $book, $revisionId)
1000 + {
1001 + $this->savePageRevision($page);
1002 + $revision = $this->getById('page_revision', $revisionId);
1003 + $page->fill($revision->toArray());
1004 + $page->slug = $this->findSuitableSlug('page', $page->name, $page->id, $book->id);
1005 + $page->text = strip_tags($page->html);
1006 + $page->updated_by = user()->id;
1007 + $page->save();
1008 + return $page;
1009 + }
1010 +
1011 +
1012 + /**
1013 + * Save a page update draft.
1014 + * @param Page $page
1015 + * @param array $data
1016 + * @return PageRevision|Page
1017 + */
1018 + public function updatePageDraft(Page $page, $data = [])
1019 + {
1020 + // If the page itself is a draft simply update that
1021 + if ($page->draft) {
1022 + $page->fill($data);
1023 + if (isset($data['html'])) {
1024 + $page->text = strip_tags($data['html']);
1025 + }
1026 + $page->save();
1027 + return $page;
1028 + }
1029 +
1030 + // Otherwise save the data to a revision
1031 + $userId = user()->id;
1032 + $drafts = $this->userUpdatePageDraftsQuery($page, $userId)->get();
1033 +
1034 + if ($drafts->count() > 0) {
1035 + $draft = $drafts->first();
1036 + } else {
1037 + $draft = $this->pageRevision->newInstance();
1038 + $draft->page_id = $page->id;
1039 + $draft->slug = $page->slug;
1040 + $draft->book_slug = $page->book->slug;
1041 + $draft->created_by = $userId;
1042 + $draft->type = 'update_draft';
1043 + }
1044 +
1045 + $draft->fill($data);
1046 + if (setting('app-editor') !== 'markdown') $draft->markdown = '';
1047 +
1048 + $draft->save();
1049 + return $draft;
1050 + }
1051 +
1052 + /**
1053 + * Get a notification message concerning the editing activity on a particular page.
1054 + * @param Page $page
1055 + * @param null $minRange
1056 + * @return string
1057 + */
1058 + public function getPageEditingActiveMessage(Page $page, $minRange = null)
1059 + {
1060 + $pageDraftEdits = $this->activePageEditingQuery($page, $minRange)->get();
1061 +
1062 + $userMessage = $pageDraftEdits->count() > 1 ? trans('entities.pages_draft_edit_active.start_a', ['count' => $pageDraftEdits->count()]): trans('entities.pages_draft_edit_active.start_b', ['userName' => $pageDraftEdits->first()->createdBy->name]);
1063 + $timeMessage = $minRange === null ? trans('entities.pages_draft_edit_active.time_a') : trans('entities.pages_draft_edit_active.time_b', ['minCount'=>$minRange]);
1064 + return trans('entities.pages_draft_edit_active.message', ['start' => $userMessage, 'time' => $timeMessage]);
1065 + }
1066 +
1067 + /**
1068 + * Change the page's parent to the given entity.
1069 + * @param Page $page
1070 + * @param Entity $parent
1071 + */
1072 + public function changePageParent(Page $page, Entity $parent)
1073 + {
1074 + $book = $parent->isA('book') ? $parent : $parent->book;
1075 + $page->chapter_id = $parent->isA('chapter') ? $parent->id : 0;
1076 + $page->save();
1077 + if ($page->book->id !== $book->id) {
1078 + $page = $this->changeBook('page', $book->id, $page);
1079 + }
1080 + $page->load('book');
1081 + $this->permissionService->buildJointPermissionsForEntity($book);
1082 + }
1083 +
1084 + /**
1085 + * Destroy the provided book and all its child entities.
1086 + * @param Book $book
1087 + */
1088 + public function destroyBook(Book $book)
1089 + {
1090 + foreach ($book->pages as $page) {
1091 + $this->destroyPage($page);
1092 + }
1093 + foreach ($book->chapters as $chapter) {
1094 + $this->destroyChapter($chapter);
1095 + }
1096 + \Activity::removeEntity($book);
1097 + $book->views()->delete();
1098 + $book->permissions()->delete();
1099 + $this->permissionService->deleteJointPermissionsForEntity($book);
1100 + $book->delete();
1101 + }
1102 +
1103 + /**
1104 + * Destroy a chapter and its relations.
1105 + * @param Chapter $chapter
1106 + */
1107 + public function destroyChapter(Chapter $chapter)
1108 + {
1109 + if (count($chapter->pages) > 0) {
1110 + foreach ($chapter->pages as $page) {
1111 + $page->chapter_id = 0;
1112 + $page->save();
1113 + }
1114 + }
1115 + \Activity::removeEntity($chapter);
1116 + $chapter->views()->delete();
1117 + $chapter->permissions()->delete();
1118 + $this->permissionService->deleteJointPermissionsForEntity($chapter);
1119 + $chapter->delete();
1120 + }
1121 +
1122 + /**
1123 + * Destroy a given page along with its dependencies.
1124 + * @param Page $page
1125 + */
1126 + public function destroyPage(Page $page)
1127 + {
1128 + \Activity::removeEntity($page);
1129 + $page->views()->delete();
1130 + $page->tags()->delete();
1131 + $page->revisions()->delete();
1132 + $page->permissions()->delete();
1133 + $this->permissionService->deleteJointPermissionsForEntity($page);
1134 +
1135 + // Delete Attached Files
1136 + $attachmentService = app(AttachmentService::class);
1137 + foreach ($page->attachments as $attachment) {
1138 + $attachmentService->deleteFile($attachment);
1139 + }
1140 +
1141 + $page->delete();
1142 + }
1143 +
462 } 1144 }
463 1145
464 1146
......
1 -<?php namespace BookStack\Repos;
2 -
3 -use Activity;
4 -use BookStack\Book;
5 -use BookStack\Chapter;
6 -use BookStack\Entity;
7 -use BookStack\Exceptions\NotFoundException;
8 -use BookStack\Services\AttachmentService;
9 -use Carbon\Carbon;
10 -use DOMDocument;
11 -use DOMXPath;
12 -use Illuminate\Support\Str;
13 -use BookStack\Page;
14 -use BookStack\PageRevision;
15 -
16 -class PageRepo extends EntityRepo
17 -{
18 -
19 - protected $pageRevision;
20 - protected $tagRepo;
21 -
22 - /**
23 - * PageRepo constructor.
24 - * @param PageRevision $pageRevision
25 - * @param TagRepo $tagRepo
26 - */
27 - public function __construct(PageRevision $pageRevision, TagRepo $tagRepo)
28 - {
29 - $this->pageRevision = $pageRevision;
30 - $this->tagRepo = $tagRepo;
31 - parent::__construct();
32 - }
33 -
34 - /**
35 - * Base query for getting pages, Takes restrictions into account.
36 - * @param bool $allowDrafts
37 - * @return mixed
38 - */
39 - private function pageQuery($allowDrafts = false)
40 - {
41 - $query = $this->permissionService->enforcePageRestrictions($this->page, 'view');
42 - if (!$allowDrafts) {
43 - $query = $query->where('draft', '=', false);
44 - }
45 - return $query;
46 - }
47 -
48 - /**
49 - * Search through page revisions and retrieve
50 - * the last page in the current book that
51 - * has a slug equal to the one given.
52 - * @param $pageSlug
53 - * @param $bookSlug
54 - * @return null | Page
55 - */
56 - public function findPageUsingOldSlug($pageSlug, $bookSlug)
57 - {
58 - $revision = $this->pageRevision->where('slug', '=', $pageSlug)
59 - ->whereHas('page', function ($query) {
60 - $this->permissionService->enforcePageRestrictions($query);
61 - })
62 - ->where('type', '=', 'version')
63 - ->where('book_slug', '=', $bookSlug)->orderBy('created_at', 'desc')
64 - ->with('page')->first();
65 - return $revision !== null ? $revision->page : null;
66 - }
67 -
68 - /**
69 - * Count the pages with a particular slug within a book.
70 - * @param $slug
71 - * @param $bookId
72 - * @return mixed
73 - */
74 - public function countBySlug($slug, $bookId)
75 - {
76 - return $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId)->count();
77 - }
78 -
79 - /**
80 - * Publish a draft page to make it a normal page.
81 - * Sets the slug and updates the content.
82 - * @param Page $draftPage
83 - * @param array $input
84 - * @return Page
85 - */
86 - public function publishDraft(Page $draftPage, array $input)
87 - {
88 - $draftPage->fill($input);
89 -
90 - // Save page tags if present
91 - if (isset($input['tags'])) {
92 - $this->tagRepo->saveTagsToEntity($draftPage, $input['tags']);
93 - }
94 -
95 - $draftPage->slug = $this->findSuitableSlug('page', $draftPage->name, false, $draftPage->book->id);
96 - $draftPage->html = $this->formatHtml($input['html']);
97 - $draftPage->text = strip_tags($draftPage->html);
98 - $draftPage->draft = false;
99 -
100 - $draftPage->save();
101 - $this->saveRevision($draftPage, trans('entities.pages_initial_revision'));
102 -
103 - return $draftPage;
104 - }
105 -
106 - /**
107 - * Get a new draft page instance.
108 - * @param Book $book
109 - * @param Chapter|bool $chapter
110 - * @return Page
111 - */
112 - public function getDraftPage(Book $book, $chapter = false)
113 - {
114 - $page = $this->page->newInstance();
115 - $page->name = trans('entities.pages_initial_name');
116 - $page->created_by = user()->id;
117 - $page->updated_by = user()->id;
118 - $page->draft = true;
119 -
120 - if ($chapter) $page->chapter_id = $chapter->id;
121 -
122 - $book->pages()->save($page);
123 - $this->permissionService->buildJointPermissionsForEntity($page);
124 - return $page;
125 - }
126 -
127 - /**
128 - * Parse te headers on the page to get a navigation menu
129 - * @param Page $page
130 - * @return array
131 - */
132 - public function getPageNav(Page $page)
133 - {
134 - if ($page->html == '') return null;
135 - libxml_use_internal_errors(true);
136 - $doc = new DOMDocument();
137 - $doc->loadHTML(mb_convert_encoding($page->html, 'HTML-ENTITIES', 'UTF-8'));
138 - $xPath = new DOMXPath($doc);
139 - $headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6");
140 -
141 - if (is_null($headers)) return null;
142 -
143 - $tree = [];
144 - foreach ($headers as $header) {
145 - $text = $header->nodeValue;
146 - $tree[] = [
147 - 'nodeName' => strtolower($header->nodeName),
148 - 'level' => intval(str_replace('h', '', $header->nodeName)),
149 - 'link' => '#' . $header->getAttribute('id'),
150 - 'text' => strlen($text) > 30 ? substr($text, 0, 27) . '...' : $text
151 - ];
152 - }
153 - return $tree;
154 - }
155 -
156 - /**
157 - * Formats a page's html to be tagged correctly
158 - * within the system.
159 - * @param string $htmlText
160 - * @return string
161 - */
162 - protected function formatHtml($htmlText)
163 - {
164 - if ($htmlText == '') return $htmlText;
165 - libxml_use_internal_errors(true);
166 - $doc = new DOMDocument();
167 - $doc->loadHTML(mb_convert_encoding($htmlText, 'HTML-ENTITIES', 'UTF-8'));
168 -
169 - $container = $doc->documentElement;
170 - $body = $container->childNodes->item(0);
171 - $childNodes = $body->childNodes;
172 -
173 - // Ensure no duplicate ids are used
174 - $idArray = [];
175 -
176 - foreach ($childNodes as $index => $childNode) {
177 - /** @var \DOMElement $childNode */
178 - if (get_class($childNode) !== 'DOMElement') continue;
179 -
180 - // Overwrite id if not a BookStack custom id
181 - if ($childNode->hasAttribute('id')) {
182 - $id = $childNode->getAttribute('id');
183 - if (strpos($id, 'bkmrk') === 0 && array_search($id, $idArray) === false) {
184 - $idArray[] = $id;
185 - continue;
186 - };
187 - }
188 -
189 - // Create an unique id for the element
190 - // Uses the content as a basis to ensure output is the same every time
191 - // the same content is passed through.
192 - $contentId = 'bkmrk-' . substr(strtolower(preg_replace('/\s+/', '-', trim($childNode->nodeValue))), 0, 20);
193 - $newId = urlencode($contentId);
194 - $loopIndex = 0;
195 - while (in_array($newId, $idArray)) {
196 - $newId = urlencode($contentId . '-' . $loopIndex);
197 - $loopIndex++;
198 - }
199 -
200 - $childNode->setAttribute('id', $newId);
201 - $idArray[] = $newId;
202 - }
203 -
204 - // Generate inner html as a string
205 - $html = '';
206 - foreach ($childNodes as $childNode) {
207 - $html .= $doc->saveHTML($childNode);
208 - }
209 -
210 - return $html;
211 - }
212 -
213 -
214 - /**
215 - * Search for image usage.
216 - * @param $imageString
217 - * @return mixed
218 - */
219 - public function searchForImage($imageString)
220 - {
221 - $pages = $this->pageQuery()->where('html', 'like', '%' . $imageString . '%')->get();
222 - foreach ($pages as $page) {
223 - $page->url = $page->getUrl();
224 - $page->html = '';
225 - $page->text = '';
226 - }
227 - return count($pages) > 0 ? $pages : false;
228 - }
229 -
230 - /**
231 - * Updates a page with any fillable data and saves it into the database.
232 - * @param Page $page
233 - * @param int $book_id
234 - * @param string $input
235 - * @return Page
236 - */
237 - public function updatePage(Page $page, $book_id, $input)
238 - {
239 - // Hold the old details to compare later
240 - $oldHtml = $page->html;
241 - $oldName = $page->name;
242 -
243 - // Prevent slug being updated if no name change
244 - if ($page->name !== $input['name']) {
245 - $page->slug = $this->findSuitableSlug('page', $input['name'], $page->id, $book_id);
246 - }
247 -
248 - // Save page tags if present
249 - if (isset($input['tags'])) {
250 - $this->tagRepo->saveTagsToEntity($page, $input['tags']);
251 - }
252 -
253 - // Update with new details
254 - $userId = user()->id;
255 - $page->fill($input);
256 - $page->html = $this->formatHtml($input['html']);
257 - $page->text = strip_tags($page->html);
258 - if (setting('app-editor') !== 'markdown') $page->markdown = '';
259 - $page->updated_by = $userId;
260 - $page->save();
261 -
262 - // Remove all update drafts for this user & page.
263 - $this->userUpdateDraftsQuery($page, $userId)->delete();
264 -
265 - // Save a revision after updating
266 - if ($oldHtml !== $input['html'] || $oldName !== $input['name'] || $input['summary'] !== null) {
267 - $this->saveRevision($page, $input['summary']);
268 - }
269 -
270 - return $page;
271 - }
272 -
273 - /**
274 - * Restores a revision's content back into a page.
275 - * @param Page $page
276 - * @param Book $book
277 - * @param int $revisionId
278 - * @return Page
279 - */
280 - public function restoreRevision(Page $page, Book $book, $revisionId)
281 - {
282 - $this->saveRevision($page);
283 - $revision = $this->getRevisionById($revisionId);
284 - $page->fill($revision->toArray());
285 - $page->slug = $this->findSuitableSlug('page', $page->name, $page->id, $book->id);
286 - $page->text = strip_tags($page->html);
287 - $page->updated_by = user()->id;
288 - $page->save();
289 - return $page;
290 - }
291 -
292 - /**
293 - * Saves a page revision into the system.
294 - * @param Page $page
295 - * @param null|string $summary
296 - * @return $this
297 - */
298 - public function saveRevision(Page $page, $summary = null)
299 - {
300 - $revision = $this->pageRevision->newInstance($page->toArray());
301 - if (setting('app-editor') !== 'markdown') $revision->markdown = '';
302 - $revision->page_id = $page->id;
303 - $revision->slug = $page->slug;
304 - $revision->book_slug = $page->book->slug;
305 - $revision->created_by = user()->id;
306 - $revision->created_at = $page->updated_at;
307 - $revision->type = 'version';
308 - $revision->summary = $summary;
309 - $revision->save();
310 -
311 - // Clear old revisions
312 - if ($this->pageRevision->where('page_id', '=', $page->id)->count() > 50) {
313 - $this->pageRevision->where('page_id', '=', $page->id)
314 - ->orderBy('created_at', 'desc')->skip(50)->take(5)->delete();
315 - }
316 -
317 - return $revision;
318 - }
319 -
320 - /**
321 - * Save a page update draft.
322 - * @param Page $page
323 - * @param array $data
324 - * @return PageRevision
325 - */
326 - public function saveUpdateDraft(Page $page, $data = [])
327 - {
328 - $userId = user()->id;
329 - $drafts = $this->userUpdateDraftsQuery($page, $userId)->get();
330 -
331 - if ($drafts->count() > 0) {
332 - $draft = $drafts->first();
333 - } else {
334 - $draft = $this->pageRevision->newInstance();
335 - $draft->page_id = $page->id;
336 - $draft->slug = $page->slug;
337 - $draft->book_slug = $page->book->slug;
338 - $draft->created_by = $userId;
339 - $draft->type = 'update_draft';
340 - }
341 -
342 - $draft->fill($data);
343 - if (setting('app-editor') !== 'markdown') $draft->markdown = '';
344 -
345 - $draft->save();
346 - return $draft;
347 - }
348 -
349 - /**
350 - * Update a draft page.
351 - * @param Page $page
352 - * @param array $data
353 - * @return Page
354 - */
355 - public function updateDraftPage(Page $page, $data = [])
356 - {
357 - $page->fill($data);
358 -
359 - if (isset($data['html'])) {
360 - $page->text = strip_tags($data['html']);
361 - }
362 -
363 - $page->save();
364 - return $page;
365 - }
366 -
367 - /**
368 - * The base query for getting user update drafts.
369 - * @param Page $page
370 - * @param $userId
371 - * @return mixed
372 - */
373 - private function userUpdateDraftsQuery(Page $page, $userId)
374 - {
375 - return $this->pageRevision->where('created_by', '=', $userId)
376 - ->where('type', 'update_draft')
377 - ->where('page_id', '=', $page->id)
378 - ->orderBy('created_at', 'desc');
379 - }
380 -
381 - /**
382 - * Checks whether a user has a draft version of a particular page or not.
383 - * @param Page $page
384 - * @param $userId
385 - * @return bool
386 - */
387 - public function hasUserGotPageDraft(Page $page, $userId)
388 - {
389 - return $this->userUpdateDraftsQuery($page, $userId)->count() > 0;
390 - }
391 -
392 - /**
393 - * Get the latest updated draft revision for a particular page and user.
394 - * @param Page $page
395 - * @param $userId
396 - * @return mixed
397 - */
398 - public function getUserPageDraft(Page $page, $userId)
399 - {
400 - return $this->userUpdateDraftsQuery($page, $userId)->first();
401 - }
402 -
403 - /**
404 - * Get the notification message that informs the user that they are editing a draft page.
405 - * @param PageRevision $draft
406 - * @return string
407 - */
408 - public function getUserPageDraftMessage(PageRevision $draft)
409 - {
410 - $message = trans('entities.pages_editing_draft_notification', ['timeDiff' => $draft->updated_at->diffForHumans()]);
411 - if ($draft->page->updated_at->timestamp <= $draft->updated_at->timestamp) return $message;
412 - return $message . "\n" . trans('entities.pages_draft_edited_notification');
413 - }
414 -
415 - /**
416 - * Check if a page is being actively editing.
417 - * Checks for edits since last page updated.
418 - * Passing in a minuted range will check for edits
419 - * within the last x minutes.
420 - * @param Page $page
421 - * @param null $minRange
422 - * @return bool
423 - */
424 - public function isPageEditingActive(Page $page, $minRange = null)
425 - {
426 - $draftSearch = $this->activePageEditingQuery($page, $minRange);
427 - return $draftSearch->count() > 0;
428 - }
429 -
430 - /**
431 - * Get a notification message concerning the editing activity on
432 - * a particular page.
433 - * @param Page $page
434 - * @param null $minRange
435 - * @return string
436 - */
437 - public function getPageEditingActiveMessage(Page $page, $minRange = null)
438 - {
439 - $pageDraftEdits = $this->activePageEditingQuery($page, $minRange)->get();
440 -
441 - $userMessage = $pageDraftEdits->count() > 1 ? trans('entities.pages_draft_edit_active.start_a', ['count' => $pageDraftEdits->count()]): trans('entities.pages_draft_edit_active.start_b', ['userName' => $pageDraftEdits->first()->createdBy->name]);
442 - $timeMessage = $minRange === null ? trans('entities.pages_draft_edit_active.time_a') : trans('entities.pages_draft_edit_active.time_b', ['minCount'=>$minRange]);
443 - return trans('entities.pages_draft_edit_active.message', ['start' => $userMessage, 'time' => $timeMessage]);
444 - }
445 -
446 - /**
447 - * A query to check for active update drafts on a particular page.
448 - * @param Page $page
449 - * @param null $minRange
450 - * @return mixed
451 - */
452 - private function activePageEditingQuery(Page $page, $minRange = null)
453 - {
454 - $query = $this->pageRevision->where('type', '=', 'update_draft')
455 - ->where('page_id', '=', $page->id)
456 - ->where('updated_at', '>', $page->updated_at)
457 - ->where('created_by', '!=', user()->id)
458 - ->with('createdBy');
459 -
460 - if ($minRange !== null) {
461 - $query = $query->where('updated_at', '>=', Carbon::now()->subMinutes($minRange));
462 - }
463 -
464 - return $query;
465 - }
466 -
467 - /**
468 - * Gets a single revision via it's id.
469 - * @param $id
470 - * @return PageRevision
471 - */
472 - public function getRevisionById($id)
473 - {
474 - return $this->pageRevision->findOrFail($id);
475 - }
476 -
477 - /**
478 - * Changes the related book for the specified page.
479 - * Changes the book id of any relations to the page that store the book id.
480 - * @param int $bookId
481 - * @param Page $page
482 - * @return Page
483 - */
484 - public function changeBook($bookId, Page $page)
485 - {
486 - $page->book_id = $bookId;
487 - foreach ($page->activity as $activity) {
488 - $activity->book_id = $bookId;
489 - $activity->save();
490 - }
491 - $page->slug = $this->findSuitableSlug('page', $page->name, $page->id, $bookId);
492 - $page->save();
493 - return $page;
494 - }
495 -
496 -
497 - /**
498 - * Change the page's parent to the given entity.
499 - * @param Page $page
500 - * @param Entity $parent
501 - */
502 - public function changePageParent(Page $page, Entity $parent)
503 - {
504 - $book = $parent->isA('book') ? $parent : $parent->book;
505 - $page->chapter_id = $parent->isA('chapter') ? $parent->id : 0;
506 - $page->save();
507 - $page = $this->changeBook($book->id, $page);
508 - $page->load('book');
509 - $this->permissionService->buildJointPermissionsForEntity($book);
510 - }
511 -
512 - /**
513 - * Destroy a given page along with its dependencies.
514 - * @param $page
515 - */
516 - public function destroy(Page $page)
517 - {
518 - Activity::removeEntity($page);
519 - $page->views()->delete();
520 - $page->tags()->delete();
521 - $page->revisions()->delete();
522 - $page->permissions()->delete();
523 - $this->permissionService->deleteJointPermissionsForEntity($page);
524 -
525 - // Delete AttachedFiles
526 - $attachmentService = app(AttachmentService::class);
527 - foreach ($page->attachments as $attachment) {
528 - $attachmentService->deleteFile($attachment);
529 - }
530 -
531 - $page->delete();
532 - }
533 -
534 - /**
535 - * Get the latest pages added to the system.
536 - * @param $count
537 - * @return mixed
538 - */
539 - public function getRecentlyCreatedPaginated($count = 20)
540 - {
541 - return $this->pageQuery()->orderBy('created_at', 'desc')->paginate($count);
542 - }
543 -
544 - /**
545 - * Get the latest pages added to the system.
546 - * @param $count
547 - * @return mixed
548 - */
549 - public function getRecentlyUpdatedPaginated($count = 20)
550 - {
551 - return $this->pageQuery()->orderBy('updated_at', 'desc')->paginate($count);
552 - }
553 -
554 -}
...@@ -38,7 +38,7 @@ class TagRepo ...@@ -38,7 +38,7 @@ class TagRepo
38 { 38 {
39 $entityInstance = $this->entity->getEntityInstance($entityType); 39 $entityInstance = $this->entity->getEntityInstance($entityType);
40 $searchQuery = $entityInstance->where('id', '=', $entityId)->with('tags'); 40 $searchQuery = $entityInstance->where('id', '=', $entityId)->with('tags');
41 - $searchQuery = $this->permissionService->enforceEntityRestrictions($searchQuery, $action); 41 + $searchQuery = $this->permissionService->enforceEntityRestrictions($entityType, $searchQuery, $action);
42 return $searchQuery->first(); 42 return $searchQuery->first();
43 } 43 }
44 44
......
...@@ -517,42 +517,6 @@ ORDER BY draft desc, priority asc"; ...@@ -517,42 +517,6 @@ ORDER BY draft desc, priority asc";
517 } 517 }
518 518
519 /** 519 /**
520 - * Add restrictions for a page query
521 - * @param $query
522 - * @param string $action
523 - * @return mixed
524 - */
525 - public function enforcePageRestrictions($query, $action = 'view')
526 - {
527 - // TODO - remove this
528 - return $this->enforceEntityRestrictions('page', $query, $action);
529 - }
530 -
531 - /**
532 - * Add on permission restrictions to a chapter query.
533 - * @param $query
534 - * @param string $action
535 - * @return mixed
536 - */
537 - public function enforceChapterRestrictions($query, $action = 'view')
538 - {
539 - // TODO - remove this
540 - return $this->enforceEntityRestrictions('chapter', $query, $action);
541 - }
542 -
543 - /**
544 - * Add restrictions to a book query.
545 - * @param $query
546 - * @param string $action
547 - * @return mixed
548 - */
549 - public function enforceBookRestrictions($query, $action = 'view')
550 - {
551 - // TODO - remove this
552 - return $this->enforceEntityRestrictions('book', $query, $action);
553 - }
554 -
555 - /**
556 * Add restrictions for a generic entity 520 * Add restrictions for a generic entity
557 * @param string $entityType 521 * @param string $entityType
558 * @param Builder|Entity $query 522 * @param Builder|Entity $query
......
...@@ -168,7 +168,7 @@ class EntityTest extends TestCase ...@@ -168,7 +168,7 @@ class EntityTest extends TestCase
168 $entities = $this->createEntityChainBelongingToUser($creator, $updater); 168 $entities = $this->createEntityChainBelongingToUser($creator, $updater);
169 $this->actingAs($creator); 169 $this->actingAs($creator);
170 app('BookStack\Repos\UserRepo')->destroy($creator); 170 app('BookStack\Repos\UserRepo')->destroy($creator);
171 - app('BookStack\Repos\PageRepo')->saveRevision($entities['page']); 171 + app('BookStack\Repos\EntityRepo')->savePageRevision($entities['page']);
172 172
173 $this->checkEntitiesViewable($entities); 173 $this->checkEntitiesViewable($entities);
174 } 174 }
...@@ -181,7 +181,7 @@ class EntityTest extends TestCase ...@@ -181,7 +181,7 @@ class EntityTest extends TestCase
181 $entities = $this->createEntityChainBelongingToUser($creator, $updater); 181 $entities = $this->createEntityChainBelongingToUser($creator, $updater);
182 $this->actingAs($updater); 182 $this->actingAs($updater);
183 app('BookStack\Repos\UserRepo')->destroy($updater); 183 app('BookStack\Repos\UserRepo')->destroy($updater);
184 - app('BookStack\Repos\PageRepo')->saveRevision($entities['page']); 184 + app('BookStack\Repos\EntityRepo')->savePageRevision($entities['page']);
185 185
186 $this->checkEntitiesViewable($entities); 186 $this->checkEntitiesViewable($entities);
187 } 187 }
......
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
4 class PageDraftTest extends TestCase 4 class PageDraftTest extends TestCase
5 { 5 {
6 protected $page; 6 protected $page;
7 - protected $pageRepo; 7 + protected $entityRepo;
8 8
9 public function setUp() 9 public function setUp()
10 { 10 {
11 parent::setUp(); 11 parent::setUp();
12 $this->page = \BookStack\Page::first(); 12 $this->page = \BookStack\Page::first();
13 - $this->pageRepo = app('\BookStack\Repos\PageRepo'); 13 + $this->entityRepo = app('\BookStack\Repos\EntityRepo');
14 } 14 }
15 15
16 public function test_draft_content_shows_if_available() 16 public function test_draft_content_shows_if_available()
...@@ -20,7 +20,7 @@ class PageDraftTest extends TestCase ...@@ -20,7 +20,7 @@ class PageDraftTest extends TestCase
20 ->dontSeeInField('html', $addedContent); 20 ->dontSeeInField('html', $addedContent);
21 21
22 $newContent = $this->page->html . $addedContent; 22 $newContent = $this->page->html . $addedContent;
23 - $this->pageRepo->saveUpdateDraft($this->page, ['html' => $newContent]); 23 + $this->entityRepo->updatePageDraft($this->page, ['html' => $newContent]);
24 $this->asAdmin()->visit($this->page->getUrl() . '/edit') 24 $this->asAdmin()->visit($this->page->getUrl() . '/edit')
25 ->seeInField('html', $newContent); 25 ->seeInField('html', $newContent);
26 } 26 }
...@@ -33,7 +33,7 @@ class PageDraftTest extends TestCase ...@@ -33,7 +33,7 @@ class PageDraftTest extends TestCase
33 33
34 $newContent = $this->page->html . $addedContent; 34 $newContent = $this->page->html . $addedContent;
35 $newUser = $this->getEditor(); 35 $newUser = $this->getEditor();
36 - $this->pageRepo->saveUpdateDraft($this->page, ['html' => $newContent]); 36 + $this->entityRepo->updatePageDraft($this->page, ['html' => $newContent]);
37 $this->actingAs($newUser)->visit($this->page->getUrl() . '/edit') 37 $this->actingAs($newUser)->visit($this->page->getUrl() . '/edit')
38 ->dontSeeInField('html', $newContent); 38 ->dontSeeInField('html', $newContent);
39 } 39 }
...@@ -41,7 +41,7 @@ class PageDraftTest extends TestCase ...@@ -41,7 +41,7 @@ class PageDraftTest extends TestCase
41 public function test_alert_message_shows_if_editing_draft() 41 public function test_alert_message_shows_if_editing_draft()
42 { 42 {
43 $this->asAdmin(); 43 $this->asAdmin();
44 - $this->pageRepo->saveUpdateDraft($this->page, ['html' => 'test content']); 44 + $this->entityRepo->updatePageDraft($this->page, ['html' => 'test content']);
45 $this->asAdmin()->visit($this->page->getUrl() . '/edit') 45 $this->asAdmin()->visit($this->page->getUrl() . '/edit')
46 ->see('You are currently editing a draft'); 46 ->see('You are currently editing a draft');
47 } 47 }
...@@ -55,7 +55,7 @@ class PageDraftTest extends TestCase ...@@ -55,7 +55,7 @@ class PageDraftTest extends TestCase
55 55
56 $newContent = $this->page->html . $addedContent; 56 $newContent = $this->page->html . $addedContent;
57 $newUser = $this->getEditor(); 57 $newUser = $this->getEditor();
58 - $this->pageRepo->saveUpdateDraft($this->page, ['html' => $newContent]); 58 + $this->entityRepo->updatePageDraft($this->page, ['html' => $newContent]);
59 59
60 $this->actingAs($newUser) 60 $this->actingAs($newUser)
61 ->visit($this->page->getUrl() . '/edit') 61 ->visit($this->page->getUrl() . '/edit')
......
...@@ -13,8 +13,8 @@ class SortTest extends TestCase ...@@ -13,8 +13,8 @@ class SortTest extends TestCase
13 public function test_drafts_do_not_show_up() 13 public function test_drafts_do_not_show_up()
14 { 14 {
15 $this->asAdmin(); 15 $this->asAdmin();
16 - $pageRepo = app('\BookStack\Repos\PageRepo'); 16 + $entityRepo = app('\BookStack\Repos\EntityRepo');
17 - $draft = $pageRepo->getDraftPage($this->book); 17 + $draft = $entityRepo->getDraftPage($this->book);
18 18
19 $this->visit($this->book->getUrl()) 19 $this->visit($this->book->getUrl())
20 ->see($draft->name) 20 ->see($draft->name)
......
...@@ -90,7 +90,7 @@ class ImageTest extends TestCase ...@@ -90,7 +90,7 @@ class ImageTest extends TestCase
90 'type' => 'gallery' 90 'type' => 'gallery'
91 ]); 91 ]);
92 92
93 - $this->assertFalse(file_exists(public_path($relPath)), 'Uploaded image has been deleted'); 93 + $this->assertFalse(file_exists(public_path($relPath)), 'Uploaded image has not been deleted as expected');
94 } 94 }
95 95
96 } 96 }
...\ No newline at end of file ...\ No newline at end of file
......