00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 @require_once('config.inc.php');
00013 require_once('log.inc.php');
00014
00015 if (!isset($hooks)) {
00016 $hooks = array();
00017 }
00018 if (!isset($modules)) {
00019 $modules = array();
00020 }
00021 if (!isset($services)) {
00022 $services = array();
00023 }
00024
00025
00026
00027
00028
00029
00030
00031 function get_hooks()
00032 {
00033 global $hooks;
00034 return $hooks;
00035 }
00036
00037
00038
00039
00040
00041
00042
00043 function get_modules()
00044 {
00045 global $modules;
00046
00047
00048 return $modules;
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 function get_service($service)
00060 {
00061 global $services;
00062 if (!isset($services[$service])) {
00063 return false;
00064 } else {
00065 return $services[$service];
00066 }
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 function invoke_hook($hook, $args = array(), $first_module = '', $last_module = '')
00081 {
00082 global $modules;
00083
00084 $ret = array();
00085
00086 load_modules();
00087
00088
00089 $func = $first_module.'_'.$hook;
00090 if (!empty($first_module) && is_callable($func)) {
00091
00092 log_msg('debug', 'modules: invoking hook '.$hook.', calling first '.$func);
00093 $cur = $func($args);
00094 $ret[$first_module] = $cur;
00095 }
00096
00097 foreach ($modules as $m) {
00098 $func = $m.'_'.$hook;
00099 if ($m != $first_module && $m != $last_module && is_callable($func)) {
00100
00101 log_msg('debug', 'modules: invoking hook '.$hook.', calling '.$func);
00102
00103
00104
00105 $cur = $func($args);
00106 $ret[$m] = $cur;
00107 }
00108 }
00109
00110
00111 $func = $last_module.'_'.$hook;
00112 if (!empty($last_module) && is_callable($func)) {
00113
00114 log_msg('debug', 'modules: invoking hook '.$hook.', calling last '.$func);
00115 $cur = $func($args);
00116 $ret[$last_module] = $cur;
00117 }
00118
00119 log_msg('debug', 'modules: invoke_hook on '.$hook.' returned '.var_dump_inl($ret));
00120 return $ret;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 function invoke_hook_first($hook, $first_module, $args = array())
00134 {
00135 return invoke_hook($hook, $args, $first_module, '');
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 function invoke_hook_last($hook, $last_module, $args = array())
00149 {
00150 return invoke_hook($hook, $args, '', $last_module);
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 function invoke_hook_while($hook, $while, $args = array())
00164 {
00165 global $modules;
00166
00167
00168 load_modules();
00169
00170 foreach ($modules as $m) {
00171 if (is_callable($m.'_'.$hook)) {
00172 $func = $m.'_'.$hook;
00173
00174 log_msg('debug', 'modules: invoking hook '.$hook.', calling '.$func);
00175 $cur = $func($args);
00176 if ($cur !== $while) {
00177 $ret = array($m=>$cur);
00178
00179
00180 return $ret;
00181 }
00182 }
00183 }
00184
00185 log_msg('debug', 'modules: invoke_hook_while on '.$hook.' returned '.var_dump_inl(array()));
00186 return array();
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 function load_modules($search = '', $optional = false)
00199 {
00200 global $modules;
00201 $late_loading = count($modules) ? true : false;
00202
00203
00204 if (($p = strpos($search, '.')) !== false) {
00205 $search = substr($search, 0, $p);
00206 }
00207
00208 $files = scandir('.');
00209 foreach ($files as $f) {
00210 if (strtolower(substr($f, 0, 7)) != 'module_' || strtolower(substr($f, -4)) != '.php') {
00211 continue;
00212 }
00213
00214 if (substr($f, -8) == '.inc.php') {
00215 $name = substr($f, 7, -8);
00216 } else {
00217 $name = substr($f, 7, -4);
00218 }
00219 if (in_array($name, $modules)) {
00220 continue;
00221 }
00222 if ($search != '' && strtolower($name) != $search) {
00223 continue;
00224 }
00225
00226 ob_start();
00227 if ($late_loading) {
00228 log_msg('debug', 'modules: late-loading module '.$name);
00229 } else {
00230 log_msg('debug', 'modules: loading module '.$name);
00231 }
00232 @include_once($f);
00233 $s = ob_get_contents();
00234 log_msg('debug', 'modules: finished loading module '.$name.', output '.quot($s));
00235 ob_end_clean();
00236
00237 $modules[] = $name;
00238 }
00239
00240
00241 if (!empty($search) && empty($modules) && !$optional) {
00242 log_msg('error', 'modules: cannot find required module '.$search.', make sure it is installed in the program directory');
00243 return false;
00244 } else {
00245 return true;
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 function register_service($service, $func, $args = array())
00260 {
00261 global $services;
00262 $trace = debug_backtrace();
00263 $services[$service] = array_merge(array('args'=>array()), array_merge($args, array('func'=>$func, 'file'=>basename($trace[0]['file']), 'line'=>$trace[0]['line'])));
00264 log_msg('debug', 'modules: '.basename($trace[0]['file']).':'.$trace[0]['line'].' registered service '.quot($service));
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 function register_hook($hook, $info = '')
00277 {
00278 global $hooks;
00279 $trace = debug_backtrace();
00280 $hooks[$hook] = array('file'=>basename($trace[0]['file']), 'line'=>$trace[0]['line'], 'info'=>$info);
00281 log_msg('debug', 'modules: '.basename($trace[0]['file']).':'.$trace[0]['line'].' registered hook '.quot($hook));
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 function response($data, $error = false)
00294 {
00295 $ret = array();
00296 if ($error === false) {
00297 $ret['#error'] = false;
00298 } else {
00299 $ret['#error'] = true;
00300 }
00301 if (is_numeric($error)) {
00302 $ret['#error_code'] = intval($error);
00303 }
00304 $ret['#data'] = $data;
00305 return $ret;
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 function run_service($service, $args = array())
00320 {
00321 global $services;
00322
00323 if (!isset($services[$service])) {
00324 return response('Unknown service '.quot($service), 400);
00325 }
00326
00327
00328 foreach ($services[$service]['args'] as $key=>$val) {
00329 if (!isset($args[$key])) {
00330 if (isset($val['req']) && $val['req']) {
00331 return response('Required argument '.quot($key).' missing', 400);
00332 } elseif (isset($val['def'])) {
00333 $args[$key] = $val['def'];
00334 }
00335 }
00336 if (isset($val['type'])) {
00337 if ($val['type'] == 'array') {
00338 if (is_array($args[$key])) {
00339
00340 } elseif (is_object($args[$key])) {
00341
00342 $args[$key] = (array)$args[$key];
00343 } else {
00344 return response('Invalid type of argument '.quot($key).', expected array', 400);
00345 }
00346 } elseif ($val['type'] == 'bool') {
00347 if (is_bool($args[$key])) {
00348
00349 } elseif (intval($args[$key]) === 1) {
00350 $args[$key] = true;
00351 } elseif (intval($args[$key]) === 0) {
00352 $args[$key] = false;
00353 } else {
00354 return response('Invalid type of argument '.quot($key).', expected bool', 400);
00355 }
00356 } elseif ($val['type'] == 'float') {
00357 if (!is_numeric($args[$key])) {
00358 return response('Invalid type of argument '.quot($key).', expected float', 400);
00359 } else {
00360 $args[$key] = floatval($args[$key]);
00361 }
00362 } elseif ($val['type'] == 'int') {
00363 if (!is_numeric($args[$key])) {
00364 return response('Invalid type of argument '.quot($key).', expected int', 400);
00365 } else {
00366 $args[$key] = intval($args[$key]);
00367 }
00368 } elseif ($val['type'] == 'string') {
00369 $args[$key] = strval($args[$key]);
00370 } else {
00371 log_msg('error', 'modules: invalid type given for argument '.quot($key).' of service '.quot($service));
00372 }
00373 }
00374 }
00375
00376 log_msg('info', 'modules: running service '.quot($service));
00377 return $services[$service]['func']($args);
00378 }