Completed
Pull Request — master (#568)
by Michael
06:11
created

upgrade_230::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
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
 * See the enclosed file license.txt for licensing information.
15
 * If you did not receive this file, get it at http://www.fsf.org/copyleft/gpl.html
16
 *
17
 * @copyright   The XOOPS project http://www.xoops.org/
18
 * @license     http://www.fsf.org/copyleft/gpl.html GNU General Public License (GPL)
19
 * @package     upgrader
20
 * @since       2.3.0
21
 * @author      Taiwen Jiang <[email protected]>
22
 * @version     $Id$
23
 */
24
25
include_once __DIR__ . "/pathcontroller.php";
26
27
class upgrade_230 extends xoopsUpgrade
28
{
29
    public $usedFiles = array('mainfile.php');
30
31
    public $tasks = array('config', 'cache', 'path', 'db', 'bmlink');
32
33
    public function __construct()
34
    {
35
        xoopsUpgrade::__construct(basename(__DIR__));
0 ignored issues
show
Bug Best Practice introduced by
The method xoopsUpgrade::__construct() is not static, but was called statically. ( Ignorable by Annotation )

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

35
        xoopsUpgrade::/** @scrutinizer ignore-call */ 
36
                      __construct(basename(__DIR__));
Loading history...
36
    }
37
38
    /**
39
     * Check if cpanel config already exists
40
41
     */
42
    public function check_config()
43
    {
44
        $xoops = Xoops::getInstance();
45
        $db = $xoops->db();
46
        $sql = "SELECT COUNT(*) FROM `" . $db->prefix('config') . "` WHERE `conf_name` IN ('welcome_type', 'cpanel')";
47
        if (!$result = $db->queryF($sql)) {
0 ignored issues
show
Bug introduced by
The method queryF() does not exist on Xoops\Core\Database\Connection. Did you maybe mean queryFromFile()? ( Ignorable by Annotation )

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

47
        if (!$result = $db->/** @scrutinizer ignore-call */ queryF($sql)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
48
            return false;
49
        }
50
        list($count) = $db->fetchRow($result);
0 ignored issues
show
Bug introduced by
The method fetchRow() does not exist on Xoops\Core\Database\Connection. ( Ignorable by Annotation )

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

50
        /** @scrutinizer ignore-call */ 
51
        list($count) = $db->fetchRow($result);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
51
        return ($count == 2) ? true : false;
52
    }
53
54
    /**
55
     * Check if cache_model table already exists
56
57
     */
58
    public function check_cache()
59
    {
60
        $xoops = Xoops::getInstance();
61
        $db = $xoops->db();
62
        $sql = "SHOW TABLES LIKE '" . $db->prefix("cache_model") . "'";
63
        $result = $db->queryF($sql);
64
        if (!$result) {
65
            return false;
66
        }
67
        if ($db->getRowsNum($result) > 0) {
0 ignored issues
show
Bug introduced by
The method getRowsNum() does not exist on Xoops\Core\Database\Connection. ( Ignorable by Annotation )

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

67
        if ($db->/** @scrutinizer ignore-call */ getRowsNum($result) > 0) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
68
            return true;
69
        }
70
        return false;
71
        /*
72
        $sql = "SELECT COUNT(*) FROM `" . $db->prefix('cache_model') . "`";
73
        if ( !$result = $db->queryF( $sql ) ) {
74
            return false;
75
        }
76
        return true;
77
        */
78
    }
79
80
    /**
81
     * Check if primary key for `block_module_link` is already set
82
83
     */
84
    public function check_bmlink()
85
    {
86
        $xoops = Xoops::getInstance();
87
        $db = $xoops->db();
88
        // MySQL 5.0+
89
        //$sql = "SHOW KEYS FROM `" . $db->prefix('block_module_link') . "` WHERE `KEY_NAME` LIKE 'PRIMARY'";
90
        $sql = "SHOW KEYS FROM `" . $db->prefix('block_module_link');
91
        if (!$result = $db->queryF($sql)) {
92
            return false;
93
        }
94
        while ($row = $db->fetchArray($result)) {
95
            if ($row['Key_name'] == 'PRIMARY') {
96
                return true;
97
            }
98
        }
99
100
        return false;
101
    }
102
103
    public function apply_bmlink()
104
    {
105
        $xoops = Xoops::getInstance();
106
        $db = $xoops->db();
107
        $sql = "SHOW KEYS FROM `" . $db->prefix('block_module_link');
108
        if (!$result = $db->queryF($sql)) {
109
            return false;
110
        }
111
        $keys_drop = array();
112
        $primary_add = true;
113
        while ($row = $db->fetchArray($result)) {
114
            if ($row['Key_name'] == 'PRIMARY') {
115
                $primary_add = false;
116
            }
117
            if (in_array($row['Key_name'], array('block_id', 'module_id'))) {
118
                $keys_drop[] = $row['Key_name'];
119
            }
120
        }
121
        foreach ($keys_drop as $drop) {
122
            $sql = "ALTER TABLE `" . $db->prefix('block_module_link') . "` DROP KEY `{$drop}`";
123
            $db->queryF($sql);
124
        }
125
        if ($primary_add) {
126
            $sql = "ALTER IGNORE TABLE `" . $db->prefix('block_module_link') . "` ADD PRIMARY KEY (`block_id`, `module_id`)";
127
            return $db->queryF($sql);
128
        }
129
        return true;
130
    }
131
132
    public function apply_config()
133
    {
134
        $xoops = Xoops::getInstance();
135
        $db = $xoops->db();
136
        $result = true;
137
        if (!$xoops->getConfig("cpanel")) {
138
            $sql = "INSERT INTO " . $db->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)";
139
140
            $result *= $db->queryF($sql);
141
        }
142
143
        $welcometype_installed = false;
144
        $sql = "SELECT COUNT(*) FROM `" . $db->prefix('config') . "` WHERE `conf_name` = 'welcome_type'";
145
        if ($result = $db->queryF($sql)) {
146
            list($count) = $db->fetchRow($result);
147
            if ($count == 1) {
148
                $welcometype_installed = true;
149
            }
150
        }
151
        if (!$welcometype_installed) {
152
            $sql = "INSERT INTO " . $db->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)";
153
154
            if (!$db->queryF($sql)) {
155
                return false;
156
            }
157
            $config_id = $db->getInsertId();
0 ignored issues
show
Bug introduced by
The method getInsertId() does not exist on Xoops\Core\Database\Connection. ( Ignorable by Annotation )

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

157
            /** @scrutinizer ignore-call */ 
158
            $config_id = $db->getInsertId();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
158
159
            $sql = "INSERT INTO " . $db->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})";
160
            if (!$result = $db->queryF($sql)) {
161
                return false;
162
            }
163
        }
