Passed
Push — master ( 88e106...e61ee7 )
by Richard
06:46 queued 13s
created

Upgrade_230::apply_bmlink()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 37
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 26
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 37
rs 9.504
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
use Xmf\Database\Tables;
13
14
/**
15
 * Upgrader from 2.0.18 to 2.3.0
16
 *
17
 * See the enclosed file license.txt for licensing information.
18
 * If you did not receive this file, get it at https://www.gnu.org/licenses/gpl-2.0.html
19
 *
20
 * @copyright    (c) 2000-2016 XOOPS Project (www.xoops.org)
21
 * @license          GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
22
 * @package          upgrader
23
 * @since            2.3.0
24
 * @author           Taiwen Jiang <[email protected]>
25
 */
26
27
include_once __DIR__ . '/pathcontroller.php';
28
29
/**
30
 * Class upgrade_230
31
 */
32
class Upgrade_230 extends XoopsUpgrade
33
{
34
    /*
35
     *  __construct()
36
     */
37
    public function __construct()
38
    {
39
        parent::__construct(basename(__DIR__));
40
        $this->usedFiles = array('mainfile.php');
41
        $this->tasks     = array('config', 'cache', 'path', 'db', 'bmlink');
42
    }
43
44
    /**
45
     * Check if cpanel config already exists
46
     *
47
     */
48
    public function check_config()
49
    {
50
        $sql = 'SELECT COUNT(*) FROM `' . $GLOBALS['xoopsDB']->prefix('config') . "` WHERE `conf_name` IN ('welcome_type', 'cpanel')";
51
        $result = $GLOBALS['xoopsDB']->queryF($sql);
52
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
53
            return false;
54
        }
55
        list($count) = $GLOBALS['xoopsDB']->fetchRow($result);
56
57
        return ($count == 2);
58
    }
59
60
    /**
61
     * Check if cache_model table already exists
62
     *
63
     */
64
    public function check_cache()
65
    {
66
        $sql    = "SHOW TABLES LIKE '" . $GLOBALS['xoopsDB']->prefix('cache_model') . "'";
67
        $result = $GLOBALS['xoopsDB']->queryF($sql);
68
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
69
            return false;
70
        }
71
72
        $temp = $GLOBALS['xoopsDB']->getRowsNum($result) > 0;
73
        return $temp;
74
75
        /*
76
        $sql = "SELECT COUNT(*) FROM `" . $GLOBALS['xoopsDB']->prefix('cache_model') . "`";
77
        if ( !$result = $GLOBALS['xoopsDB']->queryF( $sql ) ) {
78
            return false;
79
        }
80
81
        return true;
82
        */
83
    }
84
85
    /**
86
     * Check if primary key for `block_module_link` is already set
87
     *
88
     */
89
    public function check_bmlink()
90
    {
91
        // MySQL 5.0+
92
        //$sql = "SHOW KEYS FROM `" . $GLOBALS['xoopsDB']->prefix('block_module_link') . "` WHERE `KEY_NAME` LIKE 'PRIMARY'";
93
        $sql = 'SHOW KEYS FROM `' . $GLOBALS['xoopsDB']->prefix('block_module_link') . '`';
94
        $result = $GLOBALS['xoopsDB']->queryF($sql);
95
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
96
            return false;
97
        }
98
        while (false !== ($row = $GLOBALS['xoopsDB']->fetchArray($result))) {
99
            if ($row['Key_name'] === 'PRIMARY') {
100
                return true;
101
            }
102
        }
103
104
        return false;
105
    }
106
107
    /**
108
     * @return bool
109
     */
110
    public function apply_bmlink()
