SmartDbTable   B
last analyzed

Complexity

Total Complexity 52

Size/Duplication

Total Lines 467
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 52
eloc 128
c 1
b 0
f 0
dl 0
loc 467
rs 7.44

29 Methods

Rating   Name   Duplication   Size   Complexity  
A updateWhereValues() 0 18 4
A addData() 0 15 3
A exists() 0 3 1
A getAlteredFields() 0 3 1
A getData() 0 3 1
A getExistingFieldsArray() 0 15 4
A addDroppedField() 0 3 1
A __construct() 0 4 1
A setFlagForDrop() 0 3 1
A alterTable() 0 20 5
A getStructure() 0 3 1
A createTable() 0 14 2
A addNewField() 0 5 1
A name() 0 5 1
A addUpdatedField() 0 5 1
A dropFields() 0 18 4
A setData() 0 3 1
A getUpdatedFields() 0 3 1
A setStructure() 0 3 1
A updateFieldsValues() 0 17 4
A fieldExists() 0 5 1
A addUpdatedWhere() 0 6 1
A getFlagForDrop() 0 3 1
A getUpdatedWhere() 0 3 1
A getNewFields() 0 3 1
A getDroppedFields() 0 3 1
A dropTable() 0 14 2
A addAlteredField() 0 6 1
A addNewFields() 0 17 4

How to fix   Complexity   

Complex Class

Complex classes like SmartDbTable often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SmartDbTable, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Smartfaq;
4
5
/**
6
 * Detemines if a table exists in the current db
7
 *
8
 * @param string $table the table name (without XOOPS prefix)
9
 * @return bool   True if table exists, false if not
10
 *
11
 * @author xhelp development team
12
 */
13
14
use XoopsDatabaseFactory;
15
use XoopsModules\Smartfaq;
16
17
/**
18
 * @param $table
19
 * @return bool
20
 */
21
function smart_TableExists($table)
22
{
23
    $bRetVal = false;
24
    //Verifies that a MySQL table exists
25
    $xoopsDB  = XoopsDatabaseFactory::getDatabaseConnection();
26
    $realname = $xoopsDB->prefix($table);
27
    $sql      = 'SHOW TABLES FROM ' . XOOPS_DB_NAME;
28
    $ret      = $xoopsDB->queryF($sql);
29
    while ([$m_table] = $xoopsDB->fetchRow($ret)) {
30
        if ($m_table == $realname) {
31
            $bRetVal = true;
32
            break;
33
        }
34
    }
35
    $xoopsDB->freeRecordSet($ret);
36
37
    return $bRetVal;
38
}
39
40
/**
41
 * Contains the classes for updating database tables
42
 *
43
 * @license GNU
44
 * @author  marcan <[email protected]>
45
 * @link    https://www.smartfactory.ca The SmartFactory
46
 */
47
48
/**
49
 * SmartDbTable class
50
 *
51
 * Information about an individual table
52
 *
53
 * @author  marcan <[email protected]>
54
 * @link    https://www.smartfactory.ca The SmartFactory
55
 */
56
57
/**
58
 * Include the language constants for the SmartObjectDBUpdater
59
 */
60
global $xoopsConfig;
61
62
/** @var Smartfaq\Helper $helper */
63
$helper = Smartfaq\Helper::getInstance();
64
65
$helper->loadLanguage('smartdbupdater');
66
//
67
//$common_file = XOOPS_ROOT_PATH . '/modules/smartfaq/language/' . $xoopsConfig['language'] . '/smartdbupdater.php';
68
//if (!file_exists($common_file)) {
69
//    $common_file = XOOPS_ROOT_PATH . '/modules/smartfaq/language/english/smartdbupdater.php';
70
//}
71
//require_once $common_file;
72
73
/**
74
 * Class SmartDbTable
75
 */
