Subversion Repositories oidplus

Rev

Rev 1049 | Rev 1051 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1049 Rev 1050
Line 15... Line 15...
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
namespace ViaThinkSoft\OIDplus;
21
 
21
 
22
class OIDplus extends OIDplusBaseClass {
22
class OIDplus extends OIDplusBaseClass {
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();
Line 51... Line 51...
51
        );
51
        );
52
 
52
 
53
        private function __construct() {
53
        private function __construct() {
54
        }
54
        }
55
 
55
 
56
        # --- Static classes
56
        // --- Static classes
57
 
57
 
58
        private static $baseConfig = null;
58
        private static $baseConfig = null;
59
        private static $old_config_format = false;
59
        private static $oldConfigFormatLoaded = false;
60
        public static function baseConfig() {
60
        public static function baseConfig() {
61
                $first_init = false;
61
                $first_init = false;
62
 
62
 
63
                if ($first_init = is_null(self::$baseConfig)) {
63
                if ($first_init = is_null(self::$baseConfig)) {
64
                        self::$baseConfig = new OIDplusBaseConfig();
64
                        self::$baseConfig = new OIDplusBaseConfig();
Line 79... Line 79...
79
                        if (!file_exists($config_file) && file_exists($config_file_old)) {
79
                        if (!file_exists($config_file) && file_exists($config_file_old)) {
80
                                $config_file = $config_file_old;
80
                                $config_file = $config_file_old;
81
                        }
81
                        }
82
 
82
 
83
                        if (file_exists($config_file)) {
83
                        if (file_exists($config_file)) {
84
                                if (self::$old_config_format) {
84
                                if (self::$oldConfigFormatLoaded) {
85
                                        // Note: We may only include it once due to backwards compatibility,
85
                                        // Note: We may only include it once due to backwards compatibility,
86
                                        //       since in version 2.0, the configuration was defined using define() statements
86
                                        //       since in version 2.0, the configuration was defined using define() statements
87
                                        // Attention: This does mean that a full re-init (e.g. for test cases) is not possible
87
                                        // Attention: This does mean that a full re-init (e.g. for test cases) is not possible
88
                                        //            if a version 2.0 config is used!
88
                                        //            if a version 2.0 config is used!
-
 
89
 
-
 
90
                                        // We need to do this, because define() cannot be undone
-
 
91
                                        // Note: This can only happen in very special cases (e.g. test cases) where you call init() twice
-
 
92
                                        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.'));
-
 
93
                                } else {
-
 
94
                                        $tmp = file_get_contents($config_file);
-
 
95
                                        $ns = "ViaThinkSoft\OIDplus\OIDplus";
-
 
96
                                        $uses = "use $ns;";
-
 
97
                                        if ((strpos($tmp,'OIDplus::') !== false) && (strpos($tmp,$uses) === false)) {
-
 
98
                                                // Migrate config file to namespace class names
-
 
99
                                                // Note: Only config files version 2.1 are affected. Not 2.0 ones
-
 
100
 
-
 
101
                                                $tmp = "<?php\r\n\r\n$uses /* Automatically added by migration procedure */\r\n?>$tmp";
-
 
102
                                                $tmp = str_replace('?><?php', '', $tmp);
-
 
103
 
-
 
104
                                                $tmp = str_replace("\$ns\OIDplusCaptchaPluginRecaptcha::", "OIDplusCaptchaPluginRecaptcha::", $tmp);
-
 
105
                                                $tmp = str_replace("OIDplusCaptchaPluginRecaptcha::", "\$ns\OIDplusCaptchaPluginRecaptcha::", $tmp);
-
 
106
 
-
 
107
                                                $tmp = str_replace('DISABLE_PLUGIN_OIDplusPagePublicRdap',
-
 
108
                                                                   'DISABLE_PLUGIN_Frdlweb\OIDplus\OIDplusPagePublicRdap', $tmp);
-
 
109
                                                $tmp = str_replace('DISABLE_PLUGIN_OIDplusPagePublicAltIds',
-
 
110
                                                                   'DISABLE_PLUGIN_Frdlweb\OIDplus\OIDplusPagePublicAltIds', $tmp);
-
 
111
                                                $tmp = str_replace('DISABLE_PLUGIN_OIDplus',
-
 
112
                                                                   'DISABLE_PLUGIN_ViaThinkSoft\OIDplus\OIDplus', $tmp);
-
 
113
                                                $tmp = str_replace('DISABLE_PLUGIN_OIDplusPagePublicUITweaks',
-
 
114
                                                                   'DISABLE_PLUGIN_TushevOrg\OIDplus\OIDplusPagePublicUITweaks', $tmp);
-
 
115
 
-
 
116
                                                if (@file_put_contents($config_file, $tmp) === false) {
-
 
117
                                                        eval('?>'.$tmp);
-
 
118
                                                } else {
89
                                        include_once $config_file;
119
                                                        include $config_file;
-
 
120
                                                }
90
                                } else {
121
                                        } else {
91
                                        include $config_file;
122
                                                include $config_file;
92
                                }
123
                                        }
-
 
124
                                }
93
 
125
 
94
                                if (defined('OIDPLUS_CONFIG_VERSION') && (OIDPLUS_CONFIG_VERSION == 2.0)) {
126
                                if (defined('OIDPLUS_CONFIG_VERSION') && (OIDPLUS_CONFIG_VERSION == 2.0)) {
95
                                        self::$old_config_format = true;
127
                                        self::$oldConfigFormatLoaded = true;
96
 
128
 
97
                                        // Backwards compatibility 2.0 => 2.1
129
                                        // Backwards compatibility 2.0 => 2.1
98
                                        foreach (get_defined_constants(true)['user'] as $name => $value) {
130
                                        foreach (get_defined_constants(true)['user'] as $name => $value) {
99
                                                $name = str_replace('OIDPLUS_', '', $name);
131
                                                $name = str_replace('OIDPLUS_', '', $name);
100
                                                if ($name == 'SESSION_SECRET') $name = 'SERVER_SECRET';
132
                                                if ($name == 'SESSION_SECRET') $name = 'SERVER_SECRET';
101
                                                if ($name == 'MYSQL_QUERYLOG') $name = 'QUERY_LOGFILE';
133
                                                if ($name == 'MYSQL_QUERYLOG') $name = 'QUERY_LOGFILE';
-
 
134
                                                $name = str_replace('DISABLE_PLUGIN_OIDplusPagePublicRdap',
-
 
135
                                                                    'DISABLE_PLUGIN_Frdlweb\OIDplus\OIDplusPagePublicRdap', $name);
-
 
136
                                                $name = str_replace('DISABLE_PLUGIN_OIDplusPagePublicAltIds',
-
 
137
                                                                    'DISABLE_PLUGIN_Frdlweb\OIDplus\OIDplusPagePublicAltIds', $name);
-
 
138
                                                $name = str_replace('DISABLE_PLUGIN_OIDplus',
-
 
139
                                                                    'DISABLE_PLUGIN_ViaThinkSoft\OIDplus\OIDplus', $name);
-
 
140
                                                $name = str_replace('DISABLE_PLUGIN_OIDplusPagePublicUITweaks',
-
 
141
                                                                    'DISABLE_PLUGIN_TushevOrg\OIDplus\OIDplusPagePublicUITweaks', $name);
102
                                                if (($name == 'MYSQL_PASSWORD') || ($name == 'ODBC_PASSWORD') || ($name == 'PDO_PASSWORD') || ($name == 'PGSQL_PASSWORD')) {
142
                                                if (($name == 'MYSQL_PASSWORD') || ($name == 'ODBC_PASSWORD') || ($name == 'PDO_PASSWORD') || ($name == 'PGSQL_PASSWORD')) {
103
                                                        self::$baseConfig->setValue($name, base64_decode($value));
143
                                                        self::$baseConfig->setValue($name, base64_decode($value));
104
                                                } else {
144
                                                } else {
105
                                                        if ($name == 'CONFIG_VERSION') $value = 2.1;
145
                                                        if ($name == 'CONFIG_VERSION') $value = 2.1;
106
                                                        self::$baseConfig->setValue($name, $value);
146
                                                        self::$baseConfig->setValue($name, $value);
107
                                                }
147
                                                }
108
                                        }
148
                                        }
109
                                }
149
                                }
110
                        } else {
150
                        } else {
111
                                if (!is_dir(OIDplus::localpath().'setup')) {
151
                                if (!is_dir(OIDplus::localpath().'setup')) {
112
                                        throw new OIDplusConfigInitializationException(_L('File %1 is missing, but setup can\'t be started because its directory missing.','userdata/baseconfig/config.inc.php'));
152
                                        throw new OIDplusConfigInitializationException(_L('File %1 is missing, but setup can\'t be started because its directory missing.',$config_file));
113
                                } else {
153
                                } else {
114
                                        if (self::$html) {
154
                                        if (self::$html) {
115
                                                if (strpos($_SERVER['REQUEST_URI'], OIDplus::webpath(null,OIDplus::PATH_RELATIVE_TO_ROOT).'setup/') !== 0) {
155
                                                if (strpos($_SERVER['REQUEST_URI'], OIDplus::webpath(null,OIDplus::PATH_RELATIVE_TO_ROOT).'setup/') !== 0) {
116
                                                        header('Location:'.OIDplus::webpath(null,OIDplus::PATH_RELATIVE).'setup/');
156
                                                        header('Location:'.OIDplus::webpath(null,OIDplus::PATH_RELATIVE).'setup/');
117
                                                        die(_L('Redirecting to setup...'));
157
                                                        die(_L('Redirecting to setup...'));
118
                                                } else {
158
                                                } else {
119
                                                        return self::$baseConfig;
159
                                                        return self::$baseConfig;
120
                                                }
160
                                                }
121
                                        } else {
161
                                        } else {
122
                                                // This can be displayed in e.g. ajax.php
162
                                                // This can be displayed in e.g. ajax.php
123
                                                throw new OIDplusConfigInitializationException(_L('File %1 is missing. Please run setup again.','userdata/baseconfig/config.inc.php'));
163
                                                throw new OIDplusConfigInitializationException(_L('File %1 is missing. Please run setup again.',$config_file));
124
                                        }
164
                                        }
125
                                }
165
                                }
126
                        }
166
                        }
127
 
167
 
128
                        // Check important config settings
168
                        // Check important config settings
Line 185... Line 225...
185
                        });
225
                        });
