Completed
Push — master ( eb2586...ec2395 )
by Sherif
01:59
created

BaseApiController   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 35
lcom 1
cbo 3
dl 0
loc 204
rs 9.6
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 16 4
A index() 0 4 1
A find() 0 4 1
A delete() 0 4 1
A deleted() 0 4 1
A restore() 0 4 1
B checkPermission() 0 22 10
A setSessions() 0 27 5
A setRelations() 0 6 4
B updateLocaleAndTimezone() 0 19 7
1
<?php
2
3
namespace App\Modules\Core\BaseClasses;
4
5
use App\Http\Controllers\Controller;
6
use Illuminate\Http\Request;
7
use Illuminate\Support\Arr;
8
use App\Modules\Core\Http\Resources\General as GeneralResource;
9
10
class BaseApiController extends Controller
11
{
12
    /**
13
     * The config implementation.
14
     *
15
     * @var array
16
     */
17
    protected $config;
18
19
    /**
20
     * The relations implementation.
21
     *
22
     * @var array
23
     */
24
    protected $relations;
25
26
    /**
27
     * The repo implementation.
28
     *
29
     * @var object
30
     */
31
    protected $repo;
32
33
    /**
34
     * Init new object.
35
     *
36
     * @param   mixed      $repo
37
     * @param   CoreConfig $config
38
     * @param   string     $modelResource
39
     * @return  void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
40
     */
41
    public function __construct($repo, $config, $modelResource)
42
    {
43
        $this->repo = $repo;
44
        $this->modelResource = $modelResource;
45
        $this->config = $config->getConfig();
46
        $this->modelName = explode('\\', get_called_class());
47
        $this->modelName = lcfirst(str_replace('Controller', '', end($this->modelName)));
48
        $this->validationRules = property_exists($this, 'validationRules') ? $this->validationRules : false;
49
        $this->skipPermissionCheck = property_exists($this, 'skipPermissionCheck') ? $this->skipPermissionCheck : [];
50
        $this->skipLoginCheck = property_exists($this, 'skipLoginCheck') ? $this->skipLoginCheck : [];
51
        $route = explode('@', \Route::currentRouteAction())[1];
52
53
        $this->setSessions();
54
        $this->checkPermission($route);
55
        $this->setRelations($route);
56
    }
57
58
    /**
59
     * Fetch all records with relations from storage.
60
     *
61
     * @param Request $request
62
     * @return \Illuminate\Http\Response
63
     */
64
    public function index(Request $request)
65
    {
66
        return $this->modelResource::collection($this->repo->list($this->relations, $request->query(), $request->query('perPage'), $request->query('sortBy'), $request->query('desc')));
67
    }
68
69
    /**
70
     * Fetch the single object with relations from storage.
71
     *
72
     * @param  integer $id Id of the requested model.
73
     * @return \Illuminate\Http\Response
74
     */
75
    public function find($id)
76
    {
77
        return new $this->modelResource($this->repo->find($id, $this->relations));
78
    }
79
80
    /**
81
     * Delete by the given id from storage.
82
     *
83
     * @param  integer $id Id of the deleted model.
84
     * @return \Illuminate\Http\Response
85
     */
86
    public function delete($id)
87
    {
88
        return new GeneralResource($this->repo->delete($id));
89
    }
90
91
    /**
92
     * Return the deleted models in pages based on the given conditions.
93
     *
94
     * @param Request $request
95
     * @return \Illuminate\Http\Response
96
     */
97
    public function deleted(Request $request)
98
    {
99
        return $this->modelResource::collection($this->repo->deleted($request->all(), $request->query('perPage'), $request->query('sortBy'), $request->query('desc')));
100
    }
101
102
    /**
103
     * Restore the deleted model.
104
     *
105
     * @param  integer $id Id of the restored model.
106
     * @return \Illuminate\Http\Response
107
     */
108
    public function restore($id)
109
    {
110
        return new GeneralResource($this->repo->restore($id));
111
    }
112
113
    /**
114
     * Check if the logged in user can do the given permission.
115
     *
116
     * @param  string $permission
117
     * @return void
118
     */
119
    private function checkPermission($permission)
120
    {
121
        \Auth::shouldUse('api');
122
        $this->middleware('auth:api', ['except' => $this->skipLoginCheck]);
123
        
124
        if (! in_array($permission, $this->skipLoginCheck) && $user = \Auth::user()) {
125
            $user             = \Auth::user();
126
            $permission       = $permission !== 'index' ? $permission : 'list';
127
            $isPasswordClient = $user->token()->client->password_client;
128
            $this->updateLocaleAndTimezone($user);
129
130
            if ($user->blocked) {
131
                \ErrorHandler::userIsBlocked();
132
            }
133
134
            if ($isPasswordClient && (in_array($permission, $this->skipPermissionCheck) || \Core::users()->can($permission, $this->modelName))) {
135
            } elseif (! $isPasswordClient && $user->tokenCan($this->modelName.'-'.$permission)) {
136
            } else {
137
                \ErrorHandler::noPermissions();
138
            }
139
        }
140
    }
141
142
    /**
143
     * Set sessions based on the given headers in the request.
144
     *
145
     * @return void
146
     */
147
    private function setSessions()
148
    {
149
        \Session::put('time-zone', \Request::header('time-zone') ?: 0);
150
151
        $locale = \Request::header('locale');
152
        switch ($locale) {
153
            case 'en':
154
                \App::setLocale('en');
155
                \Session::put('locale', 'en');
156
                break;
157
158
            case 'ar':
159
                \App::setLocale('ar');
160
                \Session::put('locale', 'ar');
161
                break;
162
163
            case 'all':
164
                \App::setLocale('en');
165
                \Session::put('locale', 'all');
166
                break;
167
168
            default:
169
                \App::setLocale('en');
170
                \Session::put('locale', 'en');
171
                break;
172
        }
173
    }
174
175
    /**
176
     * Set relation based on the called api.
177
     *
178
     * @param  string $route
179
     * @return void
180
     */
181
    private function setRelations($route)
182
    {
183
        $route           = $route !== 'index' ? $route : 'list';
184
        $relations       = Arr::get($this->config['relations'], $this->modelName, false);
185
        $this->relations = $relations && isset($relations[$route]) ? $relations[$route] : [];
186
    }
187
188
    /**
189
     * Update the logged in user locale and time zone.
190
     *
191
     * @param  object $user
192
     * @return void
193
     */
194
    private function updateLocaleAndTimezone($user)
195
    {
196
        $update   = false;
197
        $locale   = \Session::get('locale');
198
        $timezone = \Session::get('time-zone');
199
        if ($locale && $locale !== 'all' && $locale !== $user->locale) {
200
            $user->locale = $locale;
201
            $update       = true;
202
        }
203
204
        if ($timezone && $timezone !== $user->timezone) {
205
            $user->timezone = $timezone;
206
            $update       = true;
207
        }
208
209
        if ($update) {
210
            $user->save();
211
        }
212
    }
213
}
214