Completed
Push — master ( 272243...2e6f42 )
by Sherif
13:48
created

BaseApiController::setRelations()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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