Passed
Push — master ( a45b4d...2b4fc9 )
by Andreas
17:54
created

midcom_connection::get_unique_host_name()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
ccs 4
cts 4
cp 1
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 18
    }
61
62
    /**
63
     * Get Midgard error code
64
     */
65 35
    public static function get_error() : int
66
    {
67 35
        return midgard_connection::get_instance()->get_error();
68
    }
69
70
    /**
71
     * Get Midgard error message
72
     */
73 50
    public static function get_error_string() : string
74
    {
75 50
        return midgard_connection::get_instance()->get_error_string();
76
    }
77
78
    /**
79
     * Perform a login against the midgard backend
80
     */
81 62
    public static function login(string $username, string $password, bool $trusted = false) : ?midgard_user
82
    {
83
        $login_tokens = [
84 62
            'login' => $username,
85 62
            'authtype' => midcom::get()->config->get('auth_type'),
86
        ];
87
88
        try {
89 62
            $user = new midgard_user($login_tokens);
90
        } catch (mgd_exception $e) {
91
            return null;
92
        }
93 62
        if (!$trusted && !self::verify_password($password, $user->password)) {
94 1
            return null;
95
        }
96
97 62
        if (!$user->login()) {
98
            return null;
99
        }
100 62
        return $user;
101
    }
102
103 67
    public static function verify_password(string $password, string $hash) : bool
104
    {
105 67
        if (midcom::get()->config->get('auth_type') == 'Legacy') {
106 67
            return password_verify($password, $hash);
107
        }
108
        if (midcom::get()->config->get('auth_type') == 'SHA256') {
109
            $password = hash('sha256', $password);
110
        }
111
112
        return $password === $hash;
113
    }
114
115 85
    public static function prepare_password(string $password)
116
    {
117 85
        if (midcom::get()->config->get('auth_type') == 'Legacy') {
118 85
            return password_hash($password, PASSWORD_DEFAULT);
119
        }
120
        if (midcom::get()->config->get('auth_type') == 'SHA256') {
121
            return hash('sha256', $password);
122
        }
123
124
        return $password;
125
    }
126
127 1
    public static function is_user($person) : bool
128
    {
129 1
        if (empty($person->guid)) {
130
            return false;
131
        }
132 1
        $qb = new midgard_query_builder('midgard_user');
133 1
        $qb->add_constraint('person', '=', $person->guid);
134 1
        return $qb->count() > 0;
135
    }
136
137
    /**
138
     * Get current Midgard user ID
139
     */
140 52
    public static function get_user() : int
141
    {
142 52
        if ($user = midgard_connection::get_instance()->get_user()) {
143 30
            return $user->get_person()->id;
144
        }
145 22
        return 0;
146
    }
147
148
    /**
149
     * Check if the current user is admin
150
     */
151 7
    public static function is_admin() : bool
152
    {
153 7
        if ($user = midgard_connection::get_instance()->get_user()) {
154 7
            return $user->is_admin();
155
        }
156
        return false;
157
    }
158
159
    /**
160
     * Logout the current user, if any
161
     */
162 1
    public static function logout()
163
    {
164 1
        if ($user = midgard_connection::get_instance()->get_user()) {
165 1
            $user->logout();
166
        }
167 1
    }
168
169 355
    private static function _get(string $key)
170
    {
171 355
        if (isset(self::$_data[$key])) {
172 355
            return self::$_data[$key];
173
        }
174
175
        return null;
176
    }
177
178
    /**
179
     * Lists all available MgdSchema types
180
     */
181 6
    public static function get_schema_types() : array
182
    {
183 6
        if (!isset(self::$_data['schema_types'])) {
184
            $classnames = connection::get_em()->getConfiguration()->getMetadataDriverImpl()->getAllClassNames();
185
186
            self::$_data['schema_types'] = array_filter($classnames, function($input) {
187
                return is_subclass_of($input, mgdobject::class);
188
            });
189
        }
190 6
        return self::$_data['schema_types'];
191
    }
192
193
    /**
194
     * Get various pieces of information extracted from the URL
195
     *
196
     * @return mixed The data for the requested key or null if it doesn't exist
197
     */
198 355
    public static function get_url(string $key)
199
    {
200 355
        static $parsed = false;
201 355
        if (!$parsed) {
202
            $self = defined('OPENPSA2_PREFIX') ? OPENPSA2_PREFIX : '/';
203
204
            // we're only interested in the path, so use a dummy domain for simplicity's sake
205
            $url_components = parse_url("https://openpsa2.org{$_SERVER['REQUEST_URI']}");
206
            if ($self !== '/') {
207
                $url_components['path'] = preg_replace('|^' . $self . '|', '/', $url_components['path']);
208
            }
209
            self::_parse_url($url_components['path'], $self, substr($self, 0, -1));
210
            $parsed = true;
211
        }
212
213 355
        return self::_get($key);
214
    }
215
216
    /**
217
     * Enables themes to have subdirectories (which have a similar effect to mgd1 pages)
218
     *
219
     * @param string $uri The request path
220
     * @param string $self The instance's root URL
221
     * @param string $prefix The root URL's prefix, if any (corresponds to mgd1 host)
222
     */
223 1
    private static function _parse_url(string $uri, string $self, string $prefix)
224
    {
225 1
        $uri = preg_replace('/\/[\/]+/i', '/', $uri);
226 1
        $path_parts = explode('/', $uri);
227 1
        $page_style = '';
228 1
        $path = $self;
229
230 1
        self::$_data['argv'] = [];
231 1
        $args_started = false;
232 1
        foreach ($path_parts as $part) {
233 1
            if ($part === '') {
234 1
                continue;
235
            }
236 1
            if (    midcom::get()->config->get('theme')
237 1
                 && !$args_started
238 1
                 && self::check_page_exists($part)) {
239
                $page_style .= '/' . $part;
240
                $self .= $part . '/';
241
            } else {
242 1
                self::$_data['argv'][] = $part;
243 1
                $path .= $part . '/';
244 1
                $args_started = true;
245
            }
246
        }
247
248 1
        self::$_data['page_style'] = $page_style;
249 1
        self::$_data['uri'] = $path;
250 1
        self::$_data['self'] = $self;
251 1
        self::$_data['prefix'] = $prefix;
252 1
    }
253
254
255
    /**
256
     * Iterate through possible page directories in style-tree
257
     * and check if the page exists (as a folder).
258
     */
259 1
    private static function check_page_exists(string $page_name) : bool
260
    {
261 1
        $prefix = midcom::get()->getProjectDir() . '/var/themes/';
262 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

262
        $path_array = explode('/', /** @scrutinizer ignore-type */ midcom::get()->config->get('theme'));
Loading history...
263 1
        while (!empty($path_array)) {
264 1
            $theme_path = implode('/', $path_array);
265 1
            if (is_dir($prefix . $theme_path . '/style/' . $page_name)) {
266
                return true;
267
            }
268 1
            array_pop($path_array);
269
        }
270 1
        return false;
271
    }
272
}
273