186
                        self::$config->prepareConfigKey('objecttypes_initialized', 'List of object type plugins that were initialized once', '', OIDplusConfig::PROTECTION_READONLY, function($value) {
226
                        self::$config->prepareConfigKey('objecttypes_initialized', 'List of object type plugins that were initialized once', '', OIDplusConfig::PROTECTION_READONLY, function($value) {
187
                                // Nothing here yet
227
                                // Nothing here yet
188
                        });
228
                        });
189
                        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) {
229
                        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) {
190
                                # 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?
230
                                // 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?
191
 
231
 
192
                                $ary = explode(';',$value);
232
                                $ary = explode(';',$value);
193
                                $uniq_ary = array_unique($ary);
233
                                $uniq_ary = array_unique($ary);
194
 
234
 
195
                                if (count($ary) != count($uniq_ary)) {
235
                                if (count($ary) != count($uniq_ary)) {
Line 291... Line 331...
291
                        self::$logger = new OIDplusLogger();
331
                        self::$logger = new OIDplusLogger();
292
                }
332
                }
293
                return self::$logger;
333
                return self::$logger;
294
        }
334
        }
295
 
335
 
296
        # --- SQL slang plugin
336
        // --- SQL slang plugin
297
 
337
 
298
        private static function registerSqlSlangPlugin(OIDplusSqlSlangPlugin $plugin) {
338
        private static function registerSqlSlangPlugin(OIDplusSqlSlangPlugin $plugin) {
299
                $name = $plugin::id();
339
                $name = $plugin::id();
300
                if ($name === '') return false;
340
                if ($name === '') return false;
301
 
341
 
Line 319... Line 359...
319
                } else {
359
                } else {
320
                        return null;
360
                        return null;
321
                }
361
                }
