]> BookStack Code Mirror - bookstack/blobdiff - app/Entities/Controllers/BookController.php
Permissions: Cleanup after review of enum implementation PR
[bookstack] / app / Entities / Controllers / BookController.php
index 55d28c6847e32a1227cb4663902e3388fbb27524..cbf7ffb7984896d0f70d2c88bd3073d11be771b7 100644 (file)
@@ -6,7 +6,8 @@ use BookStack\Activity\ActivityQueries;
 use BookStack\Activity\ActivityType;
 use BookStack\Activity\Models\View;
 use BookStack\Activity\Tools\UserEntityWatchOptions;
-use BookStack\Entities\Models\Bookshelf;
+use BookStack\Entities\Queries\BookQueries;
+use BookStack\Entities\Queries\BookshelfQueries;
 use BookStack\Entities\Repos\BookRepo;
 use BookStack\Entities\Tools\BookContents;
 use BookStack\Entities\Tools\Cloner;
@@ -16,7 +17,9 @@ use BookStack\Exceptions\ImageUploadException;
 use BookStack\Exceptions\NotFoundException;
 use BookStack\Facades\Activity;
 use BookStack\Http\Controller;
+use BookStack\Permissions\Permission;
 use BookStack\References\ReferenceFetcher;
+use BookStack\Util\DatabaseTransaction;
 use BookStack\Util\SimpleListOptions;
 use Illuminate\Http\Request;
 use Illuminate\Validation\ValidationException;
