Passed
Push — master ( 05faca...9c86bf )
by Richard
08:39 queued 13s
created

Upgrade_230::convert_table()   F

Complexity

Conditions 27
Paths 295

Size

Total Lines 84
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 27
eloc 46
nc 295
nop 3
dl 0
loc 84
rs 2.1458
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
/**
13
 * Upgrader from 2.0.18 to 2.3.0
14
 *
15
 * See the enclosed file license.txt for licensing information.
16
 * If you did not receive this file, get it at https://www.gnu.org/licenses/gpl-2.0.html
17
 *
18
 * @copyright    (c) 2000-2016 XOOPS Project (www.xoops.org)
19
 * @license          GNU GPL 2 or later (https://www.gnu.org/licenses/gpl-2.0.html)
20
 * @package          upgrader
21
 * @since            2.3.0
22
 * @author           Taiwen Jiang <[email protected]>
23
 */
24
25
include_once __DIR__ . '/pathcontroller.php';
26
27
/**
28
 * Class upgrade_230
29
 */
30
class Upgrade_230 extends XoopsUpgrade
31
{
32
    /*
33
     *  __construct()
34
     */
35
    public function __construct()
36
    {
37
        parent::__construct(basename(__DIR__));
38
        $this->usedFiles = array('mainfile.php');
39
        $this->tasks     = array('config', 'cache', 'path', 'db', 'bmlink');
40
    }
41
42
    /**
43
     * Check if cpanel config already exists
44
     *
45
     */
46
    public function check_config()
47
    {
48
        $sql = 'SELECT COUNT(*) FROM `' . $GLOBALS['xoopsDB']->prefix('config') . "` WHERE `conf_name` IN ('welcome_type', 'cpanel')";
49
        $result = $GLOBALS['xoopsDB']->queryF($sql);
50
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
51
            return false;
52
        }
53
        list($count) = $GLOBALS['xoopsDB']->fetchRow($result);
54
55
        return ($count == 2);
56
    }
57
58
    /**
59
     * Check if cache_model table already exists
60
     *
61
     */
62
    public function check_cache()
63
    {
64
        $sql    = "SHOW TABLES LIKE '" . $GLOBALS['xoopsDB']->prefix('cache_model') . "'";
65
        $result = $GLOBALS['xoopsDB']->queryF($sql);
66
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
67
            return false;
68
        }
69
70
        return $GLOBALS['xoopsDB']->getRowsNum($result) > 0;
71
72
        /*
73
        $sql = "SELECT COUNT(*) FROM `" . $GLOBALS['xoopsDB']->prefix('cache_model') . "`";
74
        if ( !$result = $GLOBALS['xoopsDB']->queryF( $sql ) ) {
75
            return false;
76
        }
77
78
        return true;
79
        */
80
    }
81
82
    /**
83
     * Check if primary key for `block_module_link` is already set
84
     *
85
     */
86
    public function check_bmlink()
87
    {
88
        // MySQL 5.0+
89
        //$sql = "SHOW KEYS FROM `" . $GLOBALS['xoopsDB']->prefix('block_module_link') . "` WHERE `KEY_NAME` LIKE 'PRIMARY'";
90
        $sql = 'SHOW KEYS FROM `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . '`';
91
        $result = $GLOBALS['xoopsDB']->queryF($sql);
92
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
93
            return false;
94
        }
95
        while (false !== ($row = $GLOBALS['xoopsDB']->fetchArray($result))) {
96
            if ($row['Key_name'] === 'PRIMARY') {
97
                return true;
98
            }
99
        }
100
101
        return false;
102
    }
103
104
    /**
105
     * @return bool
106
     */
107
    public function apply_bmlink()
108
    {
109
        $sql = 'SHOW KEYS FROM `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . '`';
110
        $result = $GLOBALS['xoopsDB']->queryF($sql);
111
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
112
            return false;
113
        }
114
        $keys_drop   = array();
115
        $primary_add = true;
116
        while (false !== ($row = $GLOBALS['xoopsDB']->fetchArray($result))) {
117
            if ($row['Key_name'] === 'PRIMARY') {
118
                $primary_add = false;
119
            }
120
            if (in_array($row['Key_name'], array('block_id', 'module_id'))) {
121
                $keys_drop[] = $row['Key_name'];
122
            }
123
        }
