ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
Module.php
Go to the documentation of this file.
1<?php
2namespace SimpleSAML;
3
12class Module
13{
14
20 public static $modules = array();
21
27 public static $module_info = array();
28
29
39 public static function autoloadPSR0($className)
40 {
41 $modulePrefixLength = strlen('sspmod_');
42 $classPrefix = substr($className, 0, $modulePrefixLength);
43 if ($classPrefix !== 'sspmod_') {
44 return;
45 }
46
47 $modNameEnd = strpos($className, '_', $modulePrefixLength);
48 $module = substr($className, $modulePrefixLength, $modNameEnd - $modulePrefixLength);
49 $path = explode('_', substr($className, $modNameEnd + 1));
50
51 if (!self::isModuleEnabled($module)) {
52 return;
53 }
54
55 $file = self::getModuleDir($module).'/lib/'.join('/', $path).'.php';
56 if (!file_exists($file)) {
57 return;
58 }
59 require_once($file);
60
61 if (!class_exists($className, false) && !interface_exists($className, false)) {
62 // the file exists, but the class is not defined. Is it using namespaces?
63 $nspath = join('\\', $path);
64 if (class_exists('SimpleSAML\Module\\'.$module.'\\'.$nspath) ||
65 interface_exists('SimpleSAML\Module\\'.$module.'\\'.$nspath)
66 ) {
67 // the class has been migrated, create an alias and warn about it
69 "The class or interface '$className' is now using namespaces, please use 'SimpleSAML\\Module\\".
70 $module."\\".$nspath."' instead."
71 );
72 class_alias("SimpleSAML\\Module\\$module\\$nspath", $className);
73 }
74 }
75 }
76
77
83 public static function autoloadPSR4($className)
84 {
85 $elements = explode('\\', $className);
86 if ($elements[0] === '') { // class name starting with /, ignore
87 array_shift($elements);
88 }
89 if (count($elements) < 4) {
90 return; // it can't be a module
91 }
92 if (array_shift($elements) !== 'SimpleSAML') {
93 return; // the first element is not "SimpleSAML"
94 }
95 if (array_shift($elements) !== 'Module') {
96 return; // the second element is not "module"
97 }
98
99 // this is a SimpleSAMLphp module following PSR-4
100 $module = array_shift($elements);
101 if (!self::isModuleEnabled($module)) {
102 return; // module not enabled, avoid giving out any information at all
103 }
104
105 $file = self::getModuleDir($module).'/lib/'.implode('/', $elements).'.php';
106
107 if (file_exists($file)) {
108 require_once($file);
109 }
110 }
111
112
122 public static function getModuleDir($module)
123 {
124 $baseDir = dirname(dirname(dirname(__FILE__))).'/modules';
126
127 return $moduleDir;
128 }
129
130
142 public static function isModuleEnabled($module)
143 {
145 return self::isModuleEnabledWithConf($module, $config->getArray('module.enable', array()));
146 }
147
148
149 private static function isModuleEnabledWithConf($module, $mod_config)
150 {
151 if (isset(self::$module_info[$module]['enabled'])) {
152 return self::$module_info[$module]['enabled'];
153 }
154
155 if (!empty(self::$modules) && !in_array($module, self::$modules, true)) {
156 return false;
157 }
158
159 $moduleDir = self::getModuleDir($module);
160
161 if (!is_dir($moduleDir)) {
162 self::$module_info[$module]['enabled'] = false;
163 return false;
164 }
165
166 if (isset($mod_config[$module])) {
167 if (is_bool($mod_config[$module])) {
168 self::$module_info[$module]['enabled'] = $mod_config[$module];
169 return $mod_config[$module];
170 }
171
172 throw new \Exception("Invalid module.enable value for the '$module' module.");
173 }
174
175 if (assert_options(ASSERT_ACTIVE) &&
176 !file_exists($moduleDir.'/default-enable') &&
177 !file_exists($moduleDir.'/default-disable')
178 ) {
179 \SimpleSAML\Logger::error("Missing default-enable or default-disable file for the module $module");
180 }
181
182 if (file_exists($moduleDir.'/enable')) {
183 self::$module_info[$module]['enabled'] = true;
184 return true;
185 }
186
187 if (!file_exists($moduleDir.'/disable') && file_exists($moduleDir.'/default-enable')) {
188 self::$module_info[$module]['enabled'] = true;
189 return true;
190 }
191
192 self::$module_info[$module]['enabled'] = false;
193 return false;
194 }
195
196
204 public static function getModules()
205 {
206 if (!empty(self::$modules)) {
207 return self::$modules;
208 }
209
210 $path = self::getModuleDir('.');
211
212 $dh = scandir($path);
213 if ($dh === false) {
214 throw new \Exception('Unable to open module directory "'.$path.'".');
215 }
216
217 foreach ($dh as $f) {
218 if ($f[0] === '.') {
219 continue;
220 }
221
222 if (!is_dir($path.'/'.$f)) {
223 continue;
224 }
225
226 self::$modules[] = $f;
227 }
228
229 return self::$modules;
230 }
231
232
252 public static function resolveClass($id, $type, $subclass = null)
253 {
254 assert('is_string($id)');
255 assert('is_string($type)');
256 assert('is_string($subclass) || is_null($subclass)');
257
258 $tmp = explode(':', $id, 2);
259 if (count($tmp) === 1) { // no module involved
260 $className = $tmp[0];
261 if (!class_exists($className)) {
262 throw new \Exception("Could not resolve '$id': no class named '$className'.");
263 }
264 } else { // should be a module
265 // make sure empty types are handled correctly
266 $type = (empty($type)) ? '_' : '_'.$type.'_';
267
268 // check for the old-style class names
269 $className = 'sspmod_'.$tmp[0].$type.$tmp[1];
270
271 if (!class_exists($className)) {
272 // check for the new-style class names, using namespaces
273 $type = str_replace('_', '\\', $type);
274 $newClassName = 'SimpleSAML\Module\\'.$tmp[0].$type.$tmp[1];
275
276 if (!class_exists($newClassName)) {
277 throw new \Exception("Could not resolve '$id': no class named '$className' or '$newClassName'.");
278 }
279 $className = $newClassName;
280 }
281 }
282
283 if ($subclass !== null && !is_subclass_of($className, $subclass)) {
284 throw new \Exception(
285 'Could not resolve \''.$id.'\': The class \''.$className.'\' isn\'t a subclass of \''.$subclass.'\'.'
286 );
287 }
288
289 return $className;
290 }
291
292
303 public static function getModuleURL($resource, array $parameters = array())
304 {
305 assert('is_string($resource)');
306 assert('$resource[0] !== "/"');
307
308 $url = Utils\HTTP::getBaseURL().'module.php/'.$resource;
309 if (!empty($parameters)) {
310 $url = Utils\HTTP::addURLParameters($url, $parameters);
311 }
312 return $url;
313 }
314
315
325 public static function getModuleHooks($module)
326 {
327 if (isset(self::$modules[$module]['hooks'])) {
328 return self::$modules[$module]['hooks'];
329 }
330
331 $hook_dir = self::getModuleDir($module).'/hooks';
332 if (!is_dir($hook_dir)) {
333 return array();
334 }
335
336 $hooks = array();
337 $files = scandir($hook_dir);
338 foreach ($files as $file) {
339 if ($file[0] === '.') {
340 continue;
341 }
342
343 if (!preg_match('/hook_(\w+)\.php/', $file, $matches)) {
344 continue;
345 }
346 $hook_name = $matches[1];
347 $hook_func = $module.'_hook_'.$hook_name;
348 $hooks[$hook_name] = array('file' => $hook_dir.'/'.$file, 'func' => $hook_func);
349 }
350 return $hooks;
351 }
352
353
364 public static function callHooks($hook, &$data = null)
365 {
366 assert('is_string($hook)');
367
368 $modules = self::getModules();
369 $config = \SimpleSAML_Configuration::getOptionalConfig()->getArray('module.enable', array());
370 sort($modules);
371 foreach ($modules as $module) {
372 if (!self::isModuleEnabledWithConf($module, $config)) {
373 continue;
374 }
375
376 if (!isset(self::$module_info[$module]['hooks'])) {
377 self::$module_info[$module]['hooks'] = self::getModuleHooks($module);
378 }
379
380 if (!isset(self::$module_info[$module]['hooks'][$hook])) {
381 continue;
382 }
383
384 require_once(self::$module_info[$module]['hooks'][$hook]['file']);
385
386 if (!is_callable(self::$module_info[$module]['hooks'][$hook]['func'])) {
387 throw new \SimpleSAML_Error_Exception('Invalid hook \''.$hook.'\' for module \''.$module.'\'.');
388 }
389
390 $fn = self::$module_info[$module]['hooks'][$hook]['func'];
391 $fn($data);
392 }
393 }
394}
PHPExcel root directory.
Definition: PHPExcel.php:30
An exception for terminatinating execution or to throw for unit testing.
static warning($string)
Definition: Logger.php:179
static error($string)
Definition: Logger.php:168
static autoloadPSR4($className)
Autoload function for SimpleSAMLphp modules following PSR-4.
Definition: Module.php:83
static getModuleDir($module)
Retrieve the base directory for a module.
Definition: Module.php:122
static autoloadPSR0($className)
Autoload function for SimpleSAMLphp modules following PSR-0.
Definition: Module.php:39
static getModules()
Get available modules.
Definition: Module.php:204
static resolveClass($id, $type, $subclass=null)
Resolve module class.
Definition: Module.php:252
static isModuleEnabled($module)
Determine whether a module is enabled.
Definition: Module.php:142
static isModuleEnabledWithConf($module, $mod_config)
Definition: Module.php:149
static getOptionalConfig($filename='config.php', $configSet='simplesaml')
Load a configuration file from a configuration set.
if(!array_key_exists('StateId', $_REQUEST)) $id
if($modEnd===false) $module
Definition: module.php:59
if( $url===false) if(!SimpleSAML\Module::isModuleEnabled($module)) if(strpos( $url, '\\') !==false) elseif(strpos($url, './') !==false) $moduleDir
Definition: module.php:79
Attribute-related utility methods.
$type
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file