From: Chuck Hagenbuch Date: Sun, 19 Dec 2010 18:49:40 +0000 (-0500) Subject: Revert "Cleanup registry caching." This caused registry methods not to be visible... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=3be8781b0fc7bc17f52b2a65adedd0198a780e5a;p=horde.git Revert "Cleanup registry caching." This caused registry methods not to be visible to external applications for me, plus other problems for Jan. This reverts commit 27bd896e7b07de019aa8c59565ec0ed89f28f5f9. --- diff --git a/framework/Core/lib/Horde/Registry.php b/framework/Core/lib/Horde/Registry.php index 7acfd0763..b119f5c7f 100644 --- a/framework/Core/lib/Horde/Registry.php +++ b/framework/Core/lib/Horde/Registry.php @@ -57,18 +57,18 @@ class Horde_Registry protected $_appStack = array(); /** - * The list of external services. + * The list of APIs. * - * @var array + * @param array */ - protected $_apis; + protected $_apis = array(); /** - * The list of APIs. + * Cached information. * * @var array */ - protected $_apiList = array(); + protected $_cache = array(); /** * Cached configuration information. @@ -77,19 +77,6 @@ class Horde_Registry */ protected $_confCache = array(); - /** - * Interfaces list. - * - * @var array - */ - protected $_interfaces = array(); - - /** - * Object (Application/Api) cache. - * - * @var array - */ - protected $_obCache = array(); /** * The last modified time of the newest modified registry file. @@ -99,11 +86,11 @@ class Horde_Registry protected $_regmtime; /** - * The current vhost configuration file. + * The list of cache entries to save on shutdown. * - * @var string + * @var array */ - protected $_vhost = null; + protected $_savecache = array(); /** * Application bootstrap initialization. @@ -332,7 +319,7 @@ class Horde_Registry } $GLOBALS['registry'] = $this; - $injector->setInstance(__CLASS__, $this); + $injector->setInstance('Horde_Registry', $this); /* Setup autoloader instance and callbacks. * $__autoloader is defined in horde/lib/core.php */ @@ -371,12 +358,13 @@ class Horde_Registry $this->_regmtime = max(filemtime(HORDE_BASE . '/config/registry.php'), filemtime(HORDE_BASE . '/config/registry.d')); + $vhost = null; if (!empty($conf['vhosts'])) { - $this->_vhost = HORDE_BASE . '/config/registry-' . $conf['server']['name'] . '.php'; - if (file_exists($this->_vhost)) { - $this->_regmtime = max($this->_regmtime, filemtime($this->_vhost)); + $vhost = HORDE_BASE . '/config/registry-' . $conf['server']['name'] . '.php'; + if (file_exists($vhost)) { + $this->_regmtime = max($this->_regmtime, filemtime($vhost)); } else { - $this->_vhost = null; + $vhost = null; } } @@ -400,7 +388,7 @@ class Horde_Registry $injector->setInstance('Horde_Session', $session); /* Always need to load applications information. */ - $this->_loadApplications(); + $this->_loadApplicationsCache($vhost); /* Load the language configuration. */ $this->nlsconfig = Horde::loadConfiguration('nls.php', 'horde_nls_config', 'horde'); @@ -433,6 +421,27 @@ class Horde_Registry */ public function shutdown() { + /* Store cache entries to persistent storage. */ + if (!empty($this->_savecache)) { + $ob = $GLOBALS['injector']->getInstance('Horde_Cache'); + + foreach ($this->_savecache as $key => $val) { + if ($val) { + // Entry has been updated. + $data = serialize($this->_cache[$key]); + $md5sum = hash('md5', $data); + $GLOBALS['session']->set('horde', 'registry/' . $key, $md5sum); + $id = $this->_getCacheId($key, false) . '|' . $md5sum; + if ($ob->set($id, $data, 86400)) { + Horde::logMessage('Horde_Registry: stored ' . $key . ' with cache ID ' . $id, 'DEBUG'); + } + } elseif ($id = $this->_getCacheId($key)) { + // Entry has been deleted. + $ob->expire($id); + } + } + } + /* Register access key logger for translators. */ if (!empty($GLOBALS['conf']['log_accesskeys'])) { Horde::getAccessKey(null, null, true); @@ -461,7 +470,7 @@ class Horde_Registry */ public function __clone() { - throw new Horde_Exception('Registry objects should never be cloned.'); + throw new Horde_Exception('Horde_Registry objects should never be cloned.'); } /** @@ -471,40 +480,36 @@ class Horde_Registry */ public function __sleep() { - throw new Horde_Exception('Registry objects should never be serialized.'); + throw new Horde_Exception('Horde_Registry objects should never be serialized.'); } /** - * Rebuild the registry configuration. + * Clear the registry cache. */ - public function rebuild() + public function clearCache() { - $app = $this->getApp(); - - $this->applications = $this->_apiList = $this->_apis = $this->_confCache = $this->_interfaces = array(); - $GLOBALS['session']->remove('horde', 'registry/'); - $this->_saveCache('apis'); - $this->_saveCache('app'); - - $this->_loadApplications(); - - $this->importConfig('horde'); - $this->importConfig($app); + $this->_cache = array(); + $this->_savecache['api'] = false; + $this->_savecache['appcache'] = false; } /** - * Load application configuration information. + * Fills the registry's application cache with application information. + * + * @param string $vhost TODO */ - protected function _loadApplications() + protected function _loadApplicationsCache($vhost) { /* First, try to load from cache. */ - if ($ret = $this->_loadCache('app')) { - $this->applications = $ret[0]; - $this->_interfaces = $ret[1]; + if ($this->_loadCache('appcache')) { + $this->applications = $this->_cache['appcache'][0]; + $this->_cache['interfaces'] = $this->_cache['appcache'][1]; return; } + $this->_cache['interfaces'] = array(); + /* Read the registry configuration files. */ if (!file_exists(HORDE_BASE . '/config/registry.php')) { throw new Horde_Exception('Missing registry.php configuration file'); @@ -515,8 +520,8 @@ class Horde_Registry include $r; } - if ($this->_vhost) { - include $this->_vhost; + if ($vhost) { + include $vhost; } /* Scan for all APIs provided by each app, and set other common @@ -546,10 +551,10 @@ class Horde_Registry (($app['status'] != 'admin') || $this->isAdmin())) { if (is_array($app['provides'])) { foreach ($app['provides'] as $interface) { - $this->_interfaces[$interface] = $appName; + $this->_cache['interfaces'][$interface] = $appName; } } else { - $this->_interfaces[$app['provides']] = $appName; + $this->_cache['interfaces'][$app['provides']] = $appName; } } @@ -570,21 +575,24 @@ class Horde_Registry } } - $this->_saveCache('app', array( + $this->_cache['appcache'] = array( + // Index 0 $this->applications, - $this->_interfaces - )); + // Index 1 + $this->_cache['interfaces'] + ); + $this->_savecache['appcache'] = true; } /** - * Load the list of available external services. + * Fills the registry's API cache with the available external services. * * @throws Horde_Exception */ - protected function _loadApis() + protected function _loadApiCache() { - if (isset($this->_apis) || - ($this->_apis = $this->_loadCache('apis'))) { + /* First, try to load from cache. */ + if ($this->_loadCache('api')) { return; } @@ -594,13 +602,13 @@ class Horde_Registry $status[] = 'admin'; } - $this->_apis = array(); + $this->_cache['api'] = array(); foreach (array_keys($this->applications) as $app) { if (in_array($this->applications[$app]['status'], $status)) { try { $api = $this->getApiInstance($app, 'api'); - $this->_apis[$app] = array( + $this->_cache['api'][$app] = array( 'api' => array_diff(get_class_methods($api), array('__construct'), $api->disabled), 'links' => $api->links, 'noperms' => $api->noPerms @@ -611,7 +619,7 @@ class Horde_Registry } } - $this->_saveCache('apis', $this->_api); + $this->_savecache['api'] = true; } /** @@ -625,8 +633,8 @@ class Horde_Registry */ public function getApiInstance($app, $type) { - if (isset($this->_obCache[$app][$type])) { - return $this->_obCache[$app][$type]; + if (isset($this->_cache['ob'][$app][$type])) { + return $this->_cache['ob'][$app][$type]; } $cname = Horde_String::ucfirst($type); @@ -638,16 +646,15 @@ class Horde_Registry if (file_exists($path)) { include_once $path; } else { - $classname = __CLASS__ . '_' . $cname; + $classname = 'Horde_Registry_' . $cname; } if (!class_exists($classname, false)) { throw new Horde_Exception("$app does not have an API"); } - $this->_obCache[$app][$type] = new $classname(); - - return $this->_obCache[$app][$type]; + $this->_cache['ob'][$app][$type] = new $classname(); + return $this->_cache['ob'][$app][$type]; } /** @@ -705,18 +712,16 @@ class Horde_Registry */ public function listAPIs() { - if (empty($this->_apiList) && !empty($this->_interfaces)) { - $apis = array(); - - foreach (array_keys($this->_interfaces) as $interface) { - list($api,) = explode('/', $interface, 2); - $apis[$api] = true; + if (empty($this->_apis)) { + if (!empty($this->_cache['interfaces'])) { + foreach (array_keys($this->_cache['interfaces']) as $interface) { + list($api,) = explode('/', $interface, 2); + $this->_apis[$api] = true; + } } - - $this->_apiList = array_keys($apis); } - return $this->_apiList; + return array_keys($this->_apis); } /** @@ -732,7 +737,7 @@ class Horde_Registry { $methods = array(); - $this->_loadApis(); + $this->_loadApiCache(); foreach (array_keys($this->applications) as $app) { if (isset($this->applications[$app]['provides'])) { @@ -740,17 +745,17 @@ class Horde_Registry if (!is_array($provides)) { $provides = array($provides); } - foreach ($provides as $method) { if (strpos($method, '/') !== false) { if (is_null($api) || (substr($method, 0, strlen($api)) == $api)) { $methods[$method] = true; } - } elseif (isset($this->_apis[$app]) && - (is_null($api) || ($method == $api))) { - foreach ($this->_apis[$app]['api'] as $service) { - $methods[$method . '/' . $service] = true; + } elseif (is_null($api) || ($method == $api)) { + if (isset($this->_cache['api'][$app])) { + foreach ($this->_cache['api'][$app]['api'] as $service) { + $methods[$method . '/' . $service] = true; + } } } } @@ -770,8 +775,8 @@ class Horde_Registry */ public function hasInterface($interface) { - return !empty($this->interfaces[$interface]) ? - $this->interfaces[$interface] : + return !empty($this->_cache['interfaces'][$interface]) ? + $this->_cache['interfaces'][$interface] : false; } @@ -788,10 +793,10 @@ class Horde_Registry { if (is_null($app)) { list($interface, $call) = explode('/', $method, 2); - if (!empty($this->interfaces[$method])) { - $app = $this->interfaces[$method]; - } elseif (!empty($this->interfaces[$interface])) { - $app = $this->interfaces[$interface]; + if (!empty($this->_cache['interfaces'][$method])) { + $app = $this->_cache['interfaces'][$method]; + } elseif (!empty($this->_cache['interfaces'][$interface])) { + $app = $this->_cache['interfaces'][$interface]; } else { return false; } @@ -799,9 +804,9 @@ class Horde_Registry $call = $method; } - $this->_loadApis(); + $this->_loadApiCache(); - return (isset($this->_apis[$app]) && in_array($call, $this->_apis[$app]['api'])) + return (isset($this->_cache['api'][$app]) && in_array($call, $this->_cache['api'][$app]['api'])) ? $app : false; } @@ -821,9 +826,7 @@ class Horde_Registry } catch (Horde_Exception $e) { return false; } - - return (method_exists($appob, $method) && - !in_array($method, $appob->disabled)); + return (method_exists($appob, $method) && !in_array($method, $appob->disabled)); } /** @@ -842,10 +845,10 @@ class Horde_Registry { list($interface, $call) = explode('/', $method, 2); - if (!empty($this->interfaces[$method])) { - $app = $this->interfaces[$method]; - } elseif (!empty($this->interfaces[$interface])) { - $app = $this->interfaces[$interface]; + if (!empty($this->_cache['interfaces'][$method])) { + $app = $this->_cache['interfaces'][$method]; + } elseif (!empty($this->_cache['interfaces'][$interface])) { + $app = $this->_cache['interfaces'][$interface]; } else { throw new Horde_Exception('The method "' . $method . '" is not defined in the Horde Registry.'); } @@ -888,7 +891,7 @@ class Horde_Registry /* 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, array('check_perms' => !in_array($call, $this->_apis[$app]['noperms']) && empty($options['noperms']))); + $pushed = $this->pushApp($app, array('check_perms' => !in_array($call, $this->_cache['api'][$app]['noperms']) && empty($options['noperms']))); try { $result = call_user_func_array(array($api, $call), $args); @@ -974,10 +977,10 @@ class Horde_Registry { list($interface, $call) = explode('/', $method, 2); - if (!empty($this->interfaces[$method])) { - $app = $this->interfaces[$method]; - } elseif (!empty($this->interfaces[$interface])) { - $app = $this->interfaces[$interface]; + if (!empty($this->_cache['interfaces'][$method])) { + $app = $this->_cache['interfaces'][$method]; + } elseif (!empty($this->_cache['interfaces'][$interface])) { + $app = $this->_cache['interfaces'][$interface]; } else { throw new Horde_Exception('The method "' . $method . '" is not defined in the Horde Registry.'); } @@ -999,13 +1002,13 @@ class Horde_Registry public function linkByPackage($app, $call, $args = array(), $extra = '') { /* Make sure the link is defined. */ - $this->_loadApis(); - if (empty($this->_apis[$app]['links'][$call])) { + $this->_loadApiCache(); + if (empty($this->_cache['api'][$app]['links'][$call])) { throw new Horde_Exception('The link ' . $call . ' is not defined in ' . $app . '\'s API.'); } /* Initial link value. */ - $link = $this->_apis[$app]['links'][$call]; + $link = $this->_cache['api'][$app]['links'][$call]; /* Fill in html-encoded arguments. */ foreach ($args as $key => $val) { @@ -1522,15 +1525,20 @@ class Horde_Registry * * @param string $name Cache variable name. * - * @return mixed The cached data or false if no data retrieved. + * @return boolean True if value loaded from cache. */ protected function _loadCache($name) { + if (isset($this->_cache[$name])) { + return true; + } + if ($id = $this->_getCacheId($name)) { $result = $GLOBALS['injector']->getInstance('Horde_Cache')->get($id, 86400); if ($result !== false) { - Horde::logMessage(__CLASS__ . ': retrieved ' . $name . ' with cache ID ' . $id, 'DEBUG'); - return unserialize($result); + $this->_cache[$name] = unserialize($result); + Horde::logMessage('Horde_Registry: retrieved ' . $name . ' with cache ID ' . $id, 'DEBUG'); + return true; } } @@ -1541,51 +1549,25 @@ class Horde_Registry * Get the cache storage ID for a particular cache name. * * @param string $name Cache variable name. - * @param string $md5 Use this MD5 value instead of session MD5 value. + * @param string $md5 Append MD5 value? * * @return mixed The cache ID or false if cache entry doesn't exist in * the session. */ - protected function _getCacheId($name, $md5 = null) + protected function _getCacheId($name, $md5 = true) { - $id = 'horde_registry|' . $name . '|' . $this->_regmtime; + $id = 'horde_registry_' . $name . '|' . $this->_regmtime; - if (!is_null($md5) || - ($md5 = $GLOBALS['session']->get('horde', 'registry/' . $name))) { - return $id . '|' . $md5; + if (!$md5) { + return $id; + } elseif ($hash = $GLOBALS['session']->get('horde', 'registry/' . $name)) { + return $id . '|' . $hash; } return false; } /** - * Save a registry cache entry. - * - * @param string $key The cache key. - * @param mixed $data The cache data. If null, deletes the item. - */ - protected function _saveCache($key, $data = null) - { - $ob = $GLOBALS['injector']->getInstance('Horde_Cache'); - - if (is_null($data)) { - if ($id = $this->_getCacheId($key)) { - // Entry has been deleted. - $ob->expire($id); - } - } else { - // Entry has been updated. - $data = serialize($data); - $md5sum = hash('md5', $data); - $GLOBALS['session']->set('horde', 'registry/' . $key, $md5sum); - $id = $this->_getCacheId($key, $md5sum); - if ($ob->set($id, $data, 86400)) { - Horde::logMessage(__CLASS__ . ': stored ' . $key . ' with cache ID ' . $id, 'DEBUG'); - } - } - } - - /** * Destroys any existing session on login and make sure to use a new * session ID, to avoid session fixation issues. Should be called before * checking a login. @@ -2197,7 +2179,10 @@ class Horde_Registry if ($GLOBALS['language'] == $lang) { return; } - $changed = true; + $this->clearCache(); + $this->_confCache = array(); + $this->importConfig('horde'); + $this->importConfig($this->getApp()); } $GLOBALS['language'] = $lang; @@ -2206,10 +2191,6 @@ class Horde_Registry @putenv('LC_ALL=' . $lang_charset); @putenv('LANG=' . $lang_charset); @putenv('LANGUAGE=' . $lang_charset); - - if ($changed) { - $this->rebuild(); - } } /** diff --git a/horde/admin/config/config.php b/horde/admin/config/config.php index e4c748c67..e217d8b43 100644 --- a/horde/admin/config/config.php +++ b/horde/admin/config/config.php @@ -61,7 +61,7 @@ if (Horde_Util::getFormData('submitbutton') == _("Revert Configuration")) { fwrite($fp, $php); fclose($fp); $notification->push(sprintf(_("Successfully wrote %s"), Horde_Util::realPath($configFile)), 'horde.success'); - $registry->rebuild(); + $registry->clearCache(); Horde::url('admin/config/index.php', true)->redirect(); } else { /* Cannot write. */ diff --git a/horde/admin/config/index.php b/horde/admin/config/index.php index 7abec0650..f764cbf8a 100644 --- a/horde/admin/config/index.php +++ b/horde/admin/config/index.php @@ -51,9 +51,7 @@ function _uploadFTP($params) $notification->push(sprintf(_("Could not write configuration for \"%s\": %s"), $app, $e->getMessage()), 'horde.error'); } } - - $registry->rebuild(); - + $registry->clearCache(); return $no_errors; } diff --git a/horde/admin/config/scripts.php b/horde/admin/config/scripts.php index b78b8b78e..89ff4d3e7 100644 --- a/horde/admin/config/scripts.php +++ b/horde/admin/config/scripts.php @@ -34,7 +34,7 @@ if ($clean == 'tmp') { } else { $notification->push(sprintf(_("Could not delete configuration upgrade script \"%s\"."), Horde_Util::realPath($path)), 'horde.error'); } - $registry->rebuild(); + $registry->clearCache(); Horde::url('admin/config/index.php', true)->redirect(); }