Completed
Push — master ( c8ea4b...c4213a )
by Sherif
02:51
created

BaseApiController::checkPermission()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 18
rs 8.8571
cc 6
eloc 10
nc 8
nop 1
1
<?php
2
namespace App\Modules\Core\Http\Controllers;
3
4
use App\Http\Controllers\Controller;
5
use Illuminate\Http\Request;
6
use App\Modules\Core\ErrorHandler;
7
use App\Modules\Core\CoreConfig;
8
9
10
class BaseApiController extends Controller
11
{
12
    /**
13
     * The errorHandler implementation.
14
     * 
15
     * @var errorHandler
16
     */
17
    protected $errorHandler;
18
19
    /**
20
     * The config implementation.
21
     * 
22
     * @var config
23
     */
24
    protected $config;
25
26
    /**
27
     * The model implementation.
28
     * 
29
     * @var model
30
     */
31
    protected $model;
32
33
    /**
34
     * Create new BaseApiController instance.
35
     * 
36
     * @param errorHandler
37
     */
38
    public function __construct(ErrorHandler $errorHandler, CoreConfig $config)
39
    {
40
        \Session::set('timeZoneDiff', \Request::header('time-zone-diff') ?: 0);
41
        
42
        $this->errorHandler        = $errorHandler;
0 ignored issues
show
Documentation Bug introduced by
It seems like $errorHandler of type object<App\Modules\Core\ErrorHandler> is incompatible with the declared type object<App\Modules\Core\...ntrollers\errorHandler> of property $errorHandler.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
43
        $this->config              = $config->getConfig();
0 ignored issues
show
Documentation Bug introduced by
It seems like $config->getConfig() of type array is incompatible with the declared type object<App\Modules\Core\Http\Controllers\config> of property $config.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
44
        
45
        $this->model               = property_exists($this, 'model') ? $this->model : false;
0 ignored issues
show
Documentation Bug introduced by
It seems like property_exists($this, '... ? $this->model : false can also be of type false. However, the property $model is declared as type object<App\Modules\Core\Http\Controllers\model>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
46
        $this->validationRules     = property_exists($this, 'validationRules') ? $this->validationRules : false;
47
        $this->skipPermissionCheck = property_exists($this, 'skipPermissionCheck') ? $this->skipPermissionCheck : [];
48
        $this->skipLoginCheck      = property_exists($this, 'skipLoginCheck') ? $this->skipLoginCheck : [];
49
        
50
        $this->relations           = array_key_exists($this->model, $this->config['relations']) ? $this->config['relations'][$this->model] : false;
51
        $route                     = explode('@',\Route::currentRouteAction())[1];
52
        $this->checkPermission(explode('_', snake_case($route))[1]);
53
    }
54
55
    /**
56
     * Fetch all records with relations from model repository.
57
     * 
58
     * @param  string  $sortBy
0 ignored issues
show
Bug introduced by
There is no parameter named $sortBy. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
59
     * @param  boolean $desc
0 ignored issues
show
Bug introduced by
There is no parameter named $desc. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
60
     * @return \Illuminate\Http\Response
61
     */
62
    public function getIndex() 
63
    {
64
        if ($this->model)
65
        {
66
            $relations = $this->relations && $this->relations['all'] ? $this->relations['all'] : [];
67
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->all($relations), 200);
68
        }
69
    }
70
71
    /**
72
     * Fetch the single object with relations from model repository.
73
     * 
74
     * @param  integer $id
75
     * @return \Illuminate\Http\Response
76
     */
77 View Code Duplication
    public function getFind($id) 
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
78
    {
79
        if ($this->model) 
80
        {
81
            $relations = $this->relations && $this->relations['find'] ? $this->relations['find'] : [];
82
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->find($id, $relations), 200);
83
        }
84
    }
85
86
    /**
87
     * Paginate all records with relations from model repository
88
     * that matche the given query.
89
     * 
90
     * @param  string  $query
91
     * @param  integer $perPage
92
     * @param  string  $sortBy
93
     * @param  boolean $desc
94
     * @return \Illuminate\Http\Response
95
     */
96 View Code Duplication
    public function getSearch($query = '', $perPage = 15, $sortBy = 'created_at', $desc = 1) 
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
    {
98
        if ($this->model) 
99
        {
100
            $relations = $this->relations && $this->relations['paginate'] ? $this->relations['paginate'] : [];
101
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->search($query, $perPage, $relations, $sortBy, $desc), 200);
102
        }
103
    }
