Skip to content

Commit b6a4a46

Browse files
author
Riari
committed
Improve API methods, validation & authorization
1 parent 1e3a695 commit b6a4a46

19 files changed

+218
-108
lines changed

src/Forum.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace Riari\Forum;
44

5-
use App;
6-
use Gate;
5+
use Illuminate\Support\Facades\App;
6+
use Illuminate\Support\Facades\Gate;
77

88
class Forum
99
{

src/Http/Controllers/API/BaseController.php

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function __construct(Request $request)
4343
/**
4444
* Return the model to use for this controller.
4545
*
46-
* @return string
46+
* @return \Illuminate\Database\Eloquent\Model
4747
*/
4848
abstract protected function model();
4949

@@ -65,24 +65,6 @@ public function index(Request $request)
6565
return $this->response($this->model()->paginate());
6666
}
6767

68-
/**
69-
* GET: Return a model by ID.
70-
*
71-
* @param int $id
72-
* @param Request $request
73-
* @return JsonResponse|Response
74-
*/
75-
public function fetch($id, Request $request)
76-
{
77-
$model = $this->model()->find($id);
78-
79-
if (is_null($model) || !$model->exists) {
80-
return $this->notFoundResponse();
81-
}
82-
83-
return $this->response($model);
84-
}
85-
8668
/**
8769
* PATCH: Update a model.
8870
*
@@ -92,7 +74,7 @@ public function fetch($id, Request $request)
9274
*/
9375
public function update($id, Request $request)
9476
{
95-
return $this->updateAttributes($this->model()->find($id), $request->all(), 'edit');
77+
return $this->updateModel($this->model()->find($id), $request->all(), 'edit');
9678
}
9779

