Passed
Push — master ( 284e72...816a06 )
by Iman
04:12
created

IndexImport::InsertToDB()   C

Complexity

Conditions 8
Paths 28

Size

Total Lines 36
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 23
c 0
b 0
f 0
nc 28
nop 3
dl 0
loc 36
rs 5.3846
1
<?php
2
3
namespace crocodicstudio\crudbooster\controllers\Helpers;
4
5
use crocodicstudio\crudbooster\helpers\CRUDBooster;
6
use crocodicstudio\crudbooster\helpers\DbInspector;
7
use Illuminate\Support\Facades\Cache;
8
use Illuminate\Support\Facades\DB;
9
use Illuminate\Support\Facades\Storage;
10
use Illuminate\Support\Facades\Validator;
11
use Maatwebsite\Excel\Facades\Excel;
12
13
class IndexImport
14
{
15
    /**
16
     * @return mixed
17
     */
18
    public function doneImport()
19
    {
20
        $data = [];
21
        $data['page_title'] = trans('crudbooster.import_page_title', ['module' => \CRUDBooster::getCurrentModule()->name]);
0 ignored issues
show
Bug introduced by
The type CRUDBooster was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
        session()->put('select_column', request('select_column'));
23
24
        return view('crudbooster::import', $data);
25
    }
26
27
    /**
28
     * @param $file_md5
29
     * @return mixed
30
     * @throws \Exception
31
     */
32
    public function handleImportProgress($file_md5)
33
    {
34
        $total = session('total_data_import') * 100;
35
        $prog = intval(cache('success_'.$file_md5)) / $total;
36
        $prog = round($prog, 2);
37
38
        if ($prog >= 100) {
39
            cache()->forget('success_'.$file_md5);
40
        }
41
42
        return response()->json(['progress' => $prog, 'last_error' => cache('error_'.$file_md5)]);
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

42
        return response()->/** @scrutinizer ignore-call */ json(['progress' => $prog, 'last_error' => cache('error_'.$file_md5)]);
Loading history...
43
    }
44
45
    /**
46
     * @param $file
47
     * @return string
48
     */
49
    public function uploadImportData($file)
50
    {
51
        $dir = 'uploads/'.date('Y-m');
52
        $filename = md5(str_random(5)).'.'.$file->getClientOriginalExtension();
53
54
        //Create Directory Monthly
55
        Storage::makeDirectory($dir);
56
57
        //Move file to storage
58
        Storage::putFileAs($dir, $file, $filename);
59
60
        return CRUDBooster::mainpath('import-data').'?file='.base64_encode($dir.'/'.$filename);
61
    }
62
63
    /**
64
     * @param $file
65
     * @return \Illuminate\Contracts\Validation\Validator
66
     */
67
    public function validateForImport($file)
68
    {
69
        return Validator::make(['extension' => $file->getClientOriginalExtension(),], ['extension' => 'in:xls,xlsx,csv']);
70
    }
71
72
    /**
73
     * @param $file_md5
74
     * @param $table
75
     * @param $titleField
76
     */
77
    public function InsertToDB($file_md5, $table, $titleField)
78
    {
79
        $select_column = array_filter(session('select_column'));
0 ignored issues
show
Bug introduced by
It seems like session('select_column') can also be of type Illuminate\Session\Store and Illuminate\Session\SessionManager; 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

79
        $select_column = array_filter(/** @scrutinizer ignore-type */ session('select_column'));
Loading history...
80
        $table_columns = DB::getSchemaBuilder()->getColumnListing($table);
81
82
        $file = base64_decode(request('file'));
0 ignored issues
show
Bug introduced by
It seems like request('file') can also be of type array; however, parameter $data of base64_decode() 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

82
        $file = base64_decode(/** @scrutinizer ignore-type */ request('file'));
Loading history...
83
        $file = 'storage'.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.$file;
84
        $rows = Excel::load($file, function ($reader) {
0 ignored issues
show
Unused Code introduced by
The parameter $reader 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

84
        $rows = Excel::load($file, function (/** @scrutinizer ignore-unused */ $reader) {

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...
85
        })->get();
86
87
        //$data_import_column = [];
88
        foreach ($rows as $value) {
89
            $a = $this->readAndInsert($select_column, $table_columns, $value);
90
91
            $has_title_field = true;
92
            foreach ($a as $k => $v) {
93
                if ($k == $titleField && $v == '') {
94
                    $has_title_field = false;
95
                    break;
96
                }
97
            }
98
99
            if ($has_title_field == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
100
                continue;
101
            }
102
103
            try {
104
                if (\Schema::hasColumn($table, 'created_at')) {
105
                    $a['created_at'] = YmdHis();
106
                }
107
108
                \DB::table($table)->insert($a);
109
                Cache::increment('success_'.$file_md5);
110
            } catch (\Exception $e) {
111
                $e = (string) $e;
112
                Cache::put('error_'.$file_md5, $e, 500);
113
            }
114
        }
115
    }
116
117
    /**
118
     * @param $selectColumn
119
     * @param $table_columns
120
     * @param $value
121
     * @return array
122
     */
123
    private function readAndInsert($selectColumn, $table_columns, $value)
124
    {
125
        $a = [];
126
        foreach ($selectColumn as $sk => $s) {
127
            $colname = $table_columns[$sk];
128
129
            if (! DbInspector::isForeignKey($colname) || intval($value->$s)) {
130
                $a[$colname] = $value->$s;
131
                continue;
132
            }
133
134
            //Skip if value is empty
135
            if ($value->$s == '') {
136
                continue;
137
            }
138
139
            $relation_table = DbInspector::getTableForeignKey($colname);
140
            $relation_class = $this->resolveController($relation_table);
141
            $relation_class->genericLoader();
142
143
            $titleField = $relation_class->titleField;
144
145
            $relation_insert_data = [];
146
            $relation_insert_data[$titleField] = $value->$s;
147
148
            if (\Schema::hasColumn($relation_table, 'created_at')) {
149
                $relation_insert_data['created_at'] = YmdHis();
150
            }
151
152
            try {
153
                $relation_exists = DB::table($relation_table)->where($titleField, $value->$s)->first();
154
                if ($relation_exists) {
155
                    $relation_primary_key = $relation_class->primaryKey;
156
                    $relation_id = $relation_exists->$relation_primary_key;
157
                } else {
158
                    $relation_id = DB::table($relation_table)->insertGetId($relation_insert_data);
159
                }
160
161
                $a[$colname] = $relation_id;
162
            } catch (\Exception $e) {
163
                //exit($e);
164
            }
165
        }
166
167
        return $a;
168
    }
169
170
    /**
171
     * @param $table
172
     */
173
    private function resolveController($table)
174
    {
175
        $module = DB::table('cms_moduls')->where('table_name', $table)->first();
176
        if (is_null($module)) {
177
            return ;
178
        }
179
        $relation_class = __NAMESPACE__.'\\'.$module->controller;
180
        if (! class_exists($relation_class)) {
181
            $relation_class = ctrlNamespace().'\\'.$module->controller;
182
        }
183
184
        return new $relation_class;
185
    }
186
}