Passed
Pull Request — master (#1301)
by Michael
05:44
created

Upgrade_230::check_config()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 13
rs 10
c 0
b 0
f 0
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
            // throw new \RuntimeException(
52
            //     \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
53
            // );
54
            return false;
55
        }
56
        list($count) = $GLOBALS['xoopsDB']->fetchRow($result);
57
58
        return ($count == 2);
59
    }
60
61
    /**
62
     * Check if cache_model table already exists
63
     *
64
     */
65
    public function check_cache()
66
    {
67
        $sql    = "SHOW TABLES LIKE '" . $GLOBALS['xoopsDB']->prefix('cache_model') . "'";
68
        $result = $GLOBALS['xoopsDB']->queryF($sql);
69
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
70
            // throw new \RuntimeException(
71
            //     \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
72
            // );
73
            return false;
74
        }
75
76
        return $GLOBALS['xoopsDB']->getRowsNum($result) > 0;
77
78
        /*
79
        $sql = "SELECT COUNT(*) FROM `" . $GLOBALS['xoopsDB']->prefix('cache_model') . "`";
80
        if ( !$result = $GLOBALS['xoopsDB']->queryF( $sql ) ) {
81
            return false;
82
        }
83
84
        return true;
85
        */
86
    }
87
88
    /**
89
     * Check if primary key for `block_module_link` is already set
90
     *
91
     */
92
    public function check_bmlink()
93
    {
94
        // MySQL 5.0+
95
        //$sql = "SHOW KEYS FROM `" . $GLOBALS['xoopsDB']->prefix('block_module_link') . "` WHERE `KEY_NAME` LIKE 'PRIMARY'";
96
        $sql = 'SHOW KEYS FROM `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . '`';
97
        $result = $GLOBALS['xoopsDB']->queryF($sql);
98
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
99
            // throw new \RuntimeException(
100
            //     \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
101
            // );
102
            return false;
103
        }
104
        while (false !== ($row = $GLOBALS['xoopsDB']->fetchArray($result))) {
105
            if ($row['Key_name'] === 'PRIMARY') {
106
                return true;
107
            }
108
        }
109
110
        return false;
111
    }
112
113
    /**
114
     * @return bool
115
     */
116
    public function apply_bmlink()
117
    {
118
        $sql = 'SHOW KEYS FROM `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . '`';
119
        $result = $GLOBALS['xoopsDB']->queryF($sql);
120
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
121
            // throw new \RuntimeException(
122
            //     \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
123
            // );
124
            return false;
125
        }
126
        $keys_drop   = array();
127
        $primary_add = true;
128
        while (false !== ($row = $GLOBALS['xoopsDB']->fetchArray($result))) {
129
            if ($row['Key_name'] === 'PRIMARY') {
130
                $primary_add = false;
131
            }
132
            if (in_array($row['Key_name'], array('block_id', 'module_id'))) {
133
                $keys_drop[] = $row['Key_name'];
134
            }
135
        }
136
        foreach ($keys_drop as $drop) {
137
            $sql = 'ALTER TABLE `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . "` DROP KEY `{$drop}`";
138
            $GLOBALS['xoopsDB']->queryF($sql);
139
        }
140
        if ($primary_add) {
141
            $sql = 'ALTER IGNORE TABLE `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . '` ADD PRIMARY KEY (`block_id`, `module_id`)';
142
143
            return $GLOBALS['xoopsDB']->queryF($sql);
144
        }
145
146
        return true;
147
    }
148
149
    /**
150
     * @return bool
151
     */
152
    public function apply_config()
153
    {
154
        $result = true;
155
        if (!isset($GLOBALS['xoopsConfig']['cpanel'])) {
156
            $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)";
157
158
            $result *= $GLOBALS['xoopsDB']->queryF($sql);
159
        }
160
161
        $welcometype_installed = false;
162
        $sql                   = 'SELECT COUNT(*) FROM `' . $GLOBALS['xoopsDB']->prefix('config') . "` WHERE `conf_name` = 'welcome_type'";
163
        $result = $GLOBALS['xoopsDB']->queryF($sql);
164
        if ($GLOBALS['xoopsDB']->isResultSet($result)) {
165
            list($count) = $GLOBALS['xoopsDB']->fetchRow($result);
166
            if ($count == 1) {
167
                $welcometype_installed = true;
168
            }
169
        }
170
        if (!$welcometype_installed) {
171
            $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)";
172
173
            if (!$GLOBALS['xoopsDB']->queryF($sql)) {
174
                return false;
175
            }
176
            $config_id = $GLOBALS['xoopsDB']->getInsertId();
177
178
            $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})";
