Passed
Push — master ( 6b3304...34df25 )
by Ferry
03:52
created

CB::getDeveloperPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace crocodicstudio\crudbooster\helpers;
4
5
use Illuminate\Http\File;
6
use Illuminate\Support\Facades\Cache;
7
use crocodicstudio\crudbooster\exceptions\CBValidationException;
8
use Illuminate\Support\Facades\DB;
9
use Illuminate\Support\Facades\Config;
10
use Illuminate\Validation\ValidationException;
11
use Image;
12
use Request;
13
use Route;
14
use Illuminate\Support\Facades\Schema;
15
use Illuminate\Support\Facades\Session;
16
use Illuminate\Support\Facades\Storage;
17
use Validator;
18
19
class CB
20
{
21
22
    public function htmlHelper() {
23
        return (new HTMLHelper());
24
    }
25
26
    public function getRoleByName($roleName) {
27
        return $this->find("cb_roles",['name'=>$roleName]);
28
    }
29
30
    public function fcm() {
31
        return new FCM();
32
    }
33
34
    public function sidebar() {
35
        return new SidebarMenus();
36
    }
37
38
    public function session() {
39
        return new UserSession();
40
    }
41
42
    public function getDeveloperPath($path = null) {
43
        $path = ($path)?"/".trim($path,"/"):null;
44
        return "developer/".getSetting("developer_path").$path;
45
    }
46
47
    public function getDeveloperUrl($path = null) {
48
        return url($this->getDeveloperPath($path));
49
    }
50
51
    public function getProfileUrl() {
52
        return $this->getAdminUrl()."/profile";
53
    }
54
55
    public function getLogoutUrl() {
56
        return $this->getAdminUrl()."/logout";
57
    }
58
59
    public function getLoginUrl() {
60
        return $this->getAdminUrl("login");
61
    }
62
63
    public function getAdminPath() {
64
        return getSetting("ADMIN_PATH","admin");
65
    }
66
67
    public function getAdminUrl($path = null) {
68
        $path = ($path)?"/".trim($path,"/"):null;
69
        return url($this->getAdminPath()).$path;
0 ignored issues
show
Bug introduced by
Are you sure url($this->getAdminPath()) of type Illuminate\Contracts\Routing\UrlGenerator|string can be used in concatenation? ( Ignorable by Annotation )

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

69
        return /** @scrutinizer ignore-type */ url($this->getAdminPath()).$path;
Loading history...
70
    }
71
72
    public function getAppName() {
73
        return getSetting("APP_NAME", env("APP_NAME","CRUDBOOSTER"));
74
    }
75
76
    /**
77
     * @param $filename
78
     * @param $extension
79
     * @param $file
80
     * @param null $resize_width
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $resize_width is correct as it would always require null to be passed?
Loading history...
81
     * @param null $resize_height
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $resize_height is correct as it would always require null to be passed?
Loading history...
82
     * @return string
83
     * @throws \Exception
84
     */
85
    private function uploadFileProcess($filename, $extension, $file, $encrypt = true, $resize_width = null, $resize_height = null)
86
    {
87
        if(in_array($extension,cbConfig("UPLOAD_FILE_EXTENSION_ALLOWED"))) {
88
            $file_path = cbConfig("UPLOAD_PATH_FORMAT");
89
            $file_path = str_replace("{Y}",date('Y'), $file_path);
90
            $file_path = str_replace("{m}", date('m'), $file_path);
91
            $file_path = str_replace("{d}", date("d"), $file_path);
92
93
            //Create Directory Base On Template
94
            Storage::makeDirectory($file_path);
95
            Storage::put($file_path."/index.html","&nbsp;","public");
96
            Storage::put($file_path."/.gitignore","!.gitignore","public");
97
98
            if ($encrypt == true) {
99
                $filename = md5(strRandom(5)).'.'.$extension;
100
            } else {
101
                $filename = slug($filename, '_').'.'.$extension;
102
            }
103
104
            if($resize_width || $resize_height) {
0 ignored issues
show
introduced by
$resize_height is of type null, thus it always evaluated to false.
Loading history...
105
                $this->resizeImage($file, $file_path.'/'.$filename, $resize_width, $resize_height);
106
                return $file_path.'/'.$filename;
107
            }else{
108
                if (Storage::putFileAs($file_path, $file, $filename, 'public')) {
109
                    return $file_path.'/'.$filename;
110
                } else {
111
                    throw new \Exception("Something went wrong, file can't upload!");
112
                }
113
            }
114
        }else{
115
            throw new \Exception("The file format is not allowed!");
116
        }
117
    }
118
119
    /**
120
     * @param $base64_value
121
     * @param bool $encrypt
122
     * @param null $resize_width
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $resize_width is correct as it would always require null to be passed?
Loading history...
123
     * @param null $resize_height
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $resize_height is correct as it would always require null to be passed?
Loading history...
124
     * @throws \Exception
125
     */
126
    public function uploadBase64($filename, $base64_value, $encrypt = true, $resize_width = null, $resize_height = null)
127
    {
128
        $fileData = base64_decode($base64_value);
129
        $mime_type = finfo_buffer(finfo_open(), $fileData, FILEINFO_MIME_TYPE);
130
        if($mime_type) {
131
            if($mime_type = explode('/', $mime_type)) {
132
                $ext = $mime_type[1];
133
                if($filename && $ext) {
134
                    return $this->uploadFileProcess($filename, $ext, $fileData, $encrypt, $resize_width, $resize_height);
135
                }
136
            }else {
137
                throw new \Exception("Mime type not found");
138
            }
139
        }else{
140
            throw new \Exception("Mime type not found");
141
        }
142
    }
143
144
    /**
145
     * @param $name
146
     * @param bool $encrypt
147
     * @param int $resize_width
148
     * @param null $resize_height
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $resize_height is correct as it would always require null to be passed?
Loading history...
149
     * @return string
150
     * @throws \Exception
151
     */
152
    public function uploadFile($name, $encrypt = true, $resize_width = null, $resize_height = null)
153
    {
154
        if (request()->hasFile($name)) {
155
            $file = request()->file($name);
156
            $filename = $file->getClientOriginalName();
157
            $ext = strtolower($file->getClientOriginalExtension());
158
159
            if($filename && $ext) {
160
                return $this->uploadFileProcess($filename, $ext, $file, $encrypt, $resize_width, $resize_height);
0 ignored issues
show
Bug introduced by
It seems like $resize_width can also be of type integer; however, parameter $resize_width of crocodicstudio\crudboost...CB::uploadFileProcess() 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

160
                return $this->uploadFileProcess($filename, $ext, $file, $encrypt, /** @scrutinizer ignore-type */ $resize_width, $resize_height);
Loading history...
161
            }
162
163
        } else {
164
            throw new \Exception("There is no file send to server!");
165
        }
166
    }
167
168
    /**
169
     * @param $file
170
     * @param $fullFilePath
171
     * @param null $resize_width
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $resize_width is correct as it would always require null to be passed?
Loading history...
172
     * @param null $resize_height
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $resize_height is correct as it would always require null to be passed?
Loading history...
173
     * @param int $qty
174
     * @param int $thumbQty
175
     * @throws \Exception
176
     */
177
    public function resizeImage($file, $fullFilePath, $resize_width = null, $resize_height = null, $qty = 100, $thumbQty = 75)
0 ignored issues
show
Unused Code introduced by
The parameter $thumbQty is not used and could be removed. ( Ignorable by Annotation )

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

177
    public function resizeImage($file, $fullFilePath, $resize_width = null, $resize_height = null, $qty = 100, /** @scrutinizer ignore-unused */ $thumbQty = 75)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
178
    {
179
        $images_ext = cbConfig("UPLOAD_IMAGE_EXTENSION_ALLOWED");
180
181
        $filename = basename($fullFilePath);
182
        $file_path = trim(str_replace($filename, '', $fullFilePath), '/');
0 ignored issues
show
Unused Code introduced by
The assignment to $file_path is dead and can be removed.
Loading history...
183
        $ext = pathinfo($fullFilePath, PATHINFO_EXTENSION);
184
185
        if (in_array(strtolower($ext), $images_ext)) {
186
187
            // Upload file
188
            $img = Image::make($file);
189
            $img->encode($ext, $qty);
190
191
            if ($resize_width && $resize_height) {
0 ignored issues
show
introduced by
$resize_width is of type null, thus it always evaluated to false.
Loading history...
192
                $img->fit($resize_width, $resize_height);
193
194
            } elseif ($resize_width && ! $resize_height) {
0 ignored issues
show
introduced by
$resize_width is of type null, thus it always evaluated to false.
Loading history...
195
196
                $img->resize($resize_width, null, function ($constraint) {
197
                    $constraint->aspectRatio();
198
                });
199
200
            } elseif (! $resize_width && $resize_height) {
0 ignored issues
show
introduced by
$resize_width is of type null, thus it always evaluated to false.
Loading history...
introduced by
$resize_height is of type null, thus it always evaluated to false.
Loading history...
201
202
                $img->resize(null, $resize_height, function ($constraint) {
203
                    $constraint->aspectRatio();
204
                });
205
206
            } else {
207
208
                if ($img->width() > cbConfig("DEFAULT_IMAGE_MAX_WIDTH_RES")) {
209
                    $img->resize(cbConfig("DEFAULT_IMAGE_MAX_WIDTH_RES"), null, function ($constraint) {
210
                        $constraint->aspectRatio();
211
                    });
212
                }
213
            }
214
215
            Storage::put($fullFilePath, $img, 'public');
216
        }else{
217
            throw new \Exception("The file format is not allowed!");
218
        }
219
    }
220
221
    public function update($table, $id, $data)
222
    {
223
        DB::table($table)
224
            ->where($this->pk($table), $id)
225
            ->update($data);
226
    }
227
228
    public function updateCompact($table, $id, $params) {
229
        $data = [];
230
        foreach ($params as $param) {
231
            $data[$param] = request($param);
232
        }
233
        $this->update($table, $id, $data);
234
    }
235
236
    public function find($table, $id)
237
    {
238
        if (is_array($id)) {
239
            $idHash = md5("find".$table.serialize($id));
240
            if(miscellanousSingleton()->hasData($idHash)) return miscellanousSingleton()->getData($idHash);
241
242
            $first = DB::table($table);
243
            foreach ($id as $k => $v) {
244
                $first->where($k, $v);
245
            }
246
247
            $data = $first->first();
248
            miscellanousSingleton()->setData($idHash,$data);
249
            return $data;
250
        } else {
251
            $idHash = md5("find".$table.$id);
252
            if(miscellanousSingleton()->hasData($idHash)) return miscellanousSingleton()->getData($idHash);
253
254
            $pk = $this->pk($table);
255
            $data = DB::table($table)->where($pk, $id)->first();
256
            miscellanousSingleton()->setData($idHash,$data);
257
            return $data;
258
        }
259
    }
260
261
    /**
262
     * @param $table
263
     * @param callable|string|null $conditionOrCallback
264
     * @return \Illuminate\Support\Collection|mixed
265
     */
266
    public function findAll($table, $conditionOrCallback = null)
267
    {
268
        $data = [];
269
        $idHash = null;
270
271
        if(is_array($conditionOrCallback)) {
272
            $idHash = md5("findAll".$table.serialize($conditionOrCallback));
273
            if(miscellanousSingleton()->hasData($idHash)) return miscellanousSingleton()->getData($idHash);
274
275
            $data = DB::table($table)->where($conditionOrCallback)->get();
276
        } elseif (is_callable($conditionOrCallback)) {
277
            $idHash = "findAll".$table.spl_object_hash($conditionOrCallback);
0 ignored issues
show
Bug introduced by
It seems like $conditionOrCallback can also be of type callable and string; however, parameter $obj of spl_object_hash() does only seem to accept object, 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

277
            $idHash = "findAll".$table.spl_object_hash(/** @scrutinizer ignore-type */ $conditionOrCallback);
Loading history...
278
            if(miscellanousSingleton()->hasData($idHash)) return miscellanousSingleton()->getData($idHash);
279
280
            $data = DB::table($table);
281
            $data = call_user_func($conditionOrCallback, $data);
282
            $data = $data->get();
283
        } else {
284
            $idHash = md5("findAll".$table.$conditionOrCallback);
0 ignored issues
show
Bug introduced by
Are you sure $conditionOrCallback of type callable|null|string can be used in concatenation? ( Ignorable by Annotation )

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

284
            $idHash = md5("findAll".$table./** @scrutinizer ignore-type */ $conditionOrCallback);
Loading history...
285
            if(miscellanousSingleton()->hasData($idHash)) return miscellanousSingleton()->getData($idHash);
286
287
            $data = DB::table($table);
288
            if($conditionOrCallback) {
289
                $data = $data->whereRaw($conditionOrCallback);
0 ignored issues
show
Bug introduced by
It seems like $conditionOrCallback can also be of type callable; however, parameter $sql of Illuminate\Database\Query\Builder::whereRaw() does only seem to accept string, 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

289
                $data = $data->whereRaw(/** @scrutinizer ignore-type */ $conditionOrCallback);
Loading history...
290
            }
291
            $data = $data->get();
292
        }
293
294
        if($idHash && $data) {
295
            miscellanousSingleton()->setData($idHash, $data);
296
        }
297
298
        return $data;
299
    }
300
301
    public function listAllTable()
302
    {
303
        $idHash = md5("listAllTable");
304
        if(miscellanousSingleton()->hasData($idHash)) return miscellanousSingleton()->getData($idHash);
305
        $data = DB::connection()->getDoctrineSchemaManager()->listTableNames();
306
        miscellanousSingleton()->setData($idHash, $data);
307
        return $data;
308
    }
309
310
    public function listAllColumns($table)
311
    {
312
        $idHash = md5("listAllColumns".$table);
313
        if(miscellanousSingleton()->hasData($idHash)) return miscellanousSingleton()->getData($idHash);
314
        $data = Schema::getColumnListing($table);
315
        miscellanousSingleton()->setData($idHash, $data);
316
        return $data;
317
    }
318
319
    public function redirectBack($message, $type = 'warning')
320
    {
321
        if (request()->ajax()) {
322
            return response()->json(['message' => $message, 'message_type' => $type, 'redirect_url' => $_SERVER['HTTP_REFERER']]);
323
        } else {
324
            return redirect()->back()->withInput()
325
                ->with(['message'=> $message, 'message_type'=> $type]);
326
        }
327
    }
328
329
    public function redirect($to, $message, $type = 'warning')
330
    {
331
        if (Request::ajax()) {
332
            return response()->json(['message' => $message, 'message_type' => $type, 'redirect_url' => $to]);
333
        } else {
334
            return redirect($to)->with(['message' => $message, 'message_type' => $type]);
335
        }
336
    }
337
338
339
    public function getCurrentMethod()
340
    {
341
        $action = str_replace("App\Http\Controllers", "", Route::currentRouteAction());
342
        $atloc = strpos($action, '@') + 1;
343
        $method = substr($action, $atloc);
344
345
        return $method;
346
    }
347
348
    public function stringBetween($string, $start, $end)
349
    {
350
        $string = ' '.$string;
351
        $ini = strpos($string, $start);
352
        if ($ini == 0) {
353
            return '';
354
        }
355
        $ini += strlen($start);
356
        $len = strpos($string, $end, $ini) - $ini;
357
358
        return substr($string, $ini, $len);
359
    }
360
361
    /**
362
     * @param array $rules
363
     * @param array $messages
364
     * @throws CBValidationException
365
     */
366
    public function validation($rules = [], $messages = [])
367
    {
368
        $input_arr = request()->all();
369
370
        foreach ($rules as $a => $b) {
371
            if (is_int($a)) {
372
                $rules[$b] = 'required';
373
            } else {
374
                $rules[$a] = $b;
375
            }
376
        }
377
378
        $validator = Validator::make($input_arr, $rules, $messages);
379
        if ($validator->fails()) {
380
            $message = $validator->errors()->all();
381
            throw new CBValidationException(implode("; ",$message));
382
        }
383
    }
384
385
    public function pk($table)
386
    {
387
        return $this->findPrimaryKey($table);
388
    }
389
390
    public function findPrimaryKey($table)
391
    {
392
        $pk = DB::getDoctrineSchemaManager()->listTableDetails($table)->getPrimaryKey();
393
        if(!$pk) {
394
            return null;
395
        }
396
        return $pk->getColumns()[0];
397
    }
398
399
    public function urlFilterColumn($key, $type, $value = '', $singleSorting = true)
400
    {
401
        $params = Request::all();
402
        $mainpath = trim(self::mainpath(), '/');
0 ignored issues
show
Bug introduced by
The method mainpath() does not exist on crocodicstudio\crudbooster\helpers\CB. ( Ignorable by Annotation )

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

402
        $mainpath = trim(self::/** @scrutinizer ignore-call */ mainpath(), '/');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
403
        $key = sanitizeXSS($key);
404
        $type = sanitizeXSS($type);
405
        $value = sanitizeXSS($value);
406
407
        if ($params['filter_column'] && $singleSorting) {
408
            foreach ($params['filter_column'] as $k => $filter) {
409
                foreach ($filter as $t => $val) {
410
                    if ($t == 'sorting') {
411
                        unset($params['filter_column'][$k]['sorting']);
412
                    }
413
                }
414
            }
415
        }
416
417
        $params['filter_column'][$key][$type] = $value;
418
419
        if (isset($params)) {
420
            return $mainpath.'?'.http_build_query($params);
421
        } else {
422
            return $mainpath.'?filter_column['.$key.']['.$type.']='.$value;
423
        }
424
    }
425
426
427
    public function getUrlParameters($exception = null)
428
    {
429
        $get = request()->all();
430
        $inputhtml = '';
431
432
        if ($get) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $get of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
433
            if (is_array($exception)) {
434
                foreach ($exception as $e) {
435
                    unset($get[$e]);
436
                }
437
            }
438
            $string_parameters = http_build_query($get);
439
            $string_parameters_array = explode('&', $string_parameters);
440
            foreach ($string_parameters_array as $s) {
441
                $part = explode('=', $s);
442
                if(isset($part[0]) && isset($part[1])) {
443
                    $name = htmlspecialchars(urldecode($part[0]));
444
                    $name = strip_tags($name);
445
                    $value = htmlspecialchars(urldecode($part[1]));
446
                    $value = strip_tags($value);
447
                    if ($name) {
448
                        $inputhtml .= "<input type='hidden' name='$name' value='$value'/>\n";
449
                    }
450
                }
451
            }
452
        }
453
454
        return $inputhtml;
455
    }