164
165
        return $result;
166
    }
167
168
    public function apply_cache()
169
    {
170
        $xoops = Xoops::getInstance();
171
        $db = $xoops->db();
172
        $allowWebChanges = $db->allowWebChanges;
0 ignored issues
show
Bug introduced by
The property allowWebChanges does not seem to exist on Xoops\Core\Database\Connection.
Loading history...
173
        $db->allowWebChanges = true;
174
        $result = $db->queryFromFile(__DIR__ . "/mysql.structure.sql");
175
        $db->allowWebChanges = $allowWebChanges;
176
        return $result;
177
    }
178
179
    public function check_path()
180
    {
181
        if (!(defined("XOOPS_PATH") && defined("XOOPS_VAR_PATH") && defined("XOOPS_TRUST_PATH"))) {
182
            return false;
183
        }
184
        $ctrl = new PathStuffController();
185
        if (!$ctrl->checkPath()) {
186
            return false;
187
        }
188
        if (!$ctrl->checkPermissions()) {
189
            return false;
190
        }
191
        return true;
192
    }
193
194
    public function apply_path()
195
    {
196
        return $this->update_configs('path');
197
    }
198
199
    public function check_db()
200
    {
201
        $lines = file(XOOPS_ROOT_PATH . '/mainfile.php');
202
        foreach ($lines as $line) {
203
            if (preg_match("/(define\(\s*)([\"'])(XOOPS_DB_CHARSET)\\2,\s*([\"'])([^\"']*?)\\4\s*\);/", $line)) {
204
                return true;
205
            }
206
        }
207
        return false;
208
    }
209
210
    public function apply_db()
211
    {
212
        return $this->update_configs('db');
213
    }
214
215
    public function update_configs($task)
216
    {
217
        if (!$vars = $this->set_configs($task)) {
218
            return false;
219
        }
220
        if ($task == "db" && !empty($vars["XOOPS_DB_COLLATION"])) {
221
            if ($pos = strpos($vars["XOOPS_DB_COLLATION"], "_")) {
222
                $vars["XOOPS_DB_CHARSET"] = substr($vars["XOOPS_DB_COLLATION"], 0, $pos);
223
                $this->convert_db($vars["XOOPS_DB_CHARSET"], $vars["XOOPS_DB_COLLATION"]);
224
            }
225
        }
226
227
        return $this->write_mainfile($vars);
228
    }
