Passed
Push — master ( a3358f...92b3de )
by Iman
03:20
created

IndexImport::doneImport()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
nc 1
nop 0
dl 0
loc 7
c 0
b 0
f 0
cc 1
rs 9.4285
1
<?php
2
3
namespace crocodicstudio\crudbooster\controllers\Helpers;
4
5
use crocodicstudio\crudbooster\helpers\DbInspector;
6
use crocodicstudio\crudbooster\helpers\CRUDBooster;
7
use Illuminate\Support\Facades\Storage;
8
use Illuminate\Support\Facades\Validator;
9
use Maatwebsite\Excel\Facades\Excel;
10
use Illuminate\Support\Facades\DB;
11
use Illuminate\Support\Facades\Cache;
12
13
14
class IndexImport
15
{
16
    /**
17
     * @return mixed
18
     */
19
    public function doneImport()
20
    {
21
        $data = [];
22
        $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...
23
        session()->put('select_column', request('select_column'));
24
25
        return view('crudbooster::import', $data);
26
    }
27
28
29
    /**
30
     * @param $file_md5
31
     * @return mixed
32
     */
33
    public function handleImportProgress($file_md5)
34
    {
35
        $total = session('total_data_import') * 100;
36
        $prog = intval(cache('success_'.$file_md5)) / $total;
37
        $prog = round($prog, 2);
38
39
        if ($prog >= 100) {
40
            cache()->forget('success_'.$file_md5);
41
        }
42
43
        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

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

81
        $select_column = array_filter(/** @scrutinizer ignore-type */ session('select_column'));
Loading history...
82
        $table_columns = DB::getSchemaBuilder()->getColumnListing($table);
83
84
        $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

84
        $file = base64_decode(/** @scrutinizer ignore-type */ request('file'));
Loading history...
85
        $file = 'storage'.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.$file;
86
        $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

86
        $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...
87
        })->get();
88
89
        //$data_import_column = [];
90
        foreach ($rows as $value) {
91
            $a = $this->readAndInsert($select_column, $table_columns, $value);
92
93
            $has_title_field = true;
94
            foreach ($a as $k => $v) {
95
                if ($k == $titleField && $v == '') {
96
                    $has_title_field = false;
97
                    break;
98
                }
99
            }
100
101
            if ($has_title_field == false) {
102
                continue;
103
            }
104
105
            try {
106
                if (\Schema::hasColumn($table, 'created_at')) {
107
                    $a['created_at'] = date('Y-m-d H:i:s');
108
                }
109
110
                \DB::table($table)->insert($a);
111
                Cache::increment('success_'.$file_md5);
112
            } catch (\Exception $e) {
113
                $e = (string) $e;
114
                Cache::put('error_'.$file_md5, $e, 500);
115
            }
116
        }
117
    }
118
119
    /**
120
     * @param $select_column
121
     * @param $table_columns
122
     * @param $value
123
     * @return array
124
     */
125
    private function readAndInsert($select_column, $table_columns, $value)
126
    {
127
        $a = [];
128
        foreach ($select_column as $sk => $s) {
129
            $colname = $table_columns[$sk];
130
131
            if (! DbInspector::isForeignKey($colname) || intval($value->$s)) {
132
                $a[$colname] = $value->$s;
133
                continue;
134
            }
135
136
            //Skip if value is empty
137
            if ($value->$s == '') {
138
                continue;
139
            }
140
141
            $relation_table = DbInspector::getTableForeignKey($colname);
142
            $relation_class = $this->resolveController($relation_table);
143
            $relation_class->genericLoader();
144
145
            $title_field = $relation_class->title_field;
0 ignored issues
show
Bug introduced by
The property title_field does not exist on string.
Loading history...
146
147
            $relation_insert_data = [];
148
            $relation_insert_data[$title_field] = $value->$s;
149
150
            if (\Schema::hasColumn($relation_table, 'created_at')) {
151
                $relation_insert_data['created_at'] = date('Y-m-d H:i:s');
152
            }
153
154
            try {
155
                $relation_exists = DB::table($relation_table)->where($title_field, $value->$s)->first();
156
                if ($relation_exists) {
157
                    $relation_primary_key = $relation_class->primaryKey;
0 ignored issues
show
Bug introduced by
The property primaryKey does not exist on string.
Loading history...
158
                    $relation_id = $relation_exists->$relation_primary_key;
159
                } else {
160
                    $relation_id = DB::table($relation_table)->insertGetId($relation_insert_data);
161
                }
162
163
                $a[$colname] = $relation_id;
164
            } catch (\Exception $e) {
165
                exit($e);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
166
            }
167
        }
168
169
        return $a;
170
    }
171
172
    /**
173
     * @param $relation_table
174
     * @return string
175
     */
176
    private function resolveController($relation_table)
177
    {
178
        $relation_moduls = DB::table('cms_moduls')->where('table_name', $relation_table)->first();
179
180
        $relation_class = __NAMESPACE__.'\\'.$relation_moduls->controller;
181
        if (! class_exists($relation_class)) {
182
            $relation_class = ctrlNamespace().'\\'.$relation_moduls->controller;
183
        }
184
185
        return new $relation_class;
0 ignored issues
show
Bug Best Practice introduced by
The expression return new $relation_class() returns the type object which is incompatible with the documented return type string.
Loading history...
186
    }
187
}