ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
Module.php
Go to the documentation of this file.
1 <?php
2 namespace SimpleSAML;
3 
12 class 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 }
if($url===false) if(!SimpleSAML\Module::isModuleEnabled($module)) if(strpos($url, '\\') !==false) elseif(strpos($url, './') !==false) $moduleDir
Definition: module.php:79
$type
static getModules()
Get available modules.
Definition: Module.php:204
static isModuleEnabledWithConf($module, $mod_config)
Definition: Module.php:149
if(!array_key_exists('StateId', $_REQUEST)) $id
static getModuleDir($module)
Retrieve the base directory for a module.
Definition: Module.php:122
if($modEnd===false) $module
Definition: module.php:59
Attribute-related utility methods.
static isModuleEnabled($module)
Determine whether a module is enabled.
Definition: Module.php:142
static warning($string)
Definition: Logger.php:179
static error($string)
Definition: Logger.php:168
static autoloadPSR0($className)
Autoload function for SimpleSAMLphp modules following PSR-0.
Definition: Module.php:39
Reload workbook from saved file
Create styles array
The data for the language used.
static getOptionalConfig($filename='config.php', $configSet='simplesaml')
Load a configuration file from a configuration set.
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
static resolveClass($id, $type, $subclass=null)
Resolve module class.
Definition: Module.php:252
static autoloadPSR4($className)
Autoload function for SimpleSAMLphp modules following PSR-4.
Definition: Module.php:83
PHPExcel root directory.
Definition: Database.php:30