76
class SmartDbTable
77
{
78
    /**
79
     * @var string $_name name of the table
80
     */
81
    private $_name;
82
    /**
83
     * @var string|null $_structure structure of the table
84
     */
85
    private $_structure;
86
    /**
87
     * @var array $_data containing valued of each records to be added
88
     */
89
    private $_data;
90
    /**
91
     * @var array|null $_alteredFields containing fields to be altered
92
     */
93
    private $_alteredFields;
94
    /**
95
     * @var array|null $_newFields containing new fields to be added
96
     */
97
    private $_newFields;
98
    /**
99
     * @var array|null $_droppedFields containing fields to be dropped
100
     */
101
    private $_droppedFields;
102
    /**
103
     * @var array $_flagForDrop flag table to drop it
104
     */
105
    private $_flagForDrop = false;
106
    /**
107
     * @var array|null $_updatedFields containing fields which values will be updated
108
     */
109
    private $_updatedFields;
110
    /**
111
     * @var array|null $_updatedFields containing fields which values will be updated
112
     */ //felix
113
    private $_updatedWhere;
114
115
    /**
116
     * Constructor
117
     *
118
     * @param string $name name of the table
119
     */
120
    public function __construct($name)
121
    {
122
        $this->_name = $name;
123
        $this->_data = [];
124
    }
125
126
    /**
127
     * Return the table name, prefixed with site table prefix
128
     *
129
     * @return string table name
130
     */
131
    public function name()
132
    {
133
        global $xoopsDB;
134
135
        return $xoopsDB->prefix($this->_name);
136
    }
137
138
    /**
139
     * Checks if the table already exists in the database
140
     *
141
     * @return bool TRUE if it exists, FALSE if not
142
     */
143
    public function exists()
144
    {
145
        return smart_TableExists($this->_name);
146
    }
147
148
    /**
149
     * @return mixed
150
     */
151
    public function getExistingFieldsArray()
152
    {
153
        global $xoopsDB;
154
        $result = $xoopsDB->queryF('SHOW COLUMNS FROM ' . $this->name());
155
        while (false !== ($existing_field = $xoopsDB->fetchArray($result))) {
156
            $fields[$existing_field['Field']] = $existing_field['Type'];
157
            if ('YES' !== $existing_field['Null']) {
158
                $fields[$existing_field['Field']] .= ' NOT NULL';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $fields does not seem to be defined for all execution paths leading up to this point.
Loading history...
159
            }
160
            if ($existing_field['Extra']) {
161
                $fields[$existing_field['Field']] .= ' ' . $existing_field['Extra'];
162
            }
163
        }
164
165
        return $fields;
166
    }
167
168
    /**
169
     * @param $field
170
     * @return bool
171
     */
172
    public function fieldExists($field)
173
    {
174
        $existingFields = $this->getExistingFieldsArray();
175
176
        return isset($existingFields[$field]);
177
    }
178
179
    /**
180
     * Set the table structure
181
     *
182
     * @param string $structure table structure
183
     */
184
    public function setStructure($structure): void
185
    {
186
        $this->_structure = $structure;
187
    }
188
189
    /**
190
     * Return the table structure
191
     *
192
     * @return string table structure
193
     */
194
    public function getStructure()
195
    {
196
        return \sprintf($this->_structure, $this->name());
0 ignored issues
show
Bug introduced by
It seems like $this->_structure can also be of type null; however, parameter $format of sprintf() 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

196
        return \sprintf(/** @scrutinizer ignore-type */ $this->_structure, $this->name());
Loading history...
197
    }
198
199
    /**
200
     * Add values of a record to be added
201
     *
202
     * @param string $data values of a record
203
     */
204
    public function setData($data): void
205
    {
206
        $this->_data[] = $data;
207
    }
208
209
    /**
210
     * Get the data array
211
     *
212
     * @return array containing the records values to be added
213
     */
214
    public function getData()
215
    {
216
        return $this->_data;
217
    }
218
219
    /**
220
     * Use to insert data in a table
221
     *
222
     * @return bool true if success, false if an error occurred
223
     */
224
    public function addData()
225
    {
226
        global $xoopsDB;
227
228
        foreach ($this->getData() as $data) {
229
            $query = \sprintf('INSERT INTO `%s` VALUES ("%s")', $this->name(), $data);
230
            $ret   = $xoopsDB->queryF($query);
231
            if ($ret) {
232
                echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_ADD_DATA, $this->name()) . '<br>';
233
            } else {
234
                echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_ADD_DATA_ERR, $this->name()) . '<br>';
235
            }
236
        }
237
238
        return $ret;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $ret seems to be defined by a foreach iteration on line 228. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
239
    }
240
241
    /**
242
     * Add a field to be added
243
     *
244
     * @param string $name       name of the field
245
     * @param string $properties properties of the field
246
     * @param bool   $showerror
247
     */
248
    public function addAlteredField($name, $properties, $showerror = true): void
249
    {
250
        $field['name']          = $name;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$field was never initialized. Although not strictly required by PHP, it is generally a good practice to add $field = array(); before regardless.
Loading history...
251
        $field['properties']    = $properties;
252
        $field['showerror']     = $showerror;
253
        $this->_alteredFields[] = $field;
254
    }
255
256
    /**
257
     * Invert values 0 to 1 and 1 to 0
258
     *
259
     * @param string $name name of the field
260
     * @param        $newValue
261
     * @param        $oldValue
262
     * @internal param string $old old propertie
263
     * @internal param string $new new propertie
264
     */ //felix
