Completed
Pull Request — master (#404)
by Richard
11:08
created

Upgrade_259::apply_mainfile()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 29
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 20
nc 6
nop 0
dl 0
loc 29
rs 8.5806
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 17 and the first side effect is on line 208.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
use Xmf\Database\Tables;
4
5
/**
6
 * Upgrade from 2.5.8 to 2.5.9
7
 *
8
 * See the enclosed file license.txt for licensing information.
9
 * If you did not receive this file, get it at http://www.gnu.org/licenses/gpl-2.0.html
10
 *
11
 * @copyright    (c) 2000-2016 XOOPS Project (www.xoops.org)
12
 * @license          GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
13
 * @package          Upgrade
14
 * @since            2.5.9
15
 * @author           XOOPS Team
16
 */
17
class Upgrade_259 extends XoopsUpgrade
18
{
19
    /**
20
     * __construct
21
     */
22
    public function __construct()
23
    {
24
        parent::__construct(basename(__DIR__));
25
        $this->tasks = array('sess_id', 'mainfile', 'zaplegacy');
26
        $this->usedFiles = array(
27
            'mainfile.php',
28
            XOOPS_VAR_PATH . '/data/secure.php',
29
            'modules/system/themes/legacy/legacy.php'
30
        );
31
    }
32
33
    /**
34
     * Return the length of a database table column
35
     *
36
     * @param string $table  table name
37
     * @param string $column column name
38
     *
39
     * @return int column length or zero on error
40
     */
41 View Code Duplication
    private function getColumnLength($table, $column)
42
    {
43
        /* @var $db XoopsMySQLDatabase */
44
        $db = XoopsDatabaseFactory::getDatabaseConnection();
45
46
        $dbname = constant('XOOPS_DB_NAME');
47
        $table = $db->prefix($table);
48
49
        $sql = sprintf(
50
            'SELECT `CHARACTER_MAXIMUM_LENGTH` FROM `information_schema`.`COLUMNS` '
51
            . "WHERE TABLE_SCHEMA = '%s'AND TABLE_NAME = '%s' AND COLUMN_NAME = '%s'",
52
            $db->escape($dbname),
53
            $db->escape($table),
54
            $db->escape($column)
55
        );
56
57
        /** @var mysqli_result $result */
58
        $result = $db->query($sql);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $db->query($sql) (which targets XoopsMySQLDatabase::query()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
59
        if ($result) {
60
            $row = $db->fetchRow($result);
61
            if ($row) {
62
                $columnLength = $row[0];
63
                return (int) $columnLength;
64
            }
65
        }
66
        return 0;
67
    }
68
69
    /**
70
     * In PHP 7.1 Session ID length could be any length between 22 and 256
71
     *
72
     * @return bool
73
     */
74
    public function check_sess_id()
75
    {
76
        return (bool) ($this->getColumnLength('session', 'sess_id') >= 256);
77
    }
78
79
    /**
80
     * Expand session id column to varchar(256) to accommodate expanded size possible in PHP 7.1
81
     * Force ascii character set to prevent key length issues.
82
     *
83
     * @return bool
84
     */
85 View Code Duplication
    public function apply_sess_id()
86
    {
87
        $migrate = new Tables();
88
        $migrate->useTable('session');
89
        $migrate->alterColumn('session', 'sess_id', "varchar(256) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT ''");
90
        return $migrate->executeQueue(true);
91
    }
92
93
    /**
94
     * Copy a configuration file from template, then rewrite with actual configuration values
95
     *
96
     * @param string[] $vars       config values
97
     * @param string   $path       directory path where files reside
98
     * @param string   $sourceName template file name
99
     * @param string   $fileName   configuration file name
100
     *
101
     * @return true|string true on success, error message on failure
0 ignored issues
show
Documentation introduced by
Should the return type not be string|boolean?

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...
102
     */
103
    protected function writeConfigurationFile($vars, $path, $sourceName, $fileName)
104
    {
105
        $path .= '/';
106
        clearstatcache();
107 View Code Duplication
        if (!$inFile = fopen($path . $sourceName, 'r')) {
108
            return sprintf(_FILE_ACCESS_ERROR, $sourceName);
109
        } else {
110
            $content = fread($inFile, filesize($path . $sourceName));
111
            fclose($inFile);
112
113
            foreach ($vars as $key => $val) {
114
                if (is_int($val) && preg_match("/(define\()([\"'])({$key})\\2,\s*(\d+)\s*\)/", $content)) {
115
                    $content = preg_replace("/(define\()([\"'])({$key})\\2,\s*(\d+)\s*\)/", "define('{$key}', {$val})", $content);
116
                } elseif (preg_match("/(define\()([\"'])({$key})\\2,\s*([\"'])(.*?)\\4\s*\)/", $content)) {
117
                    $val = str_replace('$', '\$', addslashes($val));
118
                    $content = preg_replace("/(define\()([\"'])({$key})\\2,\s*([\"'])(.*?)\\4\s*\)/", "define('{$key}', '{$val}')", $content);
119
                }
120
            }
121
            $outFile = fopen($path . $fileName, 'w');
122
            if (false === $outFile) {
123
                return sprintf(_FILE_ACCESS_ERROR, $fileName);
124
            }
125
            $writeResult = fwrite($outFile, $content);
126
            fclose($outFile);
127
            if (false === $writeResult) {
128
                return sprintf(_FILE_ACCESS_ERROR, $fileName);
129
            }
130
        }
131
        return true;
132
    }
133
134
    /**
135
     * Do we need to rewrite mainfile and secure?
136
     *
137
     * @return bool
138
     */
139
    public function check_mainfile()
140
    {
141
        /** @var $upgradeControl UpgradeControl */
142
        global $upgradeControl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
143
        return !$upgradeControl->needMainfileRewrite;
144
    }
145
146
    /**
147
     * Rewrite mainfile and secure file with current templates
148
     *
149
     * @return bool
150
     */
151
    public function apply_mainfile()
152
    {
153
        /** @var $upgradeControl UpgradeControl */
154
        global $upgradeControl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
155
156
        if (null === $upgradeControl->mainfileKeys['XOOPS_COOKIE_DOMAIN']) {
157
            $upgradeControl->mainfileKeys['XOOPS_COOKIE_DOMAIN'] = xoops_getBaseDomain(XOOPS_URL);
158
        }
159
        $result = $this->writeConfigurationFile(
160
            $upgradeControl->mainfileKeys,
161
            XOOPS_ROOT_PATH,
162
            'mainfile.dist.php',
163
            'mainfile.php'
164
        );
165
        if ($result !== true) {
166
            $this->logs[] = $result;
167
        } else {
168
            $result = $this->writeConfigurationFile(
169
                $upgradeControl->mainfileKeys,
170
                XOOPS_VAR_PATH . '/data',
171
                'secure.dist.php',
172
                'secure.php'
173
            );
174
            if ($result !== true) {
175
                $this->logs[] = $result;
176
            }
177
        }
178
        return ($result === true);
179
    }
180
181
    //modules/system/themes/legacy/legacy.php
182
    /**
183
     * Do we need to rewrite mainfile and secure?
184
     *
185
     * @return bool
186
     */
187
    public function check_zaplegacy()
188
    {
189
        return !file_exists('../modules/system/themes/legacy/legacy.php');
190
    }
191
192
    /**
193
     * Rewrite mainfile and secure file with current templates
194
     *
195
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be string|boolean?

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...
196
     */
197
    public function apply_zaplegacy()
198
    {
199
        $fileName = 'modules/system/themes/legacy/legacy.php';
200
        $result = rename('../' . $fileName, '../' . $fileName . '.bak');
201
        if (false === $result) {
202
            return sprintf(_FILE_ACCESS_ERROR, $fileName);
203
        }
204
        return true;
205
    }
206
}
207
208
$upg = new Upgrade_259();
209
return $upg;
210