111
    {
112
        $tableName = 'block_module_link';
113
        $tableNameOld = $tableName . '_old';
114
115
        $tables = new Tables();
116
117
        $tables->useTable($tableName);
118
        $tables->renameTable($tableName, $tableNameOld);
119
        $result = $tables->executeQueue(true);
120
        if (true!==$result) {
121
            throw new \RuntimeException(
122
                __METHOD__ . ' failed.', E_USER_ERROR
123
            );
124
        }
125
        $tables->resetQueue();
126
        $tables->addTable($tableName);
127
        $tables->addColumn($tableName, 'block_id', 'int');
128
        $tables->addColumn($tableName, 'module_id', 'int');
129
        $tables->addPrimaryKey($tableName, 'block_id, module_id');
130
        $result = $tables->executeQueue(true);
131
        if (true!==$result) {
132
            throw new \RuntimeException(
133
                __METHOD__ . ' failed.', E_USER_ERROR
134
            );
135
        }
136
        $prefixedName = $GLOBALS['xoopsDB']->prefix('block_module_link');
137
        $sql = 'INSERT INTO `' . $prefixedName . '` (`block_id`, `module_id`) ' .
138
            'SELECT DISTINCT `block_id`, `module_id` FROM `' . $prefixedName . '_old`';
139
        $result = $GLOBALS['xoopsDB']->queryF($sql);
140
        if (true!==$result) {
141
            throw new \RuntimeException(
142
                __METHOD__ . ' failed.', E_USER_ERROR
143
            );
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
            return false;
284
        }
285
286
        $sql = "SHOW TABLES LIKE '" . XOOPS_DB_PREFIX . "\_%'";
287
        $result = $GLOBALS['xoopsDB']->queryF($sql);
288
        if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
289
            return false;
290
        }
291
        $tables = array();
292
        while (false !== (list($table) = $GLOBALS['xoopsDB']->fetchRow($result))) {
293
            $tables[] = $table;
294
            //$GLOBALS["xoopsDB"]->queryF( "ALTER TABLE `{$table}` DEFAULT CHARACTER SET " . $GLOBALS["xoopsDB"]->quote($charset) . " COLLATE " . $GLOBALS["xoopsDB"]->quote($collation) );
295
            //$GLOBALS["xoopsDB"]->queryF( "ALTER TABLE `{$table}` CONVERT TO CHARACTER SET " . $GLOBALS["xoopsDB"]->quote($charset) . " COLLATE " . $GLOBALS["xoopsDB"]->quote($collation) );
296
        }
297
        $this->convert_table($tables, $charset, $collation);
298
        return null;
299
    }
300
301
    // Some code not ready to use
302
    /**
303
     * @param $tables
304
     * @param $charset
305
     * @param $collation
306
     *
307
     * @return array
308
     */
309
    public function convert_table($tables, $charset, $collation)
310
    {
311
        // Initialize vars.
312
        $string_querys     = array();
313
        $binary_querys     = array();
314
        $gen_index_querys  = array();
315
        $drop_index_querys = array();
316
        $tables_querys     = array();
317
        $optimize_querys   = array();
318
        $final_querys      = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $final_querys is dead and can be removed.
Loading history...
319
320
        // Begin Converter Core
321
        if (!empty($tables)) {
322
            foreach ((array)$tables as $table) {
323
                // Analyze tables for string types columns and generate his binary and string correctness sql sentences.
324
                $sql = "DESCRIBE $table";
325
                $result = $GLOBALS['xoopsDB']->queryF($sql);
326
                if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
327
                    throw new \RuntimeException(
328
                        \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
329
                    );
330
                }
331
                while (false !== ($myrow = $GLOBALS['xoopsDB']->fetchArray($result))) {
332
                    if (preg_match('/(char)|(text)|(enum)|(set)/', $myrow['Type'])) {
333
                        // String Type SQL Sentence.
334
                        $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';
335
336
                        // Binary String Type SQL Sentence.
337
                        if (preg_match('/(enum)|(set)/', $myrow['Type'])) {
338
                            $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';
339
                        } else {
340
                            $myrow['Type']  = str_replace('char', 'binary', $myrow['Type']);
341
                            $myrow['Type']  = str_replace('text', 'blob', $myrow['Type']);
342
                            $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';
343
                        }
344
                    }
345
                }
346
347
                // Analyze table indexs for any FULLTEXT-Type of index in the table.
348
                $fulltext_indexes = array();
349
                $sql         = "SHOW INDEX FROM `$table`";
350
                $result = $GLOBALS['xoopsDB']->queryF($sql);
351
                if (!$GLOBALS['xoopsDB']->isResultSet($result)) {
352
                    throw new \RuntimeException(
353
                        \sprintf(_DB_QUERY_ERROR, $sql) . $GLOBALS['xoopsDB']->error(), E_USER_ERROR
354
                    );
355
                }
356
                while (false !== ($myrow = $GLOBALS['xoopsDB']->fetchArray($result))) {
357
                    if (preg_match('/FULLTEXT/', $myrow['Index_type'])) {
358
                        $fulltext_indexes[$myrow['Key_name']][$myrow['Column_name']] = 1;
359
                    }
360
                }
361
362
                // Generate the SQL Sentence for drop and add every FULLTEXT index we found previously.
363
                if (!empty($fulltext_indexes)) {
364
                    foreach ((array)$fulltext_indexes as $key_name => $column) {
365
                        $drop_index_querys[] = "ALTER TABLE `$table` DROP INDEX `$key_name`";
366
                        $tmp_gen_index_query = "ALTER TABLE `$table` ADD FULLTEXT `$key_name`(";
367
                        $fields_names        = array_keys($column);
368
                        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...
369
                            $tmp_gen_index_query .= $fields_names[$i - 1] . (($i == count($column)) ? '' : ', ');
370
                        }
371
                        $gen_index_querys[] = $tmp_gen_index_query . ')';
372
                    }
373
                }
374
375
                // Generate the SQL Sentence for change default table character set.
376
                $tables_querys[] = "ALTER TABLE `$table` DEFAULT CHARACTER SET $charset COLLATE $collation";
377
378
                // Generate the SQL Sentence for Optimize Table.
379
                $optimize_querys[] = "OPTIMIZE TABLE `$table`";
380
            }
