Subversion Repositories oidplus

Rev

Rev 1146 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
  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.  
  20. spl_autoload_register(function ($fq_class_name) {
  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
  25.         $path = explode('\\',$fq_class_name);
  26.         $class_name = array_pop($path);
  27.         $namespace = implode('\\',$path);
  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 {
  55.                                         $class_refs[$cn][] = $filename;
  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. });
  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.  
  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.                 }
  101.  
  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.                 }
  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. });
  112.