]> BookStack Code Mirror - bookstack/blob - app/Entities/Controllers/BookshelfApiController.php
Permissions: Updated usage of controller methods to use enum
[bookstack] / app / Entities / Controllers / BookshelfApiController.php
1 <?php
2
3 namespace BookStack\Entities\Controllers;
4
5 use BookStack\Entities\Models\Bookshelf;
6 use BookStack\Entities\Queries\BookshelfQueries;
7 use BookStack\Entities\Repos\BookshelfRepo;
8 use BookStack\Http\ApiController;
9 use BookStack\Permissions\Permission;
10 use Exception;
11 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
12 use Illuminate\Http\Request;
13 use Illuminate\Validation\ValidationException;
14
15 class BookshelfApiController extends ApiController
16 {
17     public function __construct(
18         protected BookshelfRepo $bookshelfRepo,
19         protected BookshelfQueries $queries,
20     ) {
21     }
22
23     /**
24      * Get a listing of shelves visible to the user.
25      */
26     public function list()
27     {
28         $shelves = $this->queries
29             ->visibleForList()
30             ->with(['cover:id,name,url'])
31             ->addSelect(['created_by', 'updated_by']);
32
33         return $this->apiListingResponse($shelves, [
34             'id', 'name', 'slug', 'description', 'created_at', 'updated_at', 'created_by', 'updated_by', 'owned_by',
35         ]);
36     }
37
38     /**
39      * Create a new shelf in the system.
40      * An array of books IDs can be provided in the request. These
41      * will be added to the shelf in the same order as provided.
42      * The cover image of a shelf can be set by sending a file via an 'image' property within a 'multipart/form-data' request.
43      * If the 'image' property is null then the shelf cover image will be removed.
44      *
45      * @throws ValidationException
46      */
47     public function create(Request $request)
48     {
49         $this->checkPermission(Permission::BookshelfCreateAll);
50         $requestData = $this->validate($request, $this->rules()['create']);
51
52         $bookIds = $request->get('books', []);
53         $shelf = $this->bookshelfRepo->create($requestData, $bookIds);
54
55         return response()->json($this->forJsonDisplay($shelf));
56     }
57
58     /**
59      * View the details of a single shelf.
60      */
61     public function read(string $id)
62     {
63         $shelf = $this->queries->findVisibleByIdOrFail(intval($id));
64         $shelf = $this->forJsonDisplay($shelf);
65         $shelf->load([
66             'createdBy', 'updatedBy', 'ownedBy',
67             'books' => function (BelongsToMany $query) {
68                 $query->scopes('visible')->get(['id', 'name', 'slug']);
69             },
70         ]);
71
72         return response()->json($shelf);
73     }
74
75     /**
76      * Update the details of a single shelf.
77      * An array of books IDs can be provided in the request. These
78      * will be added to the shelf in the same order as provided and overwrite
79      * any existing book assignments.
80      * The cover image of a shelf can be set by sending a file via an 'image' property within a 'multipart/form-data' request.
81      * If the 'image' property is null then the shelf cover image will be removed.
82      *
83      * @throws ValidationException
84      */
85     public function update(Request $request, string $id)
86     {
87         $shelf = $this->queries->findVisibleByIdOrFail(intval($id));
88         $this->checkOwnablePermission(Permission::BookshelfUpdate, $shelf);
89
90         $requestData = $this->validate($request, $this->rules()['update']);
91         $bookIds = $request->get('books', null);
92
93         $shelf = $this->bookshelfRepo->update($shelf, $requestData, $bookIds);
94
95         return response()->json($this->forJsonDisplay($shelf));
96     }
97
98     /**
99      * Delete a single shelf.
100      * This will typically send the shelf to the recycle bin.
101      *
102      * @throws Exception
103      */
104     public function delete(string $id)
105     {
106         $shelf = $this->queries->findVisibleByIdOrFail(intval($id));
107         $this->checkOwnablePermission(Permission::BookshelfDelete, $shelf);
108
109         $this->bookshelfRepo->destroy($shelf);
110
111         return response('', 204);
112     }
113
114     protected function forJsonDisplay(Bookshelf $shelf): Bookshelf
115     {
116         $shelf = clone $shelf;
117         $shelf->unsetRelations()->refresh();
118
119         $shelf->load(['tags', 'cover']);
120         $shelf->makeVisible('description_html')
121             ->setAttribute('description_html', $shelf->descriptionHtml());
122
123         return $shelf;
124     }
125
126     protected function rules(): array
127     {
128         return [
129             'create' => [
130                 'name'             => ['required', 'string', 'max:255'],
131                 'description'      => ['string', 'max:1900'],
132                 'description_html' => ['string', 'max:2000'],
133                 'books'            => ['array'],
134                 'tags'             => ['array'],
135                 'image'            => array_merge(['nullable'], $this->getImageValidationRules()),
136             ],
137             'update' => [
138                 'name'             => ['string', 'min:1', 'max:255'],
139                 'description'      => ['string', 'max:1900'],
140                 'description_html' => ['string', 'max:2000'],
141                 'books'            => ['array'],
142                 'tags'             => ['array'],
143                 'image'            => array_merge(['nullable'], $this->getImageValidationRules()),
144             ],
145         ];
146     }
147 }