Completed
Push — master ( 3a32b0...328300 )
by Babak
02:24
created

BaseController::index()   F

Complexity

Conditions 14
Paths 909

Size

Total Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
nc 909
nop 1
dl 0
loc 74
rs 2.3483
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Alive2212\LaravelSmartRestful;
4
5
use Alive2212\ExcelHelper\ExcelHelper;
6
use Alive2212\LaravelQueryHelper\QueryHelper;
0 ignored issues
show
Bug introduced by
The type Alive2212\LaravelQueryHelper\QueryHelper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Alive2212\LaravelRequestHelper\RequestHelper;
0 ignored issues
show
Bug introduced by
The type Alive2212\LaravelRequestHelper\RequestHelper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Alive2212\LaravelSmartResponse\ResponseModel;
9
use Alive2212\LaravelSmartResponse\SmartResponse\SmartResponse;
0 ignored issues
show
Bug introduced by
The type Alive2212\LaravelSmartRe...tResponse\SmartResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Alive2212\LaravelStringHelper\StringHelper;
0 ignored issues
show
Bug introduced by
The type Alive2212\LaravelStringHelper\StringHelper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use App\Http\Controllers\Controller;
0 ignored issues
show
Bug introduced by
The type App\Http\Controllers\Controller was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Illuminate\Database\Eloquent\ModelNotFoundException;
13
use Illuminate\Database\QueryException;
14
use Illuminate\Http\Request;
15
use Illuminate\Support\Facades\DB;
16
use Illuminate\Support\MessageBag;
17
use Illuminate\Support\Facades\Validator;
18
19
20
abstract class BaseController extends Controller
21
{
22
    /**
23
     * to use this class
24
     * create message list as messages in message file
25
     * override __constructor and define your model
26
     * define your rules for index,store and update
27
     */
28
29
    protected $DEFAULT_RESULT_PER_PAGE = 15;
30
31
    /**
32
     * @var array
33
     */
34
    protected $pivotFields = [];
35
36
    /**
37
     * @var array
38
     */
39
    protected $uniqueFields = [];
40
41
    /**
42
     * @var bool|string
43
     */
44
    protected $modelName;
45
46
    /**
47
     * @var string
48
     */
49
    protected $messagePrefix = 'messages.api.v1.';
50
51
    /**
52
     * this model
53
     */
54
    protected $model;
55
56
    /**
57
     * index request validator rules
58
     *
59
     * @var array
60
     */
61
    protected $indexValidateArray = [
62
        //
63
    ];
64
65
    /**
66
     * array of relationship for eager loading
67
     *
68
     * @var array
69
     */
70
    protected $indexLoad = [
71
        //
72
    ];
73
74
    /**
75
     * array of relationship for eager loading
76
     *
77
     * @var array
78
     */
79
    protected $editLoad = [
80
        //
81
    ];
82
83
    /**
84
     * array of relationship for eager loading
85
     *
86
     * @var array
87
     */
88
    protected $updateLoad = [
89
        //
90
    ];
91
92
    /**
93
     * store request validator rules
94
     *
95
     * @var array
96
     */
97
    protected $storeValidateArray = [
98
        //
99
    ];
100
101
    /**
102
     * update request validator rules
103
     *
104
     * @var array
105
     */
106
    protected $updateValidateArray = [
107
        //
108
    ];
109
110
    protected $middlewareParams = [];
111
112
    /**
113
     * defaultController constructor.
114
     */
115
    public function __construct()
116
    {
117
//        dd("I have closest relationship with all US celebrities");
118
        $this->initController();
119
    }
120
121
    abstract public function initController();
122
123
    /**
124
     * Display a listing of the resource.
125
     *
126
     * @param Request $request
127
     * @return string
128
     */
129
    public function index(Request $request)
130
    {
131
        // create response model
132
        $response = new ResponseModel();
133
134
        //set default pagination
135
        if (isset($request->toArray()['page']['size'])) {
136
            if (is_null($request->toArray()['page']['size'])) {
137
                $request['page'] = ['size' => $this->DEFAULT_RESULT_PER_PAGE];
138
            }
139
        }
140
141
        //set default ordering
142
        if (isset($request->toArray()['order_by'])) {
143
            if (is_null($request['order_by'])) {
144
                $request['order_by'] = "{\"field\":\"id\",\"operator\":\"Desc\"}";
145
            }
146
        }
147
148
149
        $validationErrors = $this->checkRequestValidation($request, $this->indexValidateArray);
150
        if ($validationErrors != null) {
151
152
            // return response
153
            $response->setData(collect($validationErrors->toArray()));
154
            $response->setMessage("Validation Failed");
155
            $response->setStatus(false);
156
            $response->setError(99);
157
            return SmartResponse::response($response);
158
        }
159
160
        try {
161
            $data = $request->get('query') != null ?
162
                $this->model
163
                    ->whereKey(collect($this->model
164
                        ->search(($request->get('query')))
165
                        ->raw())->get('ids')) :
166
                $this->model;
167
            if (array_key_exists('file', $request->toArray())) {
168
                //TODO add relation on top if here and create a tree flatter array in array helper
169
                return (new ExcelHelper())->setOptions([
0 ignored issues
show
Bug introduced by
Are you sure the usage of new Alive2212\ExcelHelpe...ExcelFile()->download() targeting Alive2212\ExcelHelper\ExcelHelper::download() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
170
                    'store_format' => $request->get('file') == null ? 'xls' : $request->get('file'),
171
                    'download_format' => $request->get('file') == null ? 'xls' : $request->get('file'),
172
                ])->table($data->get()->toArray())->createExcelFile()->download();
173
            }
174
175
            // load relations
176
            if (count($this->indexLoad) > 0) {
177
                $data = $data->with($this->indexLoad);
178
            }
179
180
            // filters by
181
            if (isset($request->toArray()['filters'])) {
182
                $data = (new QueryHelper())->deepFilter($data, (new RequestHelper())->getCollectFromJson($request['filters']));
183
            }
184
185
            // order by
186
            if (isset($request->toArray()['order_by'])) {
187
                $data = (new QueryHelper())->orderBy($data, (new RequestHelper())->getCollectFromJson($request['order_by']));
188
            }
189
190
            // return response
191
            $response->setData(collect($data->paginate()));
192
            $response->setMessage("Successful");
193
            return SmartResponse::response($response);
194
195
        } catch (QueryException $exception) {
196
197
            // return response
198
            $response->setData(collect($exception->getMessage()));
199
            $response->setError($exception->getCode());
200
            $response->setMessage("Failed");
201
            $response->setStatus(false);
202
            return SmartResponse::response($response);
203
        }
204
    }
205
206
    public function checkRequestValidation(Request $request, $validationArray)
207
    {
208
        $requestParams = $request->toArray();
209
        $validator = Validator::make($request->all(), $validationArray);
210
        if ($validator->fails()) {
211
            return $validator->errors();
212
        }
213
        if (is_numeric(array_search($request->getMethod(), ["POST", "PUT", "PATCH"]))) {
214
            $errors = new MessageBag();
215
            foreach ($requestParams as $requestParamKey => $requestParamValue) {
216
                if (is_numeric(array_search($requestParamKey, $this->uniqueFields))) {
217
                    if ($this->checkExistUniqueRecord($requestParamKey, $requestParamValue)) {
218
                        $errors->add($requestParamKey, 'This ' . $requestParamKey . ' is exist try another.');
219
                    }
220
                }
221
            }
222
            if (collect($errors)->count() > 0) {
223
                return $errors;
224
            }
225
        }
226
        return null;
227
    }
228
229
    /**
230
     * @param $key
231
     * @param $value
232
     * @return bool
233
     */
234
    public function checkExistUniqueRecord($key, $value)
235
    {
236
        if ($this->model->where($key, $value)->count()) {
237
            return true;
238
        }
239
        return false;
240
    }
241
242
    /**
243
     * @param $status
244
     * @return mixed
245
     */
246
    public function message($status)
247
    {
248
        $key = $this->messagePrefix . $this->modelName . '.' . debug_backtrace()[1]['function'] . '.' . $status;
249
        return $this->getMessageFromFile($key);
250
    }
251
252
    /**
253
     * @param $key
254
     * @return mixed
255
     */
256
    public function getMessageFromFile($key)
257
    {
258
        return config($key);
259
    }
260
261
    /**
262
     * Show the form for creating a new resource.
263
     *
264
     * @return \Illuminate\Http\JsonResponse
265
     */
266
    public function create()
267
    {
268
        // Create Response Model
269
        $response = new ResponseModel();
270
271
        // return response
272
        $response->setData(collect($this->model->getFillable()));
273
        $response->setMessage("Successful");
274
        return SmartResponse::response($response);
275
    }
276
277
    /**
278
     * Store a newly created resource in storage.
279
     *
280
     * @param  \Illuminate\Http\Request $request
281
     * @return \Illuminate\Http\JsonResponse
282
     */
283
    public function store(Request $request)
284
    {
285
        // Create Response Model
286
        $response = new ResponseModel();
287
288
        // TODO must set access in middle ware
289
        //get user id
290
        $userId = auth()->id();
291
292
        //add author id into the request if doesn't exist
293
        if (isset($request['author_id'])) {
294
            if (is_null($request['author_id'])) {
295
                $request['author_id'] = $userId;
296
            }
297
        } else {
298
            $request['author_id'] = $userId;
299
        }
300
301
        //add user id into the request if doesn't exist
302
        if (isset($request['user_id'])) {
303
            if (is_null($request['user_id'])) {
304
                $request['user_id'] = $userId;
305
            }
306
        } else {
307
            $request['user_id'] = $userId;
308
        }
309
310
        $validationErrors = $this->checkRequestValidation($request, $this->storeValidateArray);
311
        if ($validationErrors != null) {
312
            if (env('APP_DEBUG', false)) {
313
                $response->setMessage(json_encode($validationErrors->getMessages()));
314
            }
315
            $response->setStatus(false);
316
            return SmartResponse::response($response);
317
        }
318
        try {
319
            // get result of model creation
320
            $result = $this->model->create($request->all());
321
            // sync many to many relation
322
            foreach ($this->pivotFields as $pivotField) {
323
                if (collect($request[$pivotField])->count()) {
324
                    $pivotField = (new StringHelper())->toCamel($pivotField);
325
                    $this->model->find($result['id'])->$pivotField()->sync(json_decode($request[$pivotField]));
326
                }
327
            }
328
            $response->setMessage('successful');
329
            $response->setData(collect($result->toArray()));
330
            $response->setStatus(true);
331
            return SmartResponse::response($response);
332
        } catch (QueryException $exception) {
333
            if (env('APP_DEBUG', false)) {
334
                $response->setMessage($exception->getMessage());
335
            }
336
            $response->setStatus(false);
337
            return SmartResponse::response($response);
338
        }
339
    }
340
341
    /**
342
     * Display the specdefaultied resource.
343
     *
344
     * @param  int $id
345
     * @return \Illuminate\Http\Response
346
     */
347
    public function show($id)
348
    {
349
        // Create Response Model
350
        $response = new ResponseModel();
0 ignored issues
show
Unused Code introduced by
The assignment to $response is dead and can be removed.
Loading history...
351
352
        try {
353
354
            return SmartResponse::json(
355
                $this->message('successful'),
356
                true,
357
                200,
358
                $this->model->findOrFail($id)
359
            );
360
        } catch (ModelNotFoundException $exception) {
361
            return SmartResponse::json(
362
                $this->message('failed'),
363
                false,
364
                200,
365
                $exception->getMessage()
366
            );
367
        }
368
    }
369
370
    /**
371
     * Show the form for editing the specified resource.
372
     *
373
     * @param  int $id
374
     * @return \Illuminate\Http\JsonResponse
375
     */
376
    public function edit($id)
377
    {
378
        // Create Response Model
379
        $response = new ResponseModel();
380
381
        try {
382
            $response->setMessage('Successful');
383
            $response->setData($this->model
384
                ->where($this->model->getKeyName(), $id)
385
                ->with(collect($this->editLoad)->count() == 0 ? $this->indexLoad : $this->editLoad)
386
                ->get());
387
            return SmartResponse::response($response);
388
        } catch (ModelNotFoundException $exception) {
389
            $response->setData(collect($exception->getMessage()));
390
            $response->setError($exception->getCode());
0 ignored issues
show
Bug introduced by
It seems like $exception->getCode() can also be of type integer; however, parameter $error of Alive2212\LaravelSmartRe...sponseModel::setError() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

390
            $response->setError(/** @scrutinizer ignore-type */ $exception->getCode());
Loading history...
391
            $response->setMessage('Failed');
392
            $response->setStatus(false);
393
            return SmartResponse::response($response);
394
        }
395
    }
396
397
    /**
398
     * Update the specified resource in storage.
399
     *
400
     * @param  \Illuminate\Http\Request $request
401
     * @param  int $id
402
     * @return \Illuminate\Http\JsonResponse
403
     */
404
    public function update(Request $request, $id)
405
    {
406
        // Create Response Model
407
        $response = new ResponseModel();
408
409
        $validationErrors = $this->checkRequestValidation($request, $this->updateValidateArray);
410
        if ($validationErrors != null) {
411
412
            // return response
413
            $response->setData(collect($validationErrors->toArray()));
414
            $response->setMessage("Validation Failed");
415
            $response->setStatus(false);
416
            $response->setError(99);
417
            return SmartResponse::response($response);
418
        }
419
        try {
420
            // sync many to many relation
421
            foreach ($this->pivotFields as $pivotField) {
422
                if (collect($request[$pivotField])->count()) {
423
                    $pivotMethod = (new StringHelper())->toCamel($pivotField);
424
                    $this->model->findOrFail($id)->$pivotMethod()->sync(json_decode($request[$pivotField], true));
425
                }
426
            }
427
            //get result of update
428
            $result = $this->model->findOrFail($id)->update($request->all());
429
430
            // return response
431
            $response->setData(collect(env('APP_DEBUG') ? $this->model->find($id) : []));
432
            $response->setMessage('Successful to change ' . $result . ' record');
433
            return SmartResponse::response($response);
434
435
436
        } catch (ModelNotFoundException $exception) {
437
438
439
            // return response
440
            $response->setData(collect($exception->getMessage()));
441
            $response->setStatus(false);
442
            $response->setMessage('Not found record');
443
444
            return SmartResponse::response($response);
445
446
        } catch (QueryException $exception) {
447
            // return response
448
            $response->setData(collect($exception->getMessage()));
449
            $response->setStatus(false);
450
            $response->setMessage('Failed');
451
452
            return SmartResponse::response($response);
453
        }
454
    }
455
456
    /**
457
     * Remove the specified resource from storage.
458
     *
459
     * @param  int $id
460
     * @return \Illuminate\Http\JsonResponse
461
     */
462
    public function destroy($id)
463
    {
464
        // Create Response Model
465
        $response = new ResponseModel();
466
467
        try {
468
            // return response
469
            $response->setData(collect($this->model->findOrFail($id)->delete()));
470
            $response->setMessage('Successful');
471
472
            return SmartResponse::response($response);
473
474
        } catch (ModelNotFoundException $exception) {
475
            // return response
476
            $response->setData(collect($exception->getMessage()));
477
            $response->setMessage('Failed');
478
            $response->setStatus(false);
479
            $response->setError($exception->getCode());
0 ignored issues
show
Bug introduced by
It seems like $exception->getCode() can also be of type integer; however, parameter $error of Alive2212\LaravelSmartRe...sponseModel::setError() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

479
            $response->setError(/** @scrutinizer ignore-type */ $exception->getCode());
Loading history...
480
481
            return SmartResponse::response($response);
482
        }
483
    }
484
}