265
266
    public function addUpdatedWhere($name, $newValue, $oldValue): void
267
    {
268
        $field['name']         = $name;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$field was never initialized. Although not strictly required by PHP, it is generally a good practice to add $field = array(); before regardless.
Loading history...
269
        $field['value']        = $newValue;
270
        $field['where']        = $oldValue;
271
        $this->_updatedWhere[] = $field;
272
    }
273
274
    /**
275
     * Add new field of a record to be added
276
     *
277
     * @param string $name       name of the field
278
     * @param string $properties properties of the field
279
     */
280
    public function addNewField($name, $properties): void
281
    {
282
        $field['name']       = $name;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$field was never initialized. Although not strictly required by PHP, it is generally a good practice to add $field = array(); before regardless.
Loading history...
283
        $field['properties'] = $properties;
284
        $this->_newFields[]  = $field;
285
    }
286
287
    /**
288
     * Get fields that need to be altered
289
     *
290
     * @return array fields that need to be altered
291
     */
292
    public function getAlteredFields()
293
    {
294
        return $this->_alteredFields;
295
    }
296
297
    /**
298
     * Add field for which the value will be updated
299
     *
300
     * @param string $name  name of the field
301
     * @param string $value value to be set
302
     */
303
    public function addUpdatedField($name, $value): void
304
    {
305
        $field['name']          = $name;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$field was never initialized. Although not strictly required by PHP, it is generally a good practice to add $field = array(); before regardless.
Loading history...
306
        $field['value']         = $value;
307
        $this->_updatedFields[] = $field;
308
    }
309
310
    /**
311
     * Get new fields to be added
312
     *
313
     * @return array fields to be added
314
     */
315
    public function getNewFields()
316
    {
317
        return $this->_newFields;
318
    }
319
320
    /**
321
     * Get fields which values need to be updated
322
     *
323
     * @return array fields which values need to be updated
324
     */
325
    public function getUpdatedFields()
326
    {
327
        return $this->_updatedFields;
328
    }
329
330
    /**
331
     * Get fields which values need to be updated
332
     *
333
     * @return array fields which values need to be updated
334
     */ //felix
335
336
    public function getUpdatedWhere()
337
    {
338
        return $this->_updatedWhere;
339
    }
340
341
    /**
342
     * Add values of a record to be added
343
     *
344
     * @param string $name name of the field
345
     */
346
    public function addDroppedField($name): void
347
    {
348
        $this->_droppedFields[] = $name;
349
    }
350
351
    /**
352
     * Get fields that need to be dropped
353
     *
354
     * @return array fields that need to be dropped
355
     */
356
    public function getDroppedFields()
357
    {
358
        return $this->_droppedFields;
359
    }
360
361
    /**
362
     * Set the flag to drop the table
363
     */
364
    public function setFlagForDrop(): void
365
    {
366
        $this->_flagForDrop = true;
0 ignored issues
show
Documentation Bug introduced by
It seems like true of type true is incompatible with the declared type array of property $_flagForDrop.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
367
    }
368
369
    /**
370
     * Get the flag to drop the table
371
     */
372
    public function getFlagForDrop()
373
    {
374
        return $this->_flagForDrop;
375
    }
376
377
    /**
378
     * Use to create a table
379
     *
380
     * @return bool true if success, false if an error occurred
381
     */
382
    public function createTable()
383
    {
384
        global $xoopsDB;
385
386
        $query = $this->getStructure();
387
388
        $ret = $xoopsDB->queryF($query);
389
        if ($ret) {
390
            echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_CREATE_TABLE, $this->name()) . '<br>';
391
        } else {
392
            echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_CREATE_TABLE_ERR, $this->name()) . '<br>';
393
        }
394
395
        return $ret;
396
    }
397
398
    /**
399
     * Use to drop a table
400
     *
401
     * @return bool true if success, false if an error occurred
402
     */
403
    public function dropTable()
404
    {
405
        global $xoopsDB;
406
407
        $query = \sprintf('DROP TABLE `%s`', $this->name());
408
        $ret   = $xoopsDB->queryF($query);
409
        if (!$ret) {
410
            echo '&nbsp;&nbsp;' . \sprintf(\_SDU_MSG_DROP_TABLE_ERR, $this->name()) . '<br>';
411
412
            return false;
413
        }
414
        echo '&nbsp;&nbsp;' . \sprintf(\_SDU_MSG_DROP_TABLE, $this->name()) . '<br>';
415
416
        return true;
417
    }