179
            if (!$result = $GLOBALS['xoopsDB']->queryF($sql)) {
180
                return false;
181
            }
182
        }
183
184
        return $result;
185
    }
186
187
    public function apply_cache()
188
    {
189
        $allowWebChanges                     = $GLOBALS['xoopsDB']->allowWebChanges;
190
        $GLOBALS['xoopsDB']->allowWebChanges = true;
191
        $result                              = $GLOBALS['xoopsDB']->queryFromFile(__DIR__ . '/mysql.structure.sql');
192
        $GLOBALS['xoopsDB']->allowWebChanges = $allowWebChanges;
193
194
        return $result;
195
    }
196
197
    /**
198
     * @return bool
199
     */
200
    public function check_path()
201
    {
202
        if (!(defined('XOOPS_PATH') && defined('XOOPS_VAR_PATH') && defined('XOOPS_TRUST_PATH'))) {
203
            return false;
204
        }
205
        $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

205
        $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...
206
        if (!$ctrl->checkPath()) {
207
            return false;
208
        }
209
        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

209
        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...
210
            return false;
211
        }
212
213
        return true;
214
    }
215
216
    /**
217
     * @return bool
218
     */
219
    public function apply_path()
220
    {
221
        return $this->update_configs('path');
222
    }
223
224
    /**
225
     * @return bool
226
     */
227
    public function check_db()
228
    {
229
        // mainfile was included to get here, just check for definition
230
        if (defined('XOOPS_DB_CHARSET')) {
231
            return true;
232
        }
233
        /*
234
        $lines = file(XOOPS_ROOT_PATH . '/mainfile.php');
235
        foreach ($lines as $line) {
236
            if (preg_match("/(define\(\s*)([\"'])(XOOPS_DB_CHARSET)\\2,\s*([\"'])([^\"']*?)\\4\s*\);/", $line)) {
237
                return true;
238
            }
239
        }
240
        */
241
        return false;
242
    }
243
244
    /**
245
     * @return bool
246
     */
247
    public function apply_db()
248
    {
249
        return $this->update_configs('db');
250
    }
251
252
    /**
253
     * @param $task
254
     *
255
     * @return bool
256
     */
257
    public function update_configs($task)
258
    {
259
        if (!$vars = $this->set_configs($task)) {
260
            return false;
261
        }
262
        if ($task === 'db' && !empty($vars['XOOPS_DB_COLLATION'])) {
263
            if ($pos = strpos($vars['XOOPS_DB_COLLATION'], '_')) {
264
                $vars['XOOPS_DB_CHARSET'] = substr($vars['XOOPS_DB_COLLATION'], 0, $pos);
265
                $this->convert_db($vars['XOOPS_DB_CHARSET'], $vars['XOOPS_DB_COLLATION']);
266
            }
267
        }
268
269
        return $this->write_mainfile($vars);
270
    }
271
272
    /**
273
     * @param $charset
274
     * @param $collation
275
     *
276
     * @return bool
277
     */
278
    public function convert_db($charset, $collation)
279
    {
280
        $sql = 'ALTER DATABASE `' . XOOPS_DB_NAME . '` DEFAULT CHARACTER SET ' . $GLOBALS['xoopsDB']->quote($charset) . ' COLLATE ' . $GLOBALS['xoopsDB']->quote($collation);
281
        $result = $GLOBALS['xoopsDB']->queryF($sql);
282
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
283
            // throw new \RuntimeException(
284
            //     \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
285
            // );
286
            return false;
287
        }