124
        foreach ($keys_drop as $drop) {
125
            $sql = 'ALTER TABLE `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . "` DROP KEY `{$drop}`";
126
            $GLOBALS['xoopsDB']->queryF($sql);
127
        }
128
        if ($primary_add) {
129
            $sql = 'ALTER IGNORE TABLE `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . '` ADD PRIMARY KEY (`block_id`, `module_id`)';
130
131
            return $GLOBALS['xoopsDB']->queryF($sql);
132
        }
133
134
        return true;
135
    }
136
137
    /**
138
     * @return bool
139
     */
140
    public function apply_config()
141
    {
142
        $result = true;
143
        if (!isset($GLOBALS['xoopsConfig']['cpanel'])) {
144
            $sql = 'INSERT INTO ' . $GLOBALS['xoopsDB']->prefix('config') . ' (conf_id, conf_modid, conf_catid, conf_name, conf_title, conf_value, conf_desc, conf_formtype, conf_valuetype, conf_order) ' . ' VALUES ' . " (NULL, 0, 1, 'cpanel', '_MD_AM_CPANEL', 'default', '_MD_AM_CPANELDSC', 'cpanel', 'other', 11)";
145
146
            $result *= $GLOBALS['xoopsDB']->queryF($sql);
147
        }
148
149
        $welcometype_installed = false;
150
        $sql                   = 'SELECT COUNT(*) FROM `' . $GLOBALS['xoopsDB']->prefix('config') . "` WHERE `conf_name` = 'welcome_type'";
151
        $result = $GLOBALS['xoopsDB']->queryF($sql);
152
        if ($GLOBALS['xoopsDB']->isResultSet($result)) {
153
            list($count) = $GLOBALS['xoopsDB']->fetchRow($result);
154
            if ($count == 1) {
155
                $welcometype_installed = true;
156
            }
157
        }
158
        if (!$welcometype_installed) {
159
            $sql = 'INSERT INTO ' . $GLOBALS['xoopsDB']->prefix('config') . ' (conf_id, conf_modid, conf_catid, conf_name, conf_title, conf_value, conf_desc, conf_formtype, conf_valuetype, conf_order) ' . ' VALUES ' . " (NULL, 0, 2, 'welcome_type', '_MD_AM_WELCOMETYPE', '1', '_MD_AM_WELCOMETYPE_DESC', 'select', 'int', 3)";
160
161
            if (!$GLOBALS['xoopsDB']->queryF($sql)) {
162
                return false;
163
            }
164
            $config_id = $GLOBALS['xoopsDB']->getInsertId();
165
166
            $sql = 'INSERT INTO ' . $GLOBALS['xoopsDB']->prefix('configoption') . ' (confop_id, confop_name, confop_value, conf_id)' . ' VALUES' . " (NULL, '_NO', '0', {$config_id})," . " (NULL, '_MD_AM_WELCOMETYPE_EMAIL', '1', {$config_id})," . " (NULL, '_MD_AM_WELCOMETYPE_PM', '2', {$config_id})," . " (NULL, '_MD_AM_WELCOMETYPE_BOTH', '3', {$config_id})";
167
            if (!$result = $GLOBALS['xoopsDB']->queryF($sql)) {
168
                return false;
169
            }
170
        }
171
172
        return $result;
173
    }
174
175
    public function apply_cache()
176
    {
177
        $allowWebChanges                     = $GLOBALS['xoopsDB']->allowWebChanges;
178
        $GLOBALS['xoopsDB']->allowWebChanges = true;
179
        $result                              = $GLOBALS['xoopsDB']->queryFromFile(__DIR__ . '/mysql.structure.sql');
180
        $GLOBALS['xoopsDB']->allowWebChanges = $allowWebChanges;
181
182
        return $result;
183
    }
184
185
    /**
186
     * @return bool
187
     */
188
    public function check_path()