381
        }
382
        // End Converter Core
383
384
        // Merge all SQL Sentences that we temporary store in arrays.
385
        $final_querys = array_merge((array)$drop_index_querys, (array)$binary_querys, (array)$tables_querys, (array)$string_querys, (array)$gen_index_querys, (array)$optimize_querys);
386
387
        foreach ($final_querys as $sql) {
388
            $GLOBALS['xoopsDB']->queryF($sql);
389
        }
390
391
        // Time to return.
392
        return $final_querys;
393
    }
394
395
    /**
396
     * @param $vars
397
     *
398
     * @return bool
399
     */
400
    public function write_mainfile($vars)
401
    {
402
        if (empty($vars)) {
403
            return false;
404
        }
405
406
        $file = __DIR__ . '/mainfile.dist.php';
407
408
        $lines = file($file);
409
        foreach (array_keys($lines) as $ln) {
410
            if (preg_match("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([0-9]+)\s*\)/", $lines[$ln], $matches)) {
411
                $val        = isset($vars[$matches[3]]) ? (string)constant($matches[3]) : (defined($matches[3]) ? (string)constant($matches[3]) : '0');
412
                $lines[$ln] = preg_replace("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([0-9]+)\s*\)/", "define('" . $matches[3] . "', " . $val . ' )', $lines[$ln]);
413
            } elseif (preg_match("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([\"'])([^\"']*?)\\4\s*\)/", $lines[$ln], $matches)) {
414
                $val        = isset($vars[$matches[3]]) ? (string)$vars[$matches[3]] : (defined($matches[3]) ? (string)constant($matches[3]) : '');
415
                $lines[$ln] = preg_replace("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([\"'])(.*?)\\4\s*\)/", "define('" . $matches[3] . "', '" . $val . "' )", $lines[$ln]);
416
            }
417
        }
418
419
        $fp = fopen(XOOPS_ROOT_PATH . '/mainfile.php', 'wt');
420
        if (!$fp) {
0 ignored issues
show
introduced by
$fp is of type resource, thus it always evaluated to false.
Loading history...
421
            echo ERR_COULD_NOT_WRITE_MAINFILE;
422
            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>';
423
424
            return false;
425
        } else {
426
            $newline = defined(PHP_EOL) ? PHP_EOL : (strpos(php_uname(), 'Windows') ? "\r\n" : "\n");
427
            $content = str_replace(array("\r\n", "\n"), $newline, implode('', $lines));
428
429
            fwrite($fp, $content);
430
            fclose($fp);
431
432
            return true;
433
        }
434
    }
435
436
    /**
437
     * @param $task
438
     *
439
     * @return array|bool
440
     */
441
    public function set_configs($task)
442
    {
443
        $ret     = array();
444
        $configs = include __DIR__ . "/settings_{$task}.php";
445
        if (!$configs || !is_array($configs)) {
446
            return $ret;
447
        }
448
        if (empty($_POST['task']) || $_POST['task'] != $task) {
449
            return false;
450
        }
451
452
        foreach ($configs as $key => $val) {
453
            $ret['XOOPS_' . $key] = $val;
454
        }
455
456
        return $ret;
457
    }
458
}
459
460
$upg = new Upgrade_230();
461
return $upg;
462