288
289
        $sql = "SHOW TABLES LIKE '" . XOOPS_DB_PREFIX . "\_%'";
290
        $result = $GLOBALS['xoopsDB']->queryF($sql);
291
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
292
            // throw new \RuntimeException(
293
            //     \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
294
            // );
295
            return false;
296
        }
297
        $tables = array();
298
        while (false !== (list($table) = $GLOBALS['xoopsDB']->fetchRow($result))) {
299
            $tables[] = $table;
300
            //$GLOBALS["xoopsDB"]->queryF( "ALTER TABLE `{$table}` DEFAULT CHARACTER SET " . $GLOBALS["xoopsDB"]->quote($charset) . " COLLATE " . $GLOBALS["xoopsDB"]->quote($collation) );
301
            //$GLOBALS["xoopsDB"]->queryF( "ALTER TABLE `{$table}` CONVERT TO CHARACTER SET " . $GLOBALS["xoopsDB"]->quote($charset) . " COLLATE " . $GLOBALS["xoopsDB"]->quote($collation) );
302
        }
303
        $this->convert_table($tables, $charset, $collation);
304
        return null;
305
    }
306
307
    // Some code not ready to use
308
    /**
309
     * @param $tables
310
     * @param $charset
311
     * @param $collation
312
     *
313
     * @return array
314
     */
315
    public function convert_table($tables, $charset, $collation)
316
    {
317
        // Initialize vars.
318
        $string_querys     = array();
319
        $binary_querys     = array();
320
        $gen_index_querys  = array();
321
        $drop_index_querys = array();
322
        $tables_querys     = array();
323
        $optimize_querys   = array();
324
        $final_querys      = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $final_querys is dead and can be removed.
Loading history...
325
326
        // Begin Converter Core
327
        if (!empty($tables)) {
328
            foreach ((array)$tables as $table) {
329
                // Analyze tables for string types columns and generate his binary and string correctness sql sentences.
330
                $sql = "DESCRIBE $table";
331
                $result = $GLOBALS['xoopsDB']->queryF($sql);
332
                if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
333
                    throw new \RuntimeException(
334
                        \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
335
                    );
336
                }
337
                while (false !== ($myrow = $GLOBALS['xoopsDB']->fetchArray($result))) {
338
                    if (preg_match('/(char)|(text)|(enum)|(set)/', $myrow['Type'])) {
339
                        // String Type SQL Sentence.
340
                        $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';
341
342
                        // Binary String Type SQL Sentence.
343
                        if (preg_match('/(enum)|(set)/', $myrow['Type'])) {
344
                            $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';
345
                        } else {
346
                            $myrow['Type']  = str_replace('char', 'binary', $myrow['Type']);
347
                            $myrow['Type']  = str_replace('text', 'blob', $myrow['Type']);
348
                            $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';
349
                        }
350
                    }
351
                }
352
353
                // Analyze table indexs for any FULLTEXT-Type of index in the table.
354
                $fulltext_indexes = array();
355
                $sql         = "SHOW INDEX FROM `$table`";
356
                $result = $GLOBALS['xoopsDB']->queryF($sql);
357
                if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
358
                    throw new \RuntimeException(
359
                        \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
360
                    );
361
                }
362
                while (false !== ($myrow = $GLOBALS['xoopsDB']->fetchArray($result))) {
363
                    if (preg_match('/FULLTEXT/', $myrow['Index_type'])) {
364
                        $fulltext_indexes[$myrow['Key_name']][$myrow['Column_name']] = 1;
365
                    }
366
                }
367
368
                // Generate the SQL Sentence for drop and add every FULLTEXT index we found previously.
369
                if (!empty($fulltext_indexes)) {
370
                    foreach ((array)$fulltext_indexes as $key_name => $column) {
371
                        $drop_index_querys[] = "ALTER TABLE `$table` DROP INDEX `$key_name`";
372
                        $tmp_gen_index_query = "ALTER TABLE `$table` ADD FULLTEXT `$key_name`(";
373
                        $fields_names        = array_keys($column);
374
                        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...
375
                            $tmp_gen_index_query .= $fields_names[$i - 1] . (($i == count($column)) ? '' : ', ');
376
                        }
377
                        $gen_index_querys[] = $tmp_gen_index_query . ')';
378
                    }
379
                }