418
419
    /**
420
     * Use to alter a table
421
     *
422
     * @return bool true if success, false if an error occurred
423
     */
424
    public function alterTable()
425
    {
426
        global $xoopsDB;
427
428
        $ret = true;
429
430
        foreach ($this->getAlteredFields() as $alteredField) {
431
            $query = \sprintf('ALTER TABLE `%s` CHANGE %s %s', $this->name(), $alteredField['name'], $alteredField['properties']);
432
            //echo $query;
433
            $ret = $ret && $xoopsDB->queryF($query);
434
            if ($alteredField['showerror']) {
435
                if ($ret) {
436
                    echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_CHGFIELD, $alteredField['name'], $this->name()) . '<br>';
437
                } else {
438
                    echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_CHGFIELD_ERR, $alteredField['name'], $this->name()) . '<br>';
439
                }
440
            }
441
        }
442
443
        return $ret;
444
    }
445
446
    /**
447
     * Use to add new fileds in the table
448
     *
449
     * @return bool true if success, false if an error occurred
450
     */
451
    public function addNewFields()
452
    {
453
        global $xoopsDB;
454
455
        $ret = true;
456
        foreach ($this->getNewFields() as $newField) {
457
            $query = \sprintf('ALTER TABLE `%s` ADD %s %s', $this->name(), $newField['name'], $newField['properties']);
458
            //echo $query;
459
            $ret = $ret && $xoopsDB->queryF($query);
460
            if ($ret) {
461
                echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_NEWFIELD, $newField['name'], $this->name()) . '<br>';
462
            } else {
463
                echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_NEWFIELD_ERR, $newField['name'], $this->name()) . '<br>';
464
            }
465
        }
466
467
        return $ret;
468
    }
469
470
    /**
471
     * Use to update fields values
472
     *
473
     * @return bool true if success, false if an error occurred
474
     */
475
    public function updateFieldsValues()
476
    {
477
        global $xoopsDB;
478
479
        $ret = true;
480
481
        foreach ($this->getUpdatedFields() as $updatedField) {
482
            $query = \sprintf('UPDATE `%s` SET %s = %s', $this->name(), $updatedField['name'], $updatedField['value']);
483
            $ret   = $ret && $xoopsDB->queryF($query);
484
            if ($ret) {
485
                echo '&nbsp;&nbsp;' . \sprintf(\_SDU_MSG_UPDATE_TABLE, $this->name()) . '<br>';
486
            } else {
487
                echo '&nbsp;&nbsp;' . \sprintf(\_SDU_MSG_UPDATE_TABLE_ERR, $this->name()) . '<br>';
488
            }
489
        }
490
491
        return $ret;
492
    }
493
494
    /**
495
     * Use to update fields values
496
     *
497
     * @return bool true if success, false if an error occurred
498
     */ //felix
499
500
    public function updateWhereValues()
501
    {
502
        global $xoopsDB;
503
504
        $ret = true;
505
506
        foreach ($this->getUpdatedWhere() as $updatedWhere) {
507
            $query = \sprintf('UPDATE `%s` SET %s = %s WHERE %s  %s', $this->name(), $updatedWhere['name'], $updatedWhere['value'], $updatedWhere['name'], $updatedWhere['where']);
508
            //echo $query."<br>";
509
            $ret = $ret && $xoopsDB->queryF($query);
510
            if ($ret) {
511
                echo '&nbsp;&nbsp;' . \sprintf(\_SDU_MSG_UPDATE_TABLE, $this->name()) . '<br>';
512
            } else {
513
                echo '&nbsp;&nbsp;' . \sprintf(\_SDU_MSG_UPDATE_TABLE_ERR, $this->name()) . '<br>';
514
            }
515
        }
516
517
        return $ret;
518
    }
519
520
    /**
521
     * Use to drop fields
522
     *
523
     * @return bool true if success, false if an error occurred
524
     */
525
    public function dropFields()
526
    {
527
        global $xoopsDB;
528
529
        $ret = true;
530
531
        foreach ($this->getDroppedFields() as $droppedField) {
532
            $query = \sprintf('ALTER TABLE `%s` DROP %s', $this->name(), $droppedField);
533
534
            $ret = $ret && $xoopsDB->queryF($query);
535
            if ($ret) {
536
                echo '&nbsp;&nbsp;' . \sprintf(_SDU_MSG_DROPFIELD, $droppedField, $this->name()) . '<br>';
537
            } else {
538
                echo '&nbsp;&nbsp;' . \sprintf(\_SDU_MSG_DROPFIELD_ERR, $droppedField, $this->name()) . '<br>';
539
            }
540
        }
541
542
        return $ret;
543
    }
544
}
545