Test Setup Failed
Pull Request — master (#150)
by Nick
14:47 queued 06:28
created

AbstractApiController::update()   A

Complexity

Conditions 3
Paths 9

Size

Total Lines 35
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5.0297

Importance

Changes 0
Metric Value
eloc 25
c 0
b 0
f 0
dl 0
loc 35
ccs 9
cts 23
cp 0.3913
rs 9.52
cc 3
nc 9
nop 2
crap 5.0297
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 28
            'index',
60
            'show',
61
            'store',
62
            'update',
63
            'destroy',
64 28
        ], '', Request::route()->getName());
65
66 28
        parent::__construct();
67 28
    }
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 4
            ], 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