20 public static $modules = array();
27 public static $module_info = array();
41 $modulePrefixLength = strlen(
'sspmod_');
42 $classPrefix = substr($className, 0, $modulePrefixLength);
43 if ($classPrefix !==
'sspmod_') {
47 $modNameEnd = strpos($className,
'_', $modulePrefixLength);
48 $module = substr($className, $modulePrefixLength, $modNameEnd - $modulePrefixLength);
49 $path = explode(
'_', substr($className, $modNameEnd + 1));
51 if (!self::isModuleEnabled(
$module)) {
56 if (!file_exists(
$file)) {
61 if (!class_exists($className,
false) && !interface_exists($className,
false)) {
63 $nspath = join(
'\\',
$path);
64 if (class_exists(
'SimpleSAML\Module\\'.
$module.
'\\'.$nspath) ||
65 interface_exists(
'SimpleSAML\Module\\'.
$module.
'\\'.$nspath)
69 "The class or interface '$className' is now using namespaces, please use 'SimpleSAML\\Module\\".
70 $module.
"\\".$nspath.
"' instead."
72 class_alias(
"SimpleSAML\\Module\\$module\\$nspath", $className);
85 $elements = explode(
'\\', $className);
86 if ($elements[0] ===
'') {
87 array_shift($elements);
89 if (count($elements) < 4) {
92 if (array_shift($elements) !==
'SimpleSAML') {
95 if (array_shift($elements) !==
'Module') {
100 $module = array_shift($elements);
101 if (!self::isModuleEnabled(
$module)) {
105 $file = self::getModuleDir(
$module).
'/lib/'.implode(
'/', $elements).
'.php';
107 if (file_exists(
$file)) {
124 $baseDir = dirname(dirname(dirname(__FILE__))).
'/modules';
145 return self::isModuleEnabledWithConf(
$module,
$config->getArray(
'module.enable', array()));
151 if (isset(self::$module_info[
$module][
'enabled'])) {
152 return self::$module_info[
$module][
'enabled'];
155 if (!empty(self::$modules) && !in_array(
$module, self::$modules,
true)) {
162 self::$module_info[
$module][
'enabled'] =
false;
166 if (isset($mod_config[
$module])) {
167 if (is_bool($mod_config[
$module])) {
172 throw new \Exception(
"Invalid module.enable value for the '$module' module.");
175 if (assert_options(ASSERT_ACTIVE) &&
183 self::$module_info[
$module][
'enabled'] =
true;
188 self::$module_info[
$module][
'enabled'] =
true;
192 self::$module_info[
$module][
'enabled'] =
false;
206 if (!empty(self::$modules)) {
207 return self::$modules;
210 $path = self::getModuleDir(
'.');
212 $dh = scandir(
$path);
214 throw new \Exception(
'Unable to open module directory "'.
$path.
'".');
217 foreach ($dh as $f) {
222 if (!is_dir(
$path.
'/'.$f)) {
226 self::$modules[] = $f;
229 return self::$modules;
254 assert(
'is_string($id)');
255 assert(
'is_string($type)');
256 assert(
'is_string($subclass) || is_null($subclass)');
258 $tmp = explode(
':',
$id, 2);
259 if (count($tmp) === 1) {
260 $className = $tmp[0];
261 if (!class_exists($className)) {
262 throw new \Exception(
"Could not resolve '$id': no class named '$className'.");
269 $className =
'sspmod_'.$tmp[0].$type.$tmp[1];
271 if (!class_exists($className)) {
274 $newClassName =
'SimpleSAML\Module\\'.$tmp[0].$type.$tmp[1];
276 if (!class_exists($newClassName)) {
277 throw new \Exception(
"Could not resolve '$id': no class named '$className' or '$newClassName'.");
279 $className = $newClassName;
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.
'\'.
'
303 public static function getModuleURL($resource, array $parameters = array())
305 assert('is_string($resource)
');
306 assert('$resource[0] !==
"/"');
308 $url = Utils\HTTP::getBaseURL().'module.php/
'.$resource;
309 if (!empty($parameters)) {
310 $url = Utils\HTTP::addURLParameters($url, $parameters);
325 public static function getModuleHooks($module)
327 if (isset(self::$modules[$module]['hooks
'])) {
328 return self::$modules[$module]['hooks
'];
331 $hook_dir = self::getModuleDir($module).'/hooks
';
332 if (!is_dir($hook_dir)) {
337 $files = scandir($hook_dir);
338 foreach ($files as $file) {
339 if ($file[0] === '.
') {
343 if (!preg_match('/hook_(\w+)\.
php/
', $file, $matches)) {
346 $hook_name = $matches[1];
347 $hook_func = $module.'_hook_
'.$hook_name;
348 $hooks[$hook_name] = array('file
' => $hook_dir.'/
'.$file, 'func
' => $hook_func);
364 public static function callHooks($hook, &$data = null)
366 assert('is_string($hook)
');
368 $modules = self::getModules();
369 $config = \SimpleSAML_Configuration::getOptionalConfig()->getArray('module.enable
', array());
371 foreach ($modules as $module) {
372 if (!self::isModuleEnabledWithConf($module, $config)) {
376 if (!isset(self::$module_info[$module]['hooks
'])) {
377 self::$module_info[$module]['hooks
'] = self::getModuleHooks($module);
380 if (!isset(self::$module_info[$module]['hooks
'][$hook])) {
384 require_once(self::$module_info[$module]['hooks
'][$hook]['file
']);
386 if (!is_callable(self::$module_info[$module]['hooks
'][$hook]['func
'])) {
387 throw new \SimpleSAML_Error_Exception('Invalid hook \
''.$hook.
'\' for module \
''.$module.
'\'.
');
390 $fn = self::$module_info[$module]['hooks
'][$hook]['func
'];
An exception for terminatinating execution or to throw for unit testing.
static autoloadPSR4($className)
Autoload function for SimpleSAMLphp modules following PSR-4.
static getModuleDir($module)
Retrieve the base directory for a module.
static autoloadPSR0($className)
Autoload function for SimpleSAMLphp modules following PSR-0.
static getModules()
Get available modules.
static resolveClass($id, $type, $subclass=null)
Resolve module class.
static isModuleEnabled($module)
Determine whether a module is enabled.
static isModuleEnabledWithConf($module, $mod_config)
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
if( $url===false) if(!SimpleSAML\Module::isModuleEnabled($module)) if(strpos( $url, '\\') !==false) elseif(strpos($url, './') !==false) $moduleDir
Attribute-related utility methods.
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file