322
        }
362
        }
323
 
363
 
324
        # --- Database plugin
364
        // --- Database plugin
325
 
365
 
326
        private static function registerDatabasePlugin(OIDplusDatabasePlugin $plugin) {
366
        private static function registerDatabasePlugin(OIDplusDatabasePlugin $plugin) {
327
                $name = $plugin::id();
367
                $name = $plugin::id();
328
                if ($name === '') return false;
368
                if ($name === '') return false;
329
 
369
 
Line 370... Line 410...
370
                }
410
                }
371
                if (!self::$dbIsolatedSession->isConnected()) self::$dbIsolatedSession->connect();
411
                if (!self::$dbIsolatedSession->isConnected()) self::$dbIsolatedSession->connect();
372
                return self::$dbIsolatedSession;
412
                return self::$dbIsolatedSession;
373
        }
413
        }
374
 
414
 
375
        # --- CAPTCHA plugin
415
        // --- CAPTCHA plugin
376
 
416
 
377
        private static function registerCaptchaPlugin(OIDplusCaptchaPlugin $plugin) {
417
        private static function registerCaptchaPlugin(OIDplusCaptchaPlugin $plugin) {
378
                $name = $plugin::id();
418
                $name = $plugin::id();
379
                if ($name === '') return false;
419
                if ($name === '') return false;
380
 
420
 
Line 413... Line 453...
413
                        }
453
                        }
414
                }
454
                }
415
                throw new OIDplusConfigInitializationException(_L('CAPTCHA plugin "%1" not found',$captcha_plugin_name));
455
                throw new OIDplusConfigInitializationException(_L('CAPTCHA plugin "%1" not found',$captcha_plugin_name));
416
        }
456
        }
417
 
457
 
418
        # --- Page plugin
458
        // --- Page plugin
419
 
459
 