229
230
    public function convert_db($charset, $collation)
231
    {
232
        $xoops = Xoops::getInstance();
233
        $db = $xoops->db();
234
        $sql = "ALTER DATABASE `" . XOOPS_DB_NAME . "` DEFAULT CHARACTER SET " . $db->quote($charset) . " COLLATE " . $db->quote($collation);
235
        if (!$db->queryF($sql)) {
236
            return false;
237
        }
238
        if (!$result = $db->queryF("SHOW TABLES LIKE '" . XOOPS_DB_PREFIX . "\_%'")) {
239
            return false;
240
        }
241
        $tables = array();
242
        while (list($table) = $db->fetchRow($result)) {
243
            $tables[] = $table;
244
            //$db->queryF( "ALTER TABLE `{$table}` DEFAULT CHARACTER SET " . $db->quote($charset) . " COLLATE " . $db->quote($collation) );
245
            //$db->queryF( "ALTER TABLE `{$table}` CONVERT TO CHARACTER SET " . $db->quote($charset) . " COLLATE " . $db->quote($collation) );
246
        }
247
        $this->convert_table($tables, $charset, $collation);
248
    }
249
250
    // Some code not ready to use
251
    public function convert_table($tables, $charset, $collation)
252
    {
253
        $xoops = Xoops::getInstance();
254
        $db = $xoops->db();
255
        // Initialize vars.
256
        $string_querys = array();
257
        $binary_querys = array();
258
        $gen_index_querys = array();
259
        $drop_index_querys = array();
260
        $tables_querys = array();
261
        $optimize_querys = array();
262
        $final_querys = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $final_querys is dead and can be removed.
Loading history...
263
264
        // Begin Converter Core
265
        if (!empty($tables)) {
266
            foreach ((array)$tables as $table) {
267
                // Analyze tables for string types columns and generate his binary and string correctness sql sentences.
268
                $resource = $db->queryF("DESCRIBE $table");
269
                while ($result = $db->fetchArray($resource)) {
270
                    if (preg_match('/(char)|(text)|(enum)|(set)/', $result['Type'])) {
271
                        // String Type SQL Sentence.
272
                        $string_querys[] = "ALTER TABLE `$table` MODIFY `" . $result['Field'] . '` ' . $result['Type'] . " CHARACTER SET $charset COLLATE $collation " . (((!empty($result['Default'])) || ($result['Default'] === '0') || ($result['Default'] === 0)) ? "DEFAULT '" . $result['Default'] . "' " : '') . ('YES' == $result['Null'] ? '' : 'NOT ') . 'NULL';
273
274
                        // Binary String Type SQL Sentence.
275
                        if (preg_match('/(enum)|(set)/', $result['Type'])) {
276
                            $binary_querys[] = "ALTER TABLE `$table` MODIFY `" . $result['Field'] . '` ' . $result['Type'] . ' CHARACTER SET binary ' . (((!empty($result['Default'])) || ($result['Default'] === '0') || ($result['Default'] === 0)) ? "DEFAULT '" . $result['Default'] . "' " : '') . ('YES' == $result['Null'] ? '' : 'NOT ') . 'NULL';
277
                        } else {
278
                            $result['Type'] = preg_replace('/char/', 'binary', $result['Type']);
279
                            $result['Type'] = preg_replace('/text/', 'blob', $result['Type']);
280
                            $binary_querys[] = "ALTER TABLE `$table` MODIFY `" . $result['Field'] . '` ' . $result['Type'] . ' ' . (((!empty($result['Default'])) || ($result['Default'] === '0') || ($result['Default'] === 0)) ? "DEFAULT '" . $result['Default'] . "' " : '') . ('YES' == $result['Null'] ? '' : 'NOT ') . 'NULL';
281
                        }
282
                    }
283
                }
284
285
                // Analyze table indexs for any FULLTEXT-Type of index in the table.
286
                $fulltext_indexes = array();
287
                $resource = $db->queryF("SHOW INDEX FROM `$table`");
288
                while ($result = $db->fetchArray($resource)) {
289
                    if (preg_match('/FULLTEXT/', $result['Index_type'])) {
290
                        $fulltext_indexes[$result['Key_name']][$result['Column_name']] = 1;
291
                    }
292
                }
293
294
                // Generate the SQL Sentence for drop and add every FULLTEXT index we found previously.
295
                if (!empty($fulltext_indexes)) {
296
                    foreach ((array)$fulltext_indexes as $key_name => $column) {
297
                        $drop_index_querys[] = "ALTER TABLE `$table` DROP INDEX `$key_name`";
298
                        $tmp_gen_index_query = "ALTER TABLE `$table` ADD FULLTEXT `$key_name`(";
299
                        $fields_names = array_keys($column);
300
                        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...
301
                            $tmp_gen_index_query .= $fields_names[$i - 1] . (($i == count($column)) ? '' : ', ');
302
                        }
303
                        $gen_index_querys[] = $tmp_gen_index_query . ')';
304
                    }
305
                }
306
307
                // Generate the SQL Sentence for change default table character set.
308
                $tables_querys[] = "ALTER TABLE `$table` DEFAULT CHARACTER SET $charset COLLATE $collation";
309
310
                // Generate the SQL Sentence for Optimize Table.
311
                $optimize_querys[] = "OPTIMIZE TABLE `$table`";
312
            }
313
        }