189
    {
190
        if (!(defined('XOOPS_PATH') && defined('XOOPS_VAR_PATH') && defined('XOOPS_TRUST_PATH'))) {
191
            return false;
192
        }
193
        $ctrl = new PathStuffController();
0 ignored issues
show
Bug introduced by
The call to PathStuffController::__construct() has too few arguments starting with xoopsPathDefault. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

193
        $ctrl = /** @scrutinizer ignore-call */ new PathStuffController();

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
194
        if (!$ctrl->checkPath()) {
195
            return false;
196
        }
197
        if (!$ctrl->checkPermissions()) {
0 ignored issues
show
Bug introduced by
The call to PathStuffController::checkPermissions() has too few arguments starting with path. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

197
        if (!$ctrl->/** @scrutinizer ignore-call */ checkPermissions()) {

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
198
            return false;
199
        }
200
201
        return true;
202
    }
203
204
    /**
205
     * @return bool
206
     */
207
    public function apply_path()
208
    {
209
        return $this->update_configs('path');
210
    }
211
212
    /**
213
     * @return bool
214
     */
215
    public function check_db()
216
    {
217
        // mainfile was included to get here, just check for definition
218
        if (defined('XOOPS_DB_CHARSET')) {
219
            return true;
220
        }
221
        /*
222
        $lines = file(XOOPS_ROOT_PATH . '/mainfile.php');
223
        foreach ($lines as $line) {
224
            if (preg_match("/(define\(\s*)([\"'])(XOOPS_DB_CHARSET)\\2,\s*([\"'])([^\"']*?)\\4\s*\);/", $line)) {
225
                return true;
226
            }
227
        }
228
        */
229
        return false;
230
    }
231
232
    /**
233
     * @return bool
234
     */
235
    public function apply_db()
236
    {
237
        return $this->update_configs('db');
238
    }
239
240
    /**
241
     * @param $task
242
     *
243
     * @return bool
244
     */
245
    public function update_configs($task)
246
    {
247
        if (!$vars = $this->set_configs($task)) {
248
            return false;
249
        }
250
        if ($task === 'db' && !empty($vars['XOOPS_DB_COLLATION'])) {
251
            if ($pos = strpos($vars['XOOPS_DB_COLLATION'], '_')) {
252
                $vars['XOOPS_DB_CHARSET'] = substr($vars['XOOPS_DB_COLLATION'], 0, $pos);
253
                $this->convert_db($vars['XOOPS_DB_CHARSET'], $vars['XOOPS_DB_COLLATION']);
254
            }
255
        }
256
257
        return $this->write_mainfile($vars);
258
    }
259
260
    /**
261
     * @param $charset
262
     * @param $collation
263
     *
264
     * @return bool
265
     */
266
    public function convert_db($charset, $collation)
267
    {
268
        $sql = 'ALTER DATABASE `' . XOOPS_DB_NAME . '` DEFAULT CHARACTER SET ' . $GLOBALS['xoopsDB']->quote($charset) . ' COLLATE ' . $GLOBALS['xoopsDB']->quote($collation);
269
        $result = $GLOBALS['xoopsDB']->queryF($sql);
270
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
271
            return false;
272
        }
273
274
        $sql = "SHOW TABLES LIKE '" . XOOPS_DB_PREFIX . "\_%'";
275
        $result = $GLOBALS['xoopsDB']->queryF($sql);
276
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
277
            return false;
278
        }
279
        $tables = array();
280
        while (false !== (list($table) = $GLOBALS['xoopsDB']->fetchRow($result))) {
281
            $tables[] = $table;
282
            //$GLOBALS["xoopsDB"]->queryF( "ALTER TABLE `{$table}` DEFAULT CHARACTER SET " . $GLOBALS["xoopsDB"]->quote($charset) . " COLLATE " . $GLOBALS["xoopsDB"]->quote($collation) );
283
            //$GLOBALS["xoopsDB"]->queryF( "ALTER TABLE `{$table}` CONVERT TO CHARACTER SET " . $GLOBALS["xoopsDB"]->quote($charset) . " COLLATE " . $GLOBALS["xoopsDB"]->quote($collation) );
284
        }
285
        $this->convert_table($tables, $charset, $collation);
286
        return null;
287
    }
288
289
    // Some code not ready to use