420
        private static function registerPagePlugin(OIDplusPagePlugin $plugin) {
460
        private static function registerPagePlugin(OIDplusPagePlugin $plugin) {
421
                self::$pagePlugins[] = $plugin;
461
                self::$pagePlugins[] = $plugin;
422
 
462
 
423
                return true;
463
                return true;
Line 425... Line 465...
425
 
465
 
426
        public static function getPagePlugins() {
466
        public static function getPagePlugins() {
427
                return self::$pagePlugins;
467
                return self::$pagePlugins;
428
        }
468
        }
429
 
469
 
430
        # --- Auth plugin
470
        // --- Auth plugin
431
 
471
 
432
        private static function registerAuthPlugin(OIDplusAuthPlugin $plugin) {
472
        private static function registerAuthPlugin(OIDplusAuthPlugin $plugin) {
433
                if (OIDplus::baseConfig()->getValue('DEBUG')) {
473
                if (OIDplus::baseConfig()->getValue('DEBUG')) {
434
                        $password = generateRandomString(25);
474
                        $password = generateRandomString(25);
435
 
475
 
Line 462... Line 502...
462
 
502
 
463
        public static function getAuthPlugins() {
503
        public static function getAuthPlugins() {
464
                return self::$authPlugins;
504
                return self::$authPlugins;
465
        }
505
        }
466
 
506
 
467
        # --- Language plugin
507
        // --- Language plugin
468
 
508
 
469
        private static function registerLanguagePlugin(OIDplusLanguagePlugin $plugin) {
509
        private static function registerLanguagePlugin(OIDplusLanguagePlugin $plugin) {
470
                self::$languagePlugins[] = $plugin;
510
                self::$languagePlugins[] = $plugin;
471
                return true;
511
                return true;
472
        }
512
        }
473
 
513
 
474
        public static function getLanguagePlugins() {
514
        public static function getLanguagePlugins() {
475
                return self::$languagePlugins;
515
                return self::$languagePlugins;
476
        }
516
        }
477
 
517
 
478
        # --- Design plugin
518
        // --- Design plugin
479
 
519
 
480
        private static function registerDesignPlugin(OIDplusDesignPlugin $plugin) {
520
        private static function registerDesignPlugin(OIDplusDesignPlugin $plugin) {
481
                self::$designPlugins[] = $plugin;
521
                self::$designPlugins[] = $plugin;
482
                return true;
522
                return true;
483
        }
523
        }
Line 494... Line 534...
494
                        }
534
                        }
495
                }
535
                }
496
                return null;
536
                return null;
497
        }
537
        }
498
 
538
 
499
        # --- Logger plugin
539
        // --- Logger plugin
500
 
540
 
501
        private static function registerLoggerPlugin(OIDplusLoggerPlugin $plugin) {
541
        private static function registerLoggerPlugin(OIDplusLoggerPlugin $plugin) {
502
                self::$loggerPlugins[] = $plugin;
542
                self::$loggerPlugins[] = $plugin;
503
                return true;
543
                return true;
504
        }
544
        }
505
 
545
 
506
        public static function getLoggerPlugins() {
546
        public static function getLoggerPlugins() {
507
                return self::$loggerPlugins;
547
                return self::$loggerPlugins;
508
        }
548
        }
509
 
549
 
510
        # --- Object type plugin
550
        // --- Object type plugin
511
 
551
 
512
        private static function registerObjectTypePlugin(OIDplusObjectTypePlugin $plugin) {
552
        private static function registerObjectTypePlugin(OIDplusObjectTypePlugin $plugin) {
513
                self::$objectTypePlugins[] = $plugin;
553
                self::$objectTypePlugins[] = $plugin;
514
 
554
 
515
                $ot = $plugin::getObjectTypeClassName();
555
                $ot = $plugin::getObjectTypeClassName();
Line 623... Line 663...
623
 
663
 
624
        public static function getDisabledObjectTypes() {
664
        public static function getDisabledObjectTypes() {
625
                return self::$disabledObjectTypes;
665
                return self::$disabledObjectTypes;
626
        }
666
        }
627
 
667
 
628
        # --- Plugin handling functions
668
        // --- Plugin handling functions
629
 
669
 
630
        public static function getAllPlugins()/*: array*/ {
670
        public static function getAllPlugins()/*: array*/ {
631
                $res = array();
671
                $res = array();
632
                $res = array_merge($res, self::$pagePlugins);
672
                $res = array_merge($res, self::$pagePlugins);
633
                $res = array_merge($res, self::$authPlugins);
673
                $res = array_merge($res, self::$authPlugins);
Line 660... Line 700...
660
                }
700
                }
661
                return null;
701
                return null;
662
        }
702
        }
663
 
703
 
664
        /**
704
        /**
-
 
705
        * Checks if the plugin is disabled
-
 
706
        * @return boolean true if plugin is enabled, false if plugin is disabled
-
 
707
        * @throws OIDplusException if the class name or config file (disabled setting) does not contain a namespace
-
 
708
        */
-
 
709
        private static function pluginCheckDisabled($class_name): bool {
-
 
710
                $path = explode('\\', $class_name);
-
 
711
 
-
 
712
                if (count($path) == 1) {
-
 
713
                        throw new OIDplusException(_L('Plugin "%1" is erroneous',$class_name).': '._L('The plugin uses no namespaces. The new version of OIDplus requires plugin class files to be in a namespace. Please notify your plugin author and ask for an update.'));
-
 
714
                }
-
 
715
 
-
 
716
                $class_end = end($path);
-
 
717
                if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_'.$class_end, false)) {
-
 
718
                        throw new OIDplusConfigInitializationException(_L('Your base configuration file is outdated. Please change "%1" to "%2".','DISABLE_PLUGIN_'.$class_end,'DISABLE_PLUGIN_'.$class_name));
-
 
719
                }
-
 
720
 
-
 
721
                if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_'.$class_name, false)) {
-
 
722
                        return false;
-
 
723
                }
-
 
724
 
-
 
725
                return true;
-
 
726
        }
-
 
727
 
-
 
728
        /**
665
        * @return array<OIDplusPluginManifest>|array<string,array<string,OIDplusPluginManifest>>
729
        * @return array<OIDplusPluginManifest>|array<string,array<string,OIDplusPluginManifest>>
666
        */
730
        */
