Passed
Push — master ( 5e6998...536951 )
by Andreas
34:10 queued 12:21
created

midcom_connection::set_loglevel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package midcom
4
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
use midgard\portable\storage\connection;
10
use midgard\portable\api\error\exception as mgd_exception;
11
use midgard\portable\api\mgdobject;
12
13
/**
14
 * Wrapper for Midgard-related functionality
15
 *
16
 * @package midcom
17
 */
18
class midcom_connection
19
{
20
    /**
21
     * @var array
22
     */
23
    private static $_data = [];
24
25
    /**
26
     * DB connection setup routine
27
     *
28
     * @throws Exception We use regular exceptions here, because this might run before things are properly set up
29
     */
30
    public static function setup(string $basedir) : bool
31
    {
32
        if (file_exists($basedir . 'config/midgard-portable.inc.php')) {
33
            include $basedir . 'config/midgard-portable.inc.php';
34
            return midgard_connection::get_instance()->is_connected();
35
        }
36
        if (file_exists($basedir . 'config/midgard-portable-default.inc.php')) {
37
            include $basedir . 'config/midgard-portable-default.inc.php';
38
            //default config has in-memory db, so all the tables may be missing
39
            return midgard_storage::class_storage_exists('midgard_user');
40
        }
41
        throw new Exception("Could not connect to database, configuration file not found");
42
    }
43
44
    /**
45
     * Set Midgard log level
46
     *
47
     * @param string $loglevel Midgard log level
48
     */
49
    static function set_loglevel($loglevel) : bool
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
50
    {
51
        return midgard_connection::get_instance()->set_loglevel($loglevel);
52
    }
53
54
    /**
55
     * Set Midgard error code
56
     */
57 18
    public static function set_error(int $errorcode)
58
    {
59 18
        midgard_connection::get_instance()->set_error($errorcode);
60
    }
61
62
    /**
63
     * Get Midgard error code
64
     */
65 38
    public static function get_error() : int
66
    {
67 38
        return midgard_connection::get_instance()->get_error();
68
    }
69
70
    /**
71
     * Get Midgard error message
72
     */
73 53
    public static function get_error_string() : string
74
    {
75 53
        return midgard_connection::get_instance()->get_error_string();
76
    }
77
78
    /**
79
     * Perform a login against the midgard backend
80
     */
81 64
    public static function login(string $username, string $password, bool $trusted = false) : ?midgard_user
82
    {
83
        $login_tokens = [
84
            'login' => $username,
85 64
            'authtype' => midcom::get()->config->get('auth_type'),
86
        ];
87
88
        try {
89 64
            $user = new midgard_user($login_tokens);
90
        } catch (mgd_exception $e) {
91
            return null;
92
        }
93 64
        if (!$trusted && !self::verify_password($password, $user->password)) {
94
            return null;
95
        }
96
97 64
        $user->login();
98 64
        return $user;
99
    }
100
101 71
    public static function verify_password(string $password, string $hash) : bool
102
    {
103 71
        if (midcom::get()->config->get('auth_type') == 'Legacy') {
104 71
            return password_verify($password, $hash);
105
        }
106
        if (midcom::get()->config->get('auth_type') == 'SHA256') {
107
            $password = hash('sha256', $password);
108
        }
109
110
        return $password === $hash;
111
    }
112
113 89
    public static function prepare_password(string $password)
114
    {
115 89
        if (midcom::get()->config->get('auth_type') == 'Legacy') {
116 89
            return password_hash($password, PASSWORD_DEFAULT);
117
        }
118
        if (midcom::get()->config->get('auth_type') == 'SHA256') {
119
            return hash('sha256', $password);
120
        }
121
122
        return $password;
123
    }
124
125
    /**
126
     * Get current Midgard user ID
127
     */
128 58
    public static function get_user() : int
129
    {
130 58
        if ($user = midgard_connection::get_instance()->get_user()) {
131 33
            return $user->get_person()->id;
132
        }
133 25
        return 0;
134
    }
135
136
    /**
137
     * Logout the current user, if any
138
     */
139 1
    public static function logout()
140
    {
141 1
        if ($user = midgard_connection::get_instance()->get_user()) {
142 1
            $user->logout();
143
        }
144
    }
145
146 360
    private static function _get(string $key)
147
    {
148 360
        if (isset(self::$_data[$key])) {
149 360
            return self::$_data[$key];
150
        }
151
152
        return null;
153
    }
154
155
    /**
156
     * Lists all available MgdSchema types
157
     */
158 6
    public static function get_schema_types() : array
159
    {
160 6
        if (!isset(self::$_data['schema_types'])) {
161
            $classnames = connection::get_em()->getConfiguration()->getMetadataDriverImpl()->getAllClassNames();
162
163
            self::$_data['schema_types'] = array_filter($classnames, function($input) {
164
                return is_subclass_of($input, mgdobject::class);
165
            });
166
        }
167 6
        return self::$_data['schema_types'];
168
    }
169
170
    /**
171
     * Get various pieces of information extracted from the URL
172
     *
173
     * @return mixed The data for the requested key or null if it doesn't exist
174
     */
175 360
    public static function get_url(string $key)
176
    {
177
        static $parsed = false;
178 360
        if (!$parsed) {
179
            $self = defined('OPENPSA2_PREFIX') ? OPENPSA2_PREFIX : '/';
180
181
            // we're only interested in the path, so use a dummy domain for simplicity's sake
182
            $url_path = (string) parse_url("https://openpsa2.org{$_SERVER['REQUEST_URI']}", PHP_URL_PATH);
183
            if ($self !== '/') {
184
                $url_path = preg_replace('|^' . $self . '|', '/', $url_path);
185
            }
186
            self::_parse_url($url_path, $self, substr($self, 0, -1));
187
            $parsed = true;
188
        }
189
190 360
        return self::_get($key);
191
    }
192
193
    /**
194
     * Enables themes to have subdirectories (which have a similar effect to mgd1 pages)
195
     *
196
     * @param string $uri The request path
197
     * @param string $self The instance's root URL
198
     * @param string $prefix The root URL's prefix, if any (corresponds to mgd1 host)
199
     */
200 1
    private static function _parse_url(string $uri, string $self, string $prefix)
201
    {
202 1
        $uri = preg_replace('/\/[\/]+/i', '/', $uri);
203 1
        $path_parts = explode('/', $uri);
204 1
        $page_style = '';
205 1
        $path = $self;
206
207 1
        $args_started = false;
208 1
        foreach ($path_parts as $part) {
209 1
            if ($part === '') {
210 1
                continue;
211
            }
212 1
            if (    midcom::get()->config->get('theme')
213
                 && !$args_started
214 1
                 && self::check_page_exists($part)) {
215
                $page_style .= '/' . $part;
216
                $self .= $part . '/';
217
            } else {
218 1
                $path .= $part . '/';
219 1
                $args_started = true;
220
            }
221
        }
222
223 1
        self::$_data['page_style'] = $page_style;
224 1
        self::$_data['uri'] = $path;
225 1
        self::$_data['self'] = $self;
226 1
        self::$_data['prefix'] = $prefix;
227
    }
228
229
230
    /**
231
     * Iterate through possible page directories in style-tree
232
     * and check if the page exists (as a folder).
233
     */
234 1
    private static function check_page_exists(string $page_name) : bool
235
    {
236 1
        $prefix = midcom::get()->getProjectDir() . '/var/themes/';
237 1
        $path_array = explode('/', midcom::get()->config->get('theme'));
0 ignored issues
show
Bug introduced by
It seems like midcom::get()->config->get('theme') can also be of type null; however, parameter $string of explode() does only seem to accept string, 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

237
        $path_array = explode('/', /** @scrutinizer ignore-type */ midcom::get()->config->get('theme'));
Loading history...
238 1
        while (!empty($path_array)) {
239 1
            $theme_path = implode('/', $path_array);
240 1
            if (is_dir($prefix . $theme_path . '/style/' . $page_name)) {
241
                return true;
242
            }
243 1
            array_pop($path_array);
244
        }
245 1
        return false;
246
    }
247
}
248