@@ -24,15 +27,13 @@ use Throwable;
 
 class BookController extends Controller
 {
-    protected BookRepo $bookRepo;
-    protected ShelfContext $shelfContext;
-    protected ReferenceFetcher $referenceFetcher;
-
-    public function __construct(ShelfContext $entityContextManager, BookRepo $bookRepo, ReferenceFetcher $referenceFetcher)
-    {
-        $this->bookRepo = $bookRepo;
-        $this->shelfContext = $entityContextManager;
-        $this->referenceFetcher = $referenceFetcher;
+    public function __construct(
+        protected ShelfContext $shelfContext,
+        protected BookRepo $bookRepo,
+        protected BookQueries $queries,
+        protected BookshelfQueries $shelfQueries,
+        protected ReferenceFetcher $referenceFetcher,
+    ) {
     }
 
     /**
@@ -47,10 +48,12 @@ class BookController extends Controller
             'updated_at' => trans('common.sort_updated_at'),
         ]);
 
-        $books = $this->bookRepo->getAllPaginated(18, $listOptions->getSort(), $listOptions->getOrder());
-        $recents = $this->isSignedIn() ? $this->bookRepo->getRecentlyViewed(4) : false;
-        $popular = $this->bookRepo->getPopular(4);
-        $new = $this->bookRepo->getRecentlyCreated(4);
+        $books = $this->queries->visibleForListWithCover()
+            ->orderBy($listOptions->getSort(), $listOptions->getOrder())
+            ->paginate(18);
+        $recents = $this->isSignedIn() ? $this->queries->recentlyViewedForCurrentUser()->take(4)->get() : false;
+        $popular = $this->queries->popularForList()->take(4)->get();
+        $new = $this->queries->visibleForList()->orderBy('created_at', 'desc')->take(4)->get();
 
         $this->shelfContext->clearShelfContext();
 
@@ -69,14 +72,14 @@ class BookController extends Controller
     /**
      * Show the form for creating a new book.
      */
-    public function create(string $shelfSlug = null)
+    public function create(?string $shelfSlug = null)
     {
-        $this->checkPermission('book-create-all');
+        $this->checkPermission(Permission::BookCreateAll);
 
         $bookshelf = null;
         if ($shelfSlug !== null) {
-            $bookshelf = Bookshelf::visible()->where('slug', '=', $shelfSlug)->firstOrFail();
-            $this->checkOwnablePermission('bookshelf-update', $bookshelf);
+            $bookshelf = $this->shelfQueries->findVisibleBySlugOrFail($shelfSlug);
+            $this->checkOwnablePermission(Permission::BookshelfUpdate, $bookshelf);
         }
 
         $this->setPageTitle(trans('entities.books_create'));
@@ -92,20 +95,21 @@ class BookController extends Controller
      * @throws ImageUploadException
      * @throws ValidationException
      */
-    public function store(Request $request, string $shelfSlug = null)
+    public function store(Request $request, ?string $shelfSlug = null)
     {
-        $this->checkPermission('book-create-all');
+        $this->checkPermission(Permission::BookCreateAll);
         $validated = $this->validate($request, [
-            'name'        => ['required', 'string', 'max:255'],
-            'description' => ['string', 'max:1000'],
-            'image'       => array_merge(['nullable'], $this->getImageValidationRules()),
-            'tags'        => ['array'],
+            'name'                => ['required', 'string', 'max:255'],
+            'description_html'    => ['string', 'max:2000'],
+            'image'               => array_merge(['nullable'], $this->getImageValidationRules()),
+            'tags'                => ['array'],
+            'default_template_id' => ['nullable', 'integer'],
         ]);
 
         $bookshelf = null;
         if ($shelfSlug !== null) {
-            $bookshelf = Bookshelf::visible()->where('slug', '=', $shelfSlug)->firstOrFail();
-            $this->checkOwnablePermission('bookshelf-update', $bookshelf);
+            $bookshelf = $this->shelfQueries->findVisibleBySlugOrFail($shelfSlug);
+            $this->checkOwnablePermission(Permission::BookshelfUpdate, $bookshelf);
         }
 
         $book = $this->bookRepo->create($validated);
@@ -123,7 +127,7 @@ class BookController extends Controller
      */
     public function show(Request $request, ActivityQueries $activities, string $slug)
     {
-        $book = $this->bookRepo->getBySlug($slug);
+        $book = $this->queries->findVisibleBySlugOrFail($slug);
         $bookChildren = (new BookContents($book))->getTree(true);
         $bookParentShelves = $book->shelves()->scopes('visible')->get();
 
@@ -141,7 +145,7 @@ class BookController extends Controller
             'bookParentShelves' => $bookParentShelves,
             'watchOptions'      => new UserEntityWatchOptions(user(), $book),
             'activity'          => $activities->entityActivity($book, 20, 1),
-            'referenceCount'    => $this->referenceFetcher->getPageReferenceCountToEntity($book),
+            'referenceCount'    => $this->referenceFetcher->getReferenceCountToEntity($book),
         ]);
     }
 
@@ -150,8 +154,8 @@ class BookController extends Controller
      */
     public function edit(string $slug)
     {
-        $book = $this->bookRepo->getBySlug($slug);
-        $this->checkOwnablePermission('book-update', $book);
+        $book = $this->queries->findVisibleBySlugOrFail($slug);
+        $this->checkOwnablePermission(Permission::BookUpdate, $book);
         $this->setPageTitle(trans('entities.books_edit_named', ['bookName' => $book->getShortName()]));
 
         return view('books.edit', ['book' => $book, 'current' => $book]);
@@ -166,14 +170,15 @@ class BookController extends Controller
      */
     public function update(Request $request, string $slug)
     {
-        $book = $this->bookRepo->getBySlug($slug);
-        $this->checkOwnablePermission('book-update', $book);
+        $book = $this->queries->findVisibleBySlugOrFail($slug);
+        $this->checkOwnablePermission(Permission::BookUpdate, $book);
 
         $validated = $this->validate($request, [
-            'name'        => ['required', 'string', 'max:255'],
-            'description' => ['string', 'max:1000'],
-            'image'       => array_merge(['nullable'], $this->getImageValidationRules()),
-            'tags'        => ['array'],
+            'name'                => ['required', 'string', 'max:255'],
+            'description_html'    => ['string', 'max:2000'],
+            'image'               => array_merge(['nullable'], $this->getImageValidationRules()),
+            'tags'                => ['array'],
+            'default_template_id' => ['nullable', 'integer'],
         ]);
 
         if ($request->has('image_reset')) {
@@ -192,8 +197,8 @@ class BookController extends Controller
      */
     public function showDelete(string $bookSlug)
     {
-        $book = $this->bookRepo->getBySlug($bookSlug);
-        $this->checkOwnablePermission('book-delete', $book);
+        $book = $this->queries->findVisibleBySlugOrFail($bookSlug);
+        $this->checkOwnablePermission(Permission::BookDelete, $book);
         $this->setPageTitle(trans('entities.books_delete_named', ['bookName' => $book->getShortName()]));
 
         return view('books.delete', ['book' => $book, 'current' => $book]);
@@ -206,8 +211,8 @@ class BookController extends Controller
      */
     public function destroy(string $bookSlug)
     {
-        $book = $this->bookRepo->getBySlug($bookSlug);
-        $this->checkOwnablePermission('book-delete', $book);
+        $book = $this->queries->findVisibleBySlugOrFail($bookSlug);
+        $this->checkOwnablePermission(Permission::BookDelete, $book);
 
         $this->bookRepo->destroy($book);
 
@@ -221,8 +226,8 @@ class BookController extends Controller
      */
     public function showCopy(string $bookSlug)
     {
-        $book = $this->bookRepo->getBySlug($bookSlug);
-        $this->checkOwnablePermission('book-view', $book);
+        $book = $this->queries->findVisibleBySlugOrFail($bookSlug);
+        $this->checkOwnablePermission(Permission::BookView, $book);
 
         session()->flashInput(['name' => $book->name]);
 
@@ -238,9 +243,9 @@ class BookController extends Controller
      */
     public function copy(Request $request, Cloner $cloner, string $bookSlug)
     {
-        $book = $this->bookRepo->getBySlug($bookSlug);
-        $this->checkOwnablePermission('book-view', $book);
-        $this->checkPermission('book-create-all');
+        $book = $this->queries->findVisibleBySlugOrFail($bookSlug);
+        $this->checkOwnablePermission(Permission::BookView, $book);
+        $this->checkPermission(Permission::BookCreateAll);
 
         $newName = $request->get('name') ?: $book->name;
         $bookCopy = $cloner->cloneBook($book, $newName);
@@ -254,13 +259,15 @@ class BookController extends Controller
      */
     public function convertToShelf(HierarchyTransformer $transformer, string $bookSlug)
     {
-        $book = $this->bookRepo->getBySlug($bookSlug);
-        $this->checkOwnablePermission('book-update', $book);
-        $this->checkOwnablePermission('book-delete', $book);
-        $this->checkPermission('bookshelf-create-all');
-        $this->checkPermission('book-create-all');
-
-        $shelf = $transformer->transformBookToShelf($book);
+        $book = $this->queries->findVisibleBySlugOrFail($bookSlug);
+        $this->checkOwnablePermission(Permission::BookUpdate, $book);
+        $this->checkOwnablePermission(Permission::BookDelete, $book);
+        $this->checkPermission(Permission::BookshelfCreateAll);
+        $this->checkPermission(Permission::BookCreateAll);
+
+        $shelf = (new DatabaseTransaction(function () use ($book, $transformer) {
+            return $transformer->transformBookToShelf($book);
+        }))->run();
 
         return redirect($shelf->getUrl());
     }