667
        public static function getAllPluginManifests($pluginFolderMasks='*', $flat=true): array {
731
        public static function getAllPluginManifests($pluginFolderMasks='*', $flat=true): array {
668
                $out = array();
732
                $out = array();
669
                // Note: glob() will sort by default, so we do not need a page priority attribute.
733
                // Note: glob() will sort by default, so we do not need a page priority attribute.
Line 705... Line 769...
705
 
769
 
706
                        $manifest = new OIDplusPluginManifest();
770
                        $manifest = new OIDplusPluginManifest();
707
                        $manifest->loadManifest($ini);
771
                        $manifest->loadManifest($ini);
708
 
772
 
709
                        $class_name = $manifest->getPhpMainClass();
773
                        $class_name = $manifest->getPhpMainClass();
710
                        if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_'.$class_name, false)) {
774
                        if ($class_name) if (!self::pluginCheckDisabled($class_name)) continue;
711
                                continue;
-
 
712
                        }
-
 
713
 
775
 
714
                        if ($flat) {
776
                        if ($flat) {
715
                                $out[] = $manifest;
777
                                $out[] = $manifest;
716
                        } else {
778
                        } else {
717
                                $plugintype_folder = basename(dirname(dirname($ini)));
779
                                $plugintype_folder = basename(dirname(dirname($ini)));
Line 750... Line 812...
750
 
812
 
751
                                // Before we load the plugin, we want to make some checks to confirm
813
                                // Before we load the plugin, we want to make some checks to confirm
752
                                // that the plugin is working correctly.
814
                                // that the plugin is working correctly.
753
 
815
 
754
                                if (!$class_name) {
816
                                if (!$class_name) {
755
                                        throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Manifest does not declare a PHP main class'));
817
                                        throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('Manifest does not declare a PHP main class'));
756
                                }
818
                                }
757
                                if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_'.$class_name, false)) {
819
                                if (!self::pluginCheckDisabled($class_name)) {
758
                                        continue;
820
                                        continue; // Plugin is disabled
759
                                }
821
                                }
760
                                if (!class_exists($class_name)) {
822
                                if (!class_exists($class_name)) {
761
                                        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));
823
                                        throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('Manifest declares PHP main class as "%1", but it could not be found',$class_name));
762
                                }
824
                                }
763
                                if (!is_subclass_of($class_name, $expectedPluginClass)) {
825
                                if (!is_subclass_of($class_name, $expectedPluginClass)) {
764
                                        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));
826
                                        throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('Plugin main class "%1" is expected to be a subclass of "%2"',$class_name,$expectedPluginClass));
765
                                }
827
                                }
766
                                if (($class_name!=$manifest->getTypeClass()) && (!is_subclass_of($class_name,$manifest->getTypeClass()))) {
828
                                if (($class_name!=$manifest->getTypeClass()) && (!is_subclass_of($class_name,$manifest->getTypeClass()))) {
767
                                        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()));
829
                                        throw new OIDplusException(_L('Plugin "%1" 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()));
768
                                }
830
                                }
769
                                if (($manifest->getTypeClass()!=$expectedPluginClass) && (!is_subclass_of($manifest->getTypeClass(),$expectedPluginClass))) {
831
                                if (($manifest->getTypeClass()!=$expectedPluginClass) && (!is_subclass_of($manifest->getTypeClass(),$expectedPluginClass))) {
770
                                        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));
832
                                        throw new OIDplusException(_L('Plugin "%1" 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));
771
                                }
833
                                }
772
 
834
 
773
                                $plugin_oid = $manifest->getOid();
835
                                $plugin_oid = $manifest->getOid();
774
                                if (!$plugin_oid) {
836
                                if (!$plugin_oid) {
775
                                        throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('Does not have an OID'));
837
                                        throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('Does not have an OID'));
776
                                }
838
                                }
777
                                if (!oid_valid_dotnotation($plugin_oid, false, false, 2)) {
839
                                if (!oid_valid_dotnotation($plugin_oid, false, false, 2)) {
778
                                        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));
840
                                        throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('Plugin OID "%1" is invalid (needs to be valid dot-notation)',$plugin_oid));
779
                                }
841
                                }
780
                                if (isset($known_plugin_oids[$plugin_oid])) {
842
                                if (isset($known_plugin_oids[$plugin_oid])) {
781
                                        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]));
843
                                        throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('The OID "%1" is already used by the plugin "%2"',$plugin_oid,$known_plugin_oids[$plugin_oid]));
782
                                }
844
                                }
783
 
845
 
784
                                $full_plugin_dir = dirname($manifest->getManifestFile());
846
                                $full_plugin_dir = dirname($manifest->getManifestFile());
785
                                $full_plugin_dir = substr($full_plugin_dir, strlen(OIDplus::localpath()));
847
                                $full_plugin_dir = substr($full_plugin_dir, strlen(OIDplus::localpath()));
786
 
848
 
787
                                $dir_is_viathinksoft = str_starts_with($full_plugin_dir, 'plugins/viathinksoft/') || str_starts_with($full_plugin_dir, 'plugins\\viathinksoft\\');
