1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Abstract API Controller. |
4
|
|
|
* |
5
|
|
|
* @package App\Http\Controllers\Api |
6
|
|
|
* |
7
|
|
|
* @author Nick Menke <[email protected]> |
8
|
|
|
* @copyright 2018-2020 Nick Menke |
9
|
|
|
* |
10
|
|
|
* @link https://github.com/nlmenke/vertebrae |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
declare(strict_types=1); |
14
|
|
|
|
15
|
|
|
namespace App\Http\Controllers\Api; |
16
|
|
|
|
17
|
|
|
use App\Http\Controllers\AbstractController; |
18
|
|
|
use App\Http\Requests\AbstractFormRequest; |
19
|
|
|
use App\Http\Resources\AbstractResource; |
20
|
|
|
use DB; |
21
|
|
|
use Exception; |
22
|
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException; |
23
|
|
|
use Illuminate\Http\JsonResponse; |
24
|
|
|
use Illuminate\Http\Response; |
25
|
|
|
use Request; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* The base API controller class. |
29
|
|
|
* |
30
|
|
|
* This class contains any functionality that would otherwise be duplicated in |
31
|
|
|
* other API controllers. All other API controllers should extend this class. |
32
|
|
|
* |
33
|
|
|
* @since x.x.x introduced |
34
|
|
|
*/ |
35
|
|
|
abstract class AbstractApiController extends AbstractController |
36
|
|
|
{ |
37
|
|
|
/** |
38
|
|
|
* The base route name used by the controller. |
39
|
|
|
* |
40
|
|
|
* @var string |
41
|
|
|
*/ |
42
|
|
|
protected $baseRouteName; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* The resource instance. |
46
|
|
|
* |
47
|
|
|
* @var AbstractResource |
48
|
|
|
*/ |
49
|
|
|
protected $resource; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Create a new API controller instance. |
53
|
|
|
* |
54
|
|
|
* @return void |
55
|
|
|
*/ |
56
|
28 |
|
public function __construct() |
57
|
|
|
{ |
58
|
28 |
|
$this->baseRouteName = str_replace([ |
59
|
|
|
'index', |
60
|
|
|
'show', |
61
|
|
|
'store', |
62
|
|
|
'update', |
63
|
|
|
'destroy', |
64
|
28 |
|
], '', Request::route()->getName()); |
65
|
|
|
|
66
|
28 |
|
parent::__construct(); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Removes a specified resource from storage. |
71
|
|
|
* |
72
|
|
|
* This method is used to delete an existing record. Successful requests |
73
|
|
|
* will result in a 204 (No Content) HTTP response code with no body, but |
74
|
|
|
* a `Location` header with a link to the index path will be provided. A |
75
|
|
|
* 404 (Not Found) may be returned if the record does not currently exist. |
76
|
|
|
* |
77
|
|
|
* @param int $id |
78
|
|
|
* |
79
|
|
|
* @throws Exception |
80
|
|
|
* |
81
|
|
|
* @return JsonResponse |
82
|
|
|
*/ |
83
|
4 |
|
public function destroy(int $id): JsonResponse |
84
|
|
|
{ |
85
|
4 |
|
DB::beginTransaction(); |
86
|
|
|
|
87
|
|
|
try { |
88
|
4 |
|
$result = $this->model->findOrFail($id); |
89
|
4 |
|
$result->delete(); |
90
|
|
|
|
91
|
4 |
|
DB::commit(); |
92
|
|
|
|
93
|
4 |
|
return $this->resource |
94
|
4 |
|
->response() |
95
|
4 |
|
->setStatusCode(Response::HTTP_NO_CONTENT) |
96
|
4 |
|
->header('Content-Language', $this->currentLocale) |
97
|
4 |
|
->header('Location', route($this->baseRouteName . 'index')); |
98
|
|
|
} catch (ModelNotFoundException $e) { |
99
|
|
|
DB::rollBack(); |
100
|
|
|
|
101
|
|
|
return JsonResponse::create([ |
|
|
|
|
102
|
|
|
'message' => trans('exceptions.http.404_message'), |
103
|
|
|
'errors' => (object)[ |
104
|
|
|
$e->getCode() => [$e->getMessage()], |
105
|
|
|
], |
106
|
|
|
], Response::HTTP_NOT_FOUND, [ |
107
|
|
|
'Content-Language' => $this->currentLocale, |
108
|
|
|
]); |
109
|
|
|
} catch (Exception $e) { |
110
|
|
|
DB::rollBack(); |
111
|
|
|
|
112
|
|
|
return JsonResponse::create([ |
|
|
|
|
113
|
|
|
'message' => trans('exceptions.http.500_message'), |
114
|
|
|
'errors' => (object)[ |
115
|
|
|
$e->getCode() => [$e->getMessage()], |
116
|
|
|
], |
117
|
|
|
], Response::HTTP_INTERNAL_SERVER_ERROR, [ |
118
|
|
|
'Content-Language' => $this->currentLocale, |
119
|
|
|
]); |
120
|
|
|
} |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Displays a listing of resources. |
125
|
|
|
* |
126
|
|
|
* This method is used to retrieve a full list of resources. Upon success: |
127
|
|
|
* by default, a JSON object with ten (10) records will be returned with an |
128
|
|
|
* HTTP response code of 200 (OK). You will also receive a listing with the |
129
|
|
|
* total number of records as well as a listing with links to the first, |
130
|
|
|
* last, previous (if applicable) and next (if applicable) pages. |
131
|
|
|
* |
132
|
|
|
* @return JsonResponse |
133
|
|
|
*/ |
134
|
4 |
|
public function index(): JsonResponse |
135
|
|
|
{ |
136
|
|
|
try { |
137
|
4 |
|
$result = $this->model; |
138
|
|
|
|
139
|
4 |
|
if (array_key_exists('index', $this->with)) { |
140
|
4 |
|
$result = $result->with($this->with['index']); |
141
|
|
|
} |
142
|
|
|
|
143
|
4 |
|
$result = $result->orderBy($this->sorting['column'], $this->sorting['direction']) |
144
|
4 |
|
->paginate($this->perPage); |
145
|
|
|
|
146
|
4 |
|
return $this->resource->collection($result) |
147
|
4 |
|
->response() |
148
|
4 |
|
->header('Content-Language', $this->currentLocale); |
149
|
|
|
} catch (Exception $e) { |
150
|
|
|
return JsonResponse::create([ |
|
|
|
|
151
|
|
|
'message' => trans('exceptions.http.500_message'), |
152
|
|
|
'errors' => (object)[ |
153
|
|
|
$e->getCode() => [$e->getMessage()], |
154
|
|
|
], |
155
|
|
|
], Response::HTTP_INTERNAL_SERVER_ERROR, [ |
156
|
|
|
'Content-Language' => $this->currentLocale, |
157
|
|
|
]); |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* Displays a specified resource. |
163
|
|
|
* |
164
|
|
|
* This method is used to retrieve a single record. Upon success: the |
165
|
|
|
* resource will be returned as a JSON object with an HTTP response code of |
166
|
|
|
* 200 (OK). If the record does not exist, you will get a 404 (Not Found) |
167
|
|
|
* HTTP response code along with any error codes thrown by the application |
168
|
|
|
* in attempt to assist with any debugging that may be necessary. |
169
|
|
|
* |
170
|
|
|
* @param int $id |
171
|
|
|
* |
172
|
|
|
* @return JsonResponse |
173
|
|
|
*/ |
174
|
16 |
|
public function show(int $id): JsonResponse |
175
|
|
|
{ |
176
|
|
|
try { |
177
|
16 |
|
$result = $this->model; |
178
|
|
|
|
179
|
16 |
|
if (array_key_exists('show', $this->with)) { |
180
|
16 |
|
$result = $result->with($this->with['show']); |
181
|
|
|
} |
182
|
|
|
|
183
|
16 |
|
$result = $result->findOrFail($id); |
184
|
|
|
|
185
|
12 |
|
return $this->resource->make($result) |
186
|
12 |
|
->response() |
187
|
12 |
|
->header('Content-Language', $this->currentLocale); |
188
|
4 |
|
} catch (ModelNotFoundException $e) { |
189
|
4 |
|
return JsonResponse::create([ |
|
|
|
|
190
|
4 |
|
'message' => trans('exceptions.http.404_message'), |
191
|
|
|
'errors' => (object)[ |
192
|
4 |
|
$e->getCode() => [$e->getMessage()], |
193
|
|
|
], |
194
|
|
|
], Response::HTTP_NOT_FOUND, [ |
195
|
4 |
|
'Content-Language' => $this->currentLocale, |
196
|
|
|
]); |
197
|
|
|
} catch (Exception $e) { |
198
|
|
|
return JsonResponse::create([ |
|
|
|
|
199
|
|
|
'message' => trans('exceptions.http.500_message'), |
200
|
|
|
'errors' => (object)[ |
201
|
|
|
$e->getCode() => [$e->getMessage()], |
202
|
|
|
], |
203
|
|
|
], Response::HTTP_INTERNAL_SERVER_ERROR, [ |
204
|
|
|
'Content-Language' => $this->currentLocale, |
205
|
|
|
]); |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Stores a newly created resource in storage. |
211
|
|
|
* |
212
|
|
|
* This method is used to create a new record. A successful request will |
213
|
|
|
* return a 201 (Created) HTTP response and the newly created entry. The |
214
|
|
|
* response will include a `Location` header with the path to the new |
215
|
|
|
* resource as well. If any validation errors exist, an HTTP response code |
216
|
|
|
* of 422 (Unprocessable Entity) will be returned along with any fields |
217
|
|
|
* that do not match the rules set by the form request. |
218
|
|
|
* |
219
|
|
|
* @param AbstractFormRequest $request |
220
|
|
|
* |
221
|
|
|
* @throws Exception |
222
|
|
|
* |
223
|
|
|
* @return JsonResponse |
224
|
|
|
*/ |
225
|
4 |
|
public function store(AbstractFormRequest $request): JsonResponse |
226
|
|
|
{ |
227
|
4 |
|
DB::beginTransaction(); |
228
|
|
|
|
229
|
|
|
try { |
230
|
4 |
|
$result = $this->model->create($request->toArray()); |
231
|
|
|
|
232
|
4 |
|
DB::commit(); |
233
|
|
|
|
234
|
4 |
|
return $this->resource->make($result) |
235
|
4 |
|
->response() |
236
|
4 |
|
->header('Content-Language', $this->currentLocale) |
237
|
4 |
|
->header('Location', route($this->baseRouteName . 'show', $result->getId())); |
238
|
|
|
} catch (Exception $e) { |
239
|
|
|
DB::rollBack(); |
240
|
|
|
|
241
|
|
|
return JsonResponse::create([ |
|
|
|
|
242
|
|
|
'message' => trans('exceptions.http.500_message'), |
243
|
|
|
'errors' => (object)[ |
244
|
|
|
$e->getCode() => [$e->getMessage()], |
245
|
|
|
], |
246
|
|
|
], Response::HTTP_INTERNAL_SERVER_ERROR, [ |
247
|
|
|
'Content-Language' => $this->currentLocale, |
248
|
|
|
]); |
249
|
|
|
} |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* Updates a specified resource in storage. |
254
|
|
|
* |
255
|
|
|
* This method is used to modify an existing record. Upon success: an HTTP |
256
|
|
|
* response of 200 (OK) will be returned with the modified entry. Invalid |
257
|
|
|
* requests will result in a 422 (Unprocessable Entity) response and any |
258
|
|
|
* fields causing the validation failure. |
259
|
|
|
* |
260
|
|
|
* @param AbstractFormRequest $request |
261
|
|
|
* @param int $id |
262
|
|
|
* |
263
|
|
|
* @throws Exception |
264
|
|
|
* |
265
|
|
|
* @return JsonResponse |
266
|
|
|
*/ |
267
|
4 |
|
public function update(AbstractFormRequest $request, int $id): JsonResponse |
268
|
|
|
{ |
269
|
4 |
|
DB::beginTransaction(); |
270
|
|
|
|
271
|
|
|
try { |
272
|
4 |
|
$result = $this->model->findOrFail($id); |
273
|
4 |
|
$result->update($request->toArray()); |
274
|
|
|
|
275
|
4 |
|
DB::commit(); |
276
|
|
|
|
277
|
4 |
|
return $this->resource->make($result) |
278
|
4 |
|
->response() |
279
|
4 |
|
->header('Content-Language', $this->currentLocale) |
280
|
4 |
|
->header('Location', route($this->baseRouteName . 'show', $result->getId())); |
281
|
|
|
} catch (ModelNotFoundException $e) { |
282
|
|
|
DB::rollBack(); |
283
|
|
|
|
284
|
|
|
return JsonResponse::create([ |
|
|
|
|
285
|
|
|
'message' => trans('exceptions.http.404_message'), |
286
|
|
|
'errors' => (object)[ |
287
|
|
|
$e->getCode() => [$e->getMessage()], |
288
|
|
|
], |
289
|
|
|
], Response::HTTP_NOT_FOUND, [ |
290
|
|
|
'Content-Language' => $this->currentLocale, |
291
|
|
|
]); |
292
|
|
|
} catch (Exception $e) { |
293
|
|
|
DB::rollBack(); |
294
|
|
|
|
295
|
|
|
return JsonResponse::create([ |
|
|
|
|
296
|
|
|
'message' => trans('exceptions.http.500_message'), |
297
|
|
|
'errors' => (object)[ |
298
|
|
|
$e->getCode() => [$e->getMessage()], |
299
|
|
|
], |
300
|
|
|
], Response::HTTP_INTERNAL_SERVER_ERROR, [ |
301
|
|
|
'Content-Language' => $this->currentLocale, |
302
|
|
|
]); |
303
|
|
|
} |
304
|
|
|
} |
305
|
|
|
} |
306
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.