314
        // End Converter Core
315
316
        // Merge all SQL Sentences that we temporary store in arrays.
317
        $final_querys = array_merge((array)$drop_index_querys, (array)$binary_querys, (array)$tables_querys, (array)$string_querys, (array)$gen_index_querys, (array)$optimize_querys);
318
319
        foreach ($final_querys as $sql) {
320
            $db->queryF($sql);
321
        }
322
323
        // Time to return.
324
        return $final_querys;
325
    }
326
327
    public function write_mainfile($vars)
328
    {
329
        if (empty($vars)) {
330
            return false;
331
        }
332
333
        $file = __DIR__ . '/mainfile.dist.php';
334
335
        $lines = file($file);
336
        foreach (array_keys($lines) as $ln) {
0 ignored issues
show
Bug introduced by
It seems like $lines can also be of type false; however, parameter $input of array_keys() does only seem to accept array, 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

336
        foreach (array_keys(/** @scrutinizer ignore-type */ $lines) as $ln) {
Loading history...
337
            if (preg_match("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([0-9]+)\s*\)/", $lines[$ln], $matches)) {
338
                $val = isset($vars[$matches[3]]) ? (string)constant($matches[3]) : (defined($matches[3]) ? (string)constant($matches[3]) : "0");
339
                $lines[$ln] = preg_replace("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([0-9]+)\s*\)/", "define( '" . $matches[3] . "', " . $val . " )", $lines[$ln]);
340
            } elseif (preg_match("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([\"'])([^\"']*?)\\4\s*\)/", $lines[$ln], $matches)) {
341
                $val = isset($vars[$matches[3]]) ? (string)$vars[$matches[3]] : (defined($matches[3]) ? (string)constant($matches[3]) : "");
342
                $lines[$ln] = preg_replace("/(define\()([\"'])(XOOPS_[^\"']+)\\2,\s*([\"'])(.*?)\\4\s*\)/", "define( '" . $matches[3] . "', '" . $val . "' )", $lines[$ln]);
343
            }
344
        }
345
346
        $fp = fopen(XOOPS_ROOT_PATH . '/mainfile.php', 'wt');
347
        if (!$fp) {
0 ignored issues
show
introduced by
The condition ! $fp can never be false.
Loading history...
348
            echo ERR_COULD_NOT_WRITE_MAINFILE;
349
            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>";
0 ignored issues
show
Bug introduced by
It seems like $lines can also be of type false; however, parameter $arr1 of array_map() does only seem to accept array, 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

349
            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", /** @scrutinizer ignore-type */ $lines)) . "</div></div></pre>";
Loading history...
350
            return false;
351
        } else {
352
            $newline = defined(PHP_EOL) ? PHP_EOL : (strpos(php_uname(), 'Windows') ? "\r\n" : "\n");
353
            $content = str_replace(array("\r\n", "\n"), $newline, implode('', $lines));
354
355
            fwrite($fp, $content);
356
            fclose($fp);
357
            return true;
358
        }
359
    }
360
361
    public function set_configs($task)
362
    {
363
        $ret = array();
364
        $configs = include __DIR__ . "/settings_{$task}.php";
365
        if (!$configs || !is_array($configs)) {
366
            return $ret;
367
        }
368
        if (empty($_POST['task']) || $_POST['task'] != $task) {
369
            return false;
370
        }
371
372
        foreach ($configs as $key => $val) {
373
            $ret['XOOPS_' . $key] = $val;
374
        }
375
        return $ret;
376
    }
377
}
378
379
$upg = new upgrade_230();
380
return $upg;
381