1
|
|
|
<?php |
2
|
|
|
namespace App\Modules\V1\Core\Http\Controllers; |
3
|
|
|
|
4
|
|
|
use App\Http\Controllers\Controller; |
5
|
|
|
use Illuminate\Http\Request; |
6
|
|
|
|
7
|
|
|
class BaseApiController extends Controller |
8
|
|
|
{ |
9
|
|
|
/** |
10
|
|
|
* The config implementation. |
11
|
|
|
* |
12
|
|
|
* @var array |
13
|
|
|
*/ |
14
|
|
|
protected $config; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* The relations implementation. |
18
|
|
|
* |
19
|
|
|
* @var array |
20
|
|
|
*/ |
21
|
|
|
protected $relations; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* The repo implementation. |
25
|
|
|
* |
26
|
|
|
* @var object |
27
|
|
|
*/ |
28
|
|
|
protected $repo; |
29
|
|
|
|
30
|
|
|
public function __construct() |
31
|
|
|
{ |
32
|
|
|
$this->config = \CoreConfig::getConfig(); |
33
|
|
|
$this->model = property_exists($this, 'model') ? $this->model : false; |
34
|
|
|
$this->validationRules = property_exists($this, 'validationRules') ? $this->validationRules : false; |
35
|
|
|
$this->skipPermissionCheck = property_exists($this, 'skipPermissionCheck') ? $this->skipPermissionCheck : []; |
36
|
|
|
$this->skipLoginCheck = property_exists($this, 'skipLoginCheck') ? $this->skipLoginCheck : []; |
37
|
|
|
$this->repo = call_user_func_array("\Core::{$this->model}", []); |
38
|
|
|
$route = explode('@',\Route::currentRouteAction())[1]; |
39
|
|
|
|
40
|
|
|
$this->checkPermission($route); |
41
|
|
|
$this->setRelations($route); |
42
|
|
|
$this->setSessions(); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Fetch all records with relations from storage. |
47
|
|
|
* |
48
|
|
|
* @param string $sortBy The name of the column to sort by. |
49
|
|
|
* @param boolean $desc Sort ascending or descinding (1: desc, 0: asc). |
50
|
|
|
* @return \Illuminate\Http\Response |
51
|
|
|
*/ |
52
|
|
View Code Duplication |
public function index($sortBy = 'created_at', $desc = 1) |
|
|
|
|
53
|
|
|
{ |
54
|
|
|
if ($this->repo) |
55
|
|
|
{ |
56
|
|
|
return \Response::json($this->repo->all($this->relations, $sortBy, $desc), 200); |
57
|
|
|
} |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Fetch the single object with relations from storage. |
62
|
|
|
* |
63
|
|
|
* @param integer $id Id of the requested model. |
64
|
|
|
* @return \Illuminate\Http\Response |
65
|
|
|
*/ |
66
|
|
|
public function find($id) |
67
|
|
|
{ |
68
|
|
|
if ($this->repo) |
69
|
|
|
{ |
70
|
|
|
return \Response::json($this->repo->find($id, $this->relations), 200); |
71
|
|
|
} |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Paginate all records with relations from storage |
76
|
|
|
* that matche the given query. |
77
|
|
|
* |
78
|
|
|
* @param string $query The search text. |
79
|
|
|
* @param integer $perPage Number of rows per page default 15. |
80
|
|
|
* @param string $sortBy The name of the column to sort by. |
81
|
|
|
* @param boolean $desc Sort ascending or descinding (1: desc, 0: asc). |
82
|
|
|
* @return \Illuminate\Http\Response |
83
|
|
|
*/ |
84
|
|
|
public function search($query = '', $perPage = 15, $sortBy = 'created_at', $desc = 1) |
85
|
|
|
{ |
86
|
|
|
if ($this->repo) |
87
|
|
|
{ |
88
|
|
|
return \Response::json($this->repo->search($query, $perPage, $this->relations, $sortBy, $desc), 200); |
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Fetch records from the storage based on the given |
94
|
|
|
* condition. |
95
|
|
|
* |
96
|
|
|
* @param \Illuminate\Http\Request $request |
97
|
|
|
* @param string $sortBy The name of the column to sort by. |
98
|
|
|
* @param boolean $desc Sort ascending or descinding (1: desc, 0: asc). |
99
|
|
|
* @return \Illuminate\Http\Response |
100
|
|
|
*/ |
101
|
|
View Code Duplication |
public function findby(Request $request, $sortBy = 'created_at', $desc = 1) |
|
|
|
|
102
|
|
|
{ |
103
|
|
|
if ($this->repo) |
104
|
|
|
{ |
105
|
|
|
return \Response::json($this->repo->findBy($request->all(), $this->relations, $sortBy, $desc), 200); |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Fetch the first record from the storage based on the given |
111
|
|
|
* condition. |
112
|
|
|
* |
113
|
|
|
* @param \Illuminate\Http\Request $request |
114
|
|
|
* @return \Illuminate\Http\Response |
115
|
|
|
*/ |
116
|
|
|
public function first(Request $request) |
117
|
|
|
{ |
118
|
|
|
if ($this->repo) |
119
|
|
|
{ |
120
|
|
|
return \Response::json($this->repo->first($request->all(), $this->relations), 200); |
121
|
|
|
} |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Paginate all records with relations from storage. |
126
|
|
|
* |
127
|
|
|
* @param integer $perPage Number of rows per page default 15. |
128
|
|
|
* @param string $sortBy The name of the column to sort by. |
129
|
|
|
* @param boolean $desc Sort ascending or descinding (1: desc, 0: asc). |
130
|
|
|
* @return \Illuminate\Http\Response |
131
|
|
|
*/ |
132
|
|
View Code Duplication |
public function paginate($perPage = 15, $sortBy = 'created_at', $desc = 1) |
|
|
|
|
133
|
|
|
{ |
134
|
|
|
if ($this->repo) |
135
|
|
|
{ |
136
|
|
|
return \Response::json($this->repo->paginate($perPage, $this->relations, $sortBy, $desc), 200); |
137
|
|
|
} |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Fetch all records with relations based on |
142
|
|
|
* the given condition from storage in pages. |
143
|
|
|
* |
144
|
|
|
* @param \Illuminate\Http\Request $request |
145
|
|
|
* @param integer $perPage Number of rows per page default 15. |
146
|
|
|
* @param string $sortBy The name of the column to sort by. |
147
|
|
|
* @param boolean $desc Sort ascending or descinding (1: desc, 0: asc). |
148
|
|
|
* @return \Illuminate\Http\Response |
149
|
|
|
*/ |
150
|
|
View Code Duplication |
public function paginateby(Request $request, $perPage = 15, $sortBy = 'created_at', $desc = 1) |
|
|
|
|
151
|
|
|
{ |
152
|
|
|
if ($this->repo) |
153
|
|
|
{ |
154
|
|
|
return \Response::json($this->repo->paginateBy($request->all(), $perPage, $this->relations, $sortBy, $desc), 200); |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Save the given model to storage. |
160
|
|
|
* |
161
|
|
|
* @param \Illuminate\Http\Request $request |
162
|
|
|
* @return \Illuminate\Http\Response |
163
|
|
|
*/ |
164
|
|
View Code Duplication |
public function save(Request $request) |
|
|
|
|
165
|
|
|
{ |
166
|
|
|
foreach ($this->validationRules as &$rule) |
167
|
|
|
{ |
168
|
|
|
if (strpos($rule, 'exists') && ! strpos($rule, 'deleted_at,NULL')) |
169
|
|
|
{ |
170
|
|
|
$rule .= ',deleted_at,NULL'; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
if ($request->has('id')) |
174
|
|
|
{ |
175
|
|
|
$rule = str_replace('{id}', $request->get('id'), $rule); |
176
|
|
|
} |
177
|
|
|
else |
178
|
|
|
{ |
179
|
|
|
$rule = str_replace(',{id}', '', $rule); |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
$this->validate($request, $this->validationRules); |
184
|
|
|
|
185
|
|
|
if ($this->repo) |
186
|
|
|
{ |
187
|
|
|
return \Response::json($this->repo->save($request->all()), 200); |
188
|
|
|
} |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Delete by the given id from storage. |
193
|
|
|
* |
194
|
|
|
* @param integer $id Id of the deleted model. |
195
|
|
|
* @return \Illuminate\Http\Response |
196
|
|
|
*/ |
197
|
|
|
public function delete($id) |
198
|
|
|
{ |
199
|
|
|
if ($this->repo) |
200
|
|
|
{ |
201
|
|
|
return \Response::json($this->repo->delete($id), 200); |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Return the deleted models in pages based on the given conditions. |
207
|
|
|
* |
208
|
|
|
* @param \Illuminate\Http\Request $request |
209
|
|
|
* @param integer $perPage Number of rows per page default 15. |
210
|
|
|
* @param string $sortBy The name of the column to sort by. |
211
|
|
|
* @param boolean $desc Sort ascending or descinding (1: desc, 0: asc). |
212
|
|
|
* @return \Illuminate\Http\Response |
213
|
|
|
*/ |
214
|
|
|
public function deleted(Request $request, $perPage = 15, $sortBy = 'created_at', $desc = 1) |
215
|
|
|
{ |
216
|
|
|
return \Response::json($this->repo->deleted($request->all(), $perPage, $sortBy, $desc), 200); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Restore the deleted model. |
221
|
|
|
* |
222
|
|
|
* @param integer $id Id of the restored model. |
223
|
|
|
* @return \Illuminate\Http\Response |
224
|
|
|
*/ |
225
|
|
|
public function restore($id) |
226
|
|
|
{ |
227
|
|
|
if ($this->repo) |
228
|
|
|
{ |
229
|
|
|
return \Response::json($this->repo->restore($id), 200); |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* Check if the logged in user can do the given permission. |
235
|
|
|
* |
236
|
|
|
* @param string $permission |
237
|
|
|
* @return void |
238
|
|
|
*/ |
239
|
|
|
private function checkPermission($permission) |
240
|
|
|
{ |
241
|
|
|
\Auth::shouldUse('api'); |
242
|
|
|
$this->middleware('auth:api', ['except' => $this->skipLoginCheck]); |
243
|
|
|
|
244
|
|
|
if ($user = \Auth::user()) |
245
|
|
|
{ |
246
|
|
|
$permission = $permission !== 'index' ? $permission : 'list'; |
247
|
|
|
$isPasswordClient = $user->token()->client->password_client; |
248
|
|
|
|
249
|
|
|
if ($user->blocked) |
250
|
|
|
{ |
251
|
|
|
\ErrorHandler::userIsBlocked(); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
if ($isPasswordClient && (in_array($permission, $this->skipPermissionCheck) || \Core::users()->can($permission, $this->model))) |
|
|
|
|
255
|
|
|
{} |
256
|
|
|
elseif ( ! $isPasswordClient && $user->tokenCan($this->model . '-' . $permission)) |
|
|
|
|
257
|
|
|
{} |
258
|
|
|
else |
259
|
|
|
{ |
260
|
|
|
|
261
|
|
|
\ErrorHandler::noPermissions(); |
262
|
|
|
} |
263
|
|
|
} |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Set sessions based on the given headers in the request. |
268
|
|
|
* |
269
|
|
|
* @return void |
270
|
|
|
*/ |
271
|
|
|
private function setSessions() |
272
|
|
|
{ |
273
|
|
|
\Session::put('timeZoneDiff', \Request::header('time-zone-diff') ?: 0); |
274
|
|
|
|
275
|
|
|
$locale = \Request::header('locale'); |
276
|
|
|
switch ($locale) |
277
|
|
|
{ |
278
|
|
|
case 'en': |
279
|
|
|
\App::setLocale('en'); |
280
|
|
|
\Session::put('locale', 'en'); |
281
|
|
|
break; |
282
|
|
|
|
283
|
|
|
case 'ar': |
284
|
|
|
\App::setLocale('ar'); |
285
|
|
|
\Session::put('locale', 'ar'); |
286
|
|
|
break; |
287
|
|
|
|
288
|
|
|
case 'all': |
289
|
|
|
\App::setLocale('en'); |
290
|
|
|
\Session::put('locale', 'all'); |
291
|
|
|
break; |
292
|
|
|
|
293
|
|
|
default: |
294
|
|
|
\App::setLocale('en'); |
295
|
|
|
\Session::put('locale', 'en'); |
296
|
|
|
break; |
297
|
|
|
} |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* Set relation based on the called api. |
302
|
|
|
* |
303
|
|
|
* @param string $route |
304
|
|
|
* @return void |
305
|
|
|
*/ |
306
|
|
|
private function setRelations($route) |
307
|
|
|
{ |
308
|
|
|
$route = $route !== 'index' ? $route : 'list'; |
309
|
|
|
$relations = array_key_exists($this->model, $this->config['relations']) ? $this->config['relations'][$this->model] : false; |
310
|
|
|
$this->relations = $relations && isset($relations[$route]) ? $relations[$route] : []; |
311
|
|
|
} |
312
|
|
|
} |
313
|
|
|
|
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.