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

PathStuffController::__construct()   C

Complexity

Conditions 8
Paths 14

Size

Total Lines 24
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 19
nc 14
nop 0
dl 0
loc 24
rs 5.7377
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 http://www.fsf.org/copyleft/gpl.html
17
 *
18
 * @copyright   The XOOPS project http://www.xoops.org/
19
 * @license     http://www.fsf.org/copyleft/gpl.html GNU General Public License (GPL)
20
 * @package     upgrader
21
 * @since       2.3.0
22
 * @author      Taiwen Jiang <[email protected]>
23
 * @version     $Id$
24
 */
25
26
27
class PathStuffController
28
{
29
    public $xoopsPath = array(
30
            'lib'   => '',
31
            'data'  => '',
32
            );
33
    public $path_lookup = array(
34
            'data'  => 'VAR_PATH',
35
            'lib'   => 'PATH',
36
            );
37
38
    public $validPath = array(
39
            'data'  => 0,
40
            'lib'   => 0,
41
            );
42
43
    public $permErrors = array(
44
            'data'  => null,
45
            );
46
47
    public function __construct()
48
    {
49
        if (isset($_SESSION['settings']['VAR_PATH'])) {
50
            foreach ($this->path_lookup as $req => $sess) {
51
                $this->xoopsPath[$req] = $_SESSION['settings'][$sess];
52
            }
53
        } else {
54
            $path = XOOPS_ROOT_PATH;
55
            if (defined("XOOPS_PATH")) {
56
                $this->xoopsPath['lib'] = XOOPS_PATH;
57
            } elseif (defined("XOOPS_TRUST_PATH")) {
58
                $this->xoopsPath['lib'] = XOOPS_TRUST_PATH;
59
            } else {
60
                $this->xoopsPath['lib'] = dirname($path) . "/xoops_lib";
61
                if (!is_dir($this->xoopsPath['lib'] . "/")) {
62
                    $this->xoopsPath['lib'] = $path . "/xoops_lib";
63
                }
64
            }
65
            if (defined("XOOPS_VAR_PATH")) {
66
                $this->xoopsPath['data'] = XOOPS_VAR_PATH;
67
            } else {
68
                $this->xoopsPath['data'] = dirname($path) . "/xoops_data";
69
                if (!is_dir($this->xoopsPath['data'] . "/")) {
70
                    $this->xoopsPath['data'] = $path . "/xoops_data";
71
                }
72
            }
73
        }
74
    }
75
76
    public function execute()
77
    {
78
        $this->readRequest();
79
        $valid = $this->validate();
80
        if ($_SERVER['REQUEST_METHOD'] == 'POST' && @$_POST['task'] == 'path') {
81
            foreach ($this->path_lookup as $req => $sess) {
82
                $_SESSION['settings'][$sess] = $this->xoopsPath[$req];
83
            }
84
            if ($valid) {
85
                return $_SESSION['settings'];
86
            } else {
87
                return false;
88
            }
89
        }
90
    }
91
92
    public function readRequest()
93
    {
94
        if ($_SERVER['REQUEST_METHOD'] == 'POST' && @$_POST['task'] == 'path') {
95
            $request = $_POST;
96
            foreach ($this->path_lookup as $req => $sess) {
97
                if (isset($request[$req])) {
98
                    $request[$req] = str_replace("\\", "/", trim($request[$req]));
99
                    if (substr($request[$req], -1) == '/') {
100
                        $request[$req] = substr($request[$req], 0, -1);
101
                    }
102
                    $this->xoopsPath[$req] = $request[$req];
103
                }
104
            }
105
        }
106
    }
107
108
    public function validate()
109
    {
110
        foreach (array_keys($this->xoopsPath) as $path) {
111
            if ($this->checkPath($path)) {
112
                $this->checkPermissions($path);
113
            }
114
        }
115
        $validPaths = (array_sum(array_values($this->validPath)) == count(array_keys($this->validPath))) ? 1 : 0;
116
        $validPerms = true;
117
        foreach ($this->permErrors as $key => $errs) {
118
            if (empty($errs)) {
119
                continue;
120
            }
121
            foreach ($errs as $path => $status) {
122
                if (empty($status)) {
123
                    $validPerms = false;
124
                    break;
125
                }
126
            }
127
        }
128
        return ($validPaths && $validPerms);
129
    }
130
131
    public function checkPath($PATH = '')
132
    {
133
        $ret = 1;
134
        if ($PATH == 'lib' || empty($PATH)) {
135
            $path = 'lib';
136
            if (is_dir($this->xoopsPath[$path]) && is_readable($this->xoopsPath[$path])) {
137
                $this->validPath[$path] = 1;
138
            }
139
            $ret *= $this->validPath[$path];
140
        }
141
        if ($PATH == 'data' || empty($PATH)) {
142
            $path = 'data';
143
            if (is_dir($this->xoopsPath[$path]) && is_readable($this->xoopsPath[$path])) {
144
                $this->validPath[$path] = 1;
145
            }
146
            $ret *= $this->validPath[$path];
147
        }
148
        return $ret;
149
    }
150
151
    public function setPermission($parent, $path, &$error)
152
    {
153
        if (is_array($path)) {
154
            foreach (array_keys($path) as $item) {
155
                if (is_string($item)) {
156
                    $error[$parent . "/" . $item] = $this->makeWritable($parent . "/" . $item);
157
                    if (empty($path[$item])) {
158
                        continue;
159
                    }
160
                    foreach ($path[$item] as $child) {
161
                        $this->setPermission($parent . "/" . $item, $child, $error);
162
                    }
163
                } else {
164
                    $error[$parent . "/" . $path[$item]] = $this->makeWritable($parent . "/" . $path[$item]);
165
                }
166
            }
167
        } else {
168
            $error[$parent . "/" . $path] = $this->makeWritable($parent . "/" . $path);
169
        }
170
        return;
171
    }
172
173
    public function checkPermissions($path = "data")
174
    {
175
        $paths = array(
176
            'data'  => array(
177
                'caches' => array(
178
                    'xoops_cache',
179
                    'smarty_cache',
180
                    'smarty_compile',
181
                    ),
182
                'configs',
183
                ),
184
            );
185
        $errors = array(
186
            'data'  => null,
187
            );
188
        if (!isset($this->xoopsPath[$path])) {
189
            return false;
190
        }
191
        if (!isset($paths[$path])) {
192
            return true;
193
        }
194
        $this->setPermission($this->xoopsPath[$path], $paths[$path], $errors[$path]);
195
        if (in_array(false, $errors[$path])) {
0 ignored issues
show
Bug introduced by
$errors[$path] of type null is incompatible with the type array expected by parameter $haystack of in_array(). ( Ignorable by Annotation )

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

195
        if (in_array(false, /** @scrutinizer ignore-type */ $errors[$path])) {
Loading history...
196
            $this->permErrors[$path] = $errors[$path];
197
            return false;
198
        }
199
        return true;
200
    }
201
202
203
    /**
204
     * Write-enable the specified file/folder
205
     * @param string $path
206
     * @param string $group
207
     * @param bool $recurse
208
     * @return false on failure, method (u-ser,g-roup,w-orld) on success
209
     */
210
    public function makeWritable($path, $group = false, $create = true)
211
    {
212
        if (!file_exists($path)) {
213
            if (!$create) {
214
                return false;
215
            } else {
216
                $perm = 6;
217
                @mkdir($path, octdec('0' . $perm . '00'));
0 ignored issues
show
Bug introduced by
It seems like octdec('0' . $perm . '00') can also be of type double; however, parameter $mode of mkdir() does only seem to accept integer, 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

217
                @mkdir($path, /** @scrutinizer ignore-type */ octdec('0' . $perm . '00'));
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for mkdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

217
                /** @scrutinizer ignore-unhandled */ @mkdir($path, octdec('0' . $perm . '00'));

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
218
            }
219
        } else {
220
            $perm = is_dir($path) ? 6 : 7;
221
        }
222
        if (!is_writable($path)) {
223
            // First try using owner bit
224
            @chmod($path, octdec('0' . $perm . '00'));
0 ignored issues
show
Bug introduced by
It seems like octdec('0' . $perm . '00') can also be of type double; however, parameter $mode of chmod() does only seem to accept integer, 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

224
            @chmod($path, /** @scrutinizer ignore-type */ octdec('0' . $perm . '00'));
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

224
            /** @scrutinizer ignore-unhandled */ @chmod($path, octdec('0' . $perm . '00'));

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
225
            clearstatcache();
226
            if (!is_writable($path) && $group !== false) {
227
                // If group has been specified, try using the group bit
228
                @chgrp($path, $group);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chgrp(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

228
                /** @scrutinizer ignore-unhandled */ @chgrp($path, $group);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
229
                @chmod($path, octdec('0' . $perm . $perm . '0'));
230
            }
231
            clearstatcache();
232
            if (!is_writable($path)) {
233
                @chmod($path, octdec('0' . $perm . $perm . $perm));
234
            }
235
        }
236
        clearstatcache();
237
        if (is_writable($path)) {
238
            $info = stat($path);
239
            //echo $path . ' : ' . sprintf( '%o', $info['mode'] ) . '....';
240
            if ($info['mode'] & 0002) {
241
                return 'w';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'w' returns the type string which is incompatible with the documented return type false.
Loading history...
242
            } elseif ($info['mode'] & 0020) {
243
                return 'g';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'g' returns the type string which is incompatible with the documented return type false.
Loading history...
244
            }
245
            return 'u';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'u' returns the type string which is incompatible with the documented return type false.
Loading history...
246
        }
247
        return false;
248
    }
249
}
250