egroupware/phpgwapi/inc/horde/Horde/Registry.php
2005-06-19 19:00:58 +00:00

1029 lines
34 KiB
PHP

<?php
/** Do not start a session. */
define('HORDE_SESSION_NONE', 1);
/** Do not write changes to session. */
define('HORDE_SESSION_READONLY', 2);
/**
* The Registry:: class provides a set of methods for communication
* between Horde applications and keeping track of application
* configuration information.
*
* $Horde: framework/Horde/Horde/Registry.php,v 1.249 2005/02/14 18:00:59 jan Exp $
*
* Copyright 1999-2005 Chuck Hagenbuch <chuck@horde.org>
* Copyright 1999-2005 Jon Parise <jon@horde.org>
* Copyright 1999-2005 Anil Madhavapeddy <anil@recoil.org>
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*
* @author Chuck Hagenbuch <chuck@horde.org>
* @author Jon Parise <jon@horde.org>
* @author Anil Madhavapeddy <anil@recoil.org>
* @since Horde 1.3
* @package Horde_Framework
*/
class Registry {
/**
* Hash storing all of the known services and callbacks.
*
* @var array $_apiCache
*/
var $_apiCache = array();
/**
* Hash storing all known data types.
*
* @var array $_typeCache
*/
var $_typeCache = array();
/**
* Hash storing all of the registered interfaces that applications
* provide.
*
* @var array $_interfaces
*/
var $_interfaces = array();
/**
* Hash storing information on each registry-aware application.
*
* @var array $applications
*/
var $applications = array();
/**
* Stack of in-use applications.
*
* @var array $_appStack
*/
var $_appStack = array();
/**
* Quick pointer to the current application.
*
* @var $_currentApp
*/
var $_currentApp = null;
/**
* Cache of $prefs objects
*
* @var array $_prefsCache
*/
var $_prefsCache = array();
/**
* Cache of application configurations.
*
* @var array $_confCache
*/
var $_confCache = array();
/**
* Returns a reference to the global Registry object, only
* creating it if it doesn't already exist.
*
* This method must be invoked as: $registry = &Registry::singleton()
*
* @param optional integer $session_flags Any session flags.
*
* @return object Registry The Horde Registry instance.
*/
function &singleton($session_flags = 0)
{
static $registry;
if (!isset($registry)) {
$registry = new Registry($session_flags);
}
return $registry;
}
/**
* Create a new registry instance. Should never be called except
* by &Registry::singleton().
*
* @param optional integer $session_flags Any session flags.
*
* @access private
*/
function Registry($session_flags = 0)
{
/* Import and global Horde's configuration values. */
$this->importConfig('horde');
/* Start a session. */
if ($session_flags & HORDE_SESSION_NONE) {
/* Never start a session if the session flags include
HORDE_SESSION_NONE. */
$_SESSION = array();
} else {
Horde::setupSessionHandler();
@session_start();
if ($session_flags & HORDE_SESSION_READONLY) {
/* Close the session immediately so no changes can be
made but values are still available. */
@session_write_close();
}
}
/* Read the registry configuration file. */
require_once HORDE_BASE . '/config/registry.php';
/* Initialize the localization routines and variables. */
# NLS::setLang();
# NLS::setTextdomain('horde', HORDE_BASE . '/locale', NLS::getCharset());
# String::setDefaultCharset(NLS::getCharset());
/* Stop system if Horde is inactive. */
if ($this->applications['horde']['status'] == 'inactive') {
Horde::fatal(_("This system is currently deactivated."), __FILE__, __LINE__);
}
/* Scan for all APIs provided by each app, and set other
* common defaults like templates and graphics. */
$appList = array_keys($this->applications);
foreach ($appList as $appName) {
$app = &$this->applications[$appName];
if (($app['status'] == 'heading') ||
($app['status'] == 'inactive') ||
($app['status'] == 'admin' && !Auth::isAdmin())) {
continue;
}
if (isset($app['provides'])) {
if (is_array($app['provides'])) {
foreach ($app['provides'] as $interface) {
$this->_interfaces[$interface] = $appName;
}
} else {
$this->_interfaces[$app['provides']] = $appName;
}
}
if (!isset($app['templates']) && isset($app['fileroot'])) {
$app['templates'] = $app['fileroot'] . '/templates';
}
if (!isset($app['jsuri']) && isset($app['webroot'])) {
$app['jsuri'] = $app['webroot'] . '/js';
}
if (!isset($app['jsfs']) && isset($app['fileroot'])) {
$app['jsfs'] = $app['fileroot'] . '/js';
}
if (!isset($app['themesuri']) && isset($app['webroot'])) {
$app['themesuri'] = $app['webroot'] . '/themes';
}
if (!isset($app['themesfs']) && isset($app['fileroot'])) {
$app['themesfs'] = $app['fileroot'] . '/themes';
}
}
# /* Create the global Perms object. */
# $GLOBALS['perms'] = &Perms::singleton();
# /* Attach javascript notification listener. */
# $notification = &Notification::singleton();
# $notification->attach('javascript');
/* Register access key logger for translators. */
if (@$GLOBALS['conf']['log_accesskeys']) {
register_shutdown_function(create_function('', 'Horde::getAccessKey(null, null, true);'));
}
}
/**
* Return a list of the installed and registered applications.
*
* @since Horde 2.2
*
* @access public
*
* @param array $filter (optional) An array of the statuses that
* should be returned. Defaults to non-hidden.
* @param boolean $assoc (optional) Associative array with app names
* as keys.
* @param integer $permission (optional) The permission level to check
* for in the list. Defaults to PERMS_SHOW.
*
* @return array List of apps registered with Horde. If no
* applications are defined returns an empty array.
*/
function listApps($filter = null, $assoc = false, $permission = PERMS_SHOW)
{
$apps = array();
if (is_null($filter)) {
$filter = array('notoolbar', 'active');
}
foreach ($this->applications as $app => $params) {
if (in_array($params['status'], $filter) &&
(defined('AUTH_HANDLER') || $this->hasPermission($app, $permission))) {
$assoc ? $apps[$app] = $app : $apps[] = $app;
}
}
return $apps;
}
/**
* Returns all available registry APIs.
*
* @access public
*
* @return array The API list.
*/
function listAPIs()
{
$apis = array();
foreach (array_keys($this->_interfaces) as $interface) {
@list($api, ) = explode('/', $interface);
$apis[] = $api;
}
return array_unique($apis);
}
/**
* Returns all of the available registry methods, or alternately
* only those for a specified API.
*
* @access public
*
* @param optional string $api Defines the API for which the methods
* shall be returned.
*
* @return array The method list.
*/
function listMethods($api = null)
{
$methods = array();
$this->_fillAPICache();
foreach (array_keys($this->applications) as $app) {
if (isset($this->applications[$app]['provides'])) {
$provides = $this->applications[$app]['provides'];
if (!is_array($provides)) {
$provides = array($provides);
}
} else {
$provides = array();
}
foreach ($provides as $method) {
if (strpos($method, '/') !== false) {
if (is_null($api) ||
(substr($method, 0, strlen($api)) == $api)) {
$methods[] = $method;
}
} elseif (is_null($api) || ($method == $api)) {
if (isset($this->_apiCache[$app])) {
foreach (array_keys($this->_apiCache[$app]) as $service) {
$methods[] = $method . '/' . $service;
}
}
}
}
}
return array_unique($methods);
}
/**
* Returns all of the available registry data types.
*
* @access public
*
* @return array The data type list.
*/
function listTypes()
{
$this->_fillAPICache();
return $this->_typeCache;
}
/**
* Returns a method's signature.
*
* @access public
*
* @param string $method The full name of the method to check for.
*
* @return array A two dimensional array. The first element contains an
* array with the parameter names, the second one the return
* type.
*/
function getSignature($method)
{
if (!($app = $this->hasMethod($method))) {
return;
}
$this->_fillAPICache();
@list(, $function) = explode('/', $method);
if (isset($this->_apiCache[$app][$function]['type']) &&
isset($this->_apiCache[$app][$function]['args'])) {
return array($this->_apiCache[$app][$function]['args'], $this->_apiCache[$app][$function]['type']);
}
}
/**
* Determine if an interface is implemented by an active
* application.
*
* @access public
*
* @param string $interface The interface to check for.
*
* @return mixed The application implementing $interface if we have it,
* false if the interface is not implemented.
*/
function hasInterface($interface)
{
return !empty($this->_interfaces[$interface]) ?
$this->_interfaces[$interface] :
false;
}
/**
* Determine if a method has been registered with the registry.
*
* @access public
*
* @param string $method The full name of the method to check for.
* @param string $app (optional) Only check this application.
*
* @return mixed The application implementing $method if we have it,
* false if the method doesn't exist.
*/
function hasMethod($method, $app = null)
{
if (is_null($app)) {
@list($interface, $call) = explode('/', $method);
if (!empty($this->_interfaces[$method])) {
$app = $this->_interfaces[$method];
} elseif (!empty($this->_interfaces[$interface])) {
$app = $this->_interfaces[$interface];
} else {
return false;
}
} else {
$call = $method;
}
$this->_fillAPICache();
return !empty($this->_apiCache[$app][$call]) ? $app : false;
}
/**
* Return the hook corresponding to the default package that
* provides the functionality requested by the $method
* parameter. $method is a string consisting of
* "packagetype/methodname".
*
* @access public
*
* @param string $method The method to call.
* @param optional array $args Arguments to the method.
*
* @return TODO
* Returns PEAR_Error on error.
*/
function call($method, $args = array())
{
@list($interface, $call) = explode('/', $method);
if (!empty($this->_interfaces[$method])) {
$app = $this->_interfaces[$method];
} elseif (!empty($this->_interfaces[$interface])) {
$app = $this->_interfaces[$interface];
} else {
return PEAR::raiseError('The method "' . $method . '" is not defined in the Horde Registry.');
}
return $this->callByPackage($app, $call, $args);
}
/**
* Output the hook corresponding to the specific package named.
*
* @access public
*
* @param string $app The application being called.
* @param string $call The method to call.
* @param optional array $args Arguments to the method.
*
* @return TODO
* Returns PEAR_Error on error.
*/
function callByPackage($app, $call, $args = array())
{
/* Note: calling hasMethod() makes sure that we've cached
* $app's services and included the API file, so we don't try
* to do it again explicitly in this method. */
if (!$this->hasMethod($call, $app)) {
return PEAR::raiseError(sprintf('The method "%s" is not defined in the API for %s.', $call, $app));
}
/* Make sure that the function actually exists. */
$function = '_' . $app . '_' . $call;
if (!function_exists($function)) {
return PEAR::raiseError('The function implementing ' . $call . ' (' . $function . ') is not defined in ' . $app . '\'s API.');
}
$checkPerms = isset($this->_apiCache[$app][$call]['checkperms']) ?
$this->_apiCache[$app][$call]['checkperms'] : true;
/* Switch application contexts now, if necessary, before
* including any files which might do it for us. Return an
* error immediately if pushApp() fails. */
$pushed = $this->pushApp($app, $checkPerms);
if (is_a($pushed, 'PEAR_Error')) {
return $pushed;
}
$res = call_user_func_array($function, $args);
/* If we changed application context in the course of this
* call, undo that change now. */
if ($pushed === true) {
$this->popApp();
}
return $res;
}
/**
* Return the hook corresponding to the default package that
* provides the functionality requested by the $method
* parameter. $method is a string consisting of
* "packagetype/methodname".
*
* @access public
*
* @param string $method The method to link to.
* @param optional array $args Arguments to the method.
* @param optional mixed $extra Extra, non-standard arguments to the
* method.
*
* @return TODO
* Returns PEAR_Error on error.
*/
function link($method, $args = array(), $extra = '')
{
@list($interface, $call) = explode('/', $method);
if (!empty($this->_interfaces[$method])) {
$app = $this->_interfaces[$method];
} elseif (!empty($this->_interfaces[$interface])) {
$app = $this->_interfaces[$interface];
} else {
return PEAR::raiseError('The method "' . $method . '" is not defined in the Horde Registry.');
}
return $this->linkByPackage($app, $call, $args, $extra);
}
/**
* Output the hook corresponding to the specific package named.
*
* @access public
*
* @param string $app The application being called.
* @param string $call The method to link to.
* @param optional array $args Arguments to the method.
* @param optional mixed $extra Extra, non-standard arguments to the
* method.
*
* @return TODO
* Returns PEAR_Error on error.
*/
function linkByPackage($app, $call, $args = array(), $extra = '')
{
/* Note: calling hasMethod makes sure that we've cached $app's
* services and included the API file, so we don't try to do
* it it again explicitly in this method. */
if (!$this->hasMethod($call, $app)) {
return PEAR::raiseError('The method "' . $call . '" is not defined in ' . $app . '\'s API.');
}
/* Make sure the link is defined. */
if (empty($this->_apiCache[$app][$call]['link'])) {
return PEAR::raiseError('The link ' . $call . ' is not defined in ' . $app . '\'s API.');
}
/* Initial link value. */
$link = $this->_apiCache[$app][$call]['link'];
/* Fill in html-encoded arguments. */
foreach ($args as $key => $val) {
$link = str_replace('%' . $key . '%', htmlentities($val), $link);
}
if (isset($this->applications[$app]['webroot'])) {
$link = str_replace('%application%', $this->get('webroot', $app), $link);
}
/* Replace htmlencoded arguments that haven't been specified with
an empty string (this is where the default would be substituted
in a stricter registry implementation). */
$link = preg_replace('|%.+%|U', '', $link);
/* Fill in urlencoded arguments. */
foreach ($args as $key => $val) {
$link = str_replace('|' . String::lower($key) . '|', urlencode($val), $link);
}
/* Append any extra, non-standard arguments. */
if (is_array($extra)) {
$extra_args = '';
foreach ($extra as $key => $val) {
$extra_args .- '&' . urlencode($key) . '=' . urlencode($val);
}
} else {
$extra_args = $extra;
}
$link = str_replace('|extra|', $extra_args, $link);
/* Replace html-encoded arguments that haven't been specified with
an empty string (this is where the default would be substituted
in a stricter registry implementation). */
$link = preg_replace('|\|.+\||U', '', $link);
return $link;
}
/**
* Replace any %application% strings with the filesystem path to
* the application.
*
* @access public
*
* @param string $path The application string.
* @param optional string $app The application being called.
*
* @return TODO
* Returns PEAR_Error on error.
*/
function applicationFilePath($path, $app = null)
{
if (is_null($app)) {
$app = $this->_currentApp;
}
if (!isset($this->applications[$app])) {
return PEAR::raiseError(sprintf(_("'%s' is not configured in the Horde Registry."), $app));
}
return str_replace('%application%', $this->applications[$app]['fileroot'], $path);
}
/**
* Replace any %application% strings with the web path to the
* application.
*
* @access public
*
* @param string $path The application string.
* @param optional string $app The application being called.
*
* @return TODO
* Returns PEAR_Error on error.
*/
function applicationWebPath($path, $app = null)
{
if (!isset($app)) {
$app = $this->_currentApp;
}
return str_replace('%application%', $this->applications[$app]['webroot'], $path);
}
/**
* Set the current application, adding it to the top of the Horde
* application stack. If this is the first application to be
* pushed, retrieve session information as well.
*
* pushApp() also reads the application's configuration file and
* sets up its global $conf hash.
*
* @access public
*
* @param string $app The name of the application to push.
* @param boolean $checkPerms (optional) Make sure that the current user
* has permissions to the application being
* loaded. Defaults to true. Should ONLY
* be disabled by system scripts (cron jobs,
* etc.) and scripts that handle login.
*
* @return boolean Whether or not the _appStack was modified.
* Return PEAR_Error on error.
*/
function pushApp($app, $checkPerms = true)
{
if ($app == $this->_currentApp) {
return false;
}
/* Bail out if application is not present or inactive. */
if (!isset($this->applications[$app]) ||
$this->applications[$app]['status'] == 'inactive' ||
($this->applications[$app]['status'] == 'admin' && !Auth::isAdmin())) {
Horde::fatal($app . ' is not activated', __FILE__, __LINE__);
}
/* If permissions checking is requested, return an error if
* the current user does not have read perms to the
* application being loaded. We allow access:
*
* - To all admins.
* - To all authenticated users if no permission is set on $app.
* - To anyone who is allowed by an explicit ACL on $app. */
if ($checkPerms && !$this->hasPermission($app)) {
Horde::logMessage(sprintf('User %s does not have READ permission for %s', Auth::getAuth(), $app), __FILE__, __LINE__, PEAR_LOG_DEBUG);
return PEAR::raiseError(sprintf(_("User %s is not authorised for %s."), Auth::getAuth(), $this->applications[$app]['name']), 'permission_denied');
}
/* Import this application's configuration values. */
$success = $this->importConfig($app);
if (is_a($success, 'PEAR_Error')) {
return $success;
}
/* Load preferences after the configuration has been loaded to
* make sure the prefs file has all the information it needs. */
$this->loadPrefs($app);
/* Reset the language in case there is a different one
* selected in the preferences. */
$language = '';
if (isset($this->_prefsCache[$app]) &&
isset($this->_prefsCache[$app]->_prefs['language'])) {
$language = $this->_prefsCache[$app]->getValue('language');
}
NLS::setLang($language);
NLS::setTextdomain($app, $this->applications[$app]['fileroot'] . '/locale', NLS::getCharset());
String::setDefaultCharset(NLS::getCharset());
/* Once we know everything succeeded and is in a consistent
* state again, push the new application onto the stack. */
array_push($this->_appStack, $app);
$this->_currentApp = $app;
return true;
}
/**
* Remove the current app from the application stack, setting the
* current app to whichever app was current before this one took
* over.
*
* @access public
*
* @return string The name of the application that was popped.
*/
function popApp()
{
/* Pop the current application off of the stack. */
$previous = array_pop($this->_appStack);
/* Import the new active application's configuration values
* and set the gettext domain and the preferred language. */
$this->_currentApp = count($this->_appStack) ? end($this->_appStack) : null;
if ($this->_currentApp) {
$this->importConfig($this->_currentApp);
$this->loadPrefs($this->_currentApp);
#$language = $GLOBALS['prefs']->getValue('language');
#if (isset($language)) {
# NLS::setLang($language);
#}
NLS::setTextdomain($this->_currentApp, $this->applications[$this->_currentApp]['fileroot'] . '/locale', NLS::getCharset());
String::setDefaultCharset(NLS::getCharset());
}
return $previous;
}
/**
* Return the current application - the app at the top of the
* application stack.
*
* @access public
*
* @return string The current application.
*/
function getApp()
{
return $this->_currentApp;
}
/**
* Check permissions on an application.
*
* @access public
*
* @return boolean Whether or not access is allowed.
*/
function hasPermission($app, $permission = PERMS_READ)
{
return true;
#return Auth::isAdmin() || ($GLOBALS['perms']->exists($app) ?
# $GLOBALS['perms']->hasPermission($app, Auth::getAuth(), $permission) :
# (bool)Auth::getAuth());
}
/**
* Reads the configuration values for the given application and
* imports them into the global $conf variable.
*
* @access public
*
* @param string $app The name of the application.
*
* @return boolean True on success, PEAR_Error on error.
*/
function importConfig($app)
{
/* Don't make config files global $registry themselves. */
global $registry;
/* Cache config values so that we don't re-read files on every
* popApp() call. */
if (!isset($this->_confCache[$app])) {
if (!isset($this->_confCache['horde'])) {
$conf = array();
ob_start();
$success = include HORDE_BASE . '/config/conf.php';
$errors = ob_get_contents();
ob_end_clean();
if (!empty($errors)) {
return PEAR::raiseError(sprintf('Failed to import Horde configuration: %s', strip_tags($errors)));
}
if (!$success) {
return PEAR::raiseError('Failed to import Horde configuration.');
}
/* Initial Horde-wide settings. */
/* Set the error reporting level in accordance with
* the config settings. */
error_reporting($conf['debug_level']);
/* Set the maximum execution time in accordance with
* the config settings. */
@set_time_limit($conf['max_exec_time']);
/* Set the umask according to config settings. */
if (isset($conf['umask'])) {
umask($conf['umask']);
}
} else {
$conf = $this->_confCache['horde'];
}
if ($app !== 'horde') {
$success = @include $this->applications[$app]['fileroot'] . '/config/conf.php';
if (!$success) {
return PEAR::raiseError('Failed to import application configuration for ' . $app);
}
}
$this->_confCache[$app] = &$conf;
}
$GLOBALS['conf'] = &$this->_confCache[$app];
return true;
}
/**
* Loads the preferences for the current user for the current
* application and imports them into the global $prefs variable.
*
* @access public
*
* @param string $app The name of the application.
*/
function loadPrefs($app = null)
{
return array();
static $prefs_default = false;
require_once 'Horde/Prefs.php';
if ($app === null) {
$app = $this->_currentApp;
}
/* If there is no logged in user, return an empty Prefs::
* object with just default preferences. */
# if (!Auth::getAuth()) {
# $prefs = &Prefs::factory('none', $app, '', '', null, false);
# $prefs->retrieve();
# $this->_prefsCache[$app] = &$prefs;
# $GLOBALS['prefs'] = &$this->_prefsCache[$app];
# $prefs_default = true;
# return;
# }
/* Cache prefs objects so that we don't re-load them on every
* popApp() call. */
# if (!isset($this->_prefsCache[$app]) ||
# !empty($prefs_default)) {
# $prefs = &Prefs::factory($GLOBALS['conf']['prefs']['driver'], $app,
# Auth::getAuth(), Auth::getCredential('password'));
# $prefs->retrieve();
# $this->_prefsCache[$app] = &$prefs;
# }
$GLOBALS['prefs'] = &$this->_prefsCache[$app];
}
/**
* Unload preferences from an application or (if no application is
* specified) from ALL applications. Useful when a user has logged
* out but you need to continue on the same page, etc.
*
* After unloading, if there is an application on the app stack to
* load preferences from, then we reload a fresh set.
*
* @access public
*
* @param string $app (optional) The application to unload prefrences for.
* If null, ALL preferences are reset.
*/
function unloadPrefs($app = null)
{
if ($app === null) {
$this->_prefsCache = array();
} elseif (isset($this->_prefsCache[$app])) {
unset($this->_prefsCache[$app]);
} else {
return;
}
if ($this->_currentApp) {
$this->loadPrefs();
}
}
/**
* Return the requested configuration parameter for the specified
* application. If no application is specified, the value of
* $this->_currentApp (the current application) is used. However,
* if the parameter is not present for that application, the
* Horde-wide value is used instead. If that is not present, we
* return null.
*
* @access public
*
* @param string $parameter The configuration value to retrieve.
* @param optional string $app The application to get the value for.
*
* @return string The requested parameter, or null if it is not set.
*/
function get($parameter, $app = null)
{
if (is_null($app)) {
$app = $this->_currentApp;
}
if (isset($this->applications[$app][$parameter])) {
$pval = $this->applications[$app][$parameter];
} else {
if ($parameter == 'icon') {
$pval = $this->_getIcon($app);
} else {
$pval = isset($this->applications['horde'][$parameter]) ? $this->applications['horde'][$parameter] : null;
}
}
if ($parameter == 'name') {
return _($pval);
} else {
return $pval;
}
}
/**
* Function to work out an application's graphics URI, taking into
* account any themes directories that may be set up.
*
* @access public
*
* @param optional string $app The application for which to get the
* image directory. If blank will default
* to current application.
*
* @return string The image directory uri path.
*/
function getImageDir($app = null)
{
if (empty($app)) {
$app = $this->_currentApp;
}
static $img_dir = array();
if (isset($img_dir[$app])) {
return $img_dir[$app];
}
/* This is the default location for the graphics. */
$img_dir[$app] = $this->get('themesuri', $app) . '/graphics';
/* Figure out if this is going to be overridden by any theme
* settings. */
if (isset($GLOBALS['prefs']) && ($theme = $GLOBALS['prefs']->getValue('theme')) &&
(@include $this->get('themesfs', 'horde') . '/' . $theme . '/info.php') &&
isset($theme_icons) &&
in_array($app, $theme_icons)) {
$img_dir[$app] = $this->get('themesuri', $app) . '/' . $theme . '/graphics';
}
return $img_dir[$app];
}
/**
* Returns the path to an application's icon, respecting whether the
* current theme has its own icons.
*
* @access private
*
* @param string $app The application for which to get the icon.
*/
function _getIcon($app)
{
return $this->getImageDir($app) . '/' . $app . '.png';
}
/**
* Query the initial page for an application - the webroot, if
* there is no initial_page set, and the initial_page, if it is
* set.
*
* @access public
*
* @param optional string $app The name of the application.
*
* @return string URL pointing to the inital page of the application.
* Returns PEAR_Error on error.
*/
function getInitialPage($app = null)
{
if (is_null($app)) {
$app = $this->_currentApp;
}
if (!isset($this->applications[$app])) {
return PEAR::raiseError(sprintf(_("'%s' is not configured in the Horde Registry."), $app));
}
return $this->applications[$app]['webroot'] . '/' . (isset($this->applications[$app]['initial_page']) ? $this->applications[$app]['initial_page'] : '');
}
/**
* Fills the registry's API cache with the available services.
*
* @access private
*/
function _fillAPICache()
{
if (!empty($this->_apiCache)) {
return;
}
$status = array('active', 'notoolbar', 'hidden');
# if (Auth::isAdmin()) {
# $status[] = 'admin';
# }
$apps = $this->listApps($status);
foreach ($apps as $app) {
$_services = $_types = null;
$api = $this->get('fileroot', $app) . '/lib/api.php';
if (is_readable($api)) {
include_once $api;
}
if (!isset($_services)) {
$this->_apiCache[$app] = array();
} else {
$this->_apiCache[$app] = $_services;
}
if (isset($_types)) {
foreach ($_types as $type => $params) {
/* Prefix non-Horde types with the application
* name. */
$prefix = $app == 'horde' ? '' : "${app}_";
$this->_typeCache[$prefix . $type] = $params;
}
}
}
}
}