456
457
458
    public function routeGet($prefix, $controller) {
459
        $alias = str_replace("@"," ", $controller);
460
        $alias = ucwords($alias);
461
        $alias = str_replace(" ","",$alias);
462
        Route::get($prefix, ['uses' => $controller, 'as' => $alias]);
463
    }
464
465
    public function routePost($prefix, $controller) {
466
        $alias = str_replace("@"," ", $controller);
467
        $alias = ucwords($alias);
468
        $alias = str_replace(" ","",$alias);
469
        Route::post($prefix, ['uses' => $controller, 'as' => $alias]);
470
    }
471
472
    public function routeGroupBackend(callable $callback, $namespace = 'crocodicstudio\crudbooster\controllers') {
473
        Route::group([
474
            'middleware' => ['web', \crocodicstudio\crudbooster\middlewares\CBBackend::class],
475
            'prefix' => cb()->getAdminPath(),
476
            'namespace' => $namespace,
477
        ], $callback);
478
    }
479
480
    public function routeGroupDeveloper(callable $callback, $namespace = 'crocodicstudio\crudbooster\controllers') {
481
        Route::group([
482
            'middleware' => ['web', \crocodicstudio\crudbooster\middlewares\CBDeveloper::class],
483
            'prefix' => "developer/".getSetting('developer_path'),
484
            'namespace' => $namespace,
485
        ], $callback);
486
    }