290
    /**
291
     * @param $tables
292
     * @param $charset
293
     * @param $collation
294
     *
295
     * @return array
296
     */
297
    public function convert_table($tables, $charset, $collation)
298
    {
299
        // Initialize vars.
300
        $string_querys     = array();
301
        $binary_querys     = array();
302
        $gen_index_querys  = array();
303
        $drop_index_querys = array();
304
        $tables_querys     = array();
305
        $optimize_querys   = array();
306
        $final_querys      = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $final_querys is dead and can be removed.
Loading history...
307
308
        // Begin Converter Core
309
        if (!empty($tables)) {
310
            foreach ((array)$tables as $table) {
311
                // Analyze tables for string types columns and generate his binary and string correctness sql sentences.
312
                $sql = "DESCRIBE $table";
313
                $result = $GLOBALS['xoopsDB']->queryF($sql);
314
                if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
315
                    throw new \RuntimeException(
316
                        \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
317
                    );
318
                }
319
                while (false !== ($myrow = $GLOBALS['xoopsDB']->fetchArray($result))) {
320
                    if (preg_match('/(char)|(text)|(enum)|(set)/', $myrow['Type'])) {
321
                        // String Type SQL Sentence.
322
                        $string_querys[] = "ALTER TABLE `$table` MODIFY `" . $myrow['Field'] . '` ' . $myrow['Type'] . " CHARACTER SET $charset COLLATE $collation " . (((!empty($myrow['Default'])) || ($myrow['Default'] === '0') || ($myrow['Default'] === 0)) ? "DEFAULT '" . $myrow['Default'] . "' " : '') . ('YES' === $myrow['Null'] ? '' : 'NOT ') . 'NULL';
323
324
                        // Binary String Type SQL Sentence.
325
                        if (preg_match('/(enum)|(set)/', $myrow['Type'])) {
326
                            $binary_querys[] = "ALTER TABLE `$table` MODIFY `" . $myrow['Field'] . '` ' . $myrow['Type'] . ' CHARACTER SET binary ' . (((!empty($myrow['Default'])) || ($myrow['Default'] === '0') || ($myrow['Default'] === 0)) ? "DEFAULT '" . $myrow['Default'] . "' " : '') . ('YES' === $myrow['Null'] ? '' : 'NOT ') . 'NULL';
327
                        } else {
328
                            $myrow['Type']  = str_replace('char', 'binary', $myrow['Type']);
329
                            $myrow['Type']  = str_replace('text', 'blob', $myrow['Type']);
330
                            $binary_querys[] = "ALTER TABLE `$table` MODIFY `" . $myrow['Field'] . '` ' . $myrow['Type'] . ' ' . (((!empty($myrow['Default'])) || ($myrow['Default'] === '0') || ($myrow['Default'] === 0)) ? "DEFAULT '" . $myrow['Default'] . "' " : '') . ('YES' === $myrow['Null'] ? '' : 'NOT ') . 'NULL';
331
                        }
332
                    }
333
                }
334
335
                // Analyze table indexs for any FULLTEXT-Type of index in the table.
336
                $fulltext_indexes = array();
337
                $sql         = "SHOW INDEX FROM `$table`";
338
                $result = $GLOBALS['xoopsDB']->queryF($sql);
339
                if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
340
                    throw new \RuntimeException(
341
                        \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
342
                    );
343
                }
344
                while (false !== ($myrow = $GLOBALS['xoopsDB']->fetchArray($result))) {
345
                    if (preg_match('/FULLTEXT/', $myrow['Index_type'])) {
346
                        $fulltext_indexes[$myrow['Key_name']][$myrow['Column_name']] = 1;
347
                    }
348
                }
349
350
                // Generate the SQL Sentence for drop and add every FULLTEXT index we found previously.
351
                if (!empty($fulltext_indexes)) {
352
                    foreach ((array)$fulltext_indexes as $key_name => $column) {
353
                        $drop_index_querys[] = "ALTER TABLE `$table` DROP INDEX `$key_name`";
354
                        $tmp_gen_index_query = "ALTER TABLE `$table` ADD FULLTEXT `$key_name`(";
355
                        $fields_names        = array_keys($column);
356
                        for ($i = 1; $i <= count($column); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
357
                            $tmp_gen_index_query .= $fields_names[$i - 1] . (($i == count($column)) ? '' : ', ');
358
                        }
359
                        $gen_index_querys[] = $tmp_gen_index_query . ')';
360
                    }
361
                }
362
363
                // Generate the SQL Sentence for change default table character set.
364
                $tables_querys[] = "ALTER TABLE `$table` DEFAULT CHARACTER SET $charset COLLATE $collation";
365
366
                // Generate the SQL Sentence for Optimize Table.
367
                $optimize_querys[] = "OPTIMIZE TABLE `$table`";
368
            }