104
105
    /**
106
     * Fetch records from the storage based on the given
107
     * condition.
108
     * 
109
     * @param  \Illuminate\Http\Request  $request
110
     * @param  string  $sortBy
111
     * @param  boolean $desc
112
     * @return \Illuminate\Http\Response
113
     */
114 View Code Duplication
    public function postFindby(Request $request, $sortBy = 'created_at', $desc = 1) 
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115
    {
116
        if ($this->model) 
117
        {
118
            $relations = $this->relations && $this->relations['findBy'] ? $this->relations['findBy'] : [];
119
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->findBy($request->all(), $relations, $sortBy, $desc), 200);
120
        }
121
    }
122
123
    /**
124
     * Fetch the first record from the storage based on the given
125
     * condition.
126
     * 
127
     * @param  \Illuminate\Http\Request  $request
128
     * @return \Illuminate\Http\Response
129
     */
130 View Code Duplication
    public function postFirst(Request $request) 
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
    {
132
        if ($this->model) 
133
        {
134
            $relations = $this->relations && $this->relations['first'] ? $this->relations['first'] : [];
135
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->first($request->all(), $relations), 200);
136
        }
137
    }
138
139
    /**
140
     * Paginate all records with relations from model repository.
141
     * 
142
     * @param  integer $perPage
143
     * @param  string  $sortBy
144
     * @param  boolean $desc
145
     * @return \Illuminate\Http\Response
146
     */
147 View Code Duplication
    public function getPaginate($perPage = 15, $sortBy = 'created_at', $desc = 1) 
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
148
    {
149
        if ($this->model) 
150
        {
151
            $relations = $this->relations && $this->relations['paginate'] ? $this->relations['paginate'] : [];
152
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->paginate($perPage, $relations, $sortBy, $desc), 200);
153
        }
154
    }
155
156
    /**
157
     * Fetch all records with relations based on
158
     * the given condition from storage in pages.
159
     * 
160
     * @param  \Illuminate\Http\Request  $request
161
     * @param  integer $perPage
162
     * @param  string  $sortBy
163
     * @param  boolean $desc
164
     * @return \Illuminate\Http\Response
165
     */
166 View Code Duplication
    public function postPaginateby(Request $request, $perPage = 15, $sortBy = 'created_at', $desc = 1) 
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
167
    {
168
        if ($this->model) 
169
        {
170
            $relations = $this->relations && $this->relations['paginateBy'] ? $this->relations['paginateBy'] : [];
171
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->paginateBy($request->all(), $perPage, $relations, $sortBy, $desc), 200);
172
        }
173
    }
174
175
    /**
176
     * Save the given model to repository.
177
     * 
178
     * @param  \Illuminate\Http\Request  $request
179
     * @return \Illuminate\Http\Response
180
     */
181
    public function postSave(Request $request) 
182
    {
183
        foreach ($this->validationRules as &$rule) 
184
        {
185
            if (strpos($rule, 'exists') && ! strpos($rule, 'deleted_at,NULL')) 
186
            {
187
                $rule .= ',deleted_at,NULL';
188
            }
189
190
            if ($request->has('id')) 
191
            {
192
                $rule = str_replace('{id}', $request->get('id'), $rule);
193
            }
194
            else
195
            {
196
                $rule = str_replace(',{id}', '', $rule);
197
            }
198
        }
199
        
200
        $this->validate($request, $this->validationRules);
201
202
        if ($this->model) 
203
        {
204
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->save($request->all()), 200);
205
        }
206
    }
207
208
    /**
209
     * Delete by the given id from model repository.
210
     * 
211
     * @param  integer  $id
212
     * @return \Illuminate\Http\Response
213
     */
214
    public function getDelete($id) 
215
    {
216
        if ($this->model) 
217
        {
218
            return \Response::json(call_user_func_array("\Core::{$this->model}", [])->delete($id), 200);
219
        }
220
    }
221
222
    /**
223
     * Check if the logged in user can do the given permission.
224
     * 
225
     * @param  string $permission
226
     * @return void
227
     */
228
    private function checkPermission($permission)
229
    {
230
        $permission = $permission !== 'index' ? $permission : 'list';
231
        if ($permission == 'method') 
232
        {
233
            $error = $this->errorHandler->notFound('method');
234
            abort($error['status'], $error['message']);
235
        }
236
        else if ( ! in_array($permission, $this->skipLoginCheck)) 
237
        {
238
            \JWTAuth::parseToken()->authenticate();
239
            if ( ! in_array($permission, $this->skipPermissionCheck) && ! \Core::users()->can($permission, $this->model))
240
            {
241
                $error = $this->errorHandler->noPermissions();
242
                abort($error['status'], $error['message']);
243
            }
244
        }
245
    }
246
}
247