Completed
Push — master ( d0c126...fcb1ca )
by Supun
07:05
created

JsonExtractor::getStringFromData()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 5
nop 1
dl 0
loc 19
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace Lifeeka\JSQL\Extractor;
4
5
use Lifeeka\JSQL\Helpers\Json;
6
7
/**
8
 * Class JsonExtractor.
9
 */
10
class JsonExtractor
11
{
12
    public $json;
13
14
    private $table = [];
15
    private $data = [];
16
17
    public $need_id = true;
18
    public $snake_case_column = true;
19
    public $snake_case_table = true;
20
    public $main_table_name = "main";
21
22
    /**
23
     * JsonExtractor constructor.
24
     *
25
     * @param Json $json
26
     */
27
    public function __construct(Json $json)
28
    {
29
        $this->json = $json;
30
    }
31
32
    /**
33
     * @return array
34
     */
35
    public function getTablesArray()
36
    {
37
        return $this->table;
38
    }
39
40
    /**
41
     * @return array
42
     */
43
    public function getDataArray()
44
    {
45
        return $this->data;
46
    }
47
48
49
    /**
50
     * @param bool $data
51
     * @param string $prefix
52
     * @return string
53
     */
54
    public function toMysqlTables($data = false, $prefix = '')
55
    {
56
        if (!$data) {//if this is not a recursive
57
            $data = $this->json->toObject();
58
        }
59
60
        foreach ($data as $key => $value) {//loop the data
61
62
            $table_name = is_numeric($key) ? $this->main_table_name : $key;
63
64
            if (is_array($value) && is_object($value[0])) {//check whether it's a array and it's firs element is a object
65
66
                $table_data = $this->getTable($prefix . $table_name, $value);//get table sql
67
                $this->table[$table_data['name']] = $table_data['column'];
68
69
                $this->toMysqlTables($this->getHighestColumnArray($value), $prefix . $table_name . '_');//get it inside tables
70
            } elseif (is_array($value) || is_object($value)) {//if it's a array and  firs element is not a object
71
72
                $table_data = $this->getTable($prefix . $table_name, $value);
73
                $this->table[$table_data['name']] = $table_data['column'];
74
            }
75
76
        }
77
    }
78
79
80
    public function toMysqlData($data = false, $prefix = '')
81
    {
82
83
        if (!$data) {//if this is not a recursive
84
            $data = $this->json->toObject();
85
        }
86
        foreach ($data as $table_name => $value) {
87
            if ($this->snake_case_table) {
88
                $table_name = $this->snakeCase($prefix . $table_name);
89
            }
90
91
            if (is_array($value)) {//if it's a array and  firs element is not a object
92
                $this->toMysqlData($value, $table_name . '_');
93
            } elseif (is_object($value)) {
94
                $this->toMysqlData($value, $table_name . '_');
95
            }
96
97
98
        }
99
    }
100
101
    //TODO
102
    public function getTableData(){
103
104
    }
105
106
107
    /**
108
     * @param $table
109
     * @param $data
110
     * @return array
111
     */
112
    public function getTable($table, $data)
113
    {
114
        $column = $this->getColumn($this->getHighestColumnArray($data));
115
116
        if ($this->snake_case_table) {
117
            $table = $this->snakeCase($table);
118
        }
119
120
        $last_columns = $column;
121
        if ($this->need_id && array_search('id', array_column($column, 'name')) === false) {
122
            $last_columns[] = [
123
                'name' => "id",
124
                'type' => "int"
125
            ];
126
        }
127
128
        return [
129
            'name' => $table,
130
            'column' => $last_columns
131
        ];
132
    }
133
134
    /**
135
     * @param $data
136
     *
137
     * @return array
138
     */
139
    public function getColumn($data)
140
    {
141
        $Columns = [];
142
143
        if (is_object($data)) {
144
            foreach ($data ?? [] as $Column => $Value) {
145
                if (!is_array($Value) && !is_object($Value) && !empty($Column) && !is_numeric($Column)) {
146
                    $Columns[] = ['name' => $Column, 'type' => gettype($this->getActualDataType($Value, ""))];
147
                }
148
            }
149
        } elseif (is_array($data)) {
150
            $Columns[] = ['name' => 'value', 'type' => gettype($this->getActualDataType($data[0], ""))];
151
        }
152
153
        return $Columns;
154
    }
155
156
    /**
157
     * @param $data
158
     * @param $column
159
     * @return array
160
     */
161
    public function getData($data, $column)
162
    {
163
164
        $values = [];
165
166
        $index = 0;
167
        foreach ($data as $row_item) {
168
            foreach ($column as $column_item) {
169
                switch (is_object($row_item)) {
170
                    case true:
171
                        $values[$index][$column_item['name']] = $this->getActualDataType(($row_item->{$column_item['name']}) ?? null, null);
172
                        break;
173
                    case false:
174
                        $values[$index][$column_item['name']] = $this->getActualDataType(($data->{$column_item['name']}) ?? null, null);
175
                        break;
176
                }
177
            }
178
            $index++;
179
        }
180
181
182
        return $values;
183
    }
184
185
    /**
186
     * @param $input
187
     *
188
     * @return string
189
     */
190
    public static function snakeCase($input)
191
    {
192
        preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
193
        $ret = $matches[0];
194
195
        foreach ($ret as &$match) {
196
            $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
197
        }
198
199
        return implode('_', $ret);
200
    }
201
202
203
    /**
204
     * @param $array
205
     * @return bool|mixed
206
     */
207
    public static function getHighestColumnArray($array)
208
    {
209
        if (is_object($array) || (is_array($array) && !is_object($array[0]) && !is_array($array[0]))) {
210
            return $array;
211
        }
212
213
        $Highest = false;
214
        $ColumnCount = false;
215
        $HighestSubCount = false;
216
217
        foreach ($array as $array_item) {
218
            $current_sub = 0;
219
            //check how many array/object have
220
            foreach ($array_item as $SubTableName => $SubArrayItem) {
221
                if (is_array($SubArrayItem) || is_object($SubArrayItem)) {
222
                    $current_sub = $current_sub + 2;
223
                }
224
            }
225
            //check how many column have
226
            if ($ColumnCount <= count($array_item) || !$Highest) {
227
                if ($current_sub > $HighestSubCount || !$Highest) {
228
                    $Highest = $array_item;
229
                    $HighestSubCount = $current_sub;
230
                    $ColumnCount = count($array_item);
231
                }
232
            }
233
        }
234
235
236
        return $Highest;
237
    }
238
239
    /**
240
     * @param $array
241
     * @return string
242
     */
243
    public static function getStringFromData($array)
244
    {
245
        $String = [];
246
247
        foreach ($array as $item_row) {
248
            $value = [];
249
            foreach ($item_row as $item) {
250
                if (empty($item) && !is_numeric($item)) {
251
                    $value[] = "null";
252
                } elseif (is_numeric($item)) {
253
                    $value[] = $item;
254
                } else {
255
                    $value[] = '"' . addcslashes($item, "W") . '"';
256
                }
257
            }
258
            $String[] = '(' . implode(",", $value) . ')';
259
        }
260
261
        return "values" . implode(", ", $String);
262
    }
263
264
    /**
265
     * @param $array
266
     * @return string
267
     */
268
    public static function getStringFromColumns($array)
269
    {
270
        $String = [];
271
        foreach ($array as $column) {
272
            $String[] = "`" . JsonExtractor::snakeCase($column['name']) . "`";
273
        }
274
275
        return implode(",", $String);
276
    }
277
278
279
    /**
280
     * @param $Data
281
     * @param $empty_val
282
     * @return int|string
283
     */
284
    public static function getActualDataType($Data, $empty_val)
285
    {
286
        $Data = trim($Data);
287
        if (is_numeric($Data)) {
288
            return $Data + 0;
289
        } elseif (empty($Data)) {
290
            return $empty_val;
291
        } else {
292
            return (string)$Data;
293
        }
294
    }
295
}
296