487
488
    /*
489
    | --------------------------------------------------------------------------------------------------------------
490
    | Alternate route for Laravel Route::controller
491
    | --------------------------------------------------------------------------------------------------------------
492
    | $prefix       = path of route
493
    | $controller   = controller name
494
    |
495
    */
496
    public function routeController($prefix, $controller)
497
    {
498
499
        $prefix = trim($prefix, '/').'/';
500
501
        if(substr($controller,0,1) != "\\") {
502
            $controller = "\App\Http\Controllers\\".$controller;
503
        }
504
505
        $exp = explode("\\", $controller);
506
        $controller_name = end($exp);
507
508
        try {
509
            Route::get($prefix, ['uses' => $controller.'@getIndex', 'as' => $controller_name.'GetIndex']);
510
511
            $controller_class = new \ReflectionClass($controller);
512
            $controller_methods = $controller_class->getMethods(\ReflectionMethod::IS_PUBLIC);
513
            $wildcards = '/{one?}/{two?}/{three?}/{four?}/{five?}';
514
            foreach ($controller_methods as $method) {
515
516
                if ($method->class != 'Illuminate\Routing\Controller' && $method->name != 'getIndex') {
517
                    if (substr($method->name, 0, 3) == 'get') {
518
                        $method_name = substr($method->name, 3);
519
                        $slug = array_filter(preg_split('/(?=[A-Z])/', $method_name));
0 ignored issues
show
Bug introduced by
It seems like preg_split('/(?=[A-Z])/', $method_name) can also be of type false; however, parameter $input of array_filter() does only seem to accept array, 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

519
                        $slug = array_filter(/** @scrutinizer ignore-type */ preg_split('/(?=[A-Z])/', $method_name));
Loading history...
520
                        $slug = strtolower(implode('-', $slug));
521
                        $slug = ($slug == 'index') ? '' : $slug;
522
                        Route::get($prefix.$slug.$wildcards, ['uses' => $controller.'@'.$method->name, 'as' => $controller_name.'Get'.$method_name]);
523
                    } elseif (substr($method->name, 0, 4) == 'post') {
524
                        $method_name = substr($method->name, 4);
525
                        $slug = array_filter(preg_split('/(?=[A-Z])/', $method_name));
526
                        Route::post($prefix.strtolower(implode('-', $slug)).$wildcards, [
527
                            'uses' => $controller.'@'.$method->name,
528
                            'as' => $controller_name.'Post'.$method_name,
529
                        ]);
530
                    }
531
                }
532
            }
533
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
534
535
        }
536
    }
537
}
538