849
                                $dir_is_viathinksoft = str_starts_with($full_plugin_dir, 'plugins/viathinksoft/') || str_starts_with($full_plugin_dir, 'plugins\\viathinksoft\\');
788
                                $oid_is_viathinksoft = str_starts_with($plugin_oid, '1.3.6.1.4.1.37476.2.5.2.4.'); // { iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 37476 products(2) oidplus(5) v2(2) plugins(4) }
850
                                $oid_is_viathinksoft = str_starts_with($plugin_oid, '1.3.6.1.4.1.37476.2.5.2.4.'); // { iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 37476 products(2) oidplus(5) v2(2) plugins(4) }
-
 
851
                                $class_is_viathinksoft = str_starts_with($class_name, 'ViaThinkSoft\\');
789
                                if ($dir_is_viathinksoft != $oid_is_viathinksoft) {
852
                                if ($dir_is_viathinksoft != $oid_is_viathinksoft) {
790
                                        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/'));
853
                                        throw new OIDplusException(_L('Plugin "%1" 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/'));
-
 
854
                                }
-
 
855
                                if ($dir_is_viathinksoft != $class_is_viathinksoft) {
-
 
856
                                        throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('Third-party plugins must not use the ViaThinkSoft PHP namespace. Please use your own vendor namespace.'));
791
                                }
857
                                }
792
 
858
 
793
                                $known_plugin_oids[$plugin_oid] = $plugintype_folder.'/'.$pluginname_folder;
859
                                $known_plugin_oids[$plugin_oid] = $plugintype_folder.'/'.$pluginname_folder;
794
 
860
 
795
                                $obj = new $class_name();
861
                                $obj = new $class_name();
796
 
862
 
797
                                if (OIDplus::baseConfig()->getValue('DEBUG')) {
863
                                if (OIDplus::baseConfig()->getValue('DEBUG')) {
798
                                        if ($obj->implementsFeature($fake_feature)) {
864
                                        if ($obj->implementsFeature($fake_feature)) {
799
                                                // see https://devblogs.microsoft.com/oldnewthing/20040211-00/?p=40663
865
                                                // see https://devblogs.microsoft.com/oldnewthing/20040211-00/?p=40663
800
                                                throw new OIDplusException(_L('Plugin "%1/%2" is erroneous',$plugintype_folder,$pluginname_folder).': '._L('implementsFeature() always returns true'));
866
                                                throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('implementsFeature() always returns true'));
801
                                        }
867
                                        }
802
                                }
868
                                }
803
 
869
 
804
                                // TODO: Maybe as additional plugin-test, we should also check if plugins are allowed to define CSS/JS, i.e. the plugin type is element of OIDplus::INTERACTIVE_PLUGIN_TYPES
870
                                // TODO: Maybe as additional plugin-test, we should also check if plugins are allowed to define CSS/JS, i.e. the plugin type is element of OIDplus::INTERACTIVE_PLUGIN_TYPES
805
                                $tmp = $manifest->getManifestLinkedFiles();
871
                                $tmp = $manifest->getManifestLinkedFiles();
806
                                foreach ($tmp as $file) {
872
                                foreach ($tmp as $file) {
807
                                        if (!file_exists($file)) {
873
                                        if (!file_exists($file)) {
808
                                                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));
874
                                                throw new OIDplusException(_L('Plugin "%1" is erroneous',$plugintype_folder.'/'.$pluginname_folder).': '._L('File %1 was defined in manifest, but it is not existing',$file));
809
                                        }
875
                                        }
810
                                }
876
                                }
811
 
877
 
812
                                // Now we can continue
878
                                // Now we can continue
813
 
879
 
Line 824... Line 890...
824
 
890
 
825
                }
891
                }
826
                return $out;
892
                return $out;
827
        }
893
        }
828
 
894
 
829
        # --- Initialization of OIDplus
895
        // --- Initialization of OIDplus
830
 
896
 
