Passed
Pull Request — master (#1135)
by Iman
04:13
created

AdminApiGeneratorController::getColumnTable()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 18
nc 6
nop 2
dl 0
loc 29
rs 5.3846
c 0
b 0
f 0
1
<?php
2
3
namespace crocodicstudio\crudbooster\Modules\ApiGeneratorModule;
4
5
use crocodicstudio\crudbooster\controllers\CBController;
6
use crocodicstudio\crudbooster\helpers\CbValidator;
7
use crocodicstudio\crudbooster\helpers\DbInspector;
8
use crocodicstudio\crudbooster\Modules\ModuleGenerator\ControllerGenerator\FieldDetector;
9
use Illuminate\Support\Facades\Request;
10
use Illuminate\Support\Facades\DB;
11
use Illuminate\Support\Facades\Route;
12
use crocodicstudio\crudbooster\helpers\CRUDBooster;
13
14
class AdminApiGeneratorController extends CBController
15
{
16
    public function cbInit()
17
    {
18
        $this->table = 'cms_apicustom';
19
        $this->primaryKey = "id";
20
        $this->title_field = "nama";
21
        $this->button_show = false;
0 ignored issues
show
Bug Best Practice introduced by
The property button_show does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
22
        $this->button_new = false;
0 ignored issues
show
Bug Best Practice introduced by
The property button_new does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
23
        $this->deleteBtn = false;
24
        $this->button_add = false;
0 ignored issues
show
Bug Best Practice introduced by
The property button_add does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
25
        $this->button_import = false;
26
        $this->buttonExport = false;
27
    }
28
29
    function getIndex()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
30
    {
31
        $this->cbLoader();
32
33
        $data = [];
34
35
        $data['page_title'] = 'API Generator';
36
        $data['apis'] = $this->table()->orderby('nama', 'asc')->get();
37
38
        return view('CbApiGen::api_documentation', $data);
39
    }
40
41
    function apiDocumentation()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
42
    {
43
        $this->cbLoader();
44
        $data = [];
45
46
        $data['apis'] = $this->table()->orderby('nama', 'asc')->get();
47
48
        return view('CbApiGen::api_documentation_public', $data);
49
    }
50
51
    function getDownloadPostman()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
52
    {
53
        $this->cbLoader();
54
        $data = [];
55
        $data['variables'] = [];
56
        $data['info'] = [
57
            'name' => cbGetsetting('appname').' - API',
58
            '_postman_id' => "1765dd11-73d1-2978-ae11-36921dc6263d",
59
            'description' => '',
60
            'schema' => 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json',
61
        ];
62
        $items = [];
63
        foreach ($this->table()->orderby('nama', 'asc')->get() as $api) {
64
            $parameters = unserialize($api->parameters);
65
            $formdata = [];
66
            $httpbuilder = [];
67
            if ($parameters) {
68
                foreach ($parameters as $p) {
69
                    $enabled = ($p['used'] == 0) ? false : true;
70
                    $name = $p['name'];
71
                    $httpbuilder[$name] = '';
72
                    if ($enabled) {
73
                        $formdata[] = ['key' => $name, 'value' => '', 'type' => 'text', 'enabled' => $enabled];
74
                    }
75
                }
76
            }
77
78
            if (strtolower($api->method_type) == 'get' && $httpbuilder) {
79
                $httpbuilder = "?".http_build_query($httpbuilder);
80
            }else{
81
                $httpbuilder = '';
82
            }
83
84
            $items[] = [
85
                'name' => $api->nama,
86
                'request' => [
87
                    'url' => url('api/'.$api->permalink).$httpbuilder,
88
                    'method' => $api->method_type ?: 'GET',
89
                    'header' => [],
90
                    'body' => [
91
                        'mode' => 'formdata',
92
                        'formdata' => $formdata,
93
                    ],
94
                    'description' => $api->keterangan,
95
                ],
96
            ];
97
        }
98
        $data['item'] = $items;
99
100
        $json = json_encode($data);
101
102
        return \Response::make($json, 200, [
103
            'Content-Type' => 'application/json',
104
            'Content-Disposition' => 'attachment; filename='.cbGetsetting('appname').' - API For POSTMAN.json',
105
        ]);
106
    }
107
108
    public function getScreetKey()
109
    {
110
        $this->cbLoader();
111
        $data['page_title'] = 'API Generator';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
112
        $data['apikeys'] = DB::table('cms_apikey')->get();
113
114
        return view('CbApiGen::api_key', $data);
115
    }
116
117
    public function getGenerator()
118
    {
119
        $this->cbLoader();
120
121
        $data['page_title'] = 'API Generator';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
122
        $data['tables'] = CRUDBooster::listCbTables();
123
124
        return view('CbApiGen::api_generator', $data);
125
    }
126
127
    public function getEditApi($id)
128
    {
129
        $this->cbLoader();
130
131
        $row = $this->findRow($id)->first();
132
133
        $data['row'] = $row;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
134
        $data['parameters'] = json_encode(unserialize($row->parameters));
135
        $data['responses'] = json_encode(unserialize($row->responses));
136
        $data['page_title'] = 'API Generator';
137
138
        $data['tables'] = CRUDBooster::listCbTables();
139
140
        return view('CbApiGen::api_generator', $data);
141
    }
142
143
    function getGenerateScreetKey()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
144
    {
145
        $this->cbLoader();
146
        //Generate a random string.
147
        $token = openssl_random_pseudo_bytes(16);
148
149
        //Convert the binary data into hexadecimal representation.
150
        $token = bin2hex($token);
151
152
        $id = DB::table('cms_apikey')->insertGetId([
153
                'screetkey' => $token,
154
                'created_at' => date('Y-m-d H:i:s'),
155
                'status' => 'active',
156
                'hit' => 0,
157
            ]);
158
159
        $response = [];
160
        $response['key'] = $token;
161
        $response['id'] = $id;
162
163
        return response()->json($response);
0 ignored issues
show
Bug introduced by
The method json() does not exist on Symfony\Component\HttpFoundation\Response. It seems like you code against a sub-type of Symfony\Component\HttpFoundation\Response such as Illuminate\Http\Response or Illuminate\Http\JsonResponse or Illuminate\Http\RedirectResponse. ( Ignorable by Annotation )

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

163
        return response()->/** @scrutinizer ignore-call */ json($response);
Loading history...
164
    }
165
166
    public function getStatusApikey()
167
    {
168
        CbValidator::valid(['id' => 'required', 'status' => 'required'], 'view');
169
170
        $id = request('id');
171
        $status = (request('status') == 1) ? "active" : "non active";
172
173
        DB::table('cms_apikey')->where('id', $id)->update(['status' => $status]);
174
175
        backWithMsg('You have been update api key status !');
176
    }
177
178
    public function getDeleteApiKey()
179
    {
180
        $id = request('id');
181
        if (DB::table('cms_apikey')->where('id', $id)->delete()) {
182
            return response()->json(['status' => 1]);
183
        }
184
185
        return response()->json(['status' => 0]);
186
    }
187
188
    function getColumnTable($table, $type = 'list')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
189
    {
190
        $this->cbLoader();
191
        $except = ['created_at', 'deleted_at', 'updated_at'];
192
193
        $result = DbInspector::getTableCols($table);
194
        $new_result = [];
195
        foreach ($result as $ro) {
196
197
            if (in_array($ro, $except)) {
198
                continue;
199
            }
200
            $type_field = DbInspector::getFieldTypes($table, $ro);
201
            $new_result[] = ['name' => $ro, 'type' => $this->getFieldType($ro, $type_field)];
202
203
            if (!in_array($type, ['list', 'detail']) || !starts_with($ro, 'id_') ) {
204
                continue;
205
            }
206
            $table2 = substr($ro, 3);
207
            foreach (DB::getSchemaBuilder()->getColumnListing($table2) as $col) {
208
                if (FieldDetector::isExceptional($col) || starts_with($ro, 'id_')) {
209
                    continue;
210
                }
211
                $col = str_replace("_$table2", "", $col);
212
                $new_result[] = ['name' => $table2.'_'.$col, 'type' => DbInspector::getFieldTypes($table2, $col)];
213
            }
214
        }
215
216
        return response()->json($new_result);
217
    }
218
219
    function postSaveApiCustom()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
220
    {
221
        $this->cbLoader();
222
        $posts = request()->all();
223
224
        $_data = [];
225
226
        $_data['nama'] = g('nama');
227
        $_data['tabel'] = $posts['tabel'];
228
        $_data['aksi'] = $posts['aksi'];
229
        $_data['permalink'] = g('permalink');
230
        $_data['method_type'] = g('method_type');
231
232
        $json = $this->json(g('params_name'), g('params_type'), g('params_config'), g('params_required'), g('params_used'));
0 ignored issues
show
Bug introduced by
The call to crocodicstudio\crudboost...ratorController::json() has too few arguments starting with json. ( Ignorable by Annotation )

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

232
        /** @scrutinizer ignore-call */ 
233
        $json = $this->json(g('params_name'), g('params_type'), g('params_config'), g('params_required'), g('params_used'));

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
233
234
        $_data['parameters'] = serialize(array_filter($json));
235
236
        $_data['sql_where'] = g('sql_where');
237
238
        $json = $this->json2(g('responses_name'), g('responses_type'), g('responses_subquery'), g('responses_used'));
239
        $json = array_filter($json);
240
        $_data['responses'] = serialize($json);
241
        $_data['keterangan'] = g('keterangan');
242
243
        $this->saveToDB($_data);
244
245
        return redirect(CRUDBooster::mainpath())->with(['message' => 'Yeay, your api has been saved successfully !', 'message_type' => 'success']);
246
    }
247
248
    function getDeleteApi($id)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
249
    {
250
        $this->cbLoader();
251
        $row = $this->findRow($id)->first();
252
        $this->findRow($id)->delete();
253
254
        $controllername = ucwords(str_replace('_', ' ', $row->permalink));
255
        $controllername = str_replace(' ', '', $controllername);
256
        @unlink(base_path(controllers_dir()."Api".$controllername."Controller.php"));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

256
        /** @scrutinizer ignore-unhandled */ @unlink(base_path(controllers_dir()."Api".$controllername."Controller.php"));

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
257
258
        return response()->json(['status' => 1]);
259
    }
260
261
    /**
262
     * @param $params_name
263
     * @param $params_type
264
     * @param $params_config
265
     * @param $params_required
266
     * @param $params_used
267
     * @param $json
268
     * @return array
269
     */
270
    private function json($params_name, $params_type, $params_config, $params_required, $params_used, $json)
0 ignored issues
show
Unused Code introduced by
The parameter $json 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

270
    private function json($params_name, $params_type, $params_config, $params_required, $params_used, /** @scrutinizer ignore-unused */ $json)

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...
271
    {
272
        $json = [];
273
        for ($i = 0, $_count = count($params_name); $i <= $_count; $i++) {
274
            if (! $params_name[$i]) {
275
                continue;
276
            }
277
            $json[] = [
278
                'name' => $params_name[$i],
279
                'type' => $params_type[$i],
280
                'config' => $params_config[$i],
281
                'required' => $params_required[$i],
282
                'used' => $params_used[$i],
283
            ];
284
        }
285
286
        return $json;
287
    }
288
289
    /**
290
     * @param $responses_name
291
     * @param $responses_type
292
     * @param $responses_subquery
293
     * @param $responses_used
294
     * @return array
295
     */
296
    private function json2($responses_name, $responses_type, $responses_subquery, $responses_used)
297
    {
298
        $json = [];
299
        for ($i = 0, $_count = count($responses_name); $i <= $_count; $i++) {
300
            if (! $responses_name[$i]) {
301
                continue;
302
            }
303
            $json[] = [
304
                'name' => $responses_name[$i],
305
                'type' => $responses_type[$i],
306
                'subquery' => $responses_subquery[$i],
307
                'used' => $responses_used[$i],
308
            ];
309
        }
310
311
        return $json;
312
    }
313
314
    /**
315
     * @param $a
316
     */
317
    private function saveToDB($a)
318
    {
319
        if (request('id')) {
320
            return $this->findRow(g('id'))->update($a);
321
        }
322
323
        $controllerName = ucwords(str_replace('_', ' ', $a['permalink']));
324
        $controllerName = str_replace(' ', '', $controllerName);
325
        $this->generateAPI($controllerName, $a['tabel'], $a['permalink'], $a['method_type']);
326
327
        return $this->table()->insert($a);
328
    }
329
330
    private function generateAPI($controller_name, $table_name, $permalink, $method_type = 'post')
331
    {
332
        $php = '<?php '.view('CbApiGen::api_stub', compact('controller_name', 'table_name', 'permalink', 'method_type'))->render();
333
        $path = base_path(controllers_dir());
334
        file_put_contents($path.'Api'.$controller_name.'Controller.php', $php);
335
    }
336
337
    /**
338
     * @param $ro string
339
     * @param $default string
340
     * @return string
341
     */
342
    private function getFieldType($ro, $default)
343
    {
344
        if (FieldDetector::isEmail($ro)) {
345
            return "email";
346
        }
347
        if (FieldDetector::isImage($ro)) {
348
            return "image";
349
        }
350
        if (FieldDetector::isPassword($ro)) {
351
            return "password";
352
        }
353
354
        if (FieldDetector::isForeignKey($ro)) {
355
            return "integer";
356
        }
357
358
        return $default;
359
    }
360
}
361