summaryrefslogtreecommitdiffstats
path: root/lib/SimpleSAML/Module.php
blob: b61ec2de532af4cf6fc4f42d5b54d5cf9ad495e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php 

/**
 * Helper class for accessing information about modules.
 *
 * @author Olav Morken, UNINETT AS.
 * @package simpleSAMLphp
 * @version $Id$
 */
class SimpleSAML_Module {


	/**
	 * Retrieve the base directory for a module.
	 *
	 * The returned path name will be an absoulte path.
	 *
	 * @param string $module  Name of the module
	 * @return string  The base directory of a module.
	 */
	public static function getModuleDir($module) {
		$baseDir = dirname(dirname(dirname(__FILE__))) . '/modules';
		$moduleDir = $baseDir . '/' . $module;

		return $moduleDir;
	}


	/**
	 * Determine whether a module is enabled.
	 *
	 * Will return FALSE if the given module doesn't exists.
	 *
	 * @param string $module  Name of the module
	 * @return bool  TRUE if the given module is enabled, FALSE if not.
	 */
	public static function isModuleEnabled($module) {

		$moduleDir = self::getModuleDir($module);

		if(!is_dir($moduleDir)) {
			return FALSE;
		}

		assert('file_exists($moduleDir . "/default-disable") || file_exists($moduleDir . "/default-enable")');

		if(file_exists($moduleDir . '/enable')) {
			return TRUE;
		}

		if(!file_exists($moduleDir . '/disable') && file_exists($moduleDir . '/default-enable')) {
			return TRUE;
		}

		return FALSE;
	}


	/**
	 * Get available modules.
	 *
	 * @return array  One string for each module.
	 */
	public static function getModules() {

		$path = self::getModuleDir('.');

		$dh = opendir($path);
		if($dh === FALSE) {
			throw new Exception('Unable to open module directory "' . $path . '".');
		}

		$modules = array();

		while( ($f = readdir($dh)) !== FALSE) {
			if($f[0] === '.') {
				continue;
			}

			if(!is_dir($path . '/' . $f)) {
				continue;
			}

			$modules[] = $f;
		}

		closedir($dh);

		return $modules;
	}


	/**
	 * Resolve module class.
	 *
	 * This function takes a string on the form "<module>:<class>" and converts it to a class
	 * name. It can also check that the given class is a subclass of a specific class. The
	 * resolved classname will be "sspmod_<module>_<$type>_<class>.
	 *
	 * It is also possible to specify a full classname instead of <module>:<class>.
	 *
	 * An exception will be thrown if the class can't be resolved.
	 *
	 * @param string $id  The string we should resolve.
	 * @param string $type  The type of the class.
	 * @param string|NULL $subclass  The class should be a subclass of this class. Optional.
	 * @return string  The classname.
	 */
	public static function resolveClass($id, $type, $subclass = NULL) {
		assert('is_string($id)');
		assert('is_string($type)');
		assert('is_string($subclass) || is_null($subclass)');

		$tmp = explode(':', $id, 2);
		if (count($tmp) === 1) {
			$className = $tmp[0];
		} else {
			$className = 'sspmod_' . $tmp[0] . '_' . $type . '_' . $tmp[1];
		}

		if (!class_exists($className)) {
			throw new Exception('Could not resolve \'' . $id .
				'\': No class named \'' . $className . '\'.');
		} elseif ($subclass !== NULL && !is_subclass_of($className, $subclass)) {
			throw new Exception('Could not resolve \'' . $id . '\': The class \'' .
				$className . '\' isn\'t a subclass of \'' . $subclass . '\'.');
		}

		return $className;
	}


	/**
	 * Get absolute URL to a specified module resource.
	 *
	 * This function creates an absolute URL to a resource stored under ".../modules/<module>/www/".
	 *
	 * @param string $resource  Resource path, on the form "<module name>/<resource>"
	 * @return string  The absolute URL to the given resource.
	 */
	public static function getModuleURL($resource) {
		assert('is_string($resource)');
		assert('$resource[0] !== "/"');

		$config = SimpleSAML_Configuration::getInstance();
		return SimpleSAML_Utilities::selfURLhost() . '/' . $config->getBaseURL() . 'module.php/' . $resource;
	}


	/**
	 * Call a hook in all enabled modules.
	 *
	 * This function iterates over all enabled modules and calls a hook in each module.
	 *
	 * @param string $hook  The name of the hook.
	 * @param mixed &$data  The data which should be passed to each hook. Will be passed as a reference.
	 */
	public static function callHooks($hook, &$data = NULL) {
		assert('is_string($hook)');

		foreach (self::getModules() as $module) {
			if (!self::isModuleEnabled($module)) {
				continue;
			}

			$hookfile = self::getModuleDir($module) . '/hooks/hook_' . $hook . '.php';
			if (!file_exists($hookfile)) {
				continue;
			}

			require_once($hookfile);

			$hookfunc = $module . '_hook_' . $hook;
			assert('is_callable($hookfunc)');

			$hookfunc($data);
		}
	}

}

?>