9880
/**
@@ -104,27 +86,17 @@ public function update($id, Request $request)
10486
*/
10587
public function destroy($id, Request $request)
10688
{
107-
$this->validate($request, ['force' => ['boolean']]);
89+
$model = $this->model();
10890

109-
$model = $this->model()->withTrashed()->find($id);
91+
$force = false;
92+
if (method_exists($model, 'forceDelete')) {
93+
$this->validate($request, ['force' => ['boolean']]);
11094

111-
if (is_null($model) || !$model->exists) {
112-
return $this->notFoundResponse();
95+
$model = $model->withTrashed();
96+
$force = (bool) $request->input('force');
11397
}
11498

115-
$model->timestamps = false;
116-
117-
if ($request->has('force') && $request->input('force') == 1) {
118-
$model->forceDelete();
119-
return $this->response($model, $this->trans('perma_deleted'));
120-
} elseif (!$model->trashed()) {
121-
$model->delete();
122-
return $this->response($model, $this->trans('deleted'));
123-
}
124-
125-
$model->timestamps = true;
126-
127-
return $this->notFoundResponse();
99+
return $this->deleteModel($model->find($id), 'delete', $force);
128100
}
129101

130102
/**
@@ -195,6 +167,10 @@ protected function bulk(Request $request, $action, $transKey, array $input = [])
195167
foreach ($items as $id) {
196168
$response = $this->{$action}($id, $request);
197169

170+
if ($response->isClientError()) {
171+
return $response;
172+
}
173+
198174
if (!$response->isNotFound()) {
199175
$models->push($response->getOriginalContent());
200176
}
@@ -211,12 +187,57 @@ protected function bulk(Request $request, $action, $transKey, array $input = [])
211187
* @param array|string $authorize
212188
* @return JsonResponse|Response
213189
*/
214-
protected function updateAttributes($model, array $attributes, $authorize = [])
190+
protected function updateModel($model, array $attributes, $authorize = [])
215191
{
216192
if (is_null($model) || !$model->exists) {
217193
return $this->notFoundResponse();
218194
}
219195

196+
$this->parseAuthorization($model, $authorize);
197+
198+
$model->update($attributes);
199+
200+
return $this->response($model, $this->trans('updated'));
201+
}
202+
203+
/**
204+
* Delete a model.
205+
*
206+
* @param Model $model
207+
* @param array|string $authorize
208+
* @param bool $force
209+
* @return JsonResponse|Response
210+
*/
211+
protected function deleteModel($model, $authorize = [], $force = false)
212+
{
213+
if (is_null($model) || !$model->exists) {
214+
return $this->notFoundResponse();
215+
}
216+
217+
$this->parseAuthorization($model, $authorize);
218+
219+
if ($force) {
220+
$model->forceDelete();
221+
222+
return $this->response($model, $this->trans('perma_deleted'));
223+
} else {
224+
$model->timestamps = false;
225+
$model->delete();
226+
$model->timestamps = true;
227+
228+
return $this->response($model, $this->trans('deleted'));
229+
}
230+
}
231+
232+
/**
233+
* Parse an authorization parameter and authorize if applicable.
234+
*
235+
* @param Model $model
236+
* @param array|string $authorize
237+
* @return JsonResponse|Response
238+
*/
239+
protected function parseAuthorization($model, $authorize = [])
240+
{
220241
if (!empty($authorize)) {
221242
// We need to authorize this change
222243

@@ -229,10 +250,6 @@ protected function updateAttributes($model, array $attributes, $authorize = [])
229250

230251
$this->authorize($ability, $authorizeModel);
231252
}
232-
233-
$model->update($attributes);
234-
235-
return $this->response($model, $this->trans('updated'));
236253
}
237254

238255
/**
@@ -292,14 +309,14 @@ protected function notFoundResponse()
292309
* Create the response for when a request fails validation.
293310
*
294311
* @param Request $request
295-
* @param array $errors
312+
* @param array|string $errors
296313
* @return JsonResponse|Response
297314
*/
298-
protected function buildFailedValidationResponse(Request $request, array $errors)
315+
protected function buildFailedValidationResponse(Request $request, $errors)
299316
{
300317
$content = [
301318
'error' => "The submitted data did not pass validation.",
302-
'validation_errors' => $errors
319+
'validation_errors' => (array) $errors
303320
];
304321

305322
return ($request->ajax() || $request->wantsJson())

src/Http/Controllers/API/CategoryController.php

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Illuminate\Http\JsonResponse;
66
use Illuminate\Http\Request;
77
use Illuminate\Support\Facades\Gate;
8+
use Riari\Forum\Forum;
89
use Riari\Forum\Models\Category;
910

1011
class CategoryController extends BaseController
@@ -111,15 +112,11 @@ public function destroy($id, Request $request)
111112
{
112113
$category = $this->model()->find($id);
113114

114-
if (is_null($category) || !$category->exists) {
115-
return $this->notFoundResponse();
115+
if (!$category->threads->isEmpty() || !$category->children->isEmpty()) {
116+
return $this->buildFailedValidationResponse($request, Forum::trans('validation', 'category_is_empty'));
116117
}
117118

118-
$this->authorize('delete', $category);
119-
120-
$category->delete();
121-
122-
return $this->response($category, $this->trans('deleted'));
119+
return $this->deleteModel($category, 'delete');
123120
}
124121

125122
/**
@@ -136,7 +133,7 @@ public function move($id, Request $request)
136133

137134
$category = $this->model()->find($id);
138135

139-
return $this->updateAttributes($category, ['category_id' => $request->input('category_id')]);
136+
return $this->updateModel($category, ['category_id' => $request->input('category_id')]);
140137
}
141138

142139
/**
@@ -148,11 +145,9 @@ public function move($id, Request $request)
148145
*/
149146
public function enableThreads($id, Request $request)
150147
{
151-
$this->authorize('createCategories');
152-
153148
$category = $this->model()->where('enable_threads', 0)->find($id);
154149

155-
return $this->updateAttributes($category, ['enable_threads' => 1]);
150+
return $this->updateModel($category, ['enable_threads' => 1], 'enableThreads');
156151
}
157152

158153
/**
@@ -164,11 +159,13 @@ public function enableThreads($id, Request $request)
164159
*/
165160
public function disableThreads($id, Request $request)
166161
{
167-
$this->authorize('createCategories');
168-
169162
$category = $this->model()->where('enable_threads', 1)->find($id);
170163

171-
return $this->updateAttributes($category, ['enable_threads' => 0]);
164+
if (!$category->threads->isEmpty()) {
165+
return $this->buildFailedValidationResponse($request, Forum::trans('validation', 'category_has_no_threads'));
166+
}
167+
168+
return $this->updateModel($category, ['enable_threads' => 0], 'enableThreads');
172169
}
173170

174171
/**
@@ -184,7 +181,7 @@ public function makePublic($id, Request $request)
184181

185182
$category = $this->model()->where('private', 1)->find($id);
186183

187-
return $this->updateAttributes($category, ['private' => 0]);
184+
return $this->updateModel($category, ['private' => 0]);
188185
}
189186

190187
/**
@@ -200,7 +197,7 @@ public function makePrivate($id, Request $request)
200197

201198
$category = $this->model()->where('private', 0)->find($id);
202199

203-
return $this->updateAttributes($category, ['private' => 1]);
200+
return $this->updateModel($category, ['private' => 1]);
204201
}
205202

206203
/**
@@ -217,7 +214,7 @@ public function rename($id, Request $request)
217214

218215
$category = $this->model()->find($id);
219216

220-
return $this->updateAttributes($category, $request->only(['title', 'description']));
217+
return $this->updateModel($category, $request->only(['title', 'description']));
221218
}
222219

223220
/**
@@ -234,6 +231,6 @@ public function reorder($id, Request $request)
234231

235232
$category = $this->model()->find($id);
236233

237-
return $this->updateAttributes($category, ['weight' => $request->input('weight')]);
234+
return $this->updateModel($category, ['weight' => $request->input('weight')]);
238235
}
239236
}

src/Http/Controllers/API/PostController.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ public function index(Request $request)
4444
return $this->response($posts);
4545
}
4646

47+
/**
48+
* GET: Return a post.
49+
*
50+
* @param int $id
51+
* @param Request $request
52+
* @return JsonResponse|Response
53+
*/
54+
public function fetch($id, Request $request)
55+
{
56+
$post = $this->model()->find($id);
57+
58+
if (is_null($post) || !$post->exists) {
59+
return $this->notFoundResponse();
60+
}
61+
62+
return $this->response($post);
63+
}
64+
4765
/**
4866
* POST: Create a new post.
4967
*

0 commit comments

Comments
 (0)