Rev 698 | Rev 702 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 698 | Rev 699 | ||
---|---|---|---|
1 | <?php |
1 | <?php |
2 | 2 | ||
3 | /* |
3 | /* |
4 | * OIDplus 2.0 |
4 | * OIDplus 2.0 |
5 | * Copyright 2019 - 2021 Daniel Marschall, ViaThinkSoft |
5 | * Copyright 2019 - 2021 Daniel Marschall, ViaThinkSoft |
6 | * |
6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
8 | * you may not use this file except in compliance with the License. |
8 | * you may not use this file except in compliance with the License. |
9 | * You may obtain a copy of the License at |
9 | * You may obtain a copy of the License at |
10 | * |
10 | * |
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
12 | * |
12 | * |
13 | * Unless required by applicable law or agreed to in writing, software |
13 | * Unless required by applicable law or agreed to in writing, software |
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | * See the License for the specific language governing permissions and |
16 | * See the License for the specific language governing permissions and |
17 | * limitations under the License. |
17 | * limitations under the License. |
18 | */ |
18 | */ |
19 | 19 | ||
20 | if (!defined('INSIDE_OIDPLUS')) die(); |
20 | if (!defined('INSIDE_OIDPLUS')) die(); |
21 | 21 | ||
22 | class OIDplus { |
22 | class OIDplus { |
23 | private static /*OIDplusPagePlugin[]*/ $pagePlugins = array(); |
23 | private static /*OIDplusPagePlugin[]*/ $pagePlugins = array(); |
24 | private static /*OIDplusAuthPlugin[]*/ $authPlugins = array(); |
24 | private static /*OIDplusAuthPlugin[]*/ $authPlugins = array(); |
25 | private static /*OIDplusLoggerPlugin[]*/ $loggerPlugins = array(); |
25 | private static /*OIDplusLoggerPlugin[]*/ $loggerPlugins = array(); |
26 | private static /*OIDplusObjectTypePlugin[]*/ $objectTypePlugins = array(); |
26 | private static /*OIDplusObjectTypePlugin[]*/ $objectTypePlugins = array(); |
27 | private static /*string[]*/ $enabledObjectTypes = array(); |
27 | private static /*string[]*/ $enabledObjectTypes = array(); |
28 | private static /*string[]*/ $disabledObjectTypes = array(); |
28 | private static /*string[]*/ $disabledObjectTypes = array(); |
29 | private static /*OIDplusDatabasePlugin[]*/ $dbPlugins = array(); |
29 | private static /*OIDplusDatabasePlugin[]*/ $dbPlugins = array(); |
30 | private static /*OIDplusSqlSlangPlugin[]*/ $sqlSlangPlugins = array(); |
30 | private static /*OIDplusSqlSlangPlugin[]*/ $sqlSlangPlugins = array(); |
31 | private static /*OIDplusLanguagePlugin[]*/ $languagePlugins = array(); |
31 | private static /*OIDplusLanguagePlugin[]*/ $languagePlugins = array(); |
32 | private static /*OIDplusDesignPlugin[]*/ $designPlugins = array(); |
32 | private static /*OIDplusDesignPlugin[]*/ $designPlugins = array(); |
33 | 33 | ||
34 | protected static $html = true; |
34 | protected static $html = true; |
35 | 35 | ||
36 | /*public*/ const DEFAULT_LANGUAGE = 'enus'; // the language of the source code |
36 | /*public*/ const DEFAULT_LANGUAGE = 'enus'; // the language of the source code |
37 | 37 | ||
38 | private function __construct() { |
38 | private function __construct() { |
39 | } |
39 | } |
40 | 40 | ||
41 | # --- Static classes |
41 | # --- Static classes |
42 | 42 | ||
43 | private static $baseConfig = null; |
43 | private static $baseConfig = null; |
44 | private static $old_config_format = false; |
44 | private static $old_config_format = false; |
45 | public static function baseConfig() { |
45 | public static function baseConfig() { |
46 | $first_init = false; |
46 | $first_init = false; |
47 | 47 | ||
48 | if ($first_init = is_null(self::$baseConfig)) { |
48 | if ($first_init = is_null(self::$baseConfig)) { |
49 | self::$baseConfig = new OIDplusBaseConfig(); |
49 | self::$baseConfig = new OIDplusBaseConfig(); |
50 | } |
50 | } |
51 | 51 | ||
52 | if ($first_init) { |
52 | if ($first_init) { |
53 | // Include a file containing various size/depth limitations of OIDs |
53 | // Include a file containing various size/depth limitations of OIDs |
54 | // It is important to include it before userdata/baseconfig/config.inc.php was included, |
54 | // It is important to include it before userdata/baseconfig/config.inc.php was included, |
55 | // so we can give userdata/baseconfig/config.inc.php the chance to override the values. |
55 | // so we can give userdata/baseconfig/config.inc.php the chance to override the values. |
56 | 56 | ||
57 | include OIDplus::localpath().'includes/oidplus_limits.inc.php'; |
57 | include OIDplus::localpath().'includes/oidplus_limits.inc.php'; |
58 | 58 | ||
59 | // Include config file |
59 | // Include config file |
60 | 60 | ||
61 | $config_file = OIDplus::localpath() . 'userdata/baseconfig/config.inc.php'; |
61 | $config_file = OIDplus::localpath() . 'userdata/baseconfig/config.inc.php'; |
62 | $config_file_old = OIDplus::localpath() . 'includes/config.inc.php'; // backwards compatibility |
62 | $config_file_old = OIDplus::localpath() . 'includes/config.inc.php'; // backwards compatibility |
63 | 63 | ||
64 | if (!file_exists($config_file) && file_exists($config_file_old)) { |
64 | if (!file_exists($config_file) && file_exists($config_file_old)) { |
65 | $config_file = $config_file_old; |
65 | $config_file = $config_file_old; |
66 | } |
66 | } |
67 | 67 | ||
68 | if (file_exists($config_file)) { |
68 | if (file_exists($config_file)) { |
69 | if (self::$old_config_format) { |
69 | if (self::$old_config_format) { |
70 | // Note: We may only include it once due to backwards compatibility, |
70 | // Note: We may only include it once due to backwards compatibility, |
71 | // since in version 2.0, the configuration was defined using define() statements |
71 | // since in version 2.0, the configuration was defined using define() statements |
72 | // Attention: This does mean that a full re-init (e.g. for test cases) is not possible |
72 | // Attention: This does mean that a full re-init (e.g. for test cases) is not possible |
73 | // if a version 2.0 config is used! |
73 | // if a version 2.0 config is used! |
74 | include_once $config_file; |
74 | include_once $config_file; |
75 | } else { |
75 | } else { |
76 | include $config_file; |
76 | include $config_file; |
77 | } |
77 | } |
78 | 78 | ||
79 | if (defined('OIDPLUS_CONFIG_VERSION') && (OIDPLUS_CONFIG_VERSION == 2.0)) { |
79 | if (defined('OIDPLUS_CONFIG_VERSION') && (OIDPLUS_CONFIG_VERSION == 2.0)) { |
80 | self::$old_config_format = true; |
80 | self::$old_config_format = true; |
81 | 81 | ||
82 | // Backwards compatibility 2.0 => 2.1 |
82 | // Backwards compatibility 2.0 => 2.1 |
83 | foreach (get_defined_constants(true)['user'] as $name => $value) { |
83 | foreach (get_defined_constants(true)['user'] as $name => $value) { |
84 | $name = str_replace('OIDPLUS_', '', $name); |
84 | $name = str_replace('OIDPLUS_', '', $name); |
85 | if ($name == 'SESSION_SECRET') $name = 'SERVER_SECRET'; |
85 | if ($name == 'SESSION_SECRET') $name = 'SERVER_SECRET'; |
86 | if ($name == 'MYSQL_QUERYLOG') $name = 'QUERY_LOGFILE'; |
86 | if ($name == 'MYSQL_QUERYLOG') $name = 'QUERY_LOGFILE'; |
87 | if (($name == 'MYSQL_PASSWORD') || ($name == 'ODBC_PASSWORD') || ($name == 'PDO_PASSWORD') || ($name == 'PGSQL_PASSWORD')) { |
87 | if (($name == 'MYSQL_PASSWORD') || ($name == 'ODBC_PASSWORD') || ($name == 'PDO_PASSWORD') || ($name == 'PGSQL_PASSWORD')) { |
88 | self::$baseConfig->setValue($name, base64_decode($value)); |
88 | self::$baseConfig->setValue($name, base64_decode($value)); |
89 | } else { |
89 | } else { |
90 | if ($name == 'CONFIG_VERSION') $value = 2.1; |
90 | if ($name == 'CONFIG_VERSION') $value = 2.1; |
91 | self::$baseConfig->setValue($name, $value); |
91 | self::$baseConfig->setValue($name, $value); |
92 | } |
92 | } |
93 | } |
93 | } |
94 | } |
94 | } |
95 | } else { |
95 | } else { |
96 | if (!is_dir(OIDplus::localpath().'setup')) { |
96 | if (!is_dir(OIDplus::localpath().'setup')) { |
97 | throw new OIDplusConfigInitializationException(_L('File %1 is missing, but setup can\'t be started because its directory missing.','userdata/baseconfig/config.inc.php')); |
97 | throw new OIDplusConfigInitializationException(_L('File %1 is missing, but setup can\'t be started because its directory missing.','userdata/baseconfig/config.inc.php')); |
98 | } else { |
98 | } else { |
99 | if (self::$html) { |
99 | if (self::$html) { |
100 | if (strpos($_SERVER['REQUEST_URI'], OIDplus::webpath(null,true).'setup/') !== 0) { |
100 | if (strpos($_SERVER['REQUEST_URI'], OIDplus::webpath(null,true).'setup/') !== 0) { |
101 | header('Location:'.OIDplus::webpath().'setup/'); |
101 | header('Location:'.OIDplus::webpath().'setup/'); |
102 | die(_L('Redirecting to setup...')); |
102 | die(_L('Redirecting to setup...')); |
103 | } else { |
103 | } else { |
104 | return self::$baseConfig; |
104 | return self::$baseConfig; |
105 | } |
105 | } |
106 | } else { |
106 | } else { |
107 | // This can be displayed in e.g. ajax.php |
107 | // This can be displayed in e.g. ajax.php |
108 | throw new OIDplusConfigInitializationException(_L('File %1 is missing. Please run setup again.','userdata/baseconfig/config.inc.php')); |
108 | throw new OIDplusConfigInitializationException(_L('File %1 is missing. Please run setup again.','userdata/baseconfig/config.inc.php')); |
109 | } |
109 | } |
110 | } |
110 | } |
111 | } |
111 | } |
112 | 112 | ||
113 | // Check important config settings |
113 | // Check important config settings |
114 | 114 | ||
115 | if (self::$baseConfig->getValue('CONFIG_VERSION') != 2.1) { |
115 | if (self::$baseConfig->getValue('CONFIG_VERSION') != 2.1) { |
116 | if (strpos($_SERVER['REQUEST_URI'], OIDplus::webpath(null,true).'setup/') !== 0) { |
116 | if (strpos($_SERVER['REQUEST_URI'], OIDplus::webpath(null,true).'setup/') !== 0) { |
117 | throw new OIDplusConfigInitializationException(_L("The information located in %1 is outdated.",realpath($config_file))); |
117 | throw new OIDplusConfigInitializationException(_L("The information located in %1 is outdated.",realpath($config_file))); |
118 | } |
118 | } |
119 | } |
119 | } |
120 | 120 | ||
121 | if (self::$baseConfig->getValue('SERVER_SECRET', '') === '') { |
121 | if (self::$baseConfig->getValue('SERVER_SECRET', '') === '') { |
122 | if (strpos($_SERVER['REQUEST_URI'], OIDplus::webpath(null,true).'setup/') !== 0) { |
122 | if (strpos($_SERVER['REQUEST_URI'], OIDplus::webpath(null,true).'setup/') !== 0) { |
123 | throw new OIDplusConfigInitializationException(_L("You must set a value for SERVER_SECRET in %1 for the system to operate secure.",realpath($config_file))); |
123 | throw new OIDplusConfigInitializationException(_L("You must set a value for SERVER_SECRET in %1 for the system to operate secure.",realpath($config_file))); |
124 | } |
124 | } |
125 | } |
125 | } |
126 | } |
126 | } |
127 | 127 | ||
128 | return self::$baseConfig; |
128 | return self::$baseConfig; |
129 | } |
129 | } |
130 | 130 | ||
131 | private static $config = null; |
131 | private static $config = null; |
132 | public static function config() { |
132 | public static function config() { |
133 | if ($first_init = is_null(self::$config)) { |
133 | if ($first_init = is_null(self::$config)) { |
134 | self::$config = new OIDplusConfig(); |
134 | self::$config = new OIDplusConfig(); |
135 | } |
135 | } |
136 | 136 | ||
137 | if ($first_init) { |
137 | if ($first_init) { |
138 | // These are important settings for base functionalities and therefore are not inside plugins |
138 | // These are important settings for base functionalities and therefore are not inside plugins |
139 | self::$config->prepareConfigKey('system_title', 'What is the name of your RA?', 'OIDplus 2.0', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
139 | self::$config->prepareConfigKey('system_title', 'What is the name of your RA?', 'OIDplus 2.0', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
140 | if (empty($value)) { |
140 | if (empty($value)) { |
141 | throw new OIDplusException(_L('Please enter a value for the system title.')); |
141 | throw new OIDplusException(_L('Please enter a value for the system title.')); |
142 | } |
142 | } |
143 | }); |
143 | }); |
144 | self::$config->prepareConfigKey('admin_email', 'E-Mail address of the system administrator', '', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
144 | self::$config->prepareConfigKey('admin_email', 'E-Mail address of the system administrator', '', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
145 | if (!empty($value) && !OIDplus::mailUtils()->validMailAddress($value)) { |
145 | if (!empty($value) && !OIDplus::mailUtils()->validMailAddress($value)) { |
146 | throw new OIDplusException(_L('This is not a correct email address')); |
146 | throw new OIDplusException(_L('This is not a correct email address')); |
147 | } |
147 | } |
148 | }); |
148 | }); |
149 | self::$config->prepareConfigKey('global_cc', 'Global CC for all outgoing emails?', '', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
149 | self::$config->prepareConfigKey('global_cc', 'Global CC for all outgoing emails?', '', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
150 | if (!empty($value) && !OIDplus::mailUtils()->validMailAddress($value)) { |
150 | if (!empty($value) && !OIDplus::mailUtils()->validMailAddress($value)) { |
151 | throw new OIDplusException(_L('This is not a correct email address')); |
151 | throw new OIDplusException(_L('This is not a correct email address')); |
152 | } |
152 | } |
153 | }); |
153 | }); |
154 | self::$config->prepareConfigKey('objecttypes_initialized', 'List of object type plugins that were initialized once', '', OIDplusConfig::PROTECTION_READONLY, function($value) { |
154 | self::$config->prepareConfigKey('objecttypes_initialized', 'List of object type plugins that were initialized once', '', OIDplusConfig::PROTECTION_READONLY, function($value) { |
155 | // Nothing here yet |
155 | // Nothing here yet |
156 | }); |
156 | }); |
157 | self::$config->prepareConfigKey('objecttypes_enabled', 'Enabled object types and their order, separated with a semicolon (please reload the page so that the change is applied)', '', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
157 | self::$config->prepareConfigKey('objecttypes_enabled', 'Enabled object types and their order, separated with a semicolon (please reload the page so that the change is applied)', '', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
158 | # TODO: when objecttypes_enabled is changed at the admin control panel, we need to do a reload of the page, so that jsTree will be updated. Is there anything we can do? |
158 | # TODO: when objecttypes_enabled is changed at the admin control panel, we need to do a reload of the page, so that jsTree will be updated. Is there anything we can do? |
159 | 159 | ||
160 | $ary = explode(';',$value); |
160 | $ary = explode(';',$value); |
161 | $uniq_ary = array_unique($ary); |
161 | $uniq_ary = array_unique($ary); |
162 | 162 | ||
163 | if (count($ary) != count($uniq_ary)) { |
163 | if (count($ary) != count($uniq_ary)) { |
164 | throw new OIDplusException(_L('Please check your input. Some object types are double.')); |
164 | throw new OIDplusException(_L('Please check your input. Some object types are double.')); |
165 | } |
165 | } |
166 | 166 | ||
167 | foreach ($ary as $ot_check) { |
167 | foreach ($ary as $ot_check) { |
168 | $ns_found = false; |
168 | $ns_found = false; |
169 | foreach (OIDplus::getEnabledObjectTypes() as $ot) { |
169 | foreach (OIDplus::getEnabledObjectTypes() as $ot) { |
170 | if ($ot::ns() == $ot_check) { |
170 | if ($ot::ns() == $ot_check) { |
171 | $ns_found = true; |
171 | $ns_found = true; |
172 | break; |
172 | break; |
173 | } |
173 | } |
174 | } |
174 | } |
175 | foreach (OIDplus::getDisabledObjectTypes() as $ot) { |
175 | foreach (OIDplus::getDisabledObjectTypes() as $ot) { |
176 | if ($ot::ns() == $ot_check) { |
176 | if ($ot::ns() == $ot_check) { |
177 | $ns_found = true; |
177 | $ns_found = true; |
178 | break; |
178 | break; |
179 | } |
179 | } |
180 | } |
180 | } |
181 | if (!$ns_found) { |
181 | if (!$ns_found) { |
182 | throw new OIDplusException(_L('Please check your input. Namespace "%1" is not found',$ot_check)); |
182 | throw new OIDplusException(_L('Please check your input. Namespace "%1" is not found',$ot_check)); |
183 | } |
183 | } |
184 | } |
184 | } |
185 | }); |
185 | }); |
186 | self::$config->prepareConfigKey('oidplus_private_key', 'Private key for this system', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) { |
186 | self::$config->prepareConfigKey('oidplus_private_key', 'Private key for this system', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) { |
187 | // Nothing here yet |
187 | // Nothing here yet |
188 | }); |
188 | }); |
189 | self::$config->prepareConfigKey('oidplus_public_key', 'Public key for this system. If you "clone" your system, you must delete this key (e.g. using phpMyAdmin), so that a new one is created.', '', OIDplusConfig::PROTECTION_READONLY, function($value) { |
189 | self::$config->prepareConfigKey('oidplus_public_key', 'Public key for this system. If you "clone" your system, you must delete this key (e.g. using phpMyAdmin), so that a new one is created.', '', OIDplusConfig::PROTECTION_READONLY, function($value) { |
190 | // Nothing here yet |
190 | // Nothing here yet |
191 | }); |
191 | }); |
192 | self::$config->prepareConfigKey('last_known_system_url', 'Last known System URL', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) { |
192 | self::$config->prepareConfigKey('last_known_system_url', 'Last known System URL', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) { |
193 | // Nothing here yet |
193 | // Nothing here yet |
194 | }); |
194 | }); |
195 | self::$config->prepareConfigKey('last_known_version', 'Last known OIDplus Version', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) { |
195 | self::$config->prepareConfigKey('last_known_version', 'Last known OIDplus Version', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) { |
196 | // Nothing here yet |
196 | // Nothing here yet |
197 | }); |
197 | }); |
198 | self::$config->prepareConfigKey('default_ra_auth_method', 'Default auth method used for generating password of RAs (must exist in plugins/[vendorname]/auth/)?', 'A3_bcrypt', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
198 | self::$config->prepareConfigKey('default_ra_auth_method', 'Default auth method used for generating password of RAs (must exist in plugins/[vendorname]/auth/)?', 'A3_bcrypt', OIDplusConfig::PROTECTION_EDITABLE, function($value) { |
199 | $good = true; |
199 | $good = true; |
200 | if (strpos($value,'/') !== false) $good = false; |
200 | if (strpos($value,'/') !== false) $good = false; |
201 | if (strpos($value,'\\') !== false) $good = false; |
201 | if (strpos($value,'\\') !== false) $good = false; |
202 | if (strpos($value,'..') !== false) $good = false; |
202 | if (strpos($value,'..') !== false) $good = false; |
203 | if (!$good) { |
203 | if (!$good) { |
204 | throw new OIDplusException(_L('Invalid auth plugin folder name. Do only enter a folder name, not an absolute or relative path')); |
204 | throw new OIDplusException(_L('Invalid auth plugin folder name. Do only enter a folder name, not an absolute or relative path')); |
205 | } |
205 | } |
206 | 206 | ||
207 | if (!rec_is_dir(OIDplus::localpath().'plugins/'.'*'.'/auth/'.$value)) { |
207 | if (!rec_is_dir(OIDplus::localpath().'plugins/'.'*'.'/auth/'.$value)) { |
208 | throw new OIDplusException(_L('The auth plugin "%1" does not exist in plugin directory %2',$value,'plugins/[vendorname]/auth/')); |
208 | throw new OIDplusException(_L('The auth plugin "%1" does not exist in plugin directory %2',$value,'plugins/[vendorname]/auth/')); |
209 | } |
209 | } |
210 | }); |
210 | }); |
211 | } |
211 | } |
212 | 212 | ||
213 | return self::$config; |
213 | return self::$config; |
214 | } |
214 | } |
215 | 215 | ||
216 | private static $gui = null; |
216 | private static $gui = null; |
217 | public static function gui() { |
217 | public static function gui() { |
218 | if (is_null(self::$gui)) { |
218 | if (is_null(self::$gui)) { |
219 | self::$gui = new OIDplusGui(); |
219 | self::$gui = new OIDplusGui(); |
220 | } |
220 | } |
221 | return self::$gui; |
221 | return self::$gui; |
222 | } |
222 | } |
223 | 223 | ||
224 | private static $authUtils = null; |
224 | private static $authUtils = null; |
225 | public static function authUtils() { |
225 | public static function authUtils() { |
226 | if (is_null(self::$authUtils)) { |
226 | if (is_null(self::$authUtils)) { |
227 | self::$authUtils = new OIDplusAuthUtils(); |
227 | self::$authUtils = new OIDplusAuthUtils(); |
228 | } |
228 | } |
229 | return self::$authUtils; |
229 | return self::$authUtils; |
230 | } |
230 | } |
231 | 231 | ||
232 | private static $mailUtils = null; |
232 | private static $mailUtils = null; |
233 | public static function mailUtils() { |
233 | public static function mailUtils() { |
234 | if (is_null(self::$mailUtils)) { |
234 | if (is_null(self::$mailUtils)) { |
235 | self::$mailUtils = new OIDplusMailUtils(); |
235 | self::$mailUtils = new OIDplusMailUtils(); |
236 | } |
236 | } |
237 | return self::$mailUtils; |
237 | return self::$mailUtils; |
238 | } |
238 | } |
239 | 239 | ||
240 | private static $cookieUtils = null; |
240 | private static $cookieUtils = null; |
241 | public static function cookieUtils() { |
241 | public static function cookieUtils() { |
242 | if (is_null(self::$cookieUtils)) { |
242 | if (is_null(self::$cookieUtils)) { |
243 | self::$cookieUtils = new OIDplusCookieUtils(); |
243 | self::$cookieUtils = new OIDplusCookieUtils(); |
244 | } |
244 | } |
245 | return self::$cookieUtils; |
245 | return self::$cookieUtils; |
246 | } |
246 | } |
247 | 247 | ||
248 | private static $menuUtils = null; |
248 | private static $menuUtils = null; |
249 | public static function menuUtils() { |
249 | public static function menuUtils() { |
250 | if (is_null(self::$menuUtils)) { |
250 | if (is_null(self::$menuUtils)) { |
251 | self::$menuUtils = new OIDplusMenuUtils(); |
251 | self::$menuUtils = new OIDplusMenuUtils(); |
252 | } |
252 | } |
253 | return self::$menuUtils; |
253 | return self::$menuUtils; |
254 | } |
254 | } |
255 | 255 | ||
256 | private static $logger = null; |
256 | private static $logger = null; |
257 | public static function logger() { |
257 | public static function logger() { |
258 | if (is_null(self::$logger)) { |
258 | if (is_null(self::$logger)) { |
259 | self::$logger = new OIDplusLogger(); |
259 | self::$logger = new OIDplusLogger(); |
260 | } |
260 | } |
261 | return self::$logger; |
261 | return self::$logger; |
262 | } |
262 | } |
263 | 263 | ||
264 | # --- SQL slang plugin |
264 | # --- SQL slang plugin |
265 | 265 | ||
266 | private static function registerSqlSlangPlugin(OIDplusSqlSlangPlugin $plugin) { |
266 | private static function registerSqlSlangPlugin(OIDplusSqlSlangPlugin $plugin) { |
267 | $name = $plugin::id(); |
267 | $name = $plugin::id(); |
268 | if ($name === '') return false; |
268 | if ($name === '') return false; |
269 | 269 | ||
270 | if (isset(self::$sqlSlangPlugins[$name])) { |
270 | if (isset(self::$sqlSlangPlugins[$name])) { |
271 | $plugintype_hf = _L('SQL slang'); |
271 | $plugintype_hf = _L('SQL slang'); |
272 | throw new OIDplusException(_L('Multiple %1 plugins use the ID %2', $plugintype_hf, $name)); |
272 | throw new OIDplusException(_L('Multiple %1 plugins use the ID %2', $plugintype_hf, $name)); |
273 | } |
273 | } |
274 | 274 | ||
275 | self::$sqlSlangPlugins[$name] = $plugin; |
275 | self::$sqlSlangPlugins[$name] = $plugin; |
276 | 276 | ||
277 | return true; |
277 | return true; |
278 | } |
278 | } |
279 | 279 | ||
280 | public static function getSqlSlangPlugins() { |
280 | public static function getSqlSlangPlugins() { |
281 | return self::$sqlSlangPlugins; |
281 | return self::$sqlSlangPlugins; |
282 | } |
282 | } |
283 | 283 | ||
284 | public static function getSqlSlangPlugin($id)/*: ?OIDplusSqlSlangPlugin*/ { |
284 | public static function getSqlSlangPlugin($id)/*: ?OIDplusSqlSlangPlugin*/ { |
285 | if (isset(self::$sqlSlangPlugins[$id])) { |
285 | if (isset(self::$sqlSlangPlugins[$id])) { |
286 | return self::$sqlSlangPlugins[$id]; |
286 | return self::$sqlSlangPlugins[$id]; |
287 | } else { |
287 | } else { |
288 | return null; |
288 | return null; |
289 | } |
289 | } |
290 | } |
290 | } |
291 | 291 | ||
292 | # --- Database plugin |
292 | # --- Database plugin |
293 | 293 | ||
294 | private static function registerDatabasePlugin(OIDplusDatabasePlugin $plugin) { |
294 | private static function registerDatabasePlugin(OIDplusDatabasePlugin $plugin) { |
295 | $name = $plugin::id(); |
295 | $name = $plugin::id(); |
296 | if ($name === '') return false; |
296 | if ($name === '') return false; |
297 | 297 | ||
298 | if (isset(self::$dbPlugins[$name])) { |
298 | if (isset(self::$dbPlugins[$name])) { |
299 | $plugintype_hf = _L('Database'); |
299 | $plugintype_hf = _L('Database'); |
300 | throw new OIDplusException(_L('Multiple %1 plugins use the ID %2', $plugintype_hf, $name)); |
300 | throw new OIDplusException(_L('Multiple %1 plugins use the ID %2', $plugintype_hf, $name)); |
301 | } |
301 | } |
302 | 302 | ||
303 | self::$dbPlugins[$name] = $plugin; |
303 | self::$dbPlugins[$name] = $plugin; |
304 | 304 | ||
305 | return true; |
305 | return true; |
306 | } |
306 | } |
307 | 307 | ||
308 | public static function getDatabasePlugins() { |
308 | public static function getDatabasePlugins() { |
309 | return self::$dbPlugins; |
309 | return self::$dbPlugins; |
310 | } |
310 | } |
311 | 311 | ||
312 | public static function getActiveDatabasePlugin() { |
312 | public static function getActiveDatabasePlugin() { |
313 | if (OIDplus::baseConfig()->getValue('DATABASE_PLUGIN', '') === '') { |
313 | if (OIDplus::baseConfig()->getValue('DATABASE_PLUGIN', '') === '') { |
314 | throw new OIDplusConfigInitializationException(_L('No database plugin selected in config file')); |
314 | throw new OIDplusConfigInitializationException(_L('No database plugin selected in config file')); |
315 | } |
315 | } |
316 | if (!isset(self::$dbPlugins[OIDplus::baseConfig()->getValue('DATABASE_PLUGIN')])) { |
316 | if (!isset(self::$dbPlugins[OIDplus::baseConfig()->getValue('DATABASE_PLUGIN')])) { |
317 | $db_plugin_name = OIDplus::baseConfig()->getValue('DATABASE_PLUGIN'); |
317 | $db_plugin_name = OIDplus::baseConfig()->getValue('DATABASE_PLUGIN'); |
318 | throw new OIDplusConfigInitializationException(_L('Database plugin "%1" not found',$db_plugin_name)); |
318 | throw new OIDplusConfigInitializationException(_L('Database plugin "%1" not found',$db_plugin_name)); |
319 | } |
319 | } |
320 | return self::$dbPlugins[OIDplus::baseConfig()->getValue('DATABASE_PLUGIN')]; |
320 | return self::$dbPlugins[OIDplus::baseConfig()->getValue('DATABASE_PLUGIN')]; |
321 | } |
321 | } |
322 | 322 | ||
323 | private static $dbMainSession = null; |
323 | private static $dbMainSession = null; |
324 | public static function db() { |
324 | public static function db() { |
325 | if (is_null(self::$dbMainSession)) { |
325 | if (is_null(self::$dbMainSession)) { |
326 | self::$dbMainSession = self::getActiveDatabasePlugin()->newConnection(); |
326 | self::$dbMainSession = self::getActiveDatabasePlugin()->newConnection(); |
327 | } |
327 | } |
328 | if (!self::$dbMainSession->isConnected()) self::$dbMainSession->connect(); |
328 | if (!self::$dbMainSession->isConnected()) self::$dbMainSession->connect(); |
329 | return self::$dbMainSession; |
329 | return self::$dbMainSession; |
330 | } |
330 | } |
331 | 331 | ||
332 | private static $dbIsolatedSession = null; |
332 | private static $dbIsolatedSession = null; |
333 | public static function dbIsolated() { |
333 | public static function dbIsolated() { |
334 | if (is_null(self::$dbIsolatedSession)) { |
334 | if (is_null(self::$dbIsolatedSession)) { |
335 | self::$dbIsolatedSession = self::getActiveDatabasePlugin()->newConnection(); |
335 | self::$dbIsolatedSession = self::getActiveDatabasePlugin()->newConnection(); |
336 | } |
336 | } |
337 | if (!self::$dbIsolatedSession->isConnected()) self::$dbIsolatedSession->connect(); |
337 | if (!self::$dbIsolatedSession->isConnected()) self::$dbIsolatedSession->connect(); |
338 | return self::$dbIsolatedSession; |
338 | return self::$dbIsolatedSession; |
339 | } |
339 | } |
340 | 340 | ||
341 | # --- Page plugin |
341 | # --- Page plugin |
342 | 342 | ||
343 | private static function registerPagePlugin(OIDplusPagePlugin $plugin) { |
343 | private static function registerPagePlugin(OIDplusPagePlugin $plugin) { |
344 | self::$pagePlugins[] = $plugin; |
344 | self::$pagePlugins[] = $plugin; |
345 | 345 | ||
346 | return true; |
346 | return true; |
347 | } |
347 | } |
348 | 348 | ||
349 | public static function getPagePlugins() { |
349 | public static function getPagePlugins() { |
350 | return self::$pagePlugins; |
350 | return self::$pagePlugins; |
351 | } |
351 | } |
352 | 352 | ||
353 | # --- Auth plugin |
353 | # --- Auth plugin |
354 | 354 | ||
355 | private static function registerAuthPlugin(OIDplusAuthPlugin $plugin) { |
355 | private static function registerAuthPlugin(OIDplusAuthPlugin $plugin) { |
356 | if (OIDplus::baseConfig()->getValue('DEBUG')) { |
356 | if (OIDplus::baseConfig()->getValue('DEBUG')) { |
357 | $password = generateRandomString(25); |
357 | $password = generateRandomString(25); |
358 | 358 | ||
359 | try { |
359 | try { |
360 | $authInfo = $plugin->generate($password); |
360 | $authInfo = $plugin->generate($password); |
361 | } catch (OIDplusException $e) { |
361 | } catch (OIDplusException $e) { |
362 | // This can happen when the AuthKey or Salt is too long |
362 | // This can happen when the AuthKey or Salt is too long |
363 | throw new OIDplusException(_L('Auth plugin "%1" is erroneous: %2',basename($plugin->getPluginDirectory()),$e->getMessage())); |
363 | throw new OIDplusException(_L('Auth plugin "%1" is erroneous: %2',basename($plugin->getPluginDirectory()),$e->getMessage())); |
364 | } |
364 | } |
365 | $salt = $authInfo->getSalt(); |
365 | $salt = $authInfo->getSalt(); |
366 | $authKey = $authInfo->getAuthKey(); |
366 | $authKey = $authInfo->getAuthKey(); |
367 | 367 | ||
368 | $authInfo_SaltDiff = clone $authInfo; |
368 | $authInfo_SaltDiff = clone $authInfo; |
369 | $authInfo_SaltDiff->setSalt(strrev($authInfo_SaltDiff->getSalt())); |
369 | $authInfo_SaltDiff->setSalt(strrev($authInfo_SaltDiff->getSalt())); |
370 | 370 | ||
371 | $authInfo_AuthKeyDiff = clone $authInfo; |
371 | $authInfo_AuthKeyDiff = clone $authInfo; |
372 | $authInfo_AuthKeyDiff->setAuthKey(strrev($authInfo_AuthKeyDiff->getAuthKey())); |
372 | $authInfo_AuthKeyDiff->setAuthKey(strrev($authInfo_AuthKeyDiff->getAuthKey())); |
373 | 373 | ||
374 | if ((!$plugin->verify($authInfo,$password)) || |
374 | if ((!$plugin->verify($authInfo,$password)) || |
375 | (!empty($salt) && $plugin->verify($authInfo_SaltDiff,$password)) || |
375 | (!empty($salt) && $plugin->verify($authInfo_SaltDiff,$password)) || |
376 | ($plugin->verify($authInfo_AuthKeyDiff,$password)) || |
376 | ($plugin->verify($authInfo_AuthKeyDiff,$password)) || |
377 | ($plugin->verify($authInfo,$password.'x'))) { |
377 | ($plugin->verify($authInfo,$password.'x'))) { |
378 | throw new OIDplusException(_L('Auth plugin "%1" is erroneous: Generate/Verify self test failed',basename($plugin->getPluginDirectory()))); |
378 | throw new OIDplusException(_L('Auth plugin "%1" is erroneous: Generate/Verify self test failed',basename($plugin->getPluginDirectory()))); |
379 | } |
379 | } |
380 | } |
380 | } |
381 | 381 | ||
382 | self::$authPlugins[] = $plugin; |
382 | self::$authPlugins[] = $plugin; |
383 | return true; |
383 | return true; |
384 | } |
384 | } |
385 | 385 | ||
386 | public static function getAuthPlugins() { |
386 | public static function getAuthPlugins() { |
387 | return self::$authPlugins; |
387 | return self::$authPlugins; |
388 | } |
388 | } |
389 | 389 | ||
390 | # --- Language plugin |
390 | # --- Language plugin |
391 | 391 | ||
392 | private static function registerLanguagePlugin(OIDplusLanguagePlugin $plugin) { |
392 | private static function registerLanguagePlugin(OIDplusLanguagePlugin $plugin) { |
393 | self::$languagePlugins[] = $plugin; |
393 | self::$languagePlugins[] = $plugin; |
394 | return true; |
394 | return true; |
395 | } |
395 | } |
396 | 396 | ||
397 | public static function getLanguagePlugins() { |
397 | public static function getLanguagePlugins() { |
398 | return self::$languagePlugins; |
398 | return self::$languagePlugins; |
399 | } |
399 | } |
400 | 400 | ||
401 | # --- Design plugin |
401 | # --- Design plugin |
402 | 402 | ||
403 | private static function registerDesignPlugin(OIDplusDesignPlugin $plugin) { |
403 | private static function registerDesignPlugin(OIDplusDesignPlugin $plugin) { |
404 | self::$designPlugins[] = $plugin; |
404 | self::$designPlugins[] = $plugin; |
405 | return true; |
405 | return true; |
406 | } |
406 | } |
407 | 407 | ||
408 | public static function getDesignPlugins() { |
408 | public static function getDesignPlugins() { |
409 | return self::$designPlugins; |
409 | return self::$designPlugins; |
410 | } |
410 | } |
411 | 411 | ||
412 | # --- Logger plugin |
412 | # --- Logger plugin |
413 | 413 | ||
414 | private static function registerLoggerPlugin(OIDplusLoggerPlugin $plugin) { |
414 | private static function registerLoggerPlugin(OIDplusLoggerPlugin $plugin) { |
415 | self::$loggerPlugins[] = $plugin; |
415 | self::$loggerPlugins[] = $plugin; |
416 | return true; |
416 | return true; |
417 | } |
417 | } |
418 | 418 | ||
419 | public static function getLoggerPlugins() { |
419 | public static function getLoggerPlugins() { |
420 | return self::$loggerPlugins; |
420 | return self::$loggerPlugins; |
421 | } |
421 | } |
422 | 422 | ||
423 | # --- Object type plugin |
423 | # --- Object type plugin |
424 | 424 | ||
425 | private static function registerObjectTypePlugin(OIDplusObjectTypePlugin $plugin) { |
425 | private static function registerObjectTypePlugin(OIDplusObjectTypePlugin $plugin) { |
426 | self::$objectTypePlugins[] = $plugin; |
426 | self::$objectTypePlugins[] = $plugin; |
427 | 427 | ||
428 | $ot = $plugin::getObjectTypeClassName(); |
428 | $ot = $plugin::getObjectTypeClassName(); |
429 | self::registerObjectType($ot); |
429 | self::registerObjectType($ot); |
430 | 430 | ||
431 | return true; |
431 | return true; |
432 | } |
432 | } |
433 | 433 | ||
434 | private static function registerObjectType($ot) { |
434 | private static function registerObjectType($ot) { |
435 | $ns = $ot::ns(); |
435 | $ns = $ot::ns(); |
436 | 436 | ||
437 | if (empty($ns)) throw new OIDplusException(_L('Attention: Empty NS at %1',$ot)); |
437 | if (empty($ns)) throw new OIDplusException(_L('Attention: Empty NS at %1',$ot)); |
438 | 438 | ||
439 | $ns_found = false; |
439 | $ns_found = false; |
440 | foreach (array_merge(OIDplus::getEnabledObjectTypes(), OIDplus::getDisabledObjectTypes()) as $test_ot) { |
440 | foreach (array_merge(OIDplus::getEnabledObjectTypes(), OIDplus::getDisabledObjectTypes()) as $test_ot) { |
441 | if ($test_ot::ns() == $ns) { |
441 | if ($test_ot::ns() == $ns) { |
442 | $ns_found = true; |
442 | $ns_found = true; |
443 | break; |
443 | break; |
444 | } |
444 | } |
445 | } |
445 | } |
446 | if ($ns_found) { |
446 | if ($ns_found) { |
447 | throw new OIDplusException(_L('Attention: Two objectType plugins use the same namespace "%1"!',$ns)); |
447 | throw new OIDplusException(_L('Attention: Two objectType plugins use the same namespace "%1"!',$ns)); |
448 | } |
448 | } |
449 | 449 | ||
450 | $init = OIDplus::config()->getValue("objecttypes_initialized"); |
450 | $init = OIDplus::config()->getValue("objecttypes_initialized"); |
451 | $init_ary = empty($init) ? array() : explode(';', $init); |
451 | $init_ary = empty($init) ? array() : explode(';', $init); |
452 | $init_ary = array_map('trim', $init_ary); |
452 | $init_ary = array_map('trim', $init_ary); |
453 | 453 | ||
454 | $enabled = OIDplus::config()->getValue("objecttypes_enabled"); |
454 | $enabled = OIDplus::config()->getValue("objecttypes_enabled"); |
455 | $enabled_ary = empty($enabled) ? array() : explode(';', $enabled); |
455 | $enabled_ary = empty($enabled) ? array() : explode(';', $enabled); |
456 | $enabled_ary = array_map('trim', $enabled_ary); |
456 | $enabled_ary = array_map('trim', $enabled_ary); |
457 | 457 | ||
458 | $do_enable = false; |
458 | $do_enable = false; |
459 | if (in_array($ns, $enabled_ary)) { |
459 | if (in_array($ns, $enabled_ary)) { |
460 | // If it is in the list of enabled object types, it is enabled (obviously) |
460 | // If it is in the list of enabled object types, it is enabled (obviously) |
461 | $do_enable = true; |
461 | $do_enable = true; |
462 | } else { |
462 | } else { |
463 | if (!OIDplus::config()->getValue('oobe_objects_done')) { |
463 | if (!OIDplus::config()->getValue('oobe_objects_done')) { |
464 | // If the OOBE wizard is NOT done, then just enable the "oid" object type by default |
464 | // If the OOBE wizard is NOT done, then just enable the "oid" object type by default |
465 | $do_enable = $ns == 'oid'; |
465 | $do_enable = $ns == 'oid'; |
466 | } else { |
466 | } else { |
467 | // If the OOBE wizard was done (once), then |
467 | // If the OOBE wizard was done (once), then |
468 | // we will enable all object types which were never initialized |
468 | // we will enable all object types which were never initialized |
469 | // (i.e. a plugin folder was freshly added) |
469 | // (i.e. a plugin folder was freshly added) |
470 | $do_enable = !in_array($ns, $init_ary); |
470 | $do_enable = !in_array($ns, $init_ary); |
471 | } |
471 | } |
472 | } |
472 | } |
473 | 473 | ||
474 | if ($do_enable) { |
474 | if ($do_enable) { |
475 | self::$enabledObjectTypes[] = $ot; |
475 | self::$enabledObjectTypes[] = $ot; |
476 | usort(self::$enabledObjectTypes, function($a, $b) { |
476 | usort(self::$enabledObjectTypes, function($a, $b) { |
477 | $enabled = OIDplus::config()->getValue("objecttypes_enabled"); |
477 | $enabled = OIDplus::config()->getValue("objecttypes_enabled"); |
478 | $enabled_ary = explode(';', $enabled); |
478 | $enabled_ary = explode(';', $enabled); |
479 | 479 | ||
480 | $idx_a = array_search($a::ns(), $enabled_ary); |
480 | $idx_a = array_search($a::ns(), $enabled_ary); |
481 | $idx_b = array_search($b::ns(), $enabled_ary); |
481 | $idx_b = array_search($b::ns(), $enabled_ary); |
482 | 482 | ||
483 | if ($idx_a == $idx_b) { |
483 | if ($idx_a == $idx_b) { |
484 | return 0; |
484 | return 0; |
485 | } |
485 | } |
486 | return ($idx_a > $idx_b) ? +1 : -1; |
486 | return ($idx_a > $idx_b) ? +1 : -1; |
487 | }); |
487 | }); |
488 | } else { |
488 | } else { |
489 | self::$disabledObjectTypes[] = $ot; |
489 | self::$disabledObjectTypes[] = $ot; |
490 | } |
490 | } |
491 | 491 | ||
492 | if (!in_array($ns, $init_ary)) { |
492 | if (!in_array($ns, $init_ary)) { |
493 | // Was never initialized before, so we add it to the list of enabled object types once |
493 | // Was never initialized before, so we add it to the list of enabled object types once |
494 | 494 | ||
495 | if ($do_enable) { |
495 | if ($do_enable) { |
496 | $enabled_ary[] = $ns; |
496 | $enabled_ary[] = $ns; |
497 | // Important: Don't validate the input, because the other object types might not be initialized yet! So use setValueNoCallback() instead setValue(). |
497 | // Important: Don't validate the input, because the other object types might not be initialized yet! So use setValueNoCallback() instead setValue(). |
498 | OIDplus::config()->setValueNoCallback("objecttypes_enabled", implode(';', $enabled_ary)); |
498 | OIDplus::config()->setValueNoCallback("objecttypes_enabled", implode(';', $enabled_ary)); |
499 | } |
499 | } |
500 | 500 | ||
501 | $init_ary[] = $ns; |
501 | $init_ary[] = $ns; |
502 | OIDplus::config()->setValue("objecttypes_initialized", implode(';', $init_ary)); |
502 | OIDplus::config()->setValue("objecttypes_initialized", implode(';', $init_ary)); |
503 | } |
503 | } |
504 | } |
504 | } |
505 | 505 | ||
506 | public static function getObjectTypePlugins() { |
506 | public static function getObjectTypePlugins() { |
507 | return self::$objectTypePlugins; |
507 | return self::$objectTypePlugins; |
508 | } |
508 | } |
509 | 509 | ||
510 | public static function getObjectTypePluginsEnabled() { |
510 | public static function getObjectTypePluginsEnabled() { |
511 | $res = array(); |
511 | $res = array(); |
512 | foreach (self::$objectTypePlugins as $plugin) { |
512 | foreach (self::$objectTypePlugins as $plugin) { |
513 | $ot = $plugin::getObjectTypeClassName(); |
513 | $ot = $plugin::getObjectTypeClassName(); |
514 | if (in_array($ot, self::$enabledObjectTypes)) $res[] = $plugin; |
514 | if (in_array($ot, self::$enabledObjectTypes)) $res[] = $plugin; |
515 | } |
515 | } |
516 | return $res; |
516 | return $res; |
517 | } |
517 | } |
518 | 518 | ||
519 | public static function getObjectTypePluginsDisabled() { |
519 | public static function getObjectTypePluginsDisabled() { |
520 | $res = array(); |
520 | $res = array(); |
521 | foreach (self::$objectTypePlugins as $plugin) { |
521 | foreach (self::$objectTypePlugins as $plugin) { |
522 | $ot = $plugin::getObjectTypeClassName(); |
522 | $ot = $plugin::getObjectTypeClassName(); |
523 | if (in_array($ot, self::$disabledObjectTypes)) $res[] = $plugin; |
523 | if (in_array($ot, self::$disabledObjectTypes)) $res[] = $plugin; |
524 | } |
524 | } |
525 | return $res; |
525 | return $res; |
526 | } |
526 | } |
527 | 527 | ||
528 | public static function getEnabledObjectTypes() { |
528 | public static function getEnabledObjectTypes() { |
529 | return self::$enabledObjectTypes; |
529 | return self::$enabledObjectTypes; |
530 | } |
530 | } |
531 | 531 | ||
532 | public static function getDisabledObjectTypes() { |
532 | public static function getDisabledObjectTypes() { |
533 | return self::$disabledObjectTypes; |
533 | return self::$disabledObjectTypes; |
534 | } |
534 | } |
535 | 535 | ||
536 | # --- Plugin handling functions |
536 | # --- Plugin handling functions |
537 | 537 | ||
538 | public static function getAllPlugins()/*: array*/ { |
538 | public static function getAllPlugins()/*: array*/ { |
539 | $res = array(); |
539 | $res = array(); |
540 | $res = array_merge($res, self::$pagePlugins); |
540 | $res = array_merge($res, self::$pagePlugins); |
541 | $res = array_merge($res, self::$authPlugins); |
541 | $res = array_merge($res, self::$authPlugins); |
542 | $res = array_merge($res, self::$loggerPlugins); |
542 | $res = array_merge($res, self::$loggerPlugins); |
543 | $res = array_merge($res, self::$objectTypePlugins); |
543 | $res = array_merge($res, self::$objectTypePlugins); |
544 | $res = array_merge($res, self::$dbPlugins); |
544 | $res = array_merge($res, self::$dbPlugins); |
545 | $res = array_merge($res, self::$sqlSlangPlugins); |
545 | $res = array_merge($res, self::$sqlSlangPlugins); |
546 | $res = array_merge($res, self::$languagePlugins); |
546 | $res = array_merge($res, self::$languagePlugins); |
547 | $res = array_merge($res, self::$designPlugins); |
547 | $res = array_merge($res, self::$designPlugins); |
548 | return $res; |
548 | return $res; |
549 | } |
549 | } |
550 | 550 | ||
551 | public static function getPluginByOid($oid)/*: ?OIDplusPlugin*/ { |
551 | public static function getPluginByOid($oid)/*: ?OIDplusPlugin*/ { |
552 | $plugins = self::getAllPlugins(); |
552 | $plugins = self::getAllPlugins(); |
553 | foreach ($plugins as $plugin) { |
553 | foreach ($plugins as $plugin) { |
554 | if (oid_dotnotation_equal($plugin->getManifest()->getOid(), $oid)) { |
554 | if (oid_dotnotation_equal($plugin->getManifest()->getOid(), $oid)) { |
555 | return $plugin; |
555 | return $plugin; |
556 | } |
556 | } |
557 | } |
557 | } |
558 | return null; |
558 | return null; |
559 | } |
559 | } |
560 | 560 | ||
561 | public static function getPluginByClassName($classname)/*: ?OIDplusPlugin*/ { |
561 | public static function getPluginByClassName($classname)/*: ?OIDplusPlugin*/ { |
562 | $plugins = self::getAllPlugins(); |
562 | $plugins = self::getAllPlugins(); |
563 | foreach ($plugins as $plugin) { |
563 | foreach ($plugins as $plugin) { |
564 | if (get_class($plugin) === $classname) { |
564 | if (get_class($plugin) === $classname) { |
565 | return $plugin; |
565 | return $plugin; |
566 | } |
566 | } |
567 | } |
567 | } |
568 | return null; |
568 | return null; |
569 | } |
569 | } |
570 | 570 | ||
571 | /** |
571 | /** |
572 | * @return array<OIDplusPluginManifest>|array<string,array<string,OIDplusPluginManifest>> |
572 | * @return array<OIDplusPluginManifest>|array<string,array<string,OIDplusPluginManifest>> |
573 | */ |
573 | */ |
574 | public static function getAllPluginManifests($pluginFolderMasks='*', $flat=true): array { |
574 | public static function getAllPluginManifests($pluginFolderMasks='*', $flat=true): array { |
575 | $out = array(); |
575 | $out = array(); |
576 | // Note: glob() will sort by default, so we do not need a page priority attribute. |
576 | // Note: glob() will sort by default, so we do not need a page priority attribute. |
577 | // So you just need to use a numeric plugin directory prefix (padded). |
577 | // So you just need to use a numeric plugin directory prefix (padded). |
578 | $ary = array(); |
578 | $ary = array(); |
579 | foreach (explode(',',$pluginFolderMasks) as $pluginFolderMask) { |
579 | foreach (explode(',',$pluginFolderMasks) as $pluginFolderMask) { |
580 | $ary = array_merge($ary,glob(OIDplus::localpath().'plugins/'.'*'.'/'.$pluginFolderMask.'/'.'*'.'/manifest.xml')); |
580 | $ary = array_merge($ary,glob(OIDplus::localpath().'plugins/'.'*'.'/'.$pluginFolderMask.'/'.'*'.'/manifest.xml')); |
581 | } |
581 | } |
582 | 582 | ||
583 | // Sort the plugins by their type and name, as if they would be in a single vendor-folder! |
583 | // Sort the plugins by their type and name, as if they would be in a single vendor-folder! |
584 | uasort($ary, function($a,$b) { |
584 | uasort($ary, function($a,$b) { |
585 | if ($a == $b) return 0; |
585 | if ($a == $b) return 0; |
586 | 586 | ||
587 | $ary = explode('/',$a); |
587 | $ary = explode('/',$a); |
588 | $bry = explode('/',$b); |
588 | $bry = explode('/',$b); |
589 | 589 | ||
590 | // First sort by type (publicPage, auth, database, language, ...) |
590 | // First sort by type (publicPage, auth, database, language, ...) |
591 | $a_type = $ary[count($ary)-1-2]; |
591 | $a_type = $ary[count($ary)-1-2]; |
592 | $b_type = $bry[count($bry)-1-2]; |
592 | $b_type = $bry[count($bry)-1-2]; |
593 | if ($a_type < $b_type) return -1; |
593 | if ($a_type < $b_type) return -1; |
594 | if ($a_type > $b_type) return 1; |
594 | if ($a_type > $b_type) return 1; |
595 | 595 | ||
596 | // Then sort by name (090_login, 100_whois, etc.) |
596 | // Then sort by name (090_login, 100_whois, etc.) |
597 | $a_name = $ary[count($ary)-1-1]; |
597 | $a_name = $ary[count($ary)-1-1]; |
598 | $b_name = $bry[count($bry)-1-1]; |
598 | $b_name = $bry[count($bry)-1-1]; |
599 | if ($a_name < $b_name) return -1; |
599 | if ($a_name < $b_name) return -1; |
600 | if ($a_name > $b_name) return 1; |
600 | if ($a_name > $b_name) return 1; |
601 | 601 | ||
602 | // If it is still equal, then finally sort by vendorname |
602 | // If it is still equal, then finally sort by vendorname |
603 | $a_vendor = $ary[count($ary)-1-3]; |
603 | $a_vendor = $ary[count($ary)-1-3]; |
604 | $b_vendor = $bry[count($bry)-1-3]; |
604 | $b_vendor = $bry[count($bry)-1-3]; |
605 | if ($a_vendor < $b_vendor) return -1; |
605 | if ($a_vendor < $b_vendor) return -1; |
606 | if ($a_vendor > $b_vendor) return 1; |
606 | if ($a_vendor > $b_vendor) return 1; |
607 | return 0; |
607 | return 0; |
608 | }); |
608 | }); |
609 | 609 | ||
610 | foreach ($ary as $ini) { |
610 | foreach ($ary as $ini) { |
611 | if (!file_exists($ini)) continue; |
611 | if (!file_exists($ini)) continue; |
612 | 612 | ||
613 | $manifest = new OIDplusPluginManifest(); |
613 | $manifest = new OIDplusPluginManifest(); |
614 | $manifest->loadManifest($ini); |
614 | $manifest->loadManifest($ini); |
615 | 615 | ||
616 | $class_name = $manifest->getPhpMainClass(); |
616 | $class_name = $manifest->getPhpMainClass(); |
617 | if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_'.$class_name, false)) { |
617 | if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_'.$class_name, false)) { |
618 | continue; |
618 | continue; |
619 | } |
619 | } |
620 | 620 | ||
621 | if ($flat) { |
621 | if ($flat) { |
622 | $out[] = $manifest; |
622 | $out[] = $manifest; |
623 | } else { |
623 | } else { |
624 | $plugintype_folder = basename(dirname(dirname($ini))); |
624 | $plugintype_folder = basename(dirname(dirname($ini))); |
625 | $pluginname_folder = basename(dirname($ini)); |
625 | $pluginname_folder = basename(dirname($ini)); |
626 | 626 | ||
627 | if (!isset($out[$plugintype_folder])) $out[$plugintype_folder] = array(); |
627 | if (!isset($out[$plugintype_folder])) $out[$plugintype_folder] = array(); |
628 | if (!isset($out[$plugintype_folder][$pluginname_folder])) $out[$plugintype_folder][$pluginname_folder] = array(); |
628 | if (!isset($out[$plugintype_folder][$pluginname_folder])) $out[$plugintype_folder][$pluginname_folder] = array(); |
629 | $out[$plugintype_folder][$pluginname_folder] = $manifest; |
629 | $out[$plugintype_folder][$pluginname_folder] = $manifest; |
630 | } |
630 | } |
631 | } |
631 | } |
632 | return $out; |
632 | return $out; |
633 | } |
633 | } |
634 | 634 | ||
635 | /** |
635 | /** |
636 | * @return array<string> |
636 | * @return array<string> |
637 | */ |
637 | */ |
638 | public static function registerAllPlugins($pluginDirName, $expectedPluginClass, $registerCallback): array { |
638 | public static function registerAllPlugins($pluginDirName, $expectedPluginClass, $registerCallback): array { |
639 | $out = array(); |
639 | $out = array(); |
640 | if (is_array($pluginDirName)) { |
640 | if (is_array($pluginDirName)) { |
641 | $ary = array(); |
641 | $ary = array(); |
642 | foreach ($pluginDirName as $pluginDirName_) { |
642 | foreach ($pluginDirName as $pluginDirName_) { |
643 | $ary = array_merge($ary, self::getAllPluginManifests($pluginDirName_, false)); |
643 | $ary = array_merge($ary, self::getAllPluginManifests($pluginDirName_, false)); |
644 | } |
644 | } |
645 | } else { |
645 | } else { |
646 | $ary = self::getAllPluginManifests($pluginDirName, false); |
646 | $ary = self::getAllPluginManifests($pluginDirName, false); |
647 | } |
647 | } |
648 | $known_plugin_oids = array(); |
648 | $known_plugin_oids = array(); |
649 | if (OIDplus::baseConfig()->getValue('DEBUG')) { |
649 | if (OIDplus::baseConfig()->getValue('DEBUG')) { |
650 | $fake_feature = uuid_to_oid(gen_uuid()); |
650 | $fake_feature = uuid_to_oid(gen_uuid()); |
651 | } else { |
651 | } else { |
652 | $fake_feature = null; |
652 | $fake_feature = null; |
653 | } |
653 | } |
654 | foreach ($ary as $plugintype_folder => $bry) { |
654 | foreach ($ary as $plugintype_folder => $bry) { |
655 | foreach ($bry as $pluginname_folder => $manifest) { |
655 | foreach ($bry as $pluginname_folder => $manifest) { |
656 | $class_name = $manifest->getPhpMainClass(); |
656 | $class_name = $manifest->getPhpMainClass(); |
657 | 657 | ||
658 | // Before we load the plugin, we want to make some checks to confirm |
658 | // Before we load the plugin, we want to make some checks to confirm |
659 | // that the plugin is working correctly. |
659 | // that the plugin is working correctly. |
660 | 660 | ||
661 | if (!$class_name) { |
661 | if (!$class_name) { |
662 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Manifest does not declare a PHP main class')); |
662 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Manifest does not declare a PHP main class')); |
663 | } |
663 | } |
664 | if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_'.$class_name, false)) { |
664 | if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_'.$class_name, false)) { |
665 | continue; |
665 | continue; |
666 | } |
666 | } |
667 | if (!class_exists($class_name)) { |
667 | if (!class_exists($class_name)) { |
668 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Manifest declares PHP main class as "%1", but it could not be found',$class_name)); |
668 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Manifest declares PHP main class as "%1", but it could not be found',$class_name)); |
669 | } |
669 | } |
670 | if (!is_subclass_of($class_name, $expectedPluginClass)) { |
670 | if (!is_subclass_of($class_name, $expectedPluginClass)) { |
671 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Plugin main class "%1" is expected to be a subclass of "%2"',$class_name,$expectedPluginClass)); |
671 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Plugin main class "%1" is expected to be a subclass of "%2"',$class_name,$expectedPluginClass)); |
672 | } |
672 | } |
673 | if (($class_name!=$manifest->getTypeClass()) && (!is_subclass_of($class_name,$manifest->getTypeClass()))) { |
673 | if (($class_name!=$manifest->getTypeClass()) && (!is_subclass_of($class_name,$manifest->getTypeClass()))) { |
674 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Plugin main class "%1" is expected to be a subclass of "%2", according to type declared in manifest',$class_name,$manifest->getTypeClass())); |
674 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Plugin main class "%1" is expected to be a subclass of "%2", according to type declared in manifest',$class_name,$manifest->getTypeClass())); |
675 | } |
675 | } |
676 | if (($manifest->getTypeClass()!=$expectedPluginClass) && (!is_subclass_of($manifest->getTypeClass(),$expectedPluginClass))) { |
676 | if (($manifest->getTypeClass()!=$expectedPluginClass) && (!is_subclass_of($manifest->getTypeClass(),$expectedPluginClass))) { |
677 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Class declared in manifest is "%1" does not fit expected class for this plugin type "%2"',$manifest->getTypeClass(),$expectedPluginClass)); |
677 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Class declared in manifest is "%1" does not fit expected class for this plugin type "%2"',$manifest->getTypeClass(),$expectedPluginClass)); |
678 | } |
678 | } |
679 | 679 | ||
680 | $plugin_oid = $manifest->getOid(); |
680 | $plugin_oid = $manifest->getOid(); |
681 | if (!$plugin_oid) { |
681 | if (!$plugin_oid) { |
682 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Does not have an OID')); |
682 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Does not have an OID')); |
683 | } |
683 | } |
684 | if (!oid_valid_dotnotation($plugin_oid, false, false, 2)) { |
684 | if (!oid_valid_dotnotation($plugin_oid, false, false, 2)) { |
685 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Plugin OID "%1" is invalid (needs to be valid dot-notation)',$plugin_oid)); |
685 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Plugin OID "%1" is invalid (needs to be valid dot-notation)',$plugin_oid)); |
686 | } |
686 | } |
687 | if (isset($known_plugin_oids[$plugin_oid])) { |
687 | if (isset($known_plugin_oids[$plugin_oid])) { |
688 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('The OID "%1" is already used by the plugin "%2"',$plugin_oid,$known_plugin_oids[$plugin_oid])); |
688 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('The OID "%1" is already used by the plugin "%2"',$plugin_oid,$known_plugin_oids[$plugin_oid])); |
689 | } |
689 | } |
690 | 690 | ||
691 | $full_plugin_dir = dirname($manifest->getManifestFile()); |
691 | $full_plugin_dir = dirname($manifest->getManifestFile()); |
692 | $full_plugin_dir = substr($full_plugin_dir, strlen(OIDplus::localpath())); |
692 | $full_plugin_dir = substr($full_plugin_dir, strlen(OIDplus::localpath())); |
693 | // { iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 37476 products(2) oidplus(5) v2(2) plugins(4) } |
693 | // { iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 37476 products(2) oidplus(5) v2(2) plugins(4) } |
694 | if (str_starts_with($full_plugin_dir, 'plugins/viathinksoft/') != str_starts_with($plugin_oid, '1.3.6.1.4.1.37476.2.5.2.4.')) { |
694 | if (str_starts_with($full_plugin_dir, 'plugins/viathinksoft/') != str_starts_with($plugin_oid, '1.3.6.1.4.1.37476.2.5.2.4.')) { |
695 | throw new OIDplusException(_L('Plugin "%1/%2" is misplaced',$plugintype_folder,$pluginname_folder).': '._L('The plugin is in the wrong folder. The folder %1 can only be used by official ViaThinkSoft plugins','plugins/viathinksoft/')); |
695 | throw new OIDplusException(_L('Plugin "%1/%2" is misplaced',$plugintype_folder,$pluginname_folder).': '._L('The plugin is in the wrong folder. The folder %1 can only be used by official ViaThinkSoft plugins','plugins/viathinksoft/')); |
696 | } |
696 | } |
697 | 697 | ||
698 | $known_plugin_oids[$plugin_oid] = $plugintype_folder.'/'.$pluginname_folder; |
698 | $known_plugin_oids[$plugin_oid] = $plugintype_folder.'/'.$pluginname_folder; |
699 | 699 | ||
700 | $obj = new $class_name(); |
700 | $obj = new $class_name(); |
701 | 701 | ||
702 | if (OIDplus::baseConfig()->getValue('DEBUG')) { |
702 | if (OIDplus::baseConfig()->getValue('DEBUG')) { |
703 | if ($obj->implementsFeature($fake_feature)) { |
703 | if ($obj->implementsFeature($fake_feature)) { |
704 | // see https://devblogs.microsoft.com/oldnewthing/20040211-00/?p=40663 |
704 | // see https://devblogs.microsoft.com/oldnewthing/20040211-00/?p=40663 |
705 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('implementsFeature() always returns true')); |
705 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('implementsFeature() always returns true')); |
706 | } |
706 | } |
707 | } |
707 | } |
708 | 708 | ||
709 | // TODO: Maybe as additional plugin-test, we should also check if plugins are allowed to define CSS/JS (since only page plugins may have them!) |
709 | // TODO: Maybe as additional plugin-test, we should also check if plugins are allowed to define CSS/JS (since only page plugins may have them!) |
710 | $tmp = array_merge( |
710 | $tmp = array_merge( |
711 | $manifest->getJSFiles(), |
711 | $manifest->getJSFiles(), |
712 | $manifest->getCSSFiles(), |
712 | $manifest->getCSSFiles(), |
713 | $manifest->getJSFilesSetup(), |
713 | $manifest->getJSFilesSetup(), |
714 | $manifest->getCSSFilesSetup() |
714 | $manifest->getCSSFilesSetup() |
715 | ); |
715 | ); |
716 | foreach ($tmp as $file) { |
716 | foreach ($tmp as $file) { |
717 | if (!file_exists($file)) { |
717 | if (!file_exists($file)) { |
718 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('File %1 was defined in manifest, but it is not existing',$file)); |
718 | throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('File %1 was defined in manifest, but it is not existing',$file)); |
719 | } |
719 | } |
720 | } |
720 | } |
721 | 721 | ||
722 | // Now we can continue |
722 | // Now we can continue |
723 | 723 | ||
724 | $out[] = $class_name; |
724 | $out[] = $class_name; |
725 | if (!is_null($registerCallback)) { |
725 | if (!is_null($registerCallback)) { |
726 | call_user_func($registerCallback, $obj); |
726 | call_user_func($registerCallback, $obj); |
727 | 727 | ||
728 | // Alternative approaches: |
728 | // Alternative approaches: |
729 | //$registerCallback[0]::{$registerCallback[1]}($obj); |
729 | //$registerCallback[0]::{$registerCallback[1]}($obj); |
730 | // or: |
730 | // or: |
731 | //forward_static_call($registerCallback, $obj); |
731 | //forward_static_call($registerCallback, $obj); |
732 | } |
732 | } |
733 | } |
733 | } |
734 | 734 | ||
735 | } |
735 | } |
736 | return $out; |
736 | return $out; |
737 | } |
737 | } |
738 | 738 | ||
739 | # --- Initialization of OIDplus |
739 | # --- Initialization of OIDplus |
740 | 740 | ||
741 | public static function init($html=true, $keepBaseConfig=true) { |
741 | public static function init($html=true, $keepBaseConfig=true) { |
742 | self::$html = $html; |
742 | self::$html = $html; |
743 | 743 | ||
744 | // Reset internal state, so we can re-init verything if required |
744 | // Reset internal state, so we can re-init verything if required |
745 | 745 | ||
746 | if (self::$old_config_format) { |
746 | if (self::$old_config_format) { |
747 | // Note: This can only happen in very special cases (e.g. test cases) where you call init() twice |
747 | // Note: This can only happen in very special cases (e.g. test cases) where you call init() twice |
748 | throw new OIDplusConfigInitializationException(_L('A full re-initialization is not possible if a version 2.0 config file (containing "defines") is used. Please update to a config 2.1 file by running setup again.')); |
748 | throw new OIDplusConfigInitializationException(_L('A full re-initialization is not possible if a version 2.0 config file (containing "defines") is used. Please update to a config 2.1 file by running setup again.')); |
749 | } |
749 | } |
750 | 750 | ||
751 | self::$config = null; |
751 | self::$config = null; |
752 | if (!$keepBaseConfig) self::$baseConfig = null; // for test cases we need to be able to control base config and setting values manually, so $keepBaseConfig needs to be true |
752 | if (!$keepBaseConfig) self::$baseConfig = null; // for test cases we need to be able to control base config and setting values manually, so $keepBaseConfig needs to be true |
753 | self::$gui = null; |
753 | self::$gui = null; |
754 | self::$authUtils = null; |
754 | self::$authUtils = null; |
755 | self::$mailUtils = null; |
755 | self::$mailUtils = null; |
756 | self::$menuUtils = null; |
756 | self::$menuUtils = null; |
757 | self::$logger = null; |
757 | self::$logger = null; |
758 | self::$dbMainSession = null; |
758 | self::$dbMainSession = null; |
759 | self::$dbIsolatedSession = null; |
759 | self::$dbIsolatedSession = null; |
760 | self::$pagePlugins = array(); |
760 | self::$pagePlugins = array(); |
761 | self::$authPlugins = array(); |
761 | self::$authPlugins = array(); |
762 | self::$loggerPlugins = array(); |
762 | self::$loggerPlugins = array(); |
763 | self::$objectTypePlugins = array(); |
763 | self::$objectTypePlugins = array(); |
764 | self::$enabledObjectTypes = array(); |
764 | self::$enabledObjectTypes = array(); |
765 | self::$disabledObjectTypes = array(); |
765 | self::$disabledObjectTypes = array(); |
766 | self::$dbPlugins = array(); |
766 | self::$dbPlugins = array(); |
767 | self::$sqlSlangPlugins = array(); |
767 | self::$sqlSlangPlugins = array(); |
768 | self::$languagePlugins = array(); |
768 | self::$languagePlugins = array(); |
769 | self::$designPlugins = array(); |
769 | self::$designPlugins = array(); |
770 | self::$system_id_cache = null; |
770 | self::$system_id_cache = null; |
771 | self::$sslAvailableCache = null; |
771 | self::$sslAvailableCache = null; |
772 | self::$translationArray = array(); |
772 | self::$translationArray = array(); |
773 | 773 | ||
774 | // Continue... |
774 | // Continue... |
775 | 775 | ||
776 | OIDplus::baseConfig(); // this loads the base configuration located in userdata/baseconfig/config.inc.php (once!) |
776 | OIDplus::baseConfig(); // this loads the base configuration located in userdata/baseconfig/config.inc.php (once!) |
777 | // You can do changes to the configuration afterwards using OIDplus::baseConfig()->... |
777 | // You can do changes to the configuration afterwards using OIDplus::baseConfig()->... |
778 | 778 | ||
779 | // Register database types (highest priority) |
779 | // Register database types (highest priority) |
780 | 780 | ||
781 | // SQL slangs |
781 | // SQL slangs |
782 | 782 | ||
783 | self::registerAllPlugins('sqlSlang', 'OIDplusSqlSlangPlugin', array('OIDplus','registerSqlSlangPlugin')); |
783 | self::registerAllPlugins('sqlSlang', 'OIDplusSqlSlangPlugin', array('OIDplus','registerSqlSlangPlugin')); |
784 | foreach (OIDplus::getSqlSlangPlugins() as $plugin) { |
784 | foreach (OIDplus::getSqlSlangPlugins() as $plugin) { |
785 | $plugin->init($html); |
785 | $plugin->init($html); |
786 | } |
786 | } |
787 | 787 | ||
788 | // Database providers |
788 | // Database providers |
789 | 789 | ||
790 | self::registerAllPlugins('database', 'OIDplusDatabasePlugin', array('OIDplus','registerDatabasePlugin')); |
790 | self::registerAllPlugins('database', 'OIDplusDatabasePlugin', array('OIDplus','registerDatabasePlugin')); |
791 | foreach (OIDplus::getDatabasePlugins() as $plugin) { |
791 | foreach (OIDplus::getDatabasePlugins() as $plugin) { |
792 | $plugin->init($html); |
792 | $plugin->init($html); |
793 | } |
793 | } |
794 | 794 | ||
795 | // Do redirect stuff etc. |
795 | // Do redirect stuff etc. |
796 | 796 | ||
797 | self::isSslAvailable(); // This function does automatic redirects |
797 | self::isSslAvailable(); // This function does automatic redirects |
798 | 798 | ||
799 | // Construct the configuration manager |
799 | // Construct the configuration manager |
800 | 800 | ||
801 | OIDplus::config(); // During the construction, various system settings are prepared if required |
801 | OIDplus::config(); // During the construction, various system settings are prepared if required |
802 | 802 | ||
803 | // Initialize public / private keys |
803 | // Initialize public / private keys |
804 | 804 | ||
805 | OIDplus::getPkiStatus(true); |
805 | OIDplus::getPkiStatus(true); |
806 | 806 | ||
807 | // Register non-DB plugins |
807 | // Register non-DB plugins |
808 | 808 | ||
809 | self::registerAllPlugins(array('publicPages', 'raPages', 'adminPages'), 'OIDplusPagePlugin', array('OIDplus','registerPagePlugin')); |
809 | self::registerAllPlugins(array('publicPages', 'raPages', 'adminPages'), 'OIDplusPagePlugin', array('OIDplus','registerPagePlugin')); |
810 | self::registerAllPlugins('auth', 'OIDplusAuthPlugin', array('OIDplus','registerAuthPlugin')); |
810 | self::registerAllPlugins('auth', 'OIDplusAuthPlugin', array('OIDplus','registerAuthPlugin')); |
811 | self::registerAllPlugins('logger', 'OIDplusLoggerPlugin', array('OIDplus','registerLoggerPlugin')); |
811 | self::registerAllPlugins('logger', 'OIDplusLoggerPlugin', array('OIDplus','registerLoggerPlugin')); |
812 | self::registerAllPlugins('objectTypes', 'OIDplusObjectTypePlugin', array('OIDplus','registerObjectTypePlugin')); |
812 | self::registerAllPlugins('objectTypes', 'OIDplusObjectTypePlugin', array('OIDplus','registerObjectTypePlugin')); |
813 | self::registerAllPlugins('language', 'OIDplusLanguagePlugin', array('OIDplus','registerLanguagePlugin')); |
813 | self::registerAllPlugins('language', 'OIDplusLanguagePlugin', array('OIDplus','registerLanguagePlugin')); |
814 | self::registerAllPlugins('design', 'OIDplusDesignPlugin', array('OIDplus','registerDesignPlugin')); |
814 | self::registerAllPlugins('design', 'OIDplusDesignPlugin', array('OIDplus','registerDesignPlugin')); |
815 | 815 | ||
816 | // Initialize non-DB plugins |
816 | // Initialize non-DB plugins |
817 | 817 | ||
818 | foreach (OIDplus::getPagePlugins() as $plugin) { |
818 | foreach (OIDplus::getPagePlugins() as $plugin) { |
819 | $plugin->init($html); |
819 | $plugin->init($html); |
820 | } |
820 | } |
821 | foreach (OIDplus::getAuthPlugins() as $plugin) { |
821 | foreach (OIDplus::getAuthPlugins() as $plugin) { |
822 | $plugin->init($html); |
822 | $plugin->init($html); |
823 | } |
823 | } |
824 | foreach (OIDplus::getLoggerPlugins() as $plugin) { |
824 | foreach (OIDplus::getLoggerPlugins() as $plugin) { |
825 | $plugin->init($html); |
825 | $plugin->init($html); |
826 | } |
826 | } |
827 | foreach (OIDplus::getObjectTypePlugins() as $plugin) { |
827 | foreach (OIDplus::getObjectTypePlugins() as $plugin) { |
828 | $plugin->init($html); |
828 | $plugin->init($html); |
829 | } |
829 | } |
830 | foreach (OIDplus::getLanguagePlugins() as $plugin) { |
830 | foreach (OIDplus::getLanguagePlugins() as $plugin) { |
831 | $plugin->init($html); |
831 | $plugin->init($html); |
832 | } |
832 | } |
833 | foreach (OIDplus::getDesignPlugins() as $plugin) { |
833 | foreach (OIDplus::getDesignPlugins() as $plugin) { |
834 | $plugin->init($html); |
834 | $plugin->init($html); |
835 | } |
835 | } |
836 | 836 | ||
837 | // Initialize other stuff (i.e. things which require the logger!) |
837 | // Initialize other stuff (i.e. things which require the logger!) |
838 | 838 | ||
839 | OIDplus::recognizeSystemUrl(); // Make sure "last_known_system_url" is set |
839 | OIDplus::recognizeSystemUrl(); // Make sure "last_known_system_url" is set |
840 | OIDplus::recognizeVersion(); // Make sure "last_known_version" is set and a log entry is created |
840 | OIDplus::recognizeVersion(); // Make sure "last_known_version" is set and a log entry is created |
841 | } |
841 | } |
842 | 842 | ||
843 | # --- System URL, System ID, PKI, and other functions |
843 | # --- System URL, System ID, PKI, and other functions |
844 | 844 | ||
845 | private static function recognizeSystemUrl() { |
845 | private static function recognizeSystemUrl() { |
846 | try { |
846 | try { |
847 | $url = OIDplus::webpath(); |
847 | $url = OIDplus::webpath(); |
848 | OIDplus::config()->setValue('last_known_system_url', $url); |
848 | OIDplus::config()->setValue('last_known_system_url', $url); |
849 | } catch (Exception $e) { |
849 | } catch (Exception $e) { |
850 | } |
850 | } |
851 | } |
851 | } |
852 | 852 | ||
853 | private static function getExecutingScriptPathDepth() { |
853 | private static function getExecutingScriptPathDepth() { |
854 | if (PHP_SAPI == 'cli') { |
854 | if (PHP_SAPI == 'cli') { |
855 | global $argv; |
855 | global $argv; |
856 | $test_dir = dirname(realpath($argv[0])); |
856 | $test_dir = dirname(realpath($argv[0])); |
857 | } else { |
857 | } else { |
858 | if (!isset($_SERVER["SCRIPT_FILENAME"])) return false; |
858 | if (!isset($_SERVER["SCRIPT_FILENAME"])) return false; |
859 | $test_dir = dirname($_SERVER['SCRIPT_FILENAME']); |
859 | $test_dir = dirname($_SERVER['SCRIPT_FILENAME']); |
860 | } |
860 | } |
861 | $test_dir = str_replace('\\', '/', $test_dir); |
861 | $test_dir = str_replace('\\', '/', $test_dir); |
862 | $steps_up = 0; |
862 | $steps_up = 0; |
863 | while (!file_exists($test_dir.'/oidplus.min.css.php')) { // We just assume that only the OIDplus base directory contains "oidplus.min.css.php" and not any subsequent directory! |
863 | while (!file_exists($test_dir.'/oidplus.min.css.php')) { // We just assume that only the OIDplus base directory contains "oidplus.min.css.php" and not any subsequent directory! |
864 | $test_dir = dirname($test_dir); |
864 | $test_dir = dirname($test_dir); |
865 | $steps_up++; |
865 | $steps_up++; |
866 | if ($steps_up == 1000) return false; // to make sure there will never be an infinite loop |
866 | if ($steps_up == 1000) return false; // to make sure there will never be an infinite loop |
867 | } |
867 | } |
868 | return $steps_up; |
868 | return $steps_up; |
869 | } |
869 | } |
870 | 870 | ||
871 | public static function isSSL() { |
871 | public static function isSSL() { |
872 | return isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on'); |
872 | return isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on'); |
873 | } |
873 | } |
874 | 874 | ||
875 | private static function getSystemUrl($relative=false) { |
875 | private static function getSystemUrl($relative=false) { |
876 | if (!$relative) { |
876 | if (!$relative) { |
877 | $res = OIDplus::baseConfig()->getValue('EXPLICIT_ABSOLUTE_SYSTEM_URL', ''); |
877 | $res = OIDplus::baseConfig()->getValue('EXPLICIT_ABSOLUTE_SYSTEM_URL', ''); |
878 | if ($res !== '') { |
878 | if ($res !== '') { |
879 | return rtrim($res,'/').'/'; |
879 | return rtrim($res,'/').'/'; |
880 | } |
880 | } |
881 | if (PHP_SAPI == 'cli') { |
881 | if (PHP_SAPI == 'cli') { |
882 | try { |
882 | try { |
883 | return OIDplus::config()->getValue('last_known_system_url', false); |
883 | return OIDplus::config()->getValue('last_known_system_url', false); |
884 | } catch (Exception $e) { |
884 | } catch (Exception $e) { |
885 | return false; |
885 | return false; |
886 | } |
886 | } |
887 | } |
887 | } |
888 | } |
888 | } |
889 | 889 | ||
890 | // First, try to find out how many levels we need to go up |
890 | // First, try to find out how many levels we need to go up |
891 | $steps_up = self::getExecutingScriptPathDepth(); |
891 | $steps_up = self::getExecutingScriptPathDepth(); |
892 | if ($steps_up === false) return false; |
892 | if ($steps_up === false) return false; |
893 | 893 | ||
894 | // Now go up these amount of levels, based on SCRIPT_NAME/argv[0] |
894 | // Now go up these amount of levels, based on SCRIPT_NAME/argv[0] |
895 | if (PHP_SAPI == 'cli') { |
895 | if (PHP_SAPI == 'cli') { |
896 | if ($relative) { |
896 | if ($relative) { |
897 | return str_repeat('../',$steps_up); |
897 | return str_repeat('../',$steps_up); |
898 | } else { |
898 | } else { |
899 | return false; |
899 | return false; |
900 | } |
900 | } |
901 | } else { |
901 | } else { |
902 | $res = dirname($_SERVER['SCRIPT_NAME'].'index.php'); // This fake 'index.php' ensures that SCRIPT_NAME does not end with '/', which would make dirname() fail |
902 | $res = dirname($_SERVER['SCRIPT_NAME'].'index.php'); // This fake 'index.php' ensures that SCRIPT_NAME does not end with '/', which would make dirname() fail |
903 | for ($i=0; $i<$steps_up; $i++) { |
903 | for ($i=0; $i<$steps_up; $i++) { |
904 | $res = dirname($res); |
904 | $res = dirname($res); |
905 | } |
905 | } |
906 | $res = str_replace('\\', '/', $res); |
906 | $res = str_replace('\\', '/', $res); |
907 | if ($res == '/') $res = ''; |
907 | if ($res == '/') $res = ''; |
908 | $res .= '/'; |
908 | $res .= '/'; |
909 | 909 | ||
910 | // Do we want to have an absolute URI? |
910 | // Do we want to have an absolute URI? |
911 | if (!$relative) { |
911 | if (!$relative) { |
912 | $is_ssl = self::isSSL(); |
912 | $is_ssl = self::isSSL(); |
913 | $protocol = $is_ssl ? 'https' : 'http'; // do not translate |
913 | $protocol = $is_ssl ? 'https' : 'http'; // do not translate |
914 | $host = $_SERVER['HTTP_HOST']; // includes port if it is not 80/443 |
914 | $host = $_SERVER['HTTP_HOST']; // includes port if it is not 80/443 |
915 | $res = $protocol.'://'.$host.$res; |
915 | $res = $protocol.'://'.$host.$res; |
916 | } |
916 | } |
917 | 917 | ||
918 | return $res; |
918 | return $res; |
919 | } |
919 | } |
920 | } |
920 | } |
921 | 921 | ||
922 | private static $system_id_cache = null; |
922 | private static $system_id_cache = null; |
923 | public static function getSystemId($oid=false) { |
923 | public static function getSystemId($oid=false) { |
924 | if (!is_null(self::$system_id_cache)) { |
924 | if (!is_null(self::$system_id_cache)) { |
925 | $out = self::$system_id_cache; |
925 | $out = self::$system_id_cache; |
926 | } else { |
926 | } else { |
927 | $out = false; |
927 | $out = false; |
928 | 928 | ||
929 | if (self::getPkiStatus(true)) { |
929 | if (self::getPkiStatus(true)) { |
930 | $pubKey = OIDplus::config()->getValue('oidplus_public_key'); |
930 | $pubKey = OIDplus::config()->getValue('oidplus_public_key'); |
931 | $m = array(); |
931 | $m = array(); |
932 | if (preg_match('@BEGIN PUBLIC KEY\-+(.+)\-+END PUBLIC KEY@ismU', $pubKey, $m)) { |
932 | if (preg_match('@BEGIN PUBLIC KEY\-+(.+)\-+END PUBLIC KEY@ismU', $pubKey, $m)) { |
933 | $out = smallhash(base64_decode($m[1])); |
933 | $out = smallhash(base64_decode($m[1])); |
934 | } |
934 | } |
935 | } |
935 | } |
936 | self::$system_id_cache = $out; |
936 | self::$system_id_cache = $out; |
937 | } |
937 | } |
938 | if (!$out) return false; |
938 | if (!$out) return false; |
939 | return ($oid ? '1.3.6.1.4.1.37476.30.9.' : '').$out; |
939 | return ($oid ? '1.3.6.1.4.1.37476.30.9.' : '').$out; |
940 | } |
940 | } |
941 | 941 | ||
942 | public static function getPkiStatus($try_generate=true) { |
942 | public static function getPkiStatus($try_generate=true) { |
943 | if (!function_exists('openssl_pkey_new')) return false; |
943 | if (!function_exists('openssl_pkey_new')) return false; |
944 | 944 | ||
945 | $privKey = OIDplus::config()->getValue('oidplus_private_key'); |
945 | $privKey = OIDplus::config()->getValue('oidplus_private_key'); |
946 | $pubKey = OIDplus::config()->getValue('oidplus_public_key'); |
946 | $pubKey = OIDplus::config()->getValue('oidplus_public_key'); |
947 | 947 | ||
948 | if ($try_generate && !verify_private_public_key($privKey, $pubKey)) { |
948 | if ($try_generate && !verify_private_public_key($privKey, $pubKey)) { |
949 | $pkey_config = array( |
949 | $pkey_config = array( |
950 | "digest_alg" => "sha512", |
950 | "digest_alg" => "sha512", |
951 | "private_key_bits" => 2048, |
951 | "private_key_bits" => 2048, |
952 | "private_key_type" => OPENSSL_KEYTYPE_RSA, |
952 | "private_key_type" => OPENSSL_KEYTYPE_RSA, |
953 | ); |
953 | ); |
954 | 954 | ||
955 | // Create the private and public key |
955 | // Create the private and public key |
956 | $res = openssl_pkey_new($pkey_config); |
956 | $res = openssl_pkey_new($pkey_config); |
957 | 957 | ||
958 | if (!$res) return false; |
958 | if (!$res) return false; |
959 | 959 | ||
960 | // Extract the private key from $res to $privKey |
960 | // Extract the private key from $res to $privKey |
961 | openssl_pkey_export($res, $privKey); |
961 | openssl_pkey_export($res, $privKey); |
962 | 962 | ||
963 | // Extract the public key from $res to $pubKey |
963 | // Extract the public key from $res to $pubKey |
964 | $pubKey = openssl_pkey_get_details($res)["key"]; |
964 | $pubKey = openssl_pkey_get_details($res)["key"]; |
965 | 965 | ||
966 | // Log |
966 | // Log |
967 | OIDplus::logger()->log("[INFO]A!", "Generating new SystemID using a new key pair"); |
967 | OIDplus::logger()->log("[INFO]A!", "Generating new SystemID using a new key pair"); |
968 | 968 | ||
969 | // Save the key pair to database |
969 | // Save the key pair to database |
970 | OIDplus::config()->setValue('oidplus_private_key', $privKey); |
970 | OIDplus::config()->setValue('oidplus_private_key', $privKey); |
971 | OIDplus::config()->setValue('oidplus_public_key', $pubKey); |
971 | OIDplus::config()->setValue('oidplus_public_key', $pubKey); |
972 | 972 | ||
973 | // Log the new system ID |
973 | // Log the new system ID |
974 | $m = array(); |
974 | $m = array(); |
975 | if (preg_match('@BEGIN PUBLIC KEY\-+(.+)\-+END PUBLIC KEY@ismU', $pubKey, $m)) { |
975 | if (preg_match('@BEGIN PUBLIC KEY\-+(.+)\-+END PUBLIC KEY@ismU', $pubKey, $m)) { |
976 | $system_id = smallhash(base64_decode($m[1])); |
976 | $system_id = smallhash(base64_decode($m[1])); |
977 | OIDplus::logger()->log("[INFO]A!", "Your SystemID is now $system_id"); |
977 | OIDplus::logger()->log("[INFO]A!", "Your SystemID is now $system_id"); |
978 | } |
978 | } |
979 | } |
979 | } |
980 | 980 | ||
981 | return verify_private_public_key($privKey, $pubKey); |
981 | return verify_private_public_key($privKey, $pubKey); |
982 | } |
982 | } |
983 | 983 | ||
984 | public static function getInstallType() { |
984 | public static function getInstallType() { |
985 | $counter = 0; |
985 | $counter = 0; |
986 | 986 | ||
987 | if ($new_version_file_exists = file_exists(OIDplus::localpath().'.version.php')) { |
987 | if ($new_version_file_exists = file_exists(OIDplus::localpath().'.version.php')) { |
988 | $counter++; |
988 | $counter++; |
989 | } |
989 | } |
990 | if ($old_version_file_exists = file_exists(OIDplus::localpath().'oidplus_version.txt')) { |
990 | if ($old_version_file_exists = file_exists(OIDplus::localpath().'oidplus_version.txt')) { |
991 | $counter++; |
991 | $counter++; |
992 | } |
992 | } |
993 | $version_file_exists = $old_version_file_exists | $new_version_file_exists; |
993 | $version_file_exists = $old_version_file_exists | $new_version_file_exists; |
994 | if ($svn_dir_exists = (is_dir(OIDplus::localpath().'.svn') || |
994 | if ($svn_dir_exists = (is_dir(OIDplus::localpath().'.svn') || |
995 | is_dir(OIDplus::localpath().'../.svn'))) { // in case we checked out the root instead of the "trunk" |
995 | is_dir(OIDplus::localpath().'../.svn'))) { // in case we checked out the root instead of the "trunk" |
996 | $counter++; |
996 | $counter++; |
997 | } |
997 | } |
998 | // if ($git_dir_exists = is_dir(OIDplus::localpath().'.git')) { |
998 | // if ($git_dir_exists = is_dir(OIDplus::localpath().'.git')) { |
999 | if ($git_dir_exists = (OIDplus::findGitFolder() !== false)) { |
999 | if ($git_dir_exists = (OIDplus::findGitFolder() !== false)) { |
1000 | $counter++; |
1000 | $counter++; |
1001 | } |
1001 | } |
1002 | 1002 | ||
1003 | if ($counter === 0) { |
1003 | if ($counter === 0) { |
1004 | return 'unknown'; // do not translate |
1004 | return 'unknown'; // do not translate |
1005 | } |
1005 | } |
1006 | else if ($counter > 1) { |
1006 | else if ($counter > 1) { |
1007 | return 'ambigous'; // do not translate |
1007 | return 'ambigous'; // do not translate |
1008 | } |
1008 | } |
1009 | else if ($svn_dir_exists) { |
1009 | else if ($svn_dir_exists) { |
1010 | return 'svn-wc'; // do not translate |
1010 | return 'svn-wc'; // do not translate |
1011 | } |
1011 | } |
1012 | else if ($git_dir_exists) { |
1012 | else if ($git_dir_exists) { |
1013 | return 'git-wc'; // do not translate |
1013 | return 'git-wc'; // do not translate |
1014 | } |
1014 | } |
1015 | else if ($version_file_exists) { |
1015 | else if ($version_file_exists) { |
1016 | return 'svn-snapshot'; // do not translate |
1016 | return 'svn-snapshot'; // do not translate |
1017 | } |
1017 | } |
1018 | } |
1018 | } |
1019 | 1019 | ||
1020 | private static function recognizeVersion() { |
1020 | private static function recognizeVersion() { |
1021 | try { |
1021 | try { |
1022 | $ver_prev = OIDplus::config()->getValue("last_known_version"); |
1022 | $ver_prev = OIDplus::config()->getValue("last_known_version"); |
1023 | $ver_now = OIDplus::getVersion(); |
1023 | $ver_now = OIDplus::getVersion(); |
1024 | if (($ver_now != '') && ($ver_prev != '') && ($ver_now != $ver_prev)) { |
1024 | if (($ver_now != '') && ($ver_prev != '') && ($ver_now != $ver_prev)) { |
1025 | // TODO: Problem: When the system was updated using SVN, then the IP address of the next random visitor of the website is logged! |
1025 | // TODO: Problem: When the system was updated using SVN, then the IP address of the next random visitor of the website is logged! |
1026 | OIDplus::logger()->log("[INFO]A!", "System version changed from '$ver_prev' to '$ver_now'"); |
1026 | OIDplus::logger()->log("[INFO]A!", "System version changed from '$ver_prev' to '$ver_now'"); |
1027 | } |
1027 | } |
1028 | OIDplus::config()->setValue("last_known_version", $ver_now); |
1028 | OIDplus::config()->setValue("last_known_version", $ver_now); |
1029 | } catch (Exception $e) { |
1029 | } catch (Exception $e) { |
1030 | } |
1030 | } |
1031 | } |
1031 | } |
1032 | 1032 | ||
1033 | public static function getVersion() { |
1033 | public static function getVersion() { |
1034 | static $cachedVersion = null; |
1034 | static $cachedVersion = null; |
1035 | if (!is_null($cachedVersion)) { |
1035 | if (!is_null($cachedVersion)) { |
1036 | return $cachedVersion; |
1036 | return $cachedVersion; |
1037 | } |
1037 | } |
1038 | 1038 | ||
1039 | $installType = OIDplus::getInstallType(); |
1039 | $installType = OIDplus::getInstallType(); |
1040 | 1040 | ||
1041 | if ($installType === 'svn-wc') { |
1041 | if ($installType === 'svn-wc') { |
1042 | $ver = get_svn_revision(OIDplus::localpath()); |
1042 | $ver = get_svn_revision(OIDplus::localpath()); |
1043 | if ($ver) |
1043 | if ($ver) |
1044 | return ($cachedVersion = 'svn-'.$ver); |
1044 | return ($cachedVersion = 'svn-'.$ver); |
1045 | $ver = get_svn_revision(OIDplus::localpath().'../'); // in case we checked out the root instead of the "trunk" |
1045 | $ver = get_svn_revision(OIDplus::localpath().'../'); // in case we checked out the root instead of the "trunk" |
1046 | if ($ver) |
1046 | if ($ver) |
1047 | return ($cachedVersion = 'svn-'.$ver); |
1047 | return ($cachedVersion = 'svn-'.$ver); |
1048 | } |
1048 | } |
1049 | 1049 | ||
1050 | if ($installType === 'git-wc') { |
1050 | if ($installType === 'git-wc') { |
1051 | $ver = OIDplus::getGitsvnRevision(OIDplus::localpath()); |
1051 | $ver = OIDplus::getGitsvnRevision(OIDplus::localpath()); |
1052 | if ($ver) |
1052 | if ($ver) |
1053 | return ($cachedVersion = 'svn-'.$ver); |
1053 | return ($cachedVersion = 'svn-'.$ver); |
1054 | } |
1054 | } |
1055 | 1055 | ||
1056 | if ($installType === 'svn-snapshot') { |
1056 | if ($installType === 'svn-snapshot') { |
1057 | $cont = ''; |
1057 | $cont = ''; |
1058 | if (file_exists($filename = OIDplus::localpath().'oidplus_version.txt')) |
1058 | if (file_exists($filename = OIDplus::localpath().'oidplus_version.txt')) |
1059 | $cont = file_get_contents($filename); |
1059 | $cont = file_get_contents($filename); |
1060 | if (file_exists($filename = OIDplus::localpath().'.version.php')) |
1060 | if (file_exists($filename = OIDplus::localpath().'.version.php')) |
1061 | $cont = file_get_contents($filename); |
1061 | $cont = file_get_contents($filename); |
1062 | $m = array(); |
1062 | $m = array(); |
1063 | if (preg_match('@Revision (\d+)@', $cont, $m)) // do not translate |
1063 | if (preg_match('@Revision (\d+)@', $cont, $m)) // do not translate |
1064 | return ($cachedVersion = 'svn-'.$m[1]); // do not translate |
1064 | return ($cachedVersion = 'svn-'.$m[1]); // do not translate |
1065 | } |
1065 | } |
1066 | 1066 | ||
1067 | return ($cachedVersion = false); // version ambigous or unknown |
1067 | return ($cachedVersion = false); // version ambigous or unknown |
1068 | } |
1068 | } |
1069 | 1069 | ||
1070 | private static $sslAvailableCache = null; |
1070 | private static $sslAvailableCache = null; |
1071 | public static function isSslAvailable() { |
1071 | public static function isSslAvailable() { |
1072 | if (!is_null(self::$sslAvailableCache)) return self::$sslAvailableCache; |
1072 | if (!is_null(self::$sslAvailableCache)) return self::$sslAvailableCache; |
1073 | 1073 | ||
1074 | if (PHP_SAPI == 'cli') { |
1074 | if (PHP_SAPI == 'cli') { |
1075 | self::$sslAvailableCache = false; |
1075 | self::$sslAvailableCache = false; |
1076 | return false; |
1076 | return false; |
1077 | } |
1077 | } |
1078 | 1078 | ||
1079 | $timeout = 2; |
1079 | $timeout = 2; |
1080 | $already_ssl = self::isSSL(); |
1080 | $already_ssl = self::isSSL(); |
1081 | $ssl_port = 443; |
1081 | $ssl_port = 443; |
1082 | 1082 | ||
1083 | $mode = OIDplus::baseConfig()->getValue('ENFORCE_SSL', 2/*auto*/); |
1083 | $mode = OIDplus::baseConfig()->getValue('ENFORCE_SSL', 2/*auto*/); |
1084 | 1084 | ||
1085 | if ($mode == 0) { |
1085 | if ($mode == 0) { |
1086 | // No SSL available |
1086 | // No SSL available |
1087 | self::$sslAvailableCache = $already_ssl; |
1087 | self::$sslAvailableCache = $already_ssl; |
1088 | return $already_ssl; |
1088 | return $already_ssl; |
1089 | } |
1089 | } |
1090 | 1090 | ||
1091 | if ($mode == 1) { |
1091 | if ($mode == 1) { |
1092 | // Force SSL |
1092 | // Force SSL |
1093 | if ($already_ssl) { |
1093 | if ($already_ssl) { |
1094 | self::$sslAvailableCache = true; |
1094 | self::$sslAvailableCache = true; |
1095 | return true; |
1095 | return true; |
1096 | } else { |
1096 | } else { |
1097 | $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; |
1097 | $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; |
1098 | header('Location:'.$location); |
1098 | header('Location:'.$location); |
1099 | die(_L('Redirecting to HTTPS...')); |
1099 | die(_L('Redirecting to HTTPS...')); |
1100 | #self::$sslAvailableCache = true; |
1100 | #self::$sslAvailableCache = true; |
1101 | #return true; |
1101 | #return true; |
1102 | } |
1102 | } |
1103 | } |
1103 | } |
1104 | 1104 | ||
1105 | if ($mode == 2) { |
1105 | if ($mode == 2) { |
1106 | // Automatic SSL detection |
1106 | // Automatic SSL detection |
1107 | 1107 | ||
1108 | if ($already_ssl) { |
1108 | if ($already_ssl) { |
1109 | // we are already on HTTPS |
1109 | // we are already on HTTPS |
1110 | OIDplus::cookieUtils()->setcookie('SSL_CHECK', '1', 0, false); |
1110 | OIDplus::cookieUtils()->setcookie('SSL_CHECK', '1', 0, false); |
1111 | self::$sslAvailableCache = true; |
1111 | self::$sslAvailableCache = true; |
1112 | return true; |
1112 | return true; |
1113 | } else { |
1113 | } else { |
1114 | if (isset($_COOKIE['SSL_CHECK'])) { |
1114 | if (isset($_COOKIE['SSL_CHECK'])) { |
1115 | // We already had the HTTPS detection done before. |
1115 | // We already had the HTTPS detection done before. |
1116 | if ($_COOKIE['SSL_CHECK']) { |
1116 | if ($_COOKIE['SSL_CHECK']) { |
1117 | // HTTPS was detected before, but we are HTTP. Redirect now |
1117 | // HTTPS was detected before, but we are HTTP. Redirect now |
1118 | $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; |
1118 | $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; |
1119 | header('Location:'.$location); |
1119 | header('Location:'.$location); |
1120 | die(_L('Redirecting to HTTPS...')); |
1120 | die(_L('Redirecting to HTTPS...')); |
1121 | #self::$sslAvailableCache = true; |
1121 | #self::$sslAvailableCache = true; |
1122 | #return true; |
1122 | #return true; |
1123 | } else { |
1123 | } else { |
1124 | // No HTTPS available. Do nothing. |
1124 | // No HTTPS available. Do nothing. |
1125 | self::$sslAvailableCache = false; |
1125 | self::$sslAvailableCache = false; |
1126 | return false; |
1126 | return false; |
1127 | } |
1127 | } |
1128 | } else { |
1128 | } else { |
1129 | // This is our first check (or the browser didn't accept the SSL_CHECK cookie) |
1129 | // This is our first check (or the browser didn't accept the SSL_CHECK cookie) |
1130 | $errno = -1; |
1130 | $errno = -1; |
1131 | $errstr = ''; |
1131 | $errstr = ''; |
1132 | if (@fsockopen($_SERVER['HTTP_HOST'], $ssl_port, $errno, $errstr, $timeout)) { |
1132 | if (@fsockopen($_SERVER['HTTP_HOST'], $ssl_port, $errno, $errstr, $timeout)) { |
1133 | // HTTPS detected. Redirect now, and remember that we had detected HTTPS |
1133 | // HTTPS detected. Redirect now, and remember that we had detected HTTPS |
1134 | OIDplus::cookieUtils()->setcookie('SSL_CHECK', '1', 0, false); |
1134 | OIDplus::cookieUtils()->setcookie('SSL_CHECK', '1', 0, false); |
1135 | $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; |
1135 | $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; |
1136 | header('Location:'.$location); |
1136 | header('Location:'.$location); |
1137 | die(_L('Redirecting to HTTPS...')); |
1137 | die(_L('Redirecting to HTTPS...')); |
1138 | #self::$sslAvailableCache = true; |
1138 | #self::$sslAvailableCache = true; |
1139 | #return true; |
1139 | #return true; |
1140 | } else { |
1140 | } else { |
1141 | // No HTTPS detected. Do nothing, and next time, don't try to detect HTTPS again. |
1141 | // No HTTPS detected. Do nothing, and next time, don't try to detect HTTPS again. |
1142 | OIDplus::cookieUtils()->setcookie('SSL_CHECK', '0', 0, false); |
1142 | OIDplus::cookieUtils()->setcookie('SSL_CHECK', '0', 0, false); |
1143 | self::$sslAvailableCache = false; |
1143 | self::$sslAvailableCache = false; |
1144 | return false; |
1144 | return false; |
1145 | } |
1145 | } |
1146 | } |
1146 | } |
1147 | } |
1147 | } |
1148 | } |
1148 | } |
1149 | } |
1149 | } |
1150 | 1150 | ||
1151 | /** |
1151 | /** |
1152 | * Gets a local path pointing to a resource |
1152 | * Gets a local path pointing to a resource |
1153 | * @param string $target Target resource (file or directory must exist), or null to get the OIDplus base directory |
1153 | * @param string $target Target resource (file or directory must exist), or null to get the OIDplus base directory |
1154 | * @param boolean $relative If true, the returning path is relative to the currently executed PHP file (not the CLI working directory) |
1154 | * @param boolean $relative If true, the returning path is relative to the currently executed PHP file (not the CLI working directory) |
1155 | * @return string|false The local path, with guaranteed trailing path delimiter for directories |
1155 | * @return string|false The local path, with guaranteed trailing path delimiter for directories |
1156 | */ |
1156 | */ |
1157 | public static function localpath($target=null, $relative=false) { |
1157 | public static function localpath($target=null, $relative=false) { |
1158 | if (is_null($target)) { |
1158 | if (is_null($target)) { |
1159 | $target = __DIR__.'/../../'; |
1159 | $target = __DIR__.'/../../'; |
1160 | } |
1160 | } |
1161 | 1161 | ||
1162 | if ($relative) { |
1162 | if ($relative) { |
1163 | // First, try to find out how many levels we need to go up |
1163 | // First, try to find out how many levels we need to go up |
1164 | $steps_up = self::getExecutingScriptPathDepth(); |
1164 | $steps_up = self::getExecutingScriptPathDepth(); |
1165 | if ($steps_up === false) return false; |
1165 | if ($steps_up === false) return false; |
1166 | 1166 | ||
1167 | // Virtually go back from the executing PHP script to the OIDplus base path |
1167 | // Virtually go back from the executing PHP script to the OIDplus base path |
1168 | $res = str_repeat('../',$steps_up); |
1168 | $res = str_repeat('../',$steps_up); |
1169 | 1169 | ||
1170 | // Then go to the desired location |
1170 | // Then go to the desired location |
1171 | $basedir = realpath(__DIR__.'/../../'); |
1171 | $basedir = realpath(__DIR__.'/../../'); |
1172 | $target = realpath($target); |
1172 | $target = realpath($target); |
1173 | if ($target === false) return false; |
1173 | if ($target === false) return false; |
1174 | $res .= substr($target, strlen($basedir)+1); |
1174 | $res .= substr($target, strlen($basedir)+1); |
1175 | $res = rtrim($res,'/'); // avoid '..//' for localpath(null,true) |
1175 | $res = rtrim($res,'/'); // avoid '..//' for localpath(null,true) |
1176 | } else { |
1176 | } else { |
1177 | $res = realpath($target); |
1177 | $res = realpath($target); |
1178 | } |
1178 | } |
1179 | 1179 | ||
1180 | if (is_dir($target)) $res .= DIRECTORY_SEPARATOR; |
1180 | if (is_dir($target)) $res .= DIRECTORY_SEPARATOR; |
1181 | 1181 | ||
1182 | return $res; |
1182 | return $res; |
1183 | } |
1183 | } |
1184 | 1184 | ||
1185 | /** |
1185 | /** |
1186 | * Gets a URL pointing to a resource |
1186 | * Gets a URL pointing to a resource |
1187 | * @param string $target Target resource (file or directory must exist), or null to get the OIDplus base directory |
1187 | * @param string $target Target resource (file or directory must exist), or null to get the OIDplus base directory |
1188 | * @param boolean $relative If true, the returning path is relative to the currently executed PHP script (i.e. index.php , not the plugin PHP script!) |
1188 | * @param boolean $relative If true, the returning path is relative to the currently executed PHP script (i.e. index.php , not the plugin PHP script!) |
1189 | * @return string|false The URL, with guaranteed trailing path delimiter for directories |
1189 | * @return string|false The URL, with guaranteed trailing path delimiter for directories |
1190 | */ |
1190 | */ |
1191 | public static function webpath($target=null, $relative=false) { |
1191 | public static function webpath($target=null, $relative=false) { |
1192 | $res = self::getSystemUrl($relative); // Note: already contains a trailing path delimiter |
1192 | $res = self::getSystemUrl($relative); // Note: already contains a trailing path delimiter |
1193 | if (!$res) return false; |
1193 | if (!$res) return false; |
1194 | 1194 | ||
1195 | if (!is_null($target)) { |
1195 | if (!is_null($target)) { |
1196 | $basedir = realpath(__DIR__.'/../../'); |
1196 | $basedir = realpath(__DIR__.'/../../'); |
1197 | $target = realpath($target); |
1197 | $target = realpath($target); |
1198 | if ($target === false) return false; |
1198 | if ($target === false) return false; |
1199 | $tmp = substr($target, strlen($basedir)+1); |
1199 | $tmp = substr($target, strlen($basedir)+1); |
1200 | $res .= str_replace(DIRECTORY_SEPARATOR,'/',$tmp); // remove OS specific path delimiters introduced by realpath() |
1200 | $res .= str_replace(DIRECTORY_SEPARATOR,'/',$tmp); // remove OS specific path delimiters introduced by realpath() |
1201 | if (is_dir($target)) $res .= '/'; |
1201 | if (is_dir($target)) $res .= '/'; |
1202 | } |
1202 | } |
1203 | 1203 | ||
1204 | return $res; |
1204 | return $res; |
1205 | } |
1205 | } |
1206 | 1206 | ||
1207 | private static $shutdown_functions = array(); |
1207 | private static $shutdown_functions = array(); |
1208 | public static function register_shutdown_function($func) { |
1208 | public static function register_shutdown_function($func) { |
1209 | self::$shutdown_functions[] = $func; |
1209 | self::$shutdown_functions[] = $func; |
1210 | } |
1210 | } |
1211 | 1211 | ||
1212 | public static function invoke_shutdown() { |
1212 | public static function invoke_shutdown() { |
1213 | foreach (self::$shutdown_functions as $func) { |
1213 | foreach (self::$shutdown_functions as $func) { |
1214 | $func(); |
1214 | $func(); |
1215 | } |
1215 | } |
1216 | } |
1216 | } |
1217 | 1217 | ||
1218 | public static function getAvailableLangs() { |
1218 | public static function getAvailableLangs() { |
1219 | $langs = array(); |
1219 | $langs = array(); |
1220 | foreach (OIDplus::getAllPluginManifests('language') as $pluginManifest) { |
1220 | foreach (OIDplus::getAllPluginManifests('language') as $pluginManifest) { |
1221 | $code = $pluginManifest->getLanguageCode(); |
1221 | $code = $pluginManifest->getLanguageCode(); |
1222 | $langs[] = $code; |
1222 | $langs[] = $code; |
1223 | } |
1223 | } |
1224 | return $langs; |
1224 | return $langs; |
1225 | } |
1225 | } |
1226 | 1226 | ||
1227 | public static function getCurrentLang() { |
1227 | public static function getCurrentLang() { |
1228 | if (isset($_GET['lang'])) { |
1228 | if (isset($_GET['lang'])) { |
1229 | $lang = $_GET['lang']; |
1229 | $lang = $_GET['lang']; |
1230 | } else if (isset($_POST['lang'])) { |
1230 | } else if (isset($_POST['lang'])) { |
1231 | $lang = $_POST['lang']; |
1231 | $lang = $_POST['lang']; |
1232 | } else if (isset($_COOKIE['LANGUAGE'])) { |
1232 | } else if (isset($_COOKIE['LANGUAGE'])) { |
1233 | $lang = $_COOKIE['LANGUAGE']; |
1233 | $lang = $_COOKIE['LANGUAGE']; |
1234 | } else { |
1234 | } else { |
1235 | $lang = self::DEFAULT_LANGUAGE; |
1235 | $lang = self::DEFAULT_LANGUAGE; |
1236 | } |
1236 | } |
1237 | $lang = substr(preg_replace('@[^a-z]@ismU', '', $lang),0,4); // sanitize |
1237 | $lang = substr(preg_replace('@[^a-z]@ismU', '', $lang),0,4); // sanitize |
1238 | return $lang; |
1238 | return $lang; |
1239 | } |
1239 | } |
1240 | 1240 | ||
1241 | public static function handleLangArgument() { |
1241 | public static function handleLangArgument() { |
1242 | if (isset($_GET['lang'])) { |
1242 | if (isset($_GET['lang'])) { |
1243 | // The "?lang=" argument is only for NoScript-Browsers/SearchEngines |
1243 | // The "?lang=" argument is only for NoScript-Browsers/SearchEngines |
1244 | // In case someone who has JavaScript clicks a ?lang= link, they should get |
1244 | // In case someone who has JavaScript clicks a ?lang= link, they should get |
1245 | // the page in that language, but the cookie must be set, otherwise |
1245 | // the page in that language, but the cookie must be set, otherwise |
1246 | // the menu and other stuff would be in their cookie-based-language and not the |
1246 | // the menu and other stuff would be in their cookie-based-language and not the |
1247 | // argument-based-language. |
1247 | // argument-based-language. |
1248 | OIDplus::cookieUtils()->setcookie('LANGUAGE', $_GET['lang'], 0, true/*HttpOnly off, because JavaScript also needs translation*/); |
1248 | OIDplus::cookieUtils()->setcookie('LANGUAGE', $_GET['lang'], 0, true/*HttpOnly off, because JavaScript also needs translation*/); |
1249 | } else if (isset($_POST['lang'])) { |
1249 | } else if (isset($_POST['lang'])) { |
1250 | OIDplus::cookieUtils()->setcookie('LANGUAGE', $_POST['lang'], 0, true/*HttpOnly off, because JavaScript also needs translation*/); |
1250 | OIDplus::cookieUtils()->setcookie('LANGUAGE', $_POST['lang'], 0, true/*HttpOnly off, because JavaScript also needs translation*/); |
1251 | } |
1251 | } |
1252 | } |
1252 | } |
1253 | 1253 | ||
1254 | private static $translationArray = array(); |
1254 | private static $translationArray = array(); |
1255 | protected static function getTranslationFileContents($translation_file) { |
1255 | protected static function getTranslationFileContents($translation_file) { |
1256 | // First, try the cache |
1256 | // First, try the cache |
1257 | $cache_file = __DIR__ . '/../../userdata/cache/translation_'.md5($translation_file).'.ser'; |
1257 | $cache_file = __DIR__ . '/../../userdata/cache/translation_'.md5($translation_file).'.ser'; |
1258 | if (file_exists($cache_file) && (filemtime($cache_file) == filemtime($translation_file))) { |
1258 | if (file_exists($cache_file) && (filemtime($cache_file) == filemtime($translation_file))) { |
1259 | $cac = @unserialize(file_get_contents($cache_file)); |
1259 | $cac = @unserialize(file_get_contents($cache_file)); |
1260 | if ($cac) return $cac; |
1260 | if ($cac) return $cac; |
1261 | } |
1261 | } |
1262 | 1262 | ||
1263 | // If not successful, then load the XML file |
1263 | // If not successful, then load the XML file |
1264 | $xml = @simplexml_load_string(file_get_contents($translation_file)); |
1264 | $xml = @simplexml_load_string(file_get_contents($translation_file)); |
1265 | if (!$xml) return array(); // if there is an UTF-8 or parsing error, don't output any errors, otherwise the JavaScript is corrupt and the page won't render correctly |
1265 | if (!$xml) return array(); // if there is an UTF-8 or parsing error, don't output any errors, otherwise the JavaScript is corrupt and the page won't render correctly |
1266 | $cac = array(); |
1266 | $cac = array(); |
1267 | foreach ($xml->message as $msg) { |
1267 | foreach ($xml->message as $msg) { |
1268 | $src = trim($msg->source->__toString()); |
1268 | $src = trim($msg->source->__toString()); |
1269 | $dst = trim($msg->target->__toString()); |
1269 | $dst = trim($msg->target->__toString()); |
1270 | $cac[$src] = $dst; |
1270 | $cac[$src] = $dst; |
1271 | } |
1271 | } |
1272 | @file_put_contents($cache_file,serialize($cac)); |
1272 | @file_put_contents($cache_file,serialize($cac)); |
1273 | @touch($cache_file,filemtime($translation_file)); |
1273 | @touch($cache_file,filemtime($translation_file)); |
1274 | return $cac; |
1274 | return $cac; |
1275 | } |
1275 | } |
1276 | public static function getTranslationArray($requested_lang='*') { |
1276 | public static function getTranslationArray($requested_lang='*') { |
1277 | foreach (OIDplus::getAllPluginManifests('language') as $pluginManifest) { |
1277 | foreach (OIDplus::getAllPluginManifests('language') as $pluginManifest) { |
1278 | $lang = $pluginManifest->getLanguageCode(); |
1278 | $lang = $pluginManifest->getLanguageCode(); |
1279 | if (strpos($lang,'/') !== false) continue; // just to be sure |
1279 | if (strpos($lang,'/') !== false) continue; // just to be sure |
1280 | if (strpos($lang,'\\') !== false) continue; // just to be sure |
1280 | if (strpos($lang,'\\') !== false) continue; // just to be sure |
1281 | if (strpos($lang,'..') !== false) continue; // just to be sure |
1281 | if (strpos($lang,'..') !== false) continue; // just to be sure |
1282 | 1282 | ||
1283 | if (($requested_lang != '*') && ($lang != $requested_lang)) continue; |
1283 | if (($requested_lang != '*') && ($lang != $requested_lang)) continue; |
1284 | 1284 | ||
1285 | if (!isset(self::$translationArray[$lang])) { |
1285 | if (!isset(self::$translationArray[$lang])) { |
1286 | self::$translationArray[$lang] = array(); |
1286 | self::$translationArray[$lang] = array(); |
1287 | 1287 | ||
1288 | $wildcard = $pluginManifest->getLanguageMessages(); |
1288 | $wildcard = $pluginManifest->getLanguageMessages(); |
1289 | if (strpos($wildcard,'/') !== false) continue; // just to be sure |
1289 | if (strpos($wildcard,'/') !== false) continue; // just to be sure |
1290 | if (strpos($wildcard,'\\') !== false) continue; // just to be sure |
1290 | if (strpos($wildcard,'\\') !== false) continue; // just to be sure |
1291 | if (strpos($wildcard,'..') !== false) continue; // just to be sure |
1291 | if (strpos($wildcard,'..') !== false) continue; // just to be sure |
1292 | 1292 | ||
1293 | $translation_files = glob(__DIR__.'/../../plugins/'.'*'.'/language/'.$lang.'/'.$wildcard); |
1293 | $translation_files = glob(__DIR__.'/../../plugins/'.'*'.'/language/'.$lang.'/'.$wildcard); |
1294 | sort($translation_files); |
1294 | sort($translation_files); |
1295 | foreach ($translation_files as $translation_file) { |
1295 | foreach ($translation_files as $translation_file) { |
1296 | if (!file_exists($translation_file)) continue; |
1296 | if (!file_exists($translation_file)) continue; |
1297 | $cac = self::getTranslationFileContents($translation_file); |
1297 | $cac = self::getTranslationFileContents($translation_file); |
1298 | foreach ($cac as $src => $dst) { |
1298 | foreach ($cac as $src => $dst) { |
1299 | self::$translationArray[$lang][$src] = $dst; |
1299 | self::$translationArray[$lang][$src] = $dst; |
1300 | } |
1300 | } |
1301 | } |
1301 | } |
1302 | } |
1302 | } |
1303 | } |
1303 | } |
1304 | return self::$translationArray; |
1304 | return self::$translationArray; |
1305 | } |
1305 | } |
1306 | 1306 | ||
- | 1307 | public static function getEditionInfo() { |
|
- | 1308 | return @parse_ini_file(__DIR__.'/../edition.ini', true)['Edition']; |
|
- | 1309 | } |
|
- | 1310 | ||
1307 | public static function findGitFolder() { |
1311 | public static function findGitFolder() { |
1308 | // Git command line saves git information in folder ".git" |
1312 | // Git command line saves git information in folder ".git" |
1309 | // Plesk git saves git information in folder "../../../git/oidplus/" (or similar) |
1313 | // Plesk git saves git information in folder "../../../git/oidplus/" (or similar) |
1310 | $dir = realpath(__DIR__); |
1314 | $dir = realpath(__DIR__); |
1311 | if (is_dir($dir.'/.git')) return $dir.'/.git'; |
1315 | if (is_dir($dir.'/.git')) return $dir.'/.git'; |
1312 | $i = 0; |
1316 | $i = 0; |
1313 | do { |
1317 | do { |
1314 | if (is_dir($dir.'/git')) { |
1318 | if (is_dir($dir.'/git')) { |
1315 | $confs = glob($dir.'/git/'.'*'.'/config'); |
1319 | $confs = glob($dir.'/git/'.'*'.'/config'); |
1316 | foreach ($confs as $conf) { |
1320 | foreach ($confs as $conf) { |
1317 | $cont = file_get_contents($conf); |
1321 | $cont = file_get_contents($conf); |
1318 | if (strpos($cont, '://github.com/danielmarschall/oidplus') !== false) { |
1322 | if (isset(OIDplus::getEditionInfo()['gitrepo']) && (OIDplus::getEditionInfo()['gitrepo'] != '') && (strpos($cont, OIDplus::getEditionInfo()['gitrepo']) !== false)) { |
1319 | return dirname($conf); |
1323 | return dirname($conf); |
1320 | } |
1324 | } |
1321 | } |
1325 | } |
1322 | } |
1326 | } |
1323 | $i++; |
1327 | $i++; |
1324 | } while (($i<100) && ($dir != ($new_dir = realpath($dir.'/../'))) && ($dir = $new_dir)); |
1328 | } while (($i<100) && ($dir != ($new_dir = realpath($dir.'/../'))) && ($dir = $new_dir)); |
1325 | return false; |
1329 | return false; |
1326 | } |
1330 | } |
1327 | 1331 | ||
1328 | public static function getGitsvnRevision($dir='') { |
1332 | public static function getGitsvnRevision($dir='') { |
1329 | try { |
1333 | try { |
1330 | // tries command line and binary parsing |
1334 | // tries command line and binary parsing |
1331 | // requires danielmarschall/git_utils.inc.php |
1335 | // requires vendor/danielmarschall/git_utils.inc.php |
1332 | $git_dir = OIDplus::findGitFolder(); |
1336 | $git_dir = OIDplus::findGitFolder(); |
1333 | if ($git_dir === false) return false; |
1337 | if ($git_dir === false) return false; |
1334 | $commit_msg = git_get_latest_commit_message($git_dir); |
1338 | $commit_msg = git_get_latest_commit_message($git_dir); |
1335 | } catch (Exception $e) { |
1339 | } catch (Exception $e) { |
1336 | return false; |
1340 | return false; |
1337 | } |
1341 | } |
1338 | 1342 | ||
1339 | $m = array(); |
1343 | $m = array(); |
1340 | if (preg_match('%git-svn-id: (.+)@(\\d+) %ismU', $commit_msg, $m)) { |
1344 | if (preg_match('%git-svn-id: (.+)@(\\d+) %ismU', $commit_msg, $m)) { |
1341 | return $m[2]; |
1345 | return $m[2]; |
1342 | } else { |
1346 | } else { |
1343 | return false; |
1347 | return false; |
1344 | } |
1348 | } |
1345 | } |
1349 | } |
1346 | 1350 | ||
1347 | } |
1351 | } |
1348 | 1352 |