Rev 1146 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1069 | daniel-mar | 1 | <?php |
2 | |||
3 | /* |
||
4 | * OIDplus 2.0 |
||
1321 | daniel-mar | 5 | * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft |
1069 | daniel-mar | 6 | * |
7 | * Licensed under the Apache License, Version 2.0 (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 |
||
10 | * |
||
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
12 | * |
||
13 | * Unless required by applicable law or agreed to in writing, software |
||
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
16 | * See the License for the specific language governing permissions and |
||
17 | * limitations under the License. |
||
18 | */ |
||
19 | |||
1131 | daniel-mar | 20 | spl_autoload_register(function ($fq_class_name) { |
1069 | daniel-mar | 21 | static $class_refs = null; |
22 | |||
23 | // We only load based on the last element of the class name (ignore namespace) |
||
24 | // If there are multiple classes matching that name we just include all class files |
||
1131 | daniel-mar | 25 | $path = explode('\\',$fq_class_name); |
26 | $class_name = array_pop($path); |
||
27 | $namespace = implode('\\',$path); |
||
1069 | daniel-mar | 28 | |
29 | if (is_null($class_refs)) { |
||
30 | $valid_plugin_folders = array( |
||
31 | 'adminPages', |
||
32 | 'auth', |
||
33 | 'database', |
||
34 | 'design', |
||
35 | 'language', |
||
36 | 'logger', |
||
37 | 'objectTypes', |
||
38 | 'publicPages', |
||
39 | 'raPages', |
||
40 | 'sqlSlang', |
||
41 | 'captcha' |
||
42 | ); |
||
43 | |||
44 | $func = function(&$class_refs, $class_files, $namespace='') { |
||
45 | foreach ($class_files as $filename) { |
||
46 | $cn = strtolower(basename($filename)); |
||
47 | $cn = preg_replace('@(\\.class){0,1}\\.phps{0,1}$@', '', $cn); |
||
48 | if (!empty($namespace)) { |
||
49 | if (substr($namespace,-1,1) !== '\\') $namespace .= '\\'; |
||
50 | $cn = strtolower($namespace) . $cn; |
||
51 | } |
||
52 | if (!isset($class_refs[$cn])) { |
||
53 | $class_refs[$cn] = array($filename); |
||
54 | } else { |
||
1116 | daniel-mar | 55 | $class_refs[$cn][] = $filename; |
1069 | daniel-mar | 56 | } |
57 | } |
||
58 | }; |
||
59 | |||
60 | $class_files = array(); |
||
61 | |||
62 | // Global namespace / OIDplus |
||
63 | // (the last has the highest priority) |
||
64 | foreach ($valid_plugin_folders as $folder) { |
||
65 | $class_files = array_merge($class_files, glob(__DIR__ . '/../plugins/'.'*'.'/'.$folder.'/'.'*'.'/'.'*'.'.class.php')); |
||
66 | } |
||
67 | $class_files = array_merge($class_files, glob(__DIR__ . '/classes/'.'*'.'.class.php')); |
||
68 | $class_files = array_merge($class_files, glob(__DIR__ . '/../vendor/danielmarschall/fileformats/'.'*'.'.class.php')); |
||
69 | $class_files = array_merge($class_files, glob(__DIR__ . '/../vendor/danielmarschall/php_utils/'.'*'.'.class.php')); |
||
70 | $class_files = array_merge($class_files, glob(__DIR__ . '/../vendor/danielmarschall/oidconverter/php/'.'*'.'.class.phps')); |
||
71 | $func($class_refs, $class_files); |
||
72 | } |
||
73 | |||
74 | $class_name = strtolower($class_name); |
||
75 | if (isset($class_refs[$class_name])) { |
||
76 | foreach ($class_refs[$class_name] as $inc) { |
||
77 | require $inc; |
||
78 | } |
||
79 | unset($class_refs[$class_name]); // this emulates a "require_once" and is faster |
||
80 | } |
||
81 | }); |
||
1131 | daniel-mar | 82 | |
83 | /* |
||
84 | * Interfaces starting with INTF_OID are "optional interfaces". If they are not found by previous autoloaders, |
||
85 | * then they will be defined by a "fake interface" that contains nothing. |
||
86 | * For OIDplus, INTF_OID interfaces are used if plugins communicate with other plugins, i.e. |
||
87 | * a plugin offers a service which another plugin can use. However, if one of the plugins does not exist, |
||
88 | * PHP shall not crash! So, this idea of "optional interfaces" was born. |
||
89 | * Previously, we used "implementsFeature()" which acted like Microsoft COM's GUID interfaces, |
||
90 | * but this had the downside that types could not be checked. |
||
91 | */ |
||
92 | spl_autoload_register(function ($fq_class_name) { |
||
93 | $path = explode('\\',$fq_class_name); |
||
94 | $class_name = array_pop($path); |
||
95 | $namespace = implode('\\',$path); |
||
96 | |||
1146 | daniel-mar | 97 | if (str_starts_with($class_name, "INTF_OID_")) { |
98 | if (($namespace != "ViaThinkSoft\\OIDplus") && str_starts_with($class_name, "INTF_OID_1_3_6_1_4_1_37476_")) { |
||
99 | throw new Exception(_L('Third-party plugin tries to access a ViaThinkSoft-INTF_OID interface "%1", but is not in the ViaThinkSoft\\OIDplus namespace', $fq_class_name)); |
||
100 | } |
||
1131 | daniel-mar | 101 | |
1146 | daniel-mar | 102 | if (($namespace == "ViaThinkSoft\\OIDplus") && !str_starts_with($class_name, "INTF_OID_1_3_6_1_4_1_37476_")) { |
103 | throw new Exception(_L('ViaThinkSoft plugin tries to access a Third-Party-INTF_OID interface "%1", but is not in the third-party namespace', $fq_class_name)); |
||
104 | } |
||
1131 | daniel-mar | 105 | |
106 | $fake_content = ""; |
||
107 | if ($namespace) $fake_content .= "namespace $namespace;\n\n"; |
||
108 | $fake_content .= "interface $class_name { }\n\n"; |
||
109 | eval($fake_content); |
||
110 | } |
||
111 | }); |