831
        public static function init($html=true, $keepBaseConfig=true) {
897
        public static function init($html=true, $keepBaseConfig=true) {
832
                self::$html = $html;
898
                self::$html = $html;
833
 
899
 
834
                // Reset internal state, so we can re-init verything if required
900
                // Reset internal state, so we can re-init verything if required
835
 
901
 
836
                if (self::$old_config_format) {
-
 
837
                        // We need to do this, because define() cannot be undone
-
 
838
                        // Note: This can only happen in very special cases (e.g. test cases) where you call init() twice
-
 
839
                        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.'));
-
 
840
                }
-
 
841
 
-
 
842
                self::$config = null;
902
                self::$config = null;
843
                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
903
                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
844
                self::$gui = null;
904
                self::$gui = null;
845
                self::$authUtils = null;
905
                self::$authUtils = null;
846
                self::$mailUtils = null;
906
                self::$mailUtils = null;
Line 870... Line 930...
870
 
930
 
871
                // Register database types (highest priority)
931
                // Register database types (highest priority)
872
 
932
 
873
                // SQL slangs
933
                // SQL slangs
874
 
934
 
875
                self::registerAllPlugins('sqlSlang', 'OIDplusSqlSlangPlugin', array('OIDplus','registerSqlSlangPlugin'));
935
                self::registerAllPlugins('sqlSlang', OIDplusSqlSlangPlugin::class, array(OIDplus::class,'registerSqlSlangPlugin'));
876
                foreach (OIDplus::getSqlSlangPlugins() as $plugin) {
936
                foreach (OIDplus::getSqlSlangPlugins() as $plugin) {
877
                        $plugin->init($html);
937
                        $plugin->init($html);
878
                }
938
                }
879
 
939
 
880
                // Database providers
940
                // Database providers
881
 
941
 
882
                self::registerAllPlugins('database', 'OIDplusDatabasePlugin', array('OIDplus','registerDatabasePlugin'));
942
                self::registerAllPlugins('database', OIDplusDatabasePlugin::class, array(OIDplus::class,'registerDatabasePlugin'));
883
                foreach (OIDplus::getDatabasePlugins() as $plugin) {
943
                foreach (OIDplus::getDatabasePlugins() as $plugin) {
884
                        $plugin->init($html);
944
                        $plugin->init($html);
885
                }
945
                }
886
 
946
 
887
                // Do redirect stuff etc.
947
                // Do redirect stuff etc.
Line 896... Line 956...
896
 
956
 
897
                OIDplus::getPkiStatus(true);
957
                OIDplus::getPkiStatus(true);
898
 
958
 
899
                // Register non-DB plugins
959
                // Register non-DB plugins
900
 
960
 
901
                self::registerAllPlugins(array('publicPages', 'raPages', 'adminPages'), 'OIDplusPagePlugin', array('OIDplus','registerPagePlugin'));
961
                self::registerAllPlugins(array('publicPages', 'raPages', 'adminPages'), OIDplusPagePlugin::class, array(OIDplus::class,'registerPagePlugin'));
902
                self::registerAllPlugins('auth', 'OIDplusAuthPlugin', array('OIDplus','registerAuthPlugin'));
962
                self::registerAllPlugins('auth', OIDplusAuthPlugin::class, array(OIDplus::class,'registerAuthPlugin'));
903
                self::registerAllPlugins('logger', 'OIDplusLoggerPlugin', array('OIDplus','registerLoggerPlugin'));
963
                self::registerAllPlugins('logger', OIDplusLoggerPlugin::class, array(OIDplus::class,'registerLoggerPlugin'));
904
                OIDplusLogger::reLogMissing(); // Some previous plugins might have tried to log. Repeat that now.
964
                OIDplusLogger::reLogMissing(); // Some previous plugins might have tried to log. Repeat that now.
905
                self::registerAllPlugins('objectTypes', 'OIDplusObjectTypePlugin', array('OIDplus','registerObjectTypePlugin'));
965
                self::registerAllPlugins('objectTypes', OIDplusObjectTypePlugin::class, array(OIDplus::class,'registerObjectTypePlugin'));
906
                self::registerAllPlugins('language', 'OIDplusLanguagePlugin', array('OIDplus','registerLanguagePlugin'));
966
                self::registerAllPlugins('language', OIDplusLanguagePlugin::class, array(OIDplus::class,'registerLanguagePlugin'));
907
                self::registerAllPlugins('design', 'OIDplusDesignPlugin', array('OIDplus','registerDesignPlugin'));
967
                self::registerAllPlugins('design', OIDplusDesignPlugin::class, array(OIDplus::class,'registerDesignPlugin'));
908
                self::registerAllPlugins('captcha', 'OIDplusCaptchaPlugin', array('OIDplus','registerCaptchaPlugin'));
968
                self::registerAllPlugins('captcha', OIDplusCaptchaPlugin::class, array(OIDplus::class,'registerCaptchaPlugin'));
909
 
969
 
910
                // Initialize non-DB plugins
970
                // Initialize non-DB plugins
911
 
971
 
912
                foreach (OIDplus::getPagePlugins() as $plugin) {
972
                foreach (OIDplus::getPagePlugins() as $plugin) {
913
                        $plugin->init($html);
973
                        $plugin->init($html);
Line 1100... Line 1160...
1100
 
1160
 
1101
                OIDplus::recognizeSystemUrl(); // Make sure "last_known_system_url" is set
1161
                OIDplus::recognizeSystemUrl(); // Make sure "last_known_system_url" is set
1102
                OIDplus::recognizeVersion(); // Make sure "last_known_version" is set and a log entry is created
1162
                OIDplus::recognizeVersion(); // Make sure "last_known_version" is set and a log entry is created
1103
        }
1163
        }
1104
 
1164
 
1105
        # --- System URL, System ID, PKI, and other functions
1165
        // --- System URL, System ID, PKI, and other functions
1106
 
1166
 
1107
        private static function recognizeSystemUrl() {
1167
        private static function recognizeSystemUrl() {
1108
                try {
1168
                try {
1109
                        $url = OIDplus::webpath(null,self::PATH_ABSOLUTE_CANONICAL); // TODO: canonical or not?
1169
                        $url = OIDplus::webpath(null,self::PATH_ABSOLUTE_CANONICAL); // TODO: canonical or not?
1110
                        OIDplus::config()->setValue('last_known_system_url', $url);
1170
                        OIDplus::config()->setValue('last_known_system_url', $url);
1111
                } catch (Exception $e) {
1171
                } catch (\Exception $e) {
1112
                }
1172
                }
1113
        }
1173
        }
1114
 
1174
 
1115
        private static function getExecutingScriptPathDepth() {
1175
        private static function getExecutingScriptPathDepth() {
1116
                if (PHP_SAPI == 'cli') {
1176
                if (PHP_SAPI == 'cli') {
Line 1159... Line 1219...
1159
                        }
1219
                        }
1160
 
1220
 
1161
                        if (PHP_SAPI == 'cli') {
1221
                        if (PHP_SAPI == 'cli') {
1162
                                try {
1222
                                try {
1163
                                        return OIDplus::config()->getValue('last_known_system_url', false);
1223
                                        return OIDplus::config()->getValue('last_known_system_url', false);
1164
                                } catch (Exception $e) {
1224
                                } catch (\Exception $e) {
1165
                                        return false;
1225
                                        return false;
1166
                                }
1226
                                }
1167
                        } else {
1227
                        } else {
1168
                                // First, try to find out how many levels we need to go up
1228
                                // First, try to find out how many levels we need to go up
1169
                                $steps_up = self::getExecutingScriptPathDepth();
1229
                                $steps_up = self::getExecutingScriptPathDepth();
Line 1397... Line 1457...
1397
 
1457
 
1398
                                // Just to be sure, recanonize objects (we don't do it at every page visit due to performance reasons)
1458
                                // Just to be sure, recanonize objects (we don't do it at every page visit due to performance reasons)
1399
                                self::recanonizeObjects();
1459
                                self::recanonizeObjects();
1400
                        }
1460
                        }
1401
                        OIDplus::config()->setValue("last_known_version", $ver_now);
1461
                        OIDplus::config()->setValue("last_known_version", $ver_now);
1402
                } catch (Exception $e) {
1462
                } catch (\Exception $e) {
1403
                }
1463
                }
1404
        }
1464
        }
