Completed
Push — master ( 2b6743...d5c6c4 )
by Richard
07:35
created

SystemMaintenance::displayTables()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 4
nop 1
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Maintenance class manager
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13
 * @license             GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
14
 * @author              Cointin Maxime (AKA Kraven30)
15
 * @package             system
16
 */
17
18
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
19
20
/**
21
 * System Maintenance
22
 *
23
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
24
 * @package             system
25
 */
26
class SystemMaintenance
27
{
28
    public $db;
29
    public $prefix;
30
31
    /**
32
     * Constructor
33
     */
34
    public function __construct()
35
    {
36
        $db           = XoopsDatabaseFactory::getDatabaseConnection();
37
        $this->db     = $db;
38
        $this->prefix = $this->db->prefix . '_';
39
    }
40
41
    /**
42
     * Display Tables
43
     *
44
     * @param bool $array
45
     *
46
     * @internal param $array
47
     * @return array|string
48
     */
49
    public function displayTables($array = true)
0 ignored issues
show
Unused Code introduced by
The parameter $array is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
50
    {
51
        $tables = array();
52
        $result = $this->db->queryF('SHOW TABLES');
53
        while ($myrow = $this->db->fetchArray($result)) {
54
            $value          = array_values($myrow);
55
            $value          = substr($value[0], strlen(XOOPS_DB_PREFIX) + 1);
56
            $tables[$value] = $value;
57
        }
58
        if ($array = true) {
0 ignored issues
show
Unused Code introduced by
$array is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
59
            return $tables;
60
        } else {
61
            return implode(',', $tables);
62
        }
63
    }
64
65
    /**
66
     * Clear sessions
67
     *
68
     * @return bool
69
     */
70
    public function CleanSession()
71
    {
72
        $result = $this->db->queryF('TRUNCATE TABLE ' . $this->db->prefix('session'));
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
73
74
        return true;
75
    }
76
77
    /**
78
     * CleanAvatar
79
     *
80
     * Clean up orphaned custom avatars left when a user is deleted.
81
     *
82
     * @author slider84 of Team FrXoops
83
     *
84
     * @return boolean
85
     */
86
    public function CleanAvatar()
87
    {
88
        $result = $this->db->queryF('SELECT avatar_id, avatar_file FROM ' . $this->db->prefix('avatar') . " WHERE avatar_type='C' AND avatar_id IN (" . 'SELECT t1.avatar_id FROM ' . $this->db->prefix('avatar_user_link') . ' AS t1 ' . 'LEFT JOIN ' . $this->db->prefix('users') . ' AS t2 ON t2.uid=t1.user_id ' . 'WHERE t2.uid IS NULL)');
89
90
        while ($myrow = $this->db->fetchArray($result)) {
91
            //delete file
92
            @unlink(XOOPS_UPLOAD_PATH . '/' . $myrow['avatar_file']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
93
            //clean avatar table
94
            $result1 = $this->db->queryF('DELETE FROM ' . $this->db->prefix('avatar') . ' WHERE avatar_id=' . $myrow['avatar_id']);
0 ignored issues
show
Unused Code introduced by
$result1 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
95
        }
96
        //clean any deleted users from avatar_user_link table
97
        $result2 = $this->db->queryF('DELETE FROM ' . $this->db->prefix('avatar_user_link') . ' WHERE user_id NOT IN (SELECT uid FROM ' . $this->db->prefix('users') . ')');
0 ignored issues
show
Unused Code introduced by
$result2 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
98
99
        return true;
100
    }
101
102
    /**
103
     * Delete all files in a directory
104
     *
105
     * @param string $dir directory to clear
106
     *
107
     * @return void
108
     */
109
    protected function clearDirectory($dir)
110
    {
111
        if (is_dir($dir)) {
112
            if ($dirHandle = opendir($dir)) {
113
                while (($file = readdir($dirHandle)) !== false) {
114
                    if (filetype($dir . $file) === 'file' && $file !== 'index.html') {
115
                        unlink($dir . $file);
116
                    }
117
                }
118
                closedir($dirHandle);
119
            }
120
        }
121
    }
122
123
    /**
124
     * Clean cache 'xoops_data/caches/smarty_cache'
125
     *
126
     * @param array $cacheList int[] of cache "ids"
127
     *                         1 = smarty cache
128
     *                         2 = smarty compile
129
     *                         3 = xoops cache
130
     * @return bool
131
     */
132
    public function CleanCache($cacheList)
133
    {
134
        foreach ($cacheList as $cache) {
135
            switch ($cache) {
136
                case 1:
137
                    $this->clearDirectory(XOOPS_VAR_PATH . '/caches/smarty_cache/');
138
                    break;
139
                case 2:
140
                    $this->clearDirectory(XOOPS_VAR_PATH . '/caches/smarty_compile/');
141
                    break;
142
                case 3:
143
                    $this->clearDirectory(XOOPS_VAR_PATH . '/caches/xoops_cache/');
144
                    break;
145
                default:
146
                    return false;
147
            }
148
        }
149
150
        return true;
151
    }
152
153
    /**
154
     * Maintenance database
155
     *
156
     * @param array tables 'list of tables'
157
     * @param array maintenance 'optimize, check, repair, analyze'
158
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
159
     */
160
    public function CheckRepairAnalyzeOptimizeQueries($tables, $maintenance)
161
    {
162
        $ret = '<table class="outer"><th>' . _AM_SYSTEM_MAINTENANCE_TABLES1 . '</th><th>' . _AM_SYSTEM_MAINTENANCE_TABLES_OPTIMIZE . '</th><th>' . _AM_SYSTEM_MAINTENANCE_TABLES_CHECK . '</th><th>' . _AM_SYSTEM_MAINTENANCE_TABLES_REPAIR . '</th><th>' . _AM_SYSTEM_MAINTENANCE_TABLES_ANALYZE . '</th>';
163
        $tab = array();
164
        for ($i = 0; $i < 4; ++$i) {
165
            $tab[$i] = $i + 1;
166
        }
167
        $tab1 = array();
168
        for ($i = 0; $i < 4; ++$i) {
169
            if (in_array($tab[$i], $maintenance)) {
170
                $tab1[$i] = $tab[$i];
171
            } else {
172
                $tab1[$i] = '0';
173
            }
174
        }
175
        unset($tab);
176
        $class       = 'odd';
177
        $tablesCount = count($tables);
178
        for ($i = 0; $i < $tablesCount; ++$i) {
179
            $ret .= '<tr class="' . $class . '"><td align="center">' . $this->prefix . $tables[$i] . '</td>';
180
            for ($j = 0; $j < 4; ++$j) {
181
                if ($tab1[$j] == 1) {
182
                    // Optimize
183
                    $result = $this->db->queryF('OPTIMIZE TABLE ' . $this->prefix . $tables[$i]);
184
                    if ($result) {
185
                        $ret .= '<td class="xo-actions txtcenter"><img src="' . system_AdminIcons('success.png') . '" /></td>';
186
                    } else {
187
                        $ret .= '<td class="xo-actions txtcenter"><img src="' . system_AdminIcons('cancel.png') . '" /></td>';
188
                    }
189 View Code Duplication
                } elseif ($tab1[$j] == 2) {
190
                    // Check tables
191
                    $result = $this->db->queryF('CHECK TABLE ' . $this->prefix . $tables[$i]);
192
                    if ($result) {
193
                        $ret .= '<td class="xo-actions txtcenter"><img src="' . system_AdminIcons('success.png') . '" /></td>';
194
                    } else {
195
                        $ret .= '<td class="xo-actions txtcenter"><img src="' . system_AdminIcons('cancel.png') . '" /></td>';
196
                    }
197
                } elseif ($tab1[$j] == 3) {
198
                    // Repair
199
                    $result = $this->db->queryF('REPAIR TABLE ' . $this->prefix . $tables[$i]);
200
                    if ($result) {
201
                        $ret .= '<td class="xo-actions txtcenter"><img src="' . system_AdminIcons('success.png') . '" /></td>';
202
                    } else {
203
                        $ret .= '<td class="xo-actions txtcenter"><img src="' . system_AdminIcons('cancel.png') . '" /></td>';
204
                    }
205 View Code Duplication
                } elseif ($tab1[$j] == 4) {
206
                    // Analyze
207
                    $result = $this->db->queryF('ANALYZE TABLE ' . $this->prefix . $tables[$i]);
208
                    if ($result) {
209
                        $ret .= '<td class="xo-actions txtcenter"><img src="' . system_AdminIcons('success.png') . '" /></td>';
210
                    } else {
211
                        $ret .= '<td class="xo-actions txtcenter"><img src="' . system_AdminIcons('cancel.png') . '" /></td>';
212
                    }
213
                } else {
214
                    $ret .= '<td>&nbsp;</td>';
215
                }
216
            }
217
            $ret .= '</tr>';
218
            $class = ($class === 'even') ? 'odd' : 'even';
219
        }
220
        $ret .= '</table>';
221
222
        return $ret;
223
    }
224
225
    /**
226
     * Dump by tables
227
     *
228
     * @param array tables 'list of tables'
229
     * @param int   drop
230
     * @return array 'ret[0] = dump, ret[1] = display result
231
     */
232
    public function dump_tables($tables, $drop)
233
    {
234
        $ret    = array();
235
        $ret[0] = "# \n";
236
        $ret[0] .= "# Dump SQL, Generate by Xoops \n";
237
        $ret[0] .= '# Date : ' . date('d-m-Y - H:i') . " \n";
238
        $ret[1]      = '<table class="outer"><tr><th width="30%">' . _AM_SYSTEM_MAINTENANCE_DUMP_TABLES . '</th><th width="35%">' . _AM_SYSTEM_MAINTENANCE_DUMP_STRUCTURES . '</th><th  width="35%">' . _AM_SYSTEM_MAINTENANCE_DUMP_NB_RECORDS . '</th></tr>';
239
        $class       = 'odd';
240
        $tablesCount = count($tables);
241
        for ($i = 0; $i < $tablesCount; ++$i) {
242
            //structure
243
            $ret = $this->dump_table_structure($ret, $this->prefix . $tables[$i], $drop, $class);
244
            //data
245
            $ret   = $this->dump_table_datas($ret, $this->prefix . $tables[$i]);
246
            $class = ($class === 'even') ? 'odd' : 'even';
247
        }
248
        $ret = $this->dump_write($ret);
249
        $ret[1] .= '</table>';
250
251
        return $ret;
252
    }
253
254
    /**
255
     * Dump by modules
256
     *
257
     * @param array modules 'list of modules'
258
     * @param int   drop
259
     * @return array 'ret[0] = dump, ret[1] = display result
260
     */
261
    public function dump_modules($modules, $drop)
262
    {
263
        $ret    = array();
264
        $ret[0] = "# \n";
265
        $ret[0] .= "# Dump SQL, Generate by Xoops \n";
266
        $ret[0] .= '# Date : ' . date('d-m-Y - H:i') . " \n";
267
        $ret[0] .= "# \n\n";
268
        $ret[1]       = '<table class="outer"><tr><th width="30%">' . _AM_SYSTEM_MAINTENANCE_DUMP_TABLES . '</th><th width="35%">' . _AM_SYSTEM_MAINTENANCE_DUMP_STRUCTURES . '</th><th  width="35%">' . _AM_SYSTEM_MAINTENANCE_DUMP_NB_RECORDS . '</th></tr>';
269
        $class        = 'odd';
270
        $modulesCount = count($modules);
271
        for ($i = 0; $i < $modulesCount; ++$i) {
272
            $module_handler = xoops_getHandler('module');
273
            $module         = $module_handler->getByDirname($modules[$i]);
274
            $ret[1] .= '<tr><th colspan="3" align="left">' . ucfirst($modules[$i]) . '</th></tr>';
275
            $modtables = $module->getInfo('tables');
276
            if ($modtables != false && is_array($modtables)) {
277
                foreach ($modtables as $table) {
278
                    //structure
279
                    $ret = $this->dump_table_structure($ret, $this->prefix . $table, $drop, $class);
280
                    //data
281
                    $ret   = $this->dump_table_datas($ret, $this->prefix . $table);
282
                    $class = ($class === 'even') ? 'odd' : 'even';
283
                }
284
            } else {
285
                $ret[1] .= '<tr><td colspan="3" align="center">' . _AM_SYSTEM_MAINTENANCE_DUMP_NO_TABLES . '</td></tr>';
286
            }
287
        }
288
        $ret[1] .= '</table>';
289
        $ret = $this->dump_write($ret);
290
291
        return $ret;
292
    }
293
294
    /**
295
     * Dump table structure
296
     *
297
     * @param array
298
     * @param string table
299
     * @param int    drop
300
     * @param string class
301
     * @return array 'ret[0] = dump, ret[1] = display result
302
     */
303
    public function dump_table_structure($ret, $table, $drop, $class)
304
    {
305
        $verif  = false;
306
        $result = $this->db->queryF('SHOW create table `' . $table . '`;');
307
        if ($result) {
308
            if ($row = $this->db->fetchArray($result)) {
309
                $ret[0] .= '# Table structure for table `' . $table . "` \n\n";
310
                if ($drop == 1) {
311
                    $ret[0] .= 'DROP TABLE IF EXISTS `' . $table . "`;\n\n";
312
                }
313
                $verif = true;
314
                $ret[0] .= $row['Create Table'] . ";\n\n";
315
            }
316
        }
317
        $ret[1] .= '<tr class="' . $class . '"><td align="center">' . $table . '</td><td class="xo-actions txtcenter">';
318
        $ret[1] .= ($verif == true) ? '<img src="' . system_AdminIcons('success.png') . '" />' : '<img src="' . system_AdminIcons('cancel.png') . '" />';
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...
319
        $ret[1] .= '</td>';
320
        $this->db->freeRecordSet($result);
321
322
        return $ret;
323
    }
324
325
    /**
326
     * Dump table data
327
     *
328
     * @param array
329
     * @param string table
330
     * @return array 'ret[0] = dump, ret[1] = display result
331
     */
332
    public function dump_table_datas($ret, $table)
333
    {
334
        $count  = 0;
335
        $result = $this->db->queryF('SELECT * FROM ' . $table . ';');
336
        if ($result) {
337
            $num_rows   = $this->db->getRowsNum($result);
338
            $num_fields = $this->db->getFieldsNum($result);
339
340
            if ($num_rows > 0) {
341
                $field_type = array();
342
                $i          = 0;
343
                while ($i < $num_fields) {
344
                    $meta = mysqli_fetch_field($result);
345
                    $field_type[] = $meta->type;
346
                    ++$i;
347
                }
348
349
                $ret[0] .= 'INSERT INTO `' . $table . "` values\n";
350
                $index = 0;
351
                while ($row = $this->db->fetchRow($result)) {
352
                    ++$count;
353
                    $ret[0] .= '(';
354
                    for ($i = 0; $i < $num_fields; ++$i) {
355
                        if (null === $row[$i]) {
356
                            $ret[0] .= 'null';
357
                        } else {
358
                            switch ($field_type[$i]) {
359
                                case 'int':
360
                                    $ret[0] .= $row[$i];
361
                                    break;
362
                                default:
363
                                    $ret[0] .= "'" . $this->db->escape($row[$i]) . "'";
364
                            }
365
                        }
366
                        if ($i < $num_fields - 1) {
367
                            $ret[0] .= ',';
368
                        }
369
                    }
370
                    $ret[0] .= ')';
371
372
                    if ($index < $num_rows - 1) {
373
                        $ret[0] .= ',';
374
                    } else {
375
                        $ret[0] .= ';';
376
                    }
377
                    $ret[0] .= "\n";
378
                    ++$index;
379
                }
380
            }
381
        }
382
        $ret[1] .= '<td align="center">';
383
        $ret[1] .= $count . '&nbsp;' . _AM_SYSTEM_MAINTENANCE_DUMP_RECORDS . '</td></tr>';
384
        $ret[0] .= "\n";
385
        $this->db->freeRecordSet($result);
386
        $ret[0] .= "\n";
387
388
        return $ret;
389
    }
390
391
    /**
392
     * Dump Write
393
     *
394
     * @param array
395
     * @return array 'ret[0] = dump, ret[1] = display result
396
     */
397
    public function dump_write($ret)
398
    {
399
        $file_name = 'dump_' . date('Y.m.d') . '_' . date('H.i.s') . '.sql';
400
        $path_file = './admin/maintenance/dump/' . $file_name;
401
        if (file_put_contents($path_file, $ret[0])) {
402
            $ret[1] .= '<table class="outer"><tr><th colspan="2" align="center">' . _AM_SYSTEM_MAINTENANCE_DUMP_FILE_CREATED . '</th><th>' . _AM_SYSTEM_MAINTENANCE_DUMP_RESULT . '</th></tr><tr><td colspan="2" align="center"><a href="' . XOOPS_URL . '/modules/system/admin/maintenance/dump/' . $file_name . '">' . $file_name . '</a></td><td  class="xo-actions txtcenter"><img src="' . system_AdminIcons('success.png') . '" /></td><tr></table>';
403
        } else {
404
            $ret[1] .= '<table class="outer"><tr><th colspan="2" align="center">' . _AM_SYSTEM_MAINTENANCE_DUMP_FILE_CREATED . '</th><th>' . _AM_SYSTEM_MAINTENANCE_DUMP_RESULT . '</th></tr><tr><td colspan="2" class="xo-actions txtcenter">' . $file_name . '</td><td  class="xo-actions txtcenter"><img src="' . system_AdminIcons('cancel.png') . '" /></td><tr></table>';
405
        }
406
407
        return $ret;
408
    }
409
}
410