380
381
                // Generate the SQL Sentence for change default table character set.
382
                $tables_querys[] = "ALTER TABLE `$table` DEFAULT CHARACTER SET $charset COLLATE $collation";
383
384
                // Generate the SQL Sentence for Optimize Table.
385
                $optimize_querys[] = "OPTIMIZE TABLE `$table`";
386
            }
387
        }
388
        // End Converter Core
389
390
        // Merge all SQL Sentences that we temporary store in arrays.
391
        $final_querys = array_merge((array)$drop_index_querys, (array)$binary_querys, (array)$tables_querys, (array)$string_querys, (array)$gen_index_querys, (array)$optimize_querys);
392
393
        foreach ($final_querys as $sql) {
394
            $GLOBALS['xoopsDB']->queryF($sql);
395
        }
396
397
        // Time to return.
398
        return $final_querys;
399
    }
400
401
    /**
402
     * @param $vars
403
     *
404
     * @return bool
405
     */
406
    public function write_mainfile($vars)
407
    {
408
        if (empty($vars)) {
409
            return false;
410
        }
411
412
        $file = __DIR__ . '/mainfile.dist.php';
413
414
        $lines = file($file);
415
        foreach (array_keys($lines) as $ln) {
416
            if (preg_match("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([0-9]+)\s*\)/", $lines[$ln], $matches)) {
417
                $val        = isset($vars[$matches[3]]) ? (string)constant($matches[3]) : (defined($matches[3]) ? (string)constant($matches[3]) : '0');
418
                $lines[$ln] = preg_replace("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([0-9]+)\s*\)/", "define('" . $matches[3] . "', " . $val . ' )', $lines[$ln]);
419
            } elseif (preg_match("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([\"'])([^\"']*?)\\4\s*\)/", $lines[$ln], $matches)) {
420
                $val        = isset($vars[$matches[3]]) ? (string)$vars[$matches[3]] : (defined($matches[3]) ? (string)constant($matches[3]) : '');
421
                $lines[$ln] = preg_replace("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([\"'])(.*?)\\4\s*\)/", "define('" . $matches[3] . "', '" . $val . "' )", $lines[$ln]);
422
            }
423
        }
424
425
        $fp = fopen(XOOPS_ROOT_PATH . '/mainfile.php', 'wt');
426
        if (!$fp) {
0 ignored issues
show
introduced by
$fp is of type resource, thus it always evaluated to false.
Loading history...
427
            echo ERR_COULD_NOT_WRITE_MAINFILE;
428
            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>';
429
430
            return false;
431
        } else {
432
            $newline = defined(PHP_EOL) ? PHP_EOL : (strpos(php_uname(), 'Windows') ? "\r\n" : "\n");
433
            $content = str_replace(array("\r\n", "\n"), $newline, implode('', $lines));
434
435
            fwrite($fp, $content);
436
            fclose($fp);
437
438
            return true;
439
        }
440
    }
441
442
    /**
443
     * @param $task
444
     *
445
     * @return array|bool
446
     */
447
    public function set_configs($task)
448
    {
449
        $ret     = array();
450
        $configs = include __DIR__ . "/settings_{$task}.php";
451
        if (!$configs || !is_array($configs)) {
452
            return $ret;
453
        }
454
        if (empty($_POST['task']) || $_POST['task'] != $task) {
455
            return false;
456
        }
457
458
        foreach ($configs as $key => $val) {
459
            $ret['XOOPS_' . $key] = $val;
460
        }
461
462
        return $ret;
463
    }
464
}
465
466
$upg = new Upgrade_230();
467
return $upg;
468