1405
 
1465
 
1406
        public static function getVersion() {
1466
        public static function getVersion() {
1407
                static $cachedVersion = null;
1467
                static $cachedVersion = null;
Line 1773... Line 1833...
1773
                        // tries command line and binary parsing
1833
                        // tries command line and binary parsing
1774
                        // requires vendor/danielmarschall/git_utils.inc.php
1834
                        // requires vendor/danielmarschall/git_utils.inc.php
1775
                        $git_dir = OIDplus::findGitFolder();
1835
                        $git_dir = OIDplus::findGitFolder();
1776
                        if ($git_dir === false) return false;
1836
                        if ($git_dir === false) return false;
1777
                        $commit_msg = git_get_latest_commit_message($git_dir);
1837
                        $commit_msg = git_get_latest_commit_message($git_dir);
1778
                } catch (Exception $e) {
1838
                } catch (\Exception $e) {
1779
                        return false;
1839
                        return false;
1780
                }
1840
                }
1781
 
1841
 
1782
                $m = array();
1842
                $m = array();
1783
                if (preg_match('%git-svn-id: (.+)@(\\d+) %ismU', $commit_msg, $m)) {
1843
                if (preg_match('%git-svn-id: (.+)@(\\d+) %ismU', $commit_msg, $m)) {
Line 1804... Line 1864...
1804
        public static function isCronjob() {
1864
        public static function isCronjob() {
1805
                return explode('.',basename($_SERVER['SCRIPT_NAME']))[0] === 'cron';
1865
                return explode('.',basename($_SERVER['SCRIPT_NAME']))[0] === 'cron';
1806
        }
1866
        }
1807
 
1867
 
1808
        private static function recanonizeObjects() {
1868
        private static function recanonizeObjects() {
1809
                #
1869
                //
1810
                # Since OIDplus svn-184, entries in the database need to have a canonical ID
1870
                // Since OIDplus svn-184, entries in the database need to have a canonical ID
1811
                # If the ID is not canonical (e.g. GUIDs missing hyphens), the object cannot be opened in OIDplus
1871
                // If the ID is not canonical (e.g. GUIDs missing hyphens), the object cannot be opened in OIDplus
1812
                # This script re-canonizes the object IDs if required.
1872
                // This script re-canonizes the object IDs if required.
1813
                # In SVN Rev 856, the canonization for GUID, IPv4 and IPv6 have changed, requiring another
1873
                // In SVN Rev 856, the canonization for GUID, IPv4 and IPv6 have changed, requiring another
1814
                # re-canonization
1874
                // re-canonization
1815
                #
1875
                //
1816
                $res = OIDplus::db()->query("select id from ###objects");
1876
                $res = OIDplus::db()->query("select id from ###objects");
1817
                while ($row = $res->fetch_array()) {
1877
                while ($row = $res->fetch_array()) {
1818
                        $ida = $row['id'];
1878
                        $ida = $row['id'];
1819
                        $obj = OIDplusObject::parse($ida);
1879
                        $obj = OIDplusObject::parse($ida);
1820
                        if (!$obj) continue;
1880
                        if (!$obj) continue;