mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-30 10:39:18 +01:00
1475 lines
53 KiB
PHP
1475 lines
53 KiB
PHP
|
<?php
|
||
|
|
||
|
include_once 'Log.php';
|
||
|
include_once 'Horde/Util.php';
|
||
|
|
||
|
/**
|
||
|
* The Horde:: class provides the functionality shared by all Horde
|
||
|
* applications.
|
||
|
*
|
||
|
* $Horde: framework/Horde/Horde.php,v 1.500 2005/02/15 21:26:50 chuck Exp $
|
||
|
*
|
||
|
* Copyright 1999-2005 Chuck Hagenbuch <chuck@horde.org>
|
||
|
* Copyright 1999-2005 Jon Parise <jon@horde.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>
|
||
|
* @since Horde 1.3
|
||
|
* @package Horde_Framework
|
||
|
*/
|
||
|
class Horde {
|
||
|
|
||
|
/**
|
||
|
* Logs a message to the global Horde log backend.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param mixed $message Either a string or a PEAR_Error object.
|
||
|
* @param string $file What file was the log function called from
|
||
|
* (e.g. __FILE__)?
|
||
|
* @param integer $line What line was the log function called from
|
||
|
* (e.g. __LINE__)?
|
||
|
* @param integer $priority The priority of the message. One of:
|
||
|
* <pre>
|
||
|
* PEAR_LOG_EMERG
|
||
|
* PEAR_LOG_ALERT
|
||
|
* PEAR_LOG_CRIT
|
||
|
* PEAR_LOG_ERR
|
||
|
* PEAR_LOG_WARNING
|
||
|
* PEAR_LOG_NOTICE
|
||
|
* PEAR_LOG_INFO
|
||
|
* PEAR_LOG_DEBUG
|
||
|
* </pre>
|
||
|
*/
|
||
|
function logMessage($message, $file, $line, $priority = PEAR_LOG_INFO)
|
||
|
{
|
||
|
global $conf;
|
||
|
|
||
|
if (!$conf['log']['enabled']) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ($priority > $conf['log']['priority']) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$logger = &Horde::getLogger();
|
||
|
if (!is_a($logger, 'Log')) {
|
||
|
Horde::fatal(PEAR::raiseError('An error has occurred. Furthermore, Horde encountered an error attempting to log this error. Please check your Horde logging configuration in horde/config/conf.php.'), __FILE__, __LINE__, false);
|
||
|
}
|
||
|
|
||
|
if (is_a($message, 'PEAR_Error')) {
|
||
|
$userinfo = $message->getUserInfo();
|
||
|
$message = $message->getMessage();
|
||
|
if (!empty($userinfo)) {
|
||
|
if (is_array($userinfo)) {
|
||
|
$userinfo = implode(', ', $userinfo);
|
||
|
}
|
||
|
$message .= ': ' . $userinfo;
|
||
|
}
|
||
|
} elseif (is_callable(array($message, 'getMessage'))) {
|
||
|
$message = $message->getMessage();
|
||
|
}
|
||
|
|
||
|
$app = isset($GLOBALS['registry']) ? $GLOBALS['registry']->getApp() : 'horde';
|
||
|
$message = '[' . $app . '] ' . $message . ' [on line ' . $line . ' of "' . $file . '"]';
|
||
|
|
||
|
/* Make sure to log in the system's locale. */
|
||
|
$locale = setlocale(LC_TIME, 0);
|
||
|
setlocale(LC_TIME, 'C');
|
||
|
|
||
|
$logger->log($message, $priority);
|
||
|
|
||
|
/* Restore original locale. */
|
||
|
setlocale(LC_TIME, $locale);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function &getLogger()
|
||
|
{
|
||
|
global $conf;
|
||
|
|
||
|
if (empty($conf['log']['enabled'])) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static $logcheck;
|
||
|
if (!isset($logcheck)) {
|
||
|
// Try to make sure that we can log messages somehow.
|
||
|
if (empty($conf['log']) ||
|
||
|
empty($conf['log']['type']) ||
|
||
|
empty($conf['log']['name']) ||
|
||
|
empty($conf['log']['ident']) ||
|
||
|
!isset($conf['log']['params'])) {
|
||
|
Horde::fatal(PEAR::raiseError('Horde is not correctly configured to log error messages. You must configure at least a text file log in horde/config/conf.php.'), __FILE__, __LINE__, false);
|
||
|
}
|
||
|
$logcheck = true;
|
||
|
}
|
||
|
|
||
|
return $logger = &Log::singleton($conf['log']['type'], $conf['log']['name'],
|
||
|
$conf['log']['ident'], $conf['log']['params']);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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.
|
||
|
*
|
||
|
* @access public
|
||
|
*/
|
||
|
function getCleanSession()
|
||
|
{
|
||
|
// Make sure to force a completely new session ID and clear
|
||
|
// all session data.
|
||
|
if (version_compare(phpversion(), '4.3.3') !== -1) {
|
||
|
session_regenerate_id();
|
||
|
session_unset();
|
||
|
} else {
|
||
|
@session_destroy();
|
||
|
if (Util::extensionExists('posix')) {
|
||
|
$new_session_id = md5(microtime() . posix_getpid());
|
||
|
} else {
|
||
|
$new_session_id = md5(uniqid(mt_rand(), true));
|
||
|
}
|
||
|
session_id($new_session_id);
|
||
|
|
||
|
// Restart the session, including setting up the session
|
||
|
// handler.
|
||
|
Horde::setupSessionHandler();
|
||
|
@session_start();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Aborts with a fatal error, displaying debug information to the user.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param mixed $error A PEAR_Error object with debug information or an
|
||
|
* error message.
|
||
|
* @param integer $file The file in which the error occured.
|
||
|
* @param integer $line The line on which the error occured.
|
||
|
* @param boolean $log Log this message via Horde::logMesage()?
|
||
|
*/
|
||
|
function fatal($error, $file, $line, $log = true)
|
||
|
{
|
||
|
@include_once 'Horde/Auth.php';
|
||
|
@include_once 'Horde/CLI.php';
|
||
|
|
||
|
$admin = class_exists('Auth') && Auth::isAdmin();
|
||
|
$cli = class_exists('Horde_CLI') && Horde_CLI::runningFromCLI();
|
||
|
|
||
|
$errortext = '<h1>' . _("A fatal error has occurred") . '</h1>';
|
||
|
if (is_a($error, 'PEAR_Error')) {
|
||
|
$info = array_merge(array('file' => 'conf.php', 'variable' => '$conf'),
|
||
|
array($error->getUserInfo()));
|
||
|
|
||
|
switch ($error->getCode()) {
|
||
|
case HORDE_ERROR_DRIVER_CONFIG_MISSING:
|
||
|
$message = sprintf(_("No configuration information specified for %s."), $info['name']) . '<br />' .
|
||
|
sprintf(_("The file %s should contain some %s settings."),
|
||
|
$GLOBALS['registry']->get('fileroot') . '/config/' . $info['file'],
|
||
|
sprintf("%s['%s']['params']", $info['variable'], $info['driver']));
|
||
|
break;
|
||
|
|
||
|
case HORDE_ERROR_DRIVER_CONFIG:
|
||
|
$message = sprintf(_("Required '%s' not specified in %s configuration."), $info['field'], $info['name']) . '<br />' .
|
||
|
sprintf(_("The file %s should contain a %s setting."),
|
||
|
$GLOBALS['registry']->get('fileroot') . '/config/' . $info['file'],
|
||
|
sprintf("%s['%s']['params']['%s']", $info['variable'], $info['driver'], $info['field']));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
$message = $error->getMessage();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
$errortext .= '<h3>' . htmlspecialchars($message) . '</h3>';
|
||
|
} elseif (is_object($error) && method_exists($error, 'getMessage')) {
|
||
|
$errortext .= '<h3>' . htmlspecialchars($error->getMessage()) . '</h3>';
|
||
|
} elseif (is_string($error)) {
|
||
|
$errortext .= '<h3>' . $error . '</h3>';
|
||
|
}
|
||
|
|
||
|
if ($admin) {
|
||
|
$errortext .= '<p><code>' . sprintf(_("[line %s of %s]"), $line, $file) . '</code></p>';
|
||
|
if (is_object($error)) {
|
||
|
$errortext .= '<h3>' . _("Details (also in Horde's logfile):") . '</h3>';
|
||
|
$errortext .= '<p><pre>' . htmlspecialchars(Util::bufferOutput('var_dump', $error)) . '</pre></p>';
|
||
|
}
|
||
|
} elseif ($log) {
|
||
|
$errortext .= '<h3>' . _("Details have been logged for the administrator.") . '</h3>';
|
||
|
}
|
||
|
|
||
|
// Log the error via Horde::logMessage() if requested.
|
||
|
if ($log) {
|
||
|
Horde::logMessage($error, $file, $line, PEAR_LOG_EMERG);
|
||
|
}
|
||
|
|
||
|
if ($cli) {
|
||
|
echo strip_tags(str_replace(array('<br />', '<p>', '</p>', '<h1>', '</h1>', '<h3>', '</h3>'), "\n", $errortext));
|
||
|
} else {
|
||
|
echo <<< HTML
|
||
|
<html>
|
||
|
<head><title>Horde :: Fatal Error</title></head>
|
||
|
<body style="background-color: white; color: black;">$errortext</body>
|
||
|
</html>
|
||
|
HTML;
|
||
|
}
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds the javascript code to the output (if output has already started)
|
||
|
* or to the list of script files to include via includeScriptFiles().
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $file The full javascript file name.
|
||
|
* @param string $app The application name. Defaults to the current
|
||
|
* application.
|
||
|
* @param boolean $direct Include the file directly without passing it
|
||
|
* through javascript.php?
|
||
|
*/
|
||
|
function addScriptFile($file, $app = null, $direct = false)
|
||
|
{
|
||
|
global $registry;
|
||
|
static $included = array();
|
||
|
|
||
|
if (empty($app)) {
|
||
|
$app = $registry->getApp();
|
||
|
}
|
||
|
|
||
|
// Don't include scripts multiple times.
|
||
|
if (!empty($included[$app][$file])) {
|
||
|
return;
|
||
|
}
|
||
|
$included[$app][$file] = true;
|
||
|
|
||
|
if (ob_get_length() || headers_sent()) {
|
||
|
if ($direct) {
|
||
|
$url = Horde::url($file{0} == '/' ? $registry->get('webroot', $app) . $file : $registry->get('jsuri', $app) . '/' . $file);
|
||
|
} else {
|
||
|
$url = Horde::url($registry->get('webroot', 'horde') . '/services/javascript.php');
|
||
|
$url = Util::addParameter($url, array('file' => $file,
|
||
|
'app' => $app));
|
||
|
}
|
||
|
echo '<script language="JavaScript" type="text/javascript" src="' . $url . '"></script>';
|
||
|
} else {
|
||
|
global $_horde_script_files;
|
||
|
$_horde_script_files[$app][] = array($file, $direct);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Includes javascript files that were needed before any headers were sent.
|
||
|
*
|
||
|
* @access public
|
||
|
*/
|
||
|
function includeScriptFiles()
|
||
|
{
|
||
|
global $_horde_script_files, $registry;
|
||
|
|
||
|
if (!empty($_horde_script_files)) {
|
||
|
$base_url = Horde::url($registry->get('webroot', 'horde') . '/services/javascript.php');
|
||
|
foreach ($_horde_script_files as $app => $files) {
|
||
|
foreach ($files as $file) {
|
||
|
if (!empty($file[1])) {
|
||
|
$url = $file[0]{0} == '/' ? $registry->get('webroot', $app) . $file[0] : $registry->get('jsuri', $app) . '/' . $file[0];
|
||
|
echo '<script language="JavaScript" type="text/javascript" src="' . Horde::url($url) . "\"></script>\n";
|
||
|
} else {
|
||
|
$url = Util::addParameter($base_url, array('file' => $file[0],
|
||
|
'app' => $app));
|
||
|
echo '<script language="JavaScript" type="text/javascript" src="' . $url . "\"></script>\n";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Includes javascript files that were needed before any headers were sent.
|
||
|
*
|
||
|
* @access public
|
||
|
*/
|
||
|
function inlineScriptFiles()
|
||
|
{
|
||
|
global $_horde_script_files, $registry;
|
||
|
|
||
|
if (!empty($_horde_script_files)) {
|
||
|
$jsWrapper = $registry->get('fileroot', 'horde') . '/services/javascript.php';
|
||
|
foreach ($_horde_script_files as $app => $files) {
|
||
|
foreach ($files as $file) {
|
||
|
if (!empty($file[1])) {
|
||
|
@readfile($file[0]{0} == '/' ? $registry->get('fileroot', $app) . $file[0] : $registry->get('jsfs', $app) . '/' . $file[0]);
|
||
|
} else {
|
||
|
$file = $file[0];
|
||
|
require $jsWrapper;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks if link should be shown and return the nescessary code.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $type Type of link to display
|
||
|
* @param string $app The name of the current Horde application.
|
||
|
* @param boolean $override Override Horde settings?
|
||
|
* @param boolean $referrer Include the current page as the referrer (url=)?
|
||
|
*
|
||
|
* @return string The HTML to create the link.
|
||
|
*/
|
||
|
function getServiceLink($type, $app, $override = false, $referrer = true)
|
||
|
{
|
||
|
if (!Horde::showService($type) && !$override) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
switch ($type) {
|
||
|
case 'help':
|
||
|
if ($GLOBALS['browser']->hasFeature('javascript')) {
|
||
|
Horde::addScriptFile('open_help_win.js', 'horde');
|
||
|
return "javascript:open_help_win('$app');";
|
||
|
} else {
|
||
|
$url = Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/help/', true);
|
||
|
return Util::addParameter($url, array('module' => $app,
|
||
|
'show' => 'topics'));
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'problem':
|
||
|
return Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/problem.php?return_url=' . urlencode(Horde::selfUrl(true)));
|
||
|
|
||
|
case 'logout':
|
||
|
return Auth::addLogoutParameters(Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/login.php'), AUTH_REASON_LOGOUT);
|
||
|
|
||
|
case 'login':
|
||
|
return Auth::getLoginScreen('', $referrer ? Horde::selfUrl(true) : null);
|
||
|
|
||
|
case 'options':
|
||
|
global $conf;
|
||
|
if (($conf['prefs']['driver'] != '') && ($conf['prefs']['driver'] != 'none')) {
|
||
|
return Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/prefs.php?app=' . $app);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $type The type of link.
|
||
|
*
|
||
|
* @return boolean True if the link is to be shown.
|
||
|
*/
|
||
|
function showService($type)
|
||
|
{
|
||
|
global $conf;
|
||
|
|
||
|
if (empty($conf['menu']['links'][$type])) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
switch ($conf['menu']['links'][$type]) {
|
||
|
case 'all':
|
||
|
return true;
|
||
|
|
||
|
case 'never':
|
||
|
return false;
|
||
|
|
||
|
case 'authenticated':
|
||
|
return (bool)Auth::getAuth();
|
||
|
|
||
|
default:
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the driver parameters for the specified backend.
|
||
|
*
|
||
|
* @param mixed $backend The backend system (e.g. 'prefs', 'categories',
|
||
|
* 'contacts') being used.
|
||
|
* The used configuration array will be
|
||
|
* $conf[$backend]. If an array gets passed, it will
|
||
|
* be $conf[$key1][$key2].
|
||
|
* @param string $type The type of driver.
|
||
|
*
|
||
|
* @return array The connection parameters.
|
||
|
*/
|
||
|
function getDriverConfig($backend, $type = 'sql')
|
||
|
{
|
||
|
global $conf;
|
||
|
|
||
|
$c = null;
|
||
|
if (is_array($backend)) {
|
||
|
require_once 'Horde/Array.php';
|
||
|
$c = Horde_Array::getElement($conf, $backend);
|
||
|
} elseif (isset($conf[$backend])) {
|
||
|
$c = $conf[$backend];
|
||
|
}
|
||
|
if (!is_null($c) && isset($c['params'])) {
|
||
|
if (isset($conf[$type])) {
|
||
|
return array_merge($conf[$type], $c['params']);
|
||
|
} else {
|
||
|
return $c['params'];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return isset($conf[$type]) ? $conf[$type] : array();
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Returns the VFS driver parameters for the specified backend.
|
||
|
*
|
||
|
* @param string $name The VFS system name (e.g. 'images', 'documents')
|
||
|
* being used.
|
||
|
*
|
||
|
* @return array A hash with the VFS parameters; the VFS driver in 'type'
|
||
|
* and the connection parameters in 'params'.
|
||
|
*/
|
||
|
function getVFSConfig($name)
|
||
|
{
|
||
|
global $conf;
|
||
|
|
||
|
if (!isset($conf[$name]['type'])) {
|
||
|
return PEAR::raiseError(_("You must configure a VFS backend."));
|
||
|
}
|
||
|
|
||
|
if ($conf[$name]['type'] == 'horde') {
|
||
|
$vfs = $conf['vfs'];
|
||
|
} else {
|
||
|
$vfs = $conf[$name];
|
||
|
}
|
||
|
|
||
|
if ($vfs['type'] == 'sql') {
|
||
|
$vfs['params'] = Horde::getDriverConfig($name, 'sql');
|
||
|
}
|
||
|
|
||
|
return $vfs;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks if all necessary parameters for a driver configuration
|
||
|
* are set and throws a fatal error with a detailed explaination
|
||
|
* how to fix this, if something is missing.
|
||
|
*
|
||
|
* @param array $params The configuration array with all parameters.
|
||
|
* @param string $driver The key name (in the configuration array) of
|
||
|
* the driver.
|
||
|
* @param array $fields An array with mandatory parameter names for
|
||
|
* this driver.
|
||
|
* @param string $name The clear text name of the driver. If not
|
||
|
* specified, the application name will be used.
|
||
|
* @param string $file The configuration file that should contain
|
||
|
* these settings.
|
||
|
* @param string $variable The name of the configuration variable.
|
||
|
*/
|
||
|
function assertDriverConfig($params, $driver, $fields, $name = null,
|
||
|
$file = 'conf.php', $variable = '$conf')
|
||
|
{
|
||
|
global $registry;
|
||
|
|
||
|
// Don't generate a fatal error if we fail during or before
|
||
|
// Registry instantiation.
|
||
|
if (is_null($name)) {
|
||
|
$name = isset($registry) ? $registry->getApp() : '[unknown]';
|
||
|
}
|
||
|
$fileroot = isset($registry) ? $registry->get('fileroot') : '';
|
||
|
|
||
|
if (!is_array($params) || !count($params)) {
|
||
|
Horde::fatal(PEAR::raiseError(
|
||
|
sprintf(_("No configuration information specified for %s."), $name) . "\n\n" .
|
||
|
sprintf(_("The file %s should contain some %s settings."),
|
||
|
$fileroot . '/config/' . $file,
|
||
|
sprintf("%s['%s']['params']", $variable, $driver))),
|
||
|
__FILE__, __LINE__);
|
||
|
}
|
||
|
|
||
|
foreach ($fields as $field) {
|
||
|
if (!isset($params[$field])) {
|
||
|
Horde::fatal(PEAR::raiseError(
|
||
|
sprintf(_("Required '%s' not specified in %s configuration."), $field, $name) . "\n\n" .
|
||
|
sprintf(_("The file %s should contain a %s setting."),
|
||
|
$fileroot . '/config/' . $file,
|
||
|
sprintf("%s['%s']['params']['%s']", $variable, $driver, $field))),
|
||
|
__FILE__, __LINE__);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a session-id-ified version of $uri.
|
||
|
* If a full URL is requested, all parameter separators get converted to
|
||
|
* "&", otherwise to "&".
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $uri The URI to be modified.
|
||
|
* @param bool $full Generate a full (http://server/path/) URL.
|
||
|
* @param int $append_session 0 = only if needed, 1 = always, -1 = never.
|
||
|
*
|
||
|
* @return string The URL with the session id appended (if needed).
|
||
|
*/
|
||
|
function url($uri, $full = false, $append_session = 0, $force_ssl = false)
|
||
|
{
|
||
|
if ($force_ssl) {
|
||
|
$full = true;
|
||
|
}
|
||
|
|
||
|
if ($full) {
|
||
|
global $conf, $registry, $browser;
|
||
|
|
||
|
/* Store connection parameters in local variables. */
|
||
|
$server_name = $conf['server']['name'];
|
||
|
$server_port = $conf['server']['port'];
|
||
|
|
||
|
$protocol = 'http';
|
||
|
if ($conf['use_ssl'] == 1) {
|
||
|
$protocol = 'https';
|
||
|
} elseif ($conf['use_ssl'] == 2 &&
|
||
|
$browser->usingSSLConnection()) {
|
||
|
$protocol = 'https';
|
||
|
} elseif ($conf['use_ssl'] == 3) {
|
||
|
$server_port = '';
|
||
|
if ($force_ssl) {
|
||
|
$protocol = 'https';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* If using non-standard ports, add the port to the URL. */
|
||
|
if (!empty($server_port) &&
|
||
|
((($protocol == 'http') && ($server_port != 80)) ||
|
||
|
(($protocol == 'https') && ($server_port != 443)))) {
|
||
|
$server_name .= ':' . $server_port;
|
||
|
}
|
||
|
|
||
|
/* Store the webroot in a local variable. */
|
||
|
$webroot = $registry->get('webroot');
|
||
|
|
||
|
$url = $protocol . '://' . $server_name;
|
||
|
if (substr($uri, 0, 1) != '/') {
|
||
|
if (substr($webroot, -1) == '/') {
|
||
|
$url .= $webroot . $uri;
|
||
|
} else {
|
||
|
$url .= $webroot . '/' . $uri;
|
||
|
}
|
||
|
} else {
|
||
|
$url .= $uri;
|
||
|
}
|
||
|
} else {
|
||
|
$url = $uri;
|
||
|
}
|
||
|
|
||
|
if (($append_session == 1) ||
|
||
|
(($append_session == 0) &&
|
||
|
!isset($_COOKIE[session_name()]))) {
|
||
|
$url = Util::addParameter($url, session_name(), session_id());
|
||
|
}
|
||
|
|
||
|
if ($full) {
|
||
|
/* We need to run the replace twice, because we only catch every
|
||
|
* second match. */
|
||
|
return preg_replace(array('/(=?.*?)&(.*?=)/',
|
||
|
'/(=?.*?)&(.*?=)/'),
|
||
|
'$1&$2', $url);
|
||
|
} elseif (preg_match('/=.*&.*=/', $url)) {
|
||
|
return $url;
|
||
|
} else {
|
||
|
return htmlentities($url);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a session-id-ified version of $uri, using the current
|
||
|
* application's webroot setting.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $uri The URI to be modified.
|
||
|
* @param bool $full Generate a full (http://server/path/) URL.
|
||
|
* @param int $append_session 0 = only if needed, 1 = always, -1 = never.
|
||
|
*
|
||
|
* @return string The url with the session id appended.
|
||
|
*/
|
||
|
function applicationUrl($uri, $full = false, $append_session = 0)
|
||
|
{
|
||
|
global $registry;
|
||
|
|
||
|
/* Store the webroot in a local variable. */
|
||
|
$webroot = $registry->get('webroot');
|
||
|
|
||
|
if ($full) {
|
||
|
return Horde::url($uri, $full, $append_session);
|
||
|
} elseif (substr($webroot, -1) == '/') {
|
||
|
return Horde::url($webroot . $uri, $full, $append_session);
|
||
|
} else {
|
||
|
return Horde::url($webroot . '/' . $uri, $full, $append_session);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns an external link passed through the dereferer to strip session
|
||
|
* IDs from the referer.
|
||
|
*
|
||
|
* @param string $url The external URL to link to.
|
||
|
* @param boolean $tag If true, a complete <a> tag is returned, only the
|
||
|
* url otherwise.
|
||
|
*
|
||
|
* @return string The correct link to the dereferer script.
|
||
|
*/
|
||
|
function externalUrl($url, $tag = false)
|
||
|
{
|
||
|
$ext = Horde::url($GLOBALS['registry']->get('webroot', 'horde') .
|
||
|
'/services/go.php', true, -1);
|
||
|
|
||
|
/* We must make sure there are no &'s in the URL. */
|
||
|
$url = preg_replace(array('/(=?.*?)&(.*?=)/', '/(=?.*?)&(.*?=)/'), '$1&$2', $url);
|
||
|
$ext = Util::addParameter($ext, 'url', $url);
|
||
|
if ($tag) {
|
||
|
$ext = Horde::link($ext, $url, '', '_blank');
|
||
|
}
|
||
|
return $ext;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a URL to be used for downloading, that takes into account any
|
||
|
* special browser quirks (i.e. IE's broken filename handling).
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $filename The filename of the download data.
|
||
|
* @param array $params Any additional parameters needed.
|
||
|
* @param string $url The URL to alter. If none passed in, will use
|
||
|
* the file 'view.php' located in the current
|
||
|
* module's base directory.
|
||
|
*
|
||
|
* @return string The download URL.
|
||
|
*/
|
||
|
function downloadUrl($filename, $params = array(), $url = null)
|
||
|
{
|
||
|
global $browser;
|
||
|
|
||
|
$horde_url = false;
|
||
|
|
||
|
if (is_null($url)) {
|
||
|
global $registry;
|
||
|
$url = Util::addParameter(Horde::url($registry->get('webroot', 'horde') . '/services/download/'), 'module', $registry->getApp());
|
||
|
$horde_url = true;
|
||
|
}
|
||
|
|
||
|
/* Add parameters. */
|
||
|
if (!is_null($params)) {
|
||
|
foreach ($params as $key => $val) {
|
||
|
$url = Util::addParameter($url, $key, $val);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* If we are using the default Horde download link, add the
|
||
|
* filename to the end of the URL. Although not necessary for
|
||
|
* many browsers, this should allow every browser to download
|
||
|
* correctly. */
|
||
|
if ($horde_url) {
|
||
|
$url = Util::addParameter($url, 'fn=/' . rawurlencode($filename));
|
||
|
} elseif ($browser->hasQuirk('break_disposition_filename')) {
|
||
|
/* Some browsers will only obtain the filename correctly
|
||
|
* if the extension is the last argument in the query
|
||
|
* string and rest of the filename appears in the
|
||
|
* PATH_INFO element. */
|
||
|
$filename = rawurlencode($filename);
|
||
|
|
||
|
/* Get the webserver ID. */
|
||
|
$server = Horde::webServerID();
|
||
|
|
||
|
/* Get the name and extension of the file. Apache 2 does
|
||
|
* NOT support PATH_INFO information being passed to the
|
||
|
* PHP module by default, so disable that
|
||
|
* functionality. */
|
||
|
if (($server != 'apache2')) {
|
||
|
if (($pos = strrpos($filename, '.'))) {
|
||
|
$name = '/' . preg_replace('/\./', '%2E', substr($filename, 0, $pos));
|
||
|
$ext = substr($filename, $pos);
|
||
|
} else {
|
||
|
$name = '/' . $filename;
|
||
|
$ext = '';
|
||
|
}
|
||
|
|
||
|
/* Enter the PATH_INFO information. */
|
||
|
if (($pos = strpos($url, '?'))) {
|
||
|
$url = substr($url, 0, $pos) . $name . substr($url, $pos);
|
||
|
} else {
|
||
|
$url .= $name;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Append the extension, if it exists. */
|
||
|
if (($server == 'apache2') || !empty($ext)) {
|
||
|
$url = Util::addParameter($url, 'fn_ext=/' . $filename);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $url;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns an anchor tag with the relevant parameters
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $url The full URL to be linked to
|
||
|
* @param string $status The JavaScript mouse-over string
|
||
|
* @param string $class The CSS class of the link
|
||
|
* @param string $target The window target to point to.
|
||
|
* @param string $onclick JavaScript action for the 'onclick' event.
|
||
|
* @param string $title The link title (tooltip).
|
||
|
* @param string $accesskey The access key to use.
|
||
|
* @param array $attributes Any other name/value pairs to add to the <a>
|
||
|
* tag.
|
||
|
*
|
||
|
* @return string The full <a href> tag.
|
||
|
*/
|
||
|
function link($url, $status = '', $class = '', $target = '', $onclick = '',
|
||
|
$title = '', $accesskey = '', $attributes = array())
|
||
|
{
|
||
|
$ret = "<a href=\"$url\"";
|
||
|
if (!empty($onclick)) {
|
||
|
$ret .= " onclick=\"$onclick\"";
|
||
|
}
|
||
|
if (!empty($status)) {
|
||
|
$ret .= ' onmouseout="window.status=\'\';" onmouseover="window.status=\'' . @htmlspecialchars(strtr(addslashes($status), array("\r" => '', "\n" => '')), ENT_QUOTES, NLS::getCharset()) . '\'; return true;"';
|
||
|
}
|
||
|
if (!empty($class)) {
|
||
|
$ret .= " class=\"$class\"";
|
||
|
}
|
||
|
if (!empty($target)) {
|
||
|
$ret .= " target=\"$target\"";
|
||
|
}
|
||
|
if (!empty($title)) {
|
||
|
$ret .= ' title="' . @htmlspecialchars($title, ENT_QUOTES, NLS::getCharset()) . '"';
|
||
|
}
|
||
|
if (!empty($accesskey)) {
|
||
|
$ret .= ' accesskey="' . htmlspecialchars($accesskey) . '"';
|
||
|
}
|
||
|
|
||
|
foreach ($attributes as $name => $value) {
|
||
|
$ret .= ' ' . htmlspecialchars($name) . '="' . htmlspecialchars($value) . '"';
|
||
|
}
|
||
|
|
||
|
return "$ret>";
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns an anchor sequence with the relevant parameters for a widget
|
||
|
* with accesskey and text.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $url The full URL to be linked to
|
||
|
* @param string $status The JavaScript mouse-over string
|
||
|
* @param string $class The CSS class of the link
|
||
|
* @param string $target The window target to point to.
|
||
|
* @param string $onclick JavaScript action for the 'onclick' event.
|
||
|
* @param string $title The link title (tooltip).
|
||
|
* @param boolean $nocheck Don't check if the access key already has been
|
||
|
* used?
|
||
|
*
|
||
|
* @return string The full <a href>Title</a> sequence.
|
||
|
*/
|
||
|
function widget($url, $status = '', $class = 'widget', $target = '',
|
||
|
$onclick = '', $title = '', $nocheck = false)
|
||
|
{
|
||
|
$ak = Horde::getAccessKey($title, $nocheck);
|
||
|
$plaintitle = Horde::stripAccessKey($title);
|
||
|
|
||
|
return Horde::link($url, $status, $class, $target, $onclick, $plaintitle, $ak) . Horde::highlightAccessKey($title, $ak) . '</a>';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a session-id-ified version of $PHP_SELF.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param boolean $query_string Include any QUERY_STRING?
|
||
|
* @param boolean $nocache Include a nocache parameter in the URL?
|
||
|
* @param boolean $full Return a full URL?
|
||
|
*
|
||
|
* @return string The requested URI.
|
||
|
*/
|
||
|
function selfUrl($query_string = false, $nocache = true, $full = false,
|
||
|
$force_ssl = false)
|
||
|
{
|
||
|
$url = $_SERVER['PHP_SELF'];
|
||
|
|
||
|
if ($query_string && !empty($_SERVER['QUERY_STRING'])) {
|
||
|
$url .= '?' . $_SERVER['QUERY_STRING'];
|
||
|
}
|
||
|
|
||
|
$url = Horde::url($url, $full, 0, $force_ssl);
|
||
|
|
||
|
if ($nocache) {
|
||
|
return Util::nocacheUrl($url);
|
||
|
} else {
|
||
|
return $url;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Constructs a correctly-pathed link to an image.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $src The image file.
|
||
|
* @param optional string $alt Text describing the image.
|
||
|
* @param optional mixed $attr Any additional attributes for the image tag.
|
||
|
* Can be a pre-built string or an array of key/value
|
||
|
* pairs that will be assembled and html-encoded.
|
||
|
* @param optional string $dir The root graphics directory.
|
||
|
*
|
||
|
* @return string The full image tag.
|
||
|
*/
|
||
|
function img($src, $alt = '', $attr = '', $dir = null)
|
||
|
{
|
||
|
/* If browser does not support images, simply return the ALT text. */
|
||
|
if (!$GLOBALS['browser']->hasFeature('images')) {
|
||
|
return @htmlspecialchars($alt, ENT_COMPAT, NLS::getCharset());
|
||
|
}
|
||
|
|
||
|
/* If no directory has been specified, get it from the registry. */
|
||
|
if ($dir === null) {
|
||
|
global $registry;
|
||
|
$dir = $registry->getImageDir();
|
||
|
}
|
||
|
|
||
|
/* If a directory has been provided, prepend it to the image source. */
|
||
|
if (!empty($dir)) {
|
||
|
$src = $dir . '/' . $src;
|
||
|
}
|
||
|
|
||
|
/* Build all of the tag attributes. */
|
||
|
$attributes = array('src' => $src,
|
||
|
'alt' => $alt,
|
||
|
'title' => $alt);
|
||
|
if (is_array($attr)) {
|
||
|
$attributes = array_merge($attributes, $attr);
|
||
|
}
|
||
|
|
||
|
$img = '<img';
|
||
|
foreach ($attributes as $attribute => $value) {
|
||
|
$img .= ' ' . $attribute . '="' . ($attribute == 'src' ? $value : @htmlspecialchars($value, ENT_COMPAT, NLS::getCharset())) . '"';
|
||
|
}
|
||
|
|
||
|
/* If the user supplied a pre-built string of attributes, add that. */
|
||
|
if (is_string($attr) && !empty($attr)) {
|
||
|
$img .= ' ' . $attr;
|
||
|
}
|
||
|
|
||
|
/* Return the closed image tag. */
|
||
|
return $img . ' />';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Determines the location of the system temporary directory. If a specific
|
||
|
* setting cannot be found, it defaults to /tmp.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @return string A directory name which can be used for temp files.
|
||
|
* Returns false if one could not be found.
|
||
|
*/
|
||
|
function getTempDir()
|
||
|
{
|
||
|
global $conf;
|
||
|
|
||
|
/* If one has been specifically set, then use that */
|
||
|
if (!empty($conf['tmpdir'])) {
|
||
|
$tmp = $conf['tmpdir'];
|
||
|
}
|
||
|
|
||
|
/* Next, try Util::getTempDir(). */
|
||
|
if (empty($tmp)) {
|
||
|
$tmp = Util::getTempDir();
|
||
|
}
|
||
|
|
||
|
/* If it is still empty, we have failed, so return false;
|
||
|
* otherwise return the directory determined. */
|
||
|
return empty($tmp) ? false : $tmp;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates a temporary filename for the lifetime of the script, and
|
||
|
* (optionally) registers it to be deleted at request shutdown.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $prefix Prefix to make the temporary name more
|
||
|
* recognizable.
|
||
|
* @param boolean $delete Delete the file at the end of the request?
|
||
|
* @param string $dir Directory to create the temporary file in.
|
||
|
* @param boolean $secure If deleting file, should we securely delete the
|
||
|
* file?
|
||
|
*
|
||
|
* @return string Returns the full path-name to the temporary file or
|
||
|
* false if a temporary file could not be created.
|
||
|
*/
|
||
|
function getTempFile($prefix = 'Horde', $delete = true, $dir = '',
|
||
|
$secure = false)
|
||
|
{
|
||
|
if (empty($dir) || !is_dir($dir)) {
|
||
|
$dir = Horde::getTempDir();
|
||
|
}
|
||
|
|
||
|
return Util::getTempFile($prefix, $delete, $dir, $secure);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Starts output compression, if requested.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @since Horde 2.2
|
||
|
*/
|
||
|
function compressOutput()
|
||
|
{
|
||
|
static $started;
|
||
|
|
||
|
if (isset($started)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Compress output if requested and possible. */
|
||
|
if ($GLOBALS['conf']['compress_pages'] &&
|
||
|
!$GLOBALS['browser']->hasQuirk('buggy_compression') &&
|
||
|
ini_get('zlib.output_compression') == '' &&
|
||
|
ini_get('output_handler') != 'ob_gzhandler') {
|
||
|
if (ob_get_level()) {
|
||
|
ob_end_clean();
|
||
|
}
|
||
|
ob_start('ob_gzhandler');
|
||
|
}
|
||
|
|
||
|
$started = true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Determines if output compression can be used.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @return boolean True if output compression can be used, false if not.
|
||
|
*/
|
||
|
function allowOutputCompression()
|
||
|
{
|
||
|
require_once 'Horde/Browser.php';
|
||
|
$browser = &Browser::singleton();
|
||
|
|
||
|
/* Turn off compression for buggy browsers. */
|
||
|
if ($browser->hasQuirk('buggy_compression')) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return (ini_get('zlib.output_compression') == '' &&
|
||
|
ini_get('output_handler') != 'ob_gzhandler');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the Web server being used.
|
||
|
* PHP string list built from the PHP 'configure' script.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @return string A web server identification string.
|
||
|
* <pre>
|
||
|
* 'aolserver' = AOL Server
|
||
|
* 'apache1' = Apache 1.x
|
||
|
* 'apache2' = Apache 2.x
|
||
|
* 'caudium' = Caudium
|
||
|
* 'cgi' = Unknown server - PHP built as CGI program
|
||
|
* 'cli' = Command Line Interface build
|
||
|
* 'embed' = Embedded PHP
|
||
|
* 'isapi' = Zeus ISAPI
|
||
|
* 'milter' = Milter
|
||
|
* 'nsapi' = NSAPI
|
||
|
* 'phttpd' = PHTTPD
|
||
|
* 'pi3web' = Pi3Web
|
||
|
* 'roxen' = Roxen/Pike
|
||
|
* 'servlet' = Servlet
|
||
|
* 'thttpd' = thttpd
|
||
|
* 'tux' = Tux
|
||
|
* 'webjames' = Webjames
|
||
|
* </pre>
|
||
|
*/
|
||
|
function webServerID()
|
||
|
{
|
||
|
$server = php_sapi_name();
|
||
|
|
||
|
if ($server == 'apache') {
|
||
|
return 'apache1';
|
||
|
} elseif (($server == 'apache2filter') ||
|
||
|
($server == 'apache2handler')) {
|
||
|
return 'apache2';
|
||
|
} else {
|
||
|
return $server;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the <link> tags for the CSS stylesheets.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string|array $app The Horde application(s).
|
||
|
* @param mixed $theme The theme to use; specify an empty value to
|
||
|
* retrieve the theme from user preferences, and
|
||
|
* false for no theme.
|
||
|
* @param boolean $inherit Inherit Horde-wide CSS?
|
||
|
*
|
||
|
* @return string <link> tags for CSS stylesheets.
|
||
|
*/
|
||
|
function stylesheetLink($apps = null, $theme = '', $inherit = true)
|
||
|
{
|
||
|
if ($theme !== false && empty($theme)) {
|
||
|
$theme = $GLOBALS['prefs']->getValue('theme');
|
||
|
}
|
||
|
|
||
|
$css = array();
|
||
|
$themes_fs = $GLOBALS['registry']->get('themesfs', 'horde');
|
||
|
if ($inherit) {
|
||
|
$themes_uri = Horde::url($GLOBALS['registry']->get('themesuri', 'horde'), false, -1);
|
||
|
$css[] = $themes_uri . '/screen.css';
|
||
|
if (!empty($theme) &&
|
||
|
file_exists($themes_fs . '/' . $theme . '/screen.css')) {
|
||
|
$css[] = $themes_uri . '/' . $theme . '/screen.css';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!empty($apps)) {
|
||
|
if (!is_array($apps)) {
|
||
|
$apps = array($apps);
|
||
|
}
|
||
|
foreach ($apps as $app) {
|
||
|
if ($inherit && $app == 'horde') {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$themes_fs = $GLOBALS['registry']->get('themesfs', $app);
|
||
|
if (file_exists($themes_fs . '/screen.css')) {
|
||
|
$themes_uri = Horde::url($GLOBALS['registry']->get('themesuri', $app), false, -1);
|
||
|
$css[] = $themes_uri . '/screen.css';
|
||
|
}
|
||
|
if (!empty($theme) &&
|
||
|
file_exists($themes_fs . '/' . $theme . '/screen.css')) {
|
||
|
$css[] = $themes_uri . '/' . $theme . '/screen.css';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$html = '';
|
||
|
foreach ($css as $css_link) {
|
||
|
$html .= '<link href="' . $css_link . '" rel="stylesheet" type="text/css" />' . "\n";
|
||
|
}
|
||
|
|
||
|
/* Load IE PNG transparency code if needed. */
|
||
|
if ($GLOBALS['browser']->hasQuirk('png_transparency') &&
|
||
|
$GLOBALS['prefs']->getValue('alpha_filter')) {
|
||
|
$url = Horde::url($GLOBALS['registry']->get('jsuri', 'horde') . '/alphaImageLoader.php', true, -1);
|
||
|
$html .= '<style type="text/css"> img { behavior: url("' . $url . '"); } </style>';
|
||
|
}
|
||
|
|
||
|
/* Load browser specific stylesheets if needed. */
|
||
|
if ($GLOBALS['browser']->isBrowser('msie')) {
|
||
|
$html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/ie.css" rel="stylesheet" type="text/css" />' . "\n";
|
||
|
if ($GLOBALS['browser']->getPlatform() == 'mac') {
|
||
|
$html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/ie5mac.css" rel="stylesheet" type="text/css" />' . "\n";
|
||
|
}
|
||
|
}
|
||
|
if ($GLOBALS['browser']->isBrowser('opera')) {
|
||
|
$html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/opera.css" rel="stylesheet" type="text/css" />' . "\n";
|
||
|
}
|
||
|
if (strpos(strtolower($GLOBALS['browser']->getAgentString()), 'safari') !== false) {
|
||
|
$html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/safari.css" rel="stylesheet" type="text/css" />' . "\n";
|
||
|
}
|
||
|
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets a custom session handler up, if there is one.
|
||
|
*
|
||
|
* @access public
|
||
|
*/
|
||
|
function setupSessionHandler()
|
||
|
{
|
||
|
global $conf;
|
||
|
|
||
|
ini_set('url_rewriter.tags', 0);
|
||
|
session_set_cookie_params($conf['session']['timeout'],
|
||
|
$conf['cookie']['path'], $conf['cookie']['domain'], $conf['use_ssl'] == 1 ? 1 : 0);
|
||
|
session_cache_limiter($conf['session']['cache_limiter']);
|
||
|
session_name(urlencode($conf['session']['name']));
|
||
|
|
||
|
$type = !empty($conf['sessionhandler']['type']) ? $conf['sessionhandler']['type'] : 'none';
|
||
|
|
||
|
if ($type == 'external') {
|
||
|
$calls = $conf['sessionhandler']['params'];
|
||
|
session_set_save_handler($calls['open'],
|
||
|
$calls['close'],
|
||
|
$calls['read'],
|
||
|
$calls['write'],
|
||
|
$calls['destroy'],
|
||
|
$calls['gc']);
|
||
|
} elseif ($type != 'none') {
|
||
|
global $_session_handler;
|
||
|
require_once 'Horde/SessionHandler.php';
|
||
|
$_session_handler = &SessionHandler::singleton($conf['sessionhandler']['type']);
|
||
|
if (!empty($_session_handler) &&
|
||
|
!is_a($_session_handler, 'PEAR_Error')) {
|
||
|
ini_set('session.save_handler', 'user');
|
||
|
session_set_save_handler(array(&$_session_handler, 'open'),
|
||
|
array(&$_session_handler, 'close'),
|
||
|
array(&$_session_handler, 'read'),
|
||
|
array(&$_session_handler, 'write'),
|
||
|
array(&$_session_handler, 'destroy'),
|
||
|
array(&$_session_handler, 'gc'));
|
||
|
} else {
|
||
|
Horde::fatal(PEAR::raiseError('Horde is unable to correctly start the custom session handler.'), __FILE__, __LINE__, false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns an un-used access key from the label given.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $label The label to choose an access key from.
|
||
|
* @param boolean $nocheck Don't check if the access key already has been
|
||
|
* used?
|
||
|
*
|
||
|
* @return string A single lower case character access key or empty
|
||
|
* string if none can be found
|
||
|
*/
|
||
|
function getAccessKey($label, $nocheck = false, $shutdown = false)
|
||
|
{
|
||
|
/* The access keys already used in this page */
|
||
|
static $_used = array();
|
||
|
|
||
|
/* The labels already used in this page */
|
||
|
static $_labels = array();
|
||
|
|
||
|
/* Shutdown call for translators? */
|
||
|
if ($shutdown) {
|
||
|
if (!count($_labels)) {
|
||
|
return;
|
||
|
}
|
||
|
$script = basename($_SERVER['PHP_SELF']);
|
||
|
$labels = array_keys($_labels);
|
||
|
sort($labels);
|
||
|
$used = array_keys($_used);
|
||
|
sort($used);
|
||
|
$remaining = str_replace($used, array(), 'abcdefghijklmnopqrstuvwxyz');
|
||
|
Horde::logMessage('Access key information for ' . $script, __FILE__, __LINE__);
|
||
|
Horde::logMessage('Used labels: ' . implode(',', $labels), __FILE__, __LINE__);
|
||
|
Horde::logMessage('Used keys: ' . implode('', $used), __FILE__, __LINE__);
|
||
|
Horde::logMessage('Free keys: ' . $remaining, __FILE__, __LINE__);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Use access keys at all? */
|
||
|
static $notsupported;
|
||
|
if (!isset($notsupported)) {
|
||
|
$notsupported = !$GLOBALS['browser']->hasFeature('accesskey') ||
|
||
|
!$GLOBALS['prefs']->getValue('widget_accesskey');
|
||
|
}
|
||
|
|
||
|
if ($notsupported || !preg_match('/_([A-Za-z])/', $label, $match)) {
|
||
|
return '';
|
||
|
}
|
||
|
$key = $match[1];
|
||
|
|
||
|
/* Has this key already been used? */
|
||
|
if (isset($_used[strtolower($key)]) &&
|
||
|
!($nocheck && isset($_labels[$label]))) {
|
||
|
return '';
|
||
|
}
|
||
|
|
||
|
/* Save key and label. */
|
||
|
$_used[strtolower($key)] = true;
|
||
|
$_labels[$label] = true;
|
||
|
|
||
|
return $key;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Strips an access key from a label.
|
||
|
* For multibyte charset strings the access key gets removed completely,
|
||
|
* otherwise only the underscore gets removed.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $label The label containing an access key.
|
||
|
*
|
||
|
* @return string The label with the access key being stripped.
|
||
|
*/
|
||
|
function stripAccessKey($label)
|
||
|
{
|
||
|
include_once HORDE_BASE . '/config/nls.php';
|
||
|
$multibyte = isset($GLOBALS['nls']['multibyte'][NLS::getCharset(true)]);
|
||
|
|
||
|
return preg_replace('/_([A-Za-z])/',
|
||
|
$multibyte && preg_match('/[\x80-\xff]/', $label) ? '' : '\1',
|
||
|
$label);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Highlights an access key in a label.
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $label The label to to highlight the access key in.
|
||
|
* @param string $accessKey The access key to highlight.
|
||
|
*
|
||
|
* @return string The HTML version of the label with the access key
|
||
|
* highlighted.
|
||
|
*/
|
||
|
function highlightAccessKey($label, $accessKey)
|
||
|
{
|
||
|
$stripped_label = Horde::stripAccesskey($label);
|
||
|
|
||
|
if (empty($accessKey)) {
|
||
|
return $stripped_label;
|
||
|
}
|
||
|
|
||
|
if (isset($GLOBALS['nls']['multibyte'][NLS::getCharset(true)])) {
|
||
|
return $stripped_label . '(' . '<span class="accessKey">' .
|
||
|
strtoupper($accessKey) . '</span>' . ')';
|
||
|
} else {
|
||
|
return str_replace('_' . $accessKey, '<span class="accessKey">' . $accessKey . '</span>', $label);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the appropriate "accesskey" and "title" attributes for an HTML
|
||
|
* tag and the given label.
|
||
|
*
|
||
|
* @param string $label The title of an HTML element
|
||
|
* @param boolean $nocheck Don't check if the access key already has been
|
||
|
* used?
|
||
|
*
|
||
|
* @return string The title, and if appropriate, the accesskey attributes
|
||
|
* for the element.
|
||
|
*/
|
||
|
function getAccessKeyAndTitle($label, $nocheck = false)
|
||
|
{
|
||
|
$ak = Horde::getAccessKey($label, $nocheck);
|
||
|
$attributes = 'title="' . Horde::stripAccessKey($label);
|
||
|
if (!empty($ak)) {
|
||
|
$attributes .= sprintf(_(" (Accesskey %s)"), $ak);
|
||
|
$attributes .= '" accesskey="' . $ak;
|
||
|
}
|
||
|
$attributes .= '"';
|
||
|
return $attributes;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a label element including an access key for usage in conjuction
|
||
|
* with a form field. User preferences regarding access keys are respected.
|
||
|
*
|
||
|
* @param string $for The form field's id attribute.
|
||
|
* @param string $label The label text.
|
||
|
* @param string $ak The access key to use. If null a new access key
|
||
|
* will be generated.
|
||
|
*
|
||
|
* @return string The html code for the label element.
|
||
|
*/
|
||
|
function label($for, $label, $ak = null)
|
||
|
{
|
||
|
global $prefs;
|
||
|
|
||
|
if (is_null($ak)) {
|
||
|
$ak = Horde::getAccesskey($label, 1);
|
||
|
}
|
||
|
$label = Horde::highlightAccessKey($label, $ak);
|
||
|
|
||
|
return sprintf('<label for="%s"%s>%s</label>',
|
||
|
$for,
|
||
|
!empty($ak) ? ' accesskey="' . $ak . '"' : '',
|
||
|
$label);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Redirects to the main Horde login page on authentication failure.
|
||
|
*
|
||
|
* @access public
|
||
|
*/
|
||
|
function authenticationFailureRedirect()
|
||
|
{
|
||
|
require_once 'Horde/CLI.php';
|
||
|
if (Horde_CLI::runningFromCLI()) {
|
||
|
$cli = &Horde_CLI::singleton();
|
||
|
$cli->fatal(_("You are not authenticated."));
|
||
|
}
|
||
|
|
||
|
$url = $GLOBALS['registry']->get('webroot', 'horde') . '/login.php';
|
||
|
$url = Util::addParameter($url, 'url', Horde::selfUrl(true));
|
||
|
$url = Auth::addLogoutParameters($url);
|
||
|
header('Location: ' . Horde::url($url, true));
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Uses DOM Tooltips (via javascript) to display the 'title'
|
||
|
* attribute for Horde::link() calls.
|
||
|
*
|
||
|
* If using this function, the following function must be called:
|
||
|
* Horde::addScriptFile('tooltip.js', 'horde', true);
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $url The full URL to be linked to
|
||
|
* @param string $status The JavaScript mouse-over string
|
||
|
* @param string $class The CSS class of the link
|
||
|
* @param string $target The window target to point to.
|
||
|
* @param string $onclick JavaScript action for the 'onclick' event.
|
||
|
* @param string $title The link title (tooltip).
|
||
|
* @param string $accesskey The access key to use.
|
||
|
* @param array $attributes Any other name/value pairs to add to the <a>
|
||
|
* tag.
|
||
|
*
|
||
|
* @return string The full <a href> tag.
|
||
|
*/
|
||
|
function linkTooltip($url, $status = '', $class = '', $target = '',
|
||
|
$onclick = '', $title = '', $accesskey = '',
|
||
|
$attributes = array())
|
||
|
{
|
||
|
$url = substr(Horde::link($url, null, $class, $target, $onclick, null, $accesskey, $attributes), 0, -1);
|
||
|
|
||
|
if (strlen($status)) {
|
||
|
$status = @htmlspecialchars(addslashes($status), ENT_QUOTES, NLS::getCharset());
|
||
|
}
|
||
|
|
||
|
$title = trim($title);
|
||
|
if (strlen($title)) {
|
||
|
require_once 'Horde/Text/Filter.php';
|
||
|
$title = Text_Filter::filter($title, 'text2html', array('parselevel' => TEXT_HTML_NOHTML, 'charset' => '', 'class' => ''));
|
||
|
$title = '<pre style="margin:0px;">' . strtr(addslashes($title), array("\r" => '', "\n" => '')) . '</pre>';
|
||
|
$url .= ' onmouseover="tooltipLink(\'' . @htmlspecialchars($title, ENT_QUOTES, NLS::getCharset()) . '\', \'' . $status . '\'); return true;" onmouseout="tooltipClose();"';
|
||
|
}
|
||
|
$url .= '>';
|
||
|
|
||
|
return $url;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Provides a standardised function to call a Horde hook, checking whether
|
||
|
* a hook config file exists and whether the function itself exists. If
|
||
|
* these two conditions are not satisfied it will return the specified
|
||
|
* value (by default a PEAR error).
|
||
|
*
|
||
|
* @access public
|
||
|
*
|
||
|
* @param string $hook The function to call.
|
||
|
* @param array $args An array of any arguments to pass to the hook
|
||
|
* function.
|
||
|
* @param string $app If specified look for hooks in the config directory
|
||
|
* of this app.
|
||
|
* @param mixed $error What to return if $app/config/hooks.php or $hook
|
||
|
* does not exist. If this is the string 'PEAR_Error'
|
||
|
* a PEAR error object is returned instead, detailing
|
||
|
* the failure.
|
||
|
*
|
||
|
* @return mixed Either the results of the hook or PEAR error on failure.
|
||
|
*/
|
||
|
function callHook($hook, $args = array(), $app = 'horde', $error = 'PEAR_Error')
|
||
|
{
|
||
|
global $registry;
|
||
|
static $hooks_loaded;
|
||
|
|
||
|
if (!isset($hooks_loaded)) {
|
||
|
if (file_exists($registry->get('fileroot', $app) . '/config/hooks.php')) {
|
||
|
require_once $registry->get('fileroot', $app) . '/config/hooks.php';
|
||
|
$hooks_loaded = true;
|
||
|
} else {
|
||
|
$hooks_loaded = false;
|
||
|
}
|
||
|
}
|
||
|
if ($hooks_loaded && function_exists($hook)) {
|
||
|
return call_user_func_array($hook, $args);
|
||
|
}
|
||
|
|
||
|
if (is_string($error) && strcmp($error, 'PEAR_Error') == 0) {
|
||
|
$error = PEAR::raiseError(sprintf('Hook %s in application %s not called.', $hook, $app));
|
||
|
Horde::logMessage($error, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||
|
}
|
||
|
|
||
|
return $error;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the initial page to load when accessing Horde.
|
||
|
*
|
||
|
* @return string The URL of the initial page.
|
||
|
*/
|
||
|
function initialPage()
|
||
|
{
|
||
|
global $prefs, $registry, $perms;
|
||
|
|
||
|
$initial_app = $prefs->getValue('initial_application');
|
||
|
if (!empty($initial_app) && $registry->hasPermission($initial_app)) {
|
||
|
return Horde::url($registry->getInitialPage($initial_app), true);
|
||
|
} elseif (isset($registry->applications['horde']['initial_page'])) {
|
||
|
return Horde::applicationUrl($registry->applications['horde']['initial_page'], true);
|
||
|
} elseif (Auth::getAuth()) {
|
||
|
return Horde::applicationUrl('services/portal/', true);
|
||
|
} else {
|
||
|
return Horde::applicationUrl('login.php', true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns an array of available menu items when in a Horde script.
|
||
|
*
|
||
|
* @return array Available menu items.
|
||
|
*/
|
||
|
function getHordeMenu()
|
||
|
{
|
||
|
global $registry, $prefs;
|
||
|
|
||
|
$menu = array();
|
||
|
|
||
|
/* The home page button. If an initial application has been set in the
|
||
|
* prefs this will default to that application. Otherwise it will go
|
||
|
* to the portal screen. */
|
||
|
$initial_app = $prefs->getValue('initial_application');
|
||
|
if (!empty($initial_app)) {
|
||
|
$url = Horde::url($registry->getInitialPage($initial_app));
|
||
|
} else {
|
||
|
$url = Horde::applicationUrl('services/portal/');
|
||
|
}
|
||
|
$menu[] = array('url' => $url,
|
||
|
'text' => _("Home"),
|
||
|
'icon' => 'horde.png',
|
||
|
'icon_path' => $registry->getImageDir());
|
||
|
|
||
|
if (Auth::isAdmin()) {
|
||
|
$menu[] = array('url' => Horde::applicationUrl('admin/'),
|
||
|
'text' => _("_Administration"),
|
||
|
'icon' => 'administration.png',
|
||
|
'icon_path' => $registry->getImageDir());
|
||
|
}
|
||
|
|
||
|
return $menu;
|
||
|
}
|
||
|
|
||
|
}
|