Passed
Push — master ( 55c7d5...aed71d )
by Dāvis
03:01
created

QuickInsertRepository::init()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 5
nop 2
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace Sludio\HelperBundle\Script\Repository;
4
5
use Sludio\HelperBundle\Script\Utils\Helper;
6
7
class QuickInsertRepository
8
{
9
    private static $mock = [];
10
    private static $metadata = [];
11
    private static $tableName;
12
    private static $identifier;
13
14
    public static $entityManager;
15
    public static $connection;
16
17
    public static function init($noFkCheck = false, $manager = null)
18
    {
19
        if (self::$connection) {
20
            return;
21
        }
22
        global $kernel;
23
24
        if ('AppCache' === get_class($kernel)) {
25
            $kernel = $kernel->getKernel();
26
        }
27
        $container = $kernel->getContainer();
28
29
        $manager = $manager ?: $container->getParameter('sludio_helper.entity.manager');
30
        self::$entityManager = $container->get('doctrine')->getManager($manager);
31
        self::$connection = self::$entityManager->getConnection();
32
33
        if (!$noFkCheck) {
34
            self::runSQL('SET FOREIGN_KEY_CHECKS = 0');
35
        }
36
    }
37
38
    public static function close($noFkCheck = false)
39
    {
40
        if (!$noFkCheck) {
41
            self::runSQL('SET FOREIGN_KEY_CHECKS = 1');
42
        }
43
    }
44
45
    private static function extract($object)
46
    {
47
        self::init(false);
48
        $data = self::extractExt($object, self::$entityManager);
49
50
        self::$mock = $data['mock'];
51
        self::$tableName = $data['table'];
52
        self::$metadata[$data['table']] = $data['meta'];
53
        self::$identifier = $data['identifier'];
54
    }
55
56
    public static function extractExt($object, $entityManager)
57
    {
58
        $metadata = $entityManager->getClassMetadata(get_class($object));
59
60
        $fields = $metadata->getFieldNames();
61
        $columns = $metadata->getColumnNames();
62
        $table = $metadata->getTableName();
63
        $identifier = null;
64
65
        $result = [];
66
        foreach ($fields as $key => $field) {
67
            foreach ($columns as $key2 => $column) {
68
                if ($key === $key2) {
69
                    $result[$table][$field] = $column;
70
                    if($field === $metadata->getIdentifier()[0]){
71
                        $identifier = $column;
72
                    }
73
                }
74
            }
75
        }
76
77
        $data = [
78
            'mock' => $result,
79
            'table' => $table,
80
            'meta' => $metadata,
81
            'identifier' => $identifier
82
        ];
83
84
        return $data;
85
    }
86
87
    private static function buildExtra($extra)
88
    {
89
        $methods = [
90
            'GROUP BY',
91
            'HAVING',
92
            'ORDER BY',
93
        ];
94
        $sql = '';
95
96
        foreach ($methods as $method) {
97
            if (isset($extra[$method])) {
98
                $sql .= ' '.$method.' ';
99
                if (is_array($extra[$method])) {
100
                    foreach ($extra[$method] as $group) {
101
                        $sql .= $group.' ';
102
                    }
103
                } else {
104
                    $sql .= $extra[$method].' ';
105
                }
106
            }
107
        }
108
109
        if (isset($extra['LIMIT'])) {
110
            if (is_array($extra['LIMIT'])) {
111
                if (isset($extra['LIMIT'][1])) {
112
                    $offset = $extra['LIMIT'][0];
113
                    $limit = $extra['LIMIT'][1];
114
                } else {
115
                    $offset = 0;
116
                    $limit = $extra['LIMIT'][0];
117
                }
118
                $sql .= 'LIMIT '.$offset.', '.$limit;
119
            }
120
        }
121
122
        $sql = str_replace('  ', ' ', $sql);
123
124
        return $sql;
125
    }
126
127
    private static function buildWhere($tableName, $where)
128
    {
129
        $whereSql = '';
130
        if (is_array($where) && !empty($where)) {
131
            reset($where);
132
            $first = key($where);
133
            $path = ' WHERE ';
134
            foreach ($where as $key => $value) {
135
                if (!is_array($value) && isset(self::$mock[$tableName][$key])) {
136
                    $whereSql .= $path.self::$mock[$tableName][$key]." = ".(is_numeric($value) ? $value : "'".addslashes(trim($value))."'");
137
                } else {
138
                    if (is_array($value)) {
139
                        $whereSql .= $path.$value[0];
140
                    } else {
141
                        $whereSql .= $path.$key." = ".(is_numeric($value) ? $value : "'".addslashes(trim($value))."'");
142
                    }
143
                }
144
                if ($key === $first) {
145
                    $path = ' AND ';
146
                }
147
            }
148
        }
149
150
        return $whereSql;
151
    }
152
153
    private static function getTable(&$object, &$tableName, &$columns, &$type, $noFkCheck = true, $manager = null, $extraFields = [])
154
    {
155
        self::init($noFkCheck, $manager);
156
        if (is_object($object)) {
157
            self::extract($object);
158
            $tableName = self::$tableName;
159
            $columns = self::$mock[$tableName] ?: [];
160
            $type = 'object';
161
        } else {
162
            $tableName = $object['table_name'];
163
            unset($object['table_name']);
164
            $type = 'table';
165
            $columns = array_keys($object) ?: [];
166
        }
167
168
        if (isset($extraFields[$tableName])) {
169
            $columns = array_merge($columns, $extraFields[$tableName]);
170
        }
171
    }
172
173
    public static function findNextId($tableName)
174
    {
175
        $result = self::get(['table_name' => 'information_schema.tables'], true, [
176
            'table_name' => $tableName,
177
            ['table_schema = DATABASE()'],
178
        ], true, ['AUTO_INCREMENT'], null, []);
179
180
        if ($result) {
181
            return $result;
182
        }
183
184
        return 1;
185
    }
186
187
    public static function findNextIdExt($object, $entityManager = null)
188
    {
189
        self::init(true);
190
        $data = self::extractExt($object, $entityManager);
191
192
        return self::findNextId($data['table']);
193
    }
194
195
    public static function runSQL($sql, $noFkCheck = true, $manager = null)
196
    {
197
        $sql = trim(preg_replace('/\s+/', ' ', $sql));
198
        self::init($noFkCheck, $manager);
199
        $sth = self::$connection->prepare($sql);
200
        $sth->execute();
201
202
        self::close($noFkCheck);
203
        if (substr($sql, 0, 6) === "SELECT") {
204
            return $sth->fetchAll();
205
        }
206
    }
207
208
    public static function get($object, $one = false, $where = [], $noFkCheck = true, $fields = [], $manager = null, $extra = [])
209
    {
210
        self::getTable($object, $tableName, $columns, $type, $noFkCheck, $manager);
211
212
        $select = (isset($extra['MODE']) ? 'SELECT '.$extra['MODE'] : 'SELECT').' ';
213
        $fields = $fields ?: ['id'];
214
        $sql = $select.(implode(', ', $fields)).' FROM '.$tableName.self::buildWhere($tableName, $where).self::buildExtra($extra);
215
216
        $result = self::runSQL($sql) ?: null;
217
218
        if ($result) {
219
            $field = null;
220
            if (count($fields) === 1 && $fields[0] !== '*') {
221
                $field = $fields[0];
222
            }
223
            if ($field) {
224
                if (!$one) {
225
                    foreach ($result as &$res) {
226
                        $res = $res[$field];
227
                    }
228
                } else {
229
                    $result = $result[0][$field];
230
                }
231
            } elseif ($one) {
232
                $result = $result[0];
233
            }
234
        }
235
236
        return $result;
237
    }
238
239
    private static function value($object, $variable, $type, $check = true)
240
    {
241
        $value = null;
242
        if ($type === 'object') {
243
            $value = $object->{'get'.ucfirst(Helper::toCamelCase($variable))}();
244
        } else {
245
            if (isset($object[$variable])) {
246
                $value = $object[$variable];
247
            }
248
        }
249
250
        if ($check) {
251
            Helper::variable($value);
252
        }
253
254
        return $value;
255
    }
256
257
    public static function persist($object, $full = false, $extraFields = [], $noFkCheck = false, $manager = null)
258
    {
259
        self::getTable($object, $tableName, $columns, $type, $noFkCheck, $manager, $extraFields);
260
261
        $id = self::findNextId($tableName);
262
        $data = [];
263
264
        $idd = null;
265
        foreach ($columns as $value => $key) {
266
            if (!is_array($key) && !is_array($value)) {
267
                $value = self::value($object, $value, $type);
268
                if ($value !== null) {
269
                    $data[$key] = $value;
270
                    if ($key === self::$identifier) {
271
                        $idd = $value;
272
                    }
273
                }
274
            }
275
        }
276
277
        if (!$full) {
278
            $data[self::$identifier] = $id;
279
        } else {
280
            $id = $idd;
281
        }
282
283
        if (Helper::isEmpty($data) && $id !== null) {
284
            return null;
285
        }
286
287
        $sql = '
288
            INSERT INTO
289
                '.$tableName.'
290
                    ('.implode(',', array_keys($data)).')
291
            VALUES
292
                ('.implode(',', array_values($data)).')
293
        ';
294
295
        self::runSQL($sql);
296
297
        return $id;
298
    }
299
300
    public static function update($id, $object, $extraFields = [], $noFkCheck = false, $manager = null)
301
    {
302
        self::getTable($object, $tableName, $columns, $type, $noFkCheck, $manager, $extraFields);
303
304
        $result = self::get(['table_name' => $tableName], true, ['id' => $id], true, ['*']);
305
        unset($result['id']);
306
        $data = [];
307
308
        $flip = array_flip($columns);
309
        foreach ($result as $key => $value) {
310
            $content = self::value($object, $key, $type, false);
311
            if ($content !== $value) {
312
                $data[$key] = $content;
313
            }
314
            if (!$id && $content === null) {
315
                unset($data[$key]);
316
            }
317
        }
318
319
        if ($data) {
320
            $sql = '
321
                UPDATE
322
                    '.$tableName.'
323
                SET
324
325
            ';
326
            foreach ($data as $key => $value) {
327
                $meta = self::$metadata[$tableName]->getFieldMapping($flip[$key])['type'];
328
                if (in_array($meta, [
329
                    'boolean',
330
                    'integer',
331
                    'longint',
332
                ])) {
333
                    $value = intval($value);
334
                } else {
335
                    $value = "'".addslashes(trim($value))."'";
336
                }
337
                $sql .= " ".$key." = ".$value.",";
338
            }
339
            $sql = substr($sql, 0, -1).' WHERE id = '.$id;
340
341
            self::runSQL($sql);
342
        }
343
    }
344
345 View Code Duplication
    public static function delete($object, $where = [], $noFkCheck = false, $manager = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
346
    {
347
        self::getTable($object, $tableName, $columns, $type, $noFkCheck, $manager);
348
349
        $sql = 'DELETE FROM '.$tableName.self::buildWhere($tableName, $where);
350
        self::runSQL($sql);
351
    }
352
353 View Code Duplication
    public static function link($object, $data, $noFkCheck = false, $manager = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
354
    {
355
        self::getTable($object, $tableName, $columns, $type, $noFkCheck, $manager);
356
357
        $data['table_name'] = $tableName;
358
        self::persist($data, true, [], $noFkCheck, $manager);
359
    }
360
}
361