369
        }
370
        // End Converter Core
371
372
        // Merge all SQL Sentences that we temporary store in arrays.
373
        $final_querys = array_merge((array)$drop_index_querys, (array)$binary_querys, (array)$tables_querys, (array)$string_querys, (array)$gen_index_querys, (array)$optimize_querys);
374
375
        foreach ($final_querys as $sql) {
376
            $GLOBALS['xoopsDB']->queryF($sql);
377
        }
378
379
        // Time to return.
380
        return $final_querys;
381
    }
382
383
    /**
384
     * @param $vars
385
     *
386
     * @return bool
387
     */
388
    public function write_mainfile($vars)
389
    {
390
        if (empty($vars)) {
391
            return false;
392
        }
393
394
        $file = __DIR__ . '/mainfile.dist.php';
395
396
        $lines = file($file);
397
        foreach (array_keys($lines) as $ln) {
398
            if (preg_match("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([0-9]+)\s*\)/", $lines[$ln], $matches)) {
399
                $val        = isset($vars[$matches[3]]) ? (string)constant($matches[3]) : (defined($matches[3]) ? (string)constant($matches[3]) : '0');
400
                $lines[$ln] = preg_replace("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([0-9]+)\s*\)/", "define('" . $matches[3] . "', " . $val . ' )', $lines[$ln]);
401
            } elseif (preg_match("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([\"'])([^\"']*?)\\4\s*\)/", $lines[$ln], $matches)) {
402
                $val        = isset($vars[$matches[3]]) ? (string)$vars[$matches[3]] : (defined($matches[3]) ? (string)constant($matches[3]) : '');
403
                $lines[$ln] = preg_replace("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([\"'])(.*?)\\4\s*\)/", "define('" . $matches[3] . "', '" . $val . "' )", $lines[$ln]);
404
            }
405
        }
406
407
        $fp = fopen(XOOPS_ROOT_PATH . '/mainfile.php', 'wt');
408
        if (!$fp) {
0 ignored issues
show
introduced by
$fp is of type resource, thus it always evaluated to false.
Loading history...
409
            echo ERR_COULD_NOT_WRITE_MAINFILE;
410
            echo "<pre style='border: 1px solid black; width: 80%; overflow: auto;'><div style='color: #ff0000; font-weight: bold;'><div>" . implode('</div><div>', array_map('htmlspecialchars', $lines)) . '</div></div></pre>';
411
412
            return false;
413
        } else {
414
            $newline = defined(PHP_EOL) ? PHP_EOL : (strpos(php_uname(), 'Windows') ? "\r\n" : "\n");
415
            $content = str_replace(array("\r\n", "\n"), $newline, implode('', $lines));
416
417
            fwrite($fp, $content);
418
            fclose($fp);
419
420
            return true;
421
        }
422
    }
423
424
    /**
425
     * @param $task
426
     *
427
     * @return array|bool
428
     */
429
    public function set_configs($task)
430
    {
431
        $ret     = array();
432
        $configs = include __DIR__ . "/settings_{$task}.php";
433
        if (!$configs || !is_array($configs)) {
434
            return $ret;
435
        }
436
        if (empty($_POST['task']) || $_POST['task'] != $task) {
437
            return false;
438
        }
439
440
        foreach ($configs as $key => $val) {
441
            $ret['XOOPS_' . $key] = $val;
442
        }
443
444
        return $ret;
445
    }
446
}
447
448
$upg = new Upgrade_230();
449
return $upg;
450