| [ Index ] |
|
Code source de Horde 3.1.3 |
1 <?php 2 3 include_once 'Log.php'; 4 include_once 'Horde/Util.php'; 5 6 /** 7 * The Horde:: class provides the functionality shared by all Horde 8 * applications. 9 * 10 * $Horde: framework/Horde/Horde.php,v 1.489.2.54 2006/07/31 08:49:47 jan Exp $ 11 * 12 * Copyright 1999-2006 Chuck Hagenbuch <chuck@horde.org> 13 * Copyright 1999-2006 Jon Parise <jon@horde.org> 14 * 15 * See the enclosed file COPYING for license information (LGPL). If you 16 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. 17 * 18 * @author Chuck Hagenbuch <chuck@horde.org> 19 * @author Jon Parise <jon@horde.org> 20 * @since Horde 1.3 21 * @package Horde_Framework 22 */ 23 class Horde { 24 25 /** 26 * Logs a message to the global Horde log backend. 27 * 28 * @param mixed $message Either a string or a PEAR_Error object. 29 * @param string $file What file was the log function called from 30 * (e.g. __FILE__)? 31 * @param integer $line What line was the log function called from 32 * (e.g. __LINE__)? 33 * @param integer $priority The priority of the message. One of: 34 * <pre> 35 * PEAR_LOG_EMERG 36 * PEAR_LOG_ALERT 37 * PEAR_LOG_CRIT 38 * PEAR_LOG_ERR 39 * PEAR_LOG_WARNING 40 * PEAR_LOG_NOTICE 41 * PEAR_LOG_INFO 42 * PEAR_LOG_DEBUG 43 * </pre> 44 */ 45 function logMessage($message, $file, $line, $priority = PEAR_LOG_INFO) 46 { 47 global $conf; 48 49 if (!$conf['log']['enabled']) { 50 return; 51 } 52 53 if ($priority > $conf['log']['priority']) { 54 return; 55 } 56 57 $logger = &Horde::getLogger(); 58 if (!is_a($logger, 'Log')) { 59 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); 60 } 61 62 if (is_a($message, 'PEAR_Error')) { 63 $userinfo = $message->getUserInfo(); 64 $message = $message->getMessage(); 65 if (!empty($userinfo)) { 66 if (is_array($userinfo)) { 67 $userinfo = @implode(', ', $userinfo); 68 } 69 $message .= ': ' . $userinfo; 70 } 71 } elseif (is_callable(array($message, 'getMessage'))) { 72 $message = $message->getMessage(); 73 } 74 75 $app = isset($GLOBALS['registry']) ? $GLOBALS['registry']->getApp() : 'horde'; 76 $message = '[' . $app . '] ' . $message . ' [on line ' . $line . ' of "' . $file . '"]'; 77 78 /* Make sure to log in the system's locale. */ 79 $locale = setlocale(LC_TIME, 0); 80 setlocale(LC_TIME, 'C'); 81 82 $logger->log($message, $priority); 83 84 /* Restore original locale. */ 85 setlocale(LC_TIME, $locale); 86 87 return true; 88 } 89 90 /** 91 */ 92 function &getLogger() 93 { 94 global $conf; 95 96 if (empty($conf['log']['enabled'])) { 97 return false; 98 } 99 100 static $logcheck; 101 if (!isset($logcheck)) { 102 // Try to make sure that we can log messages somehow. 103 if (empty($conf['log']) || 104 empty($conf['log']['type']) || 105 empty($conf['log']['name']) || 106 empty($conf['log']['ident']) || 107 !isset($conf['log']['params'])) { 108 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); 109 } 110 $logcheck = true; 111 } 112 113 return $logger = &Log::singleton($conf['log']['type'], $conf['log']['name'], 114 $conf['log']['ident'], $conf['log']['params']); 115 } 116 117 /** 118 * Destroys any existing session on login and make sure to use a new 119 * session ID, to avoid session fixation issues. Should be called before 120 * checking a login. 121 */ 122 function getCleanSession() 123 { 124 // Make sure to force a completely new session ID and clear 125 // all session data. 126 if (version_compare(phpversion(), '4.3.3') !== -1) { 127 session_regenerate_id(); 128 session_unset(); 129 } else { 130 @session_destroy(); 131 if (Util::extensionExists('posix')) { 132 $new_session_id = md5(microtime() . posix_getpid()); 133 } else { 134 $new_session_id = md5(uniqid(mt_rand(), true)); 135 } 136 session_id($new_session_id); 137 138 // Restart the session, including setting up the session 139 // handler. 140 Horde::setupSessionHandler(); 141 @session_start(); 142 } 143 144 /* Reset cookie timeouts, if necessary. */ 145 if (!empty($GLOBALS['conf']['session']['timeout'])) { 146 $app = $GLOBALS['registry']->getApp(); 147 if (Secret::clearKey($app)) { 148 Secret::setKey($app); 149 } 150 Secret::setKey('auth'); 151 } 152 } 153 154 /** 155 * Aborts with a fatal error, displaying debug information to the user. 156 * 157 * @param mixed $error A PEAR_Error object with debug information or an 158 * error message. 159 * @param integer $file The file in which the error occured. 160 * @param integer $line The line on which the error occured. 161 * @param boolean $log Log this message via Horde::logMessage()? 162 */ 163 function fatal($error, $file, $line, $log = true) 164 { 165 @include_once 'Horde/Auth.php'; 166 @include_once 'Horde/CLI.php'; 167 168 $admin = class_exists('Auth') && Auth::isAdmin(); 169 $cli = class_exists('Horde_CLI') && Horde_CLI::runningFromCLI(); 170 171 $errortext = '<h1>' . _("A fatal error has occurred") . '</h1>'; 172 if (is_a($error, 'PEAR_Error')) { 173 $info = array_merge(array('file' => 'conf.php', 'variable' => '$conf'), 174 array($error->getUserInfo())); 175 176 switch ($error->getCode()) { 177 case HORDE_ERROR_DRIVER_CONFIG_MISSING: 178 $message = sprintf(_("No configuration information specified for %s."), $info['name']) . '<br />' . 179 sprintf(_("The file %s should contain some %s settings."), 180 $GLOBALS['registry']->get('fileroot') . '/config/' . $info['file'], 181 sprintf("%s['%s']['params']", $info['variable'], $info['driver'])); 182 break; 183 184 case HORDE_ERROR_DRIVER_CONFIG: 185 $message = sprintf(_("Required \"%s\" not specified in %s configuration."), $info['field'], $info['name']) . '<br />' . 186 sprintf(_("The file %s should contain a %s setting."), 187 $GLOBALS['registry']->get('fileroot') . '/config/' . $info['file'], 188 sprintf("%s['%s']['params']['%s']", $info['variable'], $info['driver'], $info['field'])); 189 break; 190 191 default: 192 $message = $error->getMessage(); 193 break; 194 } 195 196 $errortext .= '<h3>' . htmlspecialchars($message) . '</h3>'; 197 } elseif (is_object($error) && method_exists($error, 'getMessage')) { 198 $errortext .= '<h3>' . htmlspecialchars($error->getMessage()) . '</h3>'; 199 } elseif (is_string($error)) { 200 $errortext .= '<h3>' . htmlspecialchars($error) . '</h3>'; 201 } 202 203 if ($admin) { 204 $errortext .= '<p><code>' . sprintf(_("[line %s of %s]"), $line, $file) . '</code></p>'; 205 if (is_object($error)) { 206 $errortext .= '<h3>' . _("Details (also in Horde's logfile):") . '</h3>'; 207 $errortext .= '<p><pre>' . htmlspecialchars(Util::bufferOutput('var_dump', $error)) . '</pre></p>'; 208 } 209 } elseif ($log) { 210 $errortext .= '<h3>' . _("Details have been logged for the administrator.") . '</h3>'; 211 } 212 213 // Log the error via Horde::logMessage() if requested. 214 if ($log) { 215 Horde::logMessage($error, $file, $line, PEAR_LOG_EMERG); 216 } 217 218 if ($cli) { 219 echo strip_tags(str_replace(array('<br />', '<p>', '</p>', '<h1>', '</h1>', '<h3>', '</h3>'), "\n", $errortext)); 220 } else { 221 echo <<< HTML 222 <html> 223 <head><title>Horde :: Fatal Error</title></head> 224 <body style="background:#fff; color:#000">$errortext</body> 225 </html> 226 HTML; 227 } 228 exit; 229 } 230 231 /** 232 * Adds the javascript code to the output (if output has already started) 233 * or to the list of script files to include via includeScriptFiles(). 234 * 235 * @param string $file The full javascript file name. 236 * @param string $app The application name. Defaults to the current 237 * application. 238 * @param boolean $direct Include the file directly without passing it 239 * through javascript.php? 240 */ 241 function addScriptFile($file, $app = null, $direct = false) 242 { 243 global $registry; 244 static $included = array(); 245 246 if (empty($app)) { 247 $app = $registry->getApp(); 248 } 249 250 // Skip any js files that have since been deprecated. 251 $ignored_files = array('horde' => array('tooltip.js' => 1)); 252 if (!empty($ignored_files[$app][$file])) { 253 return; 254 } 255 256 // Don't include scripts multiple times. 257 if (!empty($included[$app][$file])) { 258 return; 259 } 260 $included[$app][$file] = true; 261 262 // Explicitly check for a non-PHP version of the script. 263 if (!$direct && file_exists($file{0} == '/' ? $registry->get('fileroot', $app) . $file : $registry->get('jsfs', $app) . '/' . $file)) { 264 $direct = true; 265 } 266 267 // If headers have already been sent, we need to output a 268 // <script> tag directly. 269 if (ob_get_length() || headers_sent()) { 270 if ($direct) { 271 $url = Horde::url($file{0} == '/' ? $registry->get('webroot', $app) . $file : $registry->get('jsuri', $app) . '/' . $file); 272 } else { 273 $url = Horde::url($registry->get('webroot', 'horde') . '/services/javascript.php'); 274 $url = Util::addParameter($url, array('file' => $file, 275 'app' => $app)); 276 } 277 echo '<script type="text/javascript" src="' . $url . '"></script>' . "\n"; 278 } else { 279 global $_horde_script_files; 280 $_horde_script_files[$app][] = array($file, $direct); 281 } 282 } 283 284 /** 285 * Includes javascript files that were needed before any headers were sent. 286 */ 287 function includeScriptFiles() 288 { 289 global $_horde_script_files, $registry; 290 291 /* If there is no javascript available, there's no point in including 292 * the rest of the files. */ 293 if (!$GLOBALS['browser']->hasFeature('javascript')) { 294 return; 295 } 296 297 /* Add general UI js library. */ 298 Horde::addScriptFile('horde.js', 'horde', true); 299 if ($GLOBALS['browser']->hasQuirk('windowed_controls')) { 300 /* Fixes for IE that can't easily be done without browser 301 * detection. */ 302 Horde::addScriptFile('horde.ie.js', 'horde', true); 303 } 304 305 if (!empty($_horde_script_files)) { 306 $base_url = Horde::url($registry->get('webroot', 'horde') . '/services/javascript.php'); 307 foreach ($_horde_script_files as $app => $files) { 308 foreach ($files as $file) { 309 if (!empty($file[1])) { 310 $url = $file[0]{0} == '/' ? $registry->get('webroot', $app) . $file[0] : $registry->get('jsuri', $app) . '/' . $file[0]; 311 echo '<script type="text/javascript" src="' . Horde::url($url) . "\"></script>\n"; 312 } else { 313 $url = Util::addParameter($base_url, array('file' => $file[0], 314 'app' => $app)); 315 echo '<script type="text/javascript" src="' . $url . "\"></script>\n"; 316 } 317 } 318 } 319 } 320 } 321 322 /** 323 * Includes javascript files that were needed before any headers were sent. 324 */ 325 function inlineScriptFiles() 326 { 327 global $_horde_script_files, $registry; 328 329 if (!empty($_horde_script_files)) { 330 $jsWrapper = $registry->get('fileroot', 'horde') . '/services/javascript.php'; 331 foreach ($_horde_script_files as $app => $files) { 332 foreach ($files as $file) { 333 if (!empty($file[1])) { 334 @readfile($file[0]{0} == '/' ? $registry->get('fileroot', $app) . $file[0] : $registry->get('jsfs', $app) . '/' . $file[0]); 335 } else { 336 $file = $file[0]; 337 require $jsWrapper; 338 } 339 } 340 } 341 } 342 } 343 344 /** 345 * Checks if link should be shown and return the nescessary code. 346 * 347 * @param string $type Type of link to display 348 * @param string $app The name of the current Horde application. 349 * @param boolean $override Override Horde settings? 350 * @param boolean $referrer Include the current page as the referrer (url=)? 351 * 352 * @return string The HTML to create the link. 353 */ 354 function getServiceLink($type, $app, $override = false, $referrer = true) 355 { 356 if (!Horde::showService($type) && !$override) { 357 return false; 358 } 359 360 switch ($type) { 361 case 'help': 362 if ($GLOBALS['browser']->hasFeature('javascript')) { 363 Horde::addScriptFile('popup.js', 'horde', true); 364 } 365 $url = Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/help/', true); 366 return Util::addParameter($url, 'module', $app); 367 368 case 'problem': 369 return Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/problem.php?return_url=' . urlencode(Horde::selfUrl(true, true, true))); 370 371 case 'logout': 372 return Horde::url(Auth::addLogoutParameters($GLOBALS['registry']->get('webroot', 'horde') . '/login.php', AUTH_REASON_LOGOUT)); 373 374 case 'login': 375 return Auth::getLoginScreen('', $referrer ? Horde::selfUrl(true) : null); 376 377 case 'options': 378 global $conf; 379 if (($conf['prefs']['driver'] != '') && ($conf['prefs']['driver'] != 'none')) { 380 return Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/prefs.php?app=' . $app); 381 } 382 break; 383 } 384 385 return false; 386 } 387 388 /** 389 * @param string $type The type of link. 390 * 391 * @return boolean True if the link is to be shown. 392 */ 393 function showService($type) 394 { 395 global $conf; 396 397 if (empty($conf['menu']['links'][$type])) { 398 return false; 399 } 400 401 switch ($conf['menu']['links'][$type]) { 402 case 'all': 403 return true; 404 405 case 'never': 406 return false; 407 408 case 'authenticated': 409 return (bool)Auth::getAuth(); 410 411 default: 412 return false; 413 } 414 } 415 416 /** 417 * Returns the driver parameters for the specified backend. 418 * 419 * @param mixed $backend The backend system (e.g. 'prefs', 'categories', 420 * 'contacts') being used. 421 * The used configuration array will be 422 * $conf[$backend]. If an array gets passed, it will 423 * be $conf[$key1][$key2]. 424 * @param string $type The type of driver. 425 * 426 * @return array The connection parameters. 427 */ 428 function getDriverConfig($backend, $type = 'sql') 429 { 430 global $conf; 431 432 $c = null; 433 if (is_array($backend)) { 434 require_once 'Horde/Array.php'; 435 $c = Horde_Array::getElement($conf, $backend); 436 } elseif (isset($conf[$backend])) { 437 $c = $conf[$backend]; 438 } 439 if (!is_null($c) && isset($c['params'])) { 440 if (isset($conf[$type])) { 441 return array_merge($conf[$type], $c['params']); 442 } else { 443 return $c['params']; 444 } 445 } 446 447 return isset($conf[$type]) ? $conf[$type] : array(); 448 } 449 450 451 /** 452 * Returns the VFS driver parameters for the specified backend. 453 * 454 * @param string $name The VFS system name (e.g. 'images', 'documents') 455 * being used. 456 * 457 * @return array A hash with the VFS parameters; the VFS driver in 'type' 458 * and the connection parameters in 'params'. 459 */ 460 function getVFSConfig($name) 461 { 462 global $conf; 463 464 if (!isset($conf[$name]['type'])) { 465 return PEAR::raiseError(_("You must configure a VFS backend.")); 466 } 467 468 if ($conf[$name]['type'] == 'horde') { 469 $vfs = $conf['vfs']; 470 } else { 471 $vfs = $conf[$name]; 472 } 473 474 if ($vfs['type'] == 'sql') { 475 $vfs['params'] = Horde::getDriverConfig($name, 'sql'); 476 } 477 478 return $vfs; 479 } 480 481 /** 482 * Checks if all necessary parameters for a driver configuration 483 * are set and throws a fatal error with a detailed explaination 484 * how to fix this, if something is missing. 485 * 486 * @param array $params The configuration array with all parameters. 487 * @param string $driver The key name (in the configuration array) of 488 * the driver. 489 * @param array $fields An array with mandatory parameter names for 490 * this driver. 491 * @param string $name The clear text name of the driver. If not 492 * specified, the application name will be used. 493 * @param string $file The configuration file that should contain 494 * these settings. 495 * @param string $variable The name of the configuration variable. 496 */ 497 function assertDriverConfig($params, $driver, $fields, $name = null, 498 $file = 'conf.php', $variable = '$conf') 499 { 500 global $registry; 501 502 // Don't generate a fatal error if we fail during or before 503 // Registry instantiation. 504 if (is_null($name)) { 505 $name = isset($registry) ? $registry->getApp() : '[unknown]'; 506 } 507 $fileroot = isset($registry) ? $registry->get('fileroot') : ''; 508 509 if (!is_array($params) || !count($params)) { 510 Horde::fatal(PEAR::raiseError( 511 sprintf(_("No configuration information specified for %s."), $name) . "\n\n" . 512 sprintf(_("The file %s should contain some %s settings."), 513 $fileroot . '/config/' . $file, 514 sprintf("%s['%s']['params']", $variable, $driver))), 515 __FILE__, __LINE__); 516 } 517 518 foreach ($fields as $field) { 519 if (!isset($params[$field])) { 520 Horde::fatal(PEAR::raiseError( 521 sprintf(_("Required \"%s\" not specified in %s configuration."), $field, $name) . "\n\n" . 522 sprintf(_("The file %s should contain a %s setting."), 523 $fileroot . '/config/' . $file, 524 sprintf("%s['%s']['params']['%s']", $variable, $driver, $field))), 525 __FILE__, __LINE__); 526 } 527 } 528 } 529 530 /** 531 * Returns a session-id-ified version of $uri. 532 * If a full URL is requested, all parameter separators get converted to 533 * "&", otherwise to "&". 534 * 535 * @param string $uri The URI to be modified. 536 * @param boolean $full Generate a full (http://server/path/) 537 * URL. 538 * @param integer $append_session 0 = only if needed, 1 = always, -1 = 539 * never. 540 * 541 * @return string The URL with the session id appended (if needed). 542 */ 543 function url($uri, $full = false, $append_session = 0, $force_ssl = false) 544 { 545 if ($force_ssl) { 546 $full = true; 547 } 548 549 if ($full) { 550 global $conf, $registry, $browser; 551 552 /* Store connection parameters in local variables. */ 553 $server_name = $conf['server']['name']; 554 $server_port = $conf['server']['port']; 555 556 $protocol = 'http'; 557 if ($conf['use_ssl'] == 1) { 558 $protocol = 'https'; 559 } elseif ($conf['use_ssl'] == 2 && 560 $browser->usingSSLConnection()) { 561 $protocol = 'https'; 562 } elseif ($conf['use_ssl'] == 3) { 563 $server_port = ''; 564 if ($force_ssl) { 565 $protocol = 'https'; 566 } 567 } 568 569 /* If using non-standard ports, add the port to the URL. */ 570 if (!empty($server_port) && 571 ((($protocol == 'http') && ($server_port != 80)) || 572 (($protocol == 'https') && ($server_port != 443)))) { 573 $server_name .= ':' . $server_port; 574 } 575 576 /* Store the webroot in a local variable. */ 577 $webroot = $registry->get('webroot'); 578 579 $url = $protocol . '://' . $server_name; 580 if (substr($uri, 0, 1) != '/') { 581 if (substr($webroot, -1) == '/') { 582 $url .= $webroot . $uri; 583 } else { 584 $url .= $webroot . '/' . $uri; 585 } 586 } else { 587 $url .= $uri; 588 } 589 } else { 590 $url = $uri; 591 } 592 593 if (empty($GLOBALS['conf']['session']['use_only_cookies']) && 594 (($append_session == 1) || 595 (($append_session == 0) && 596 !isset($_COOKIE[session_name()])))) { 597 $url = Util::addParameter($url, session_name(), session_id()); 598 } 599 600 if ($full) { 601 /* We need to run the replace twice, because we only catch every 602 * second match. */ 603 return preg_replace(array('/(=?.*?)&(.*?=)/', 604 '/(=?.*?)&(.*?=)/'), 605 '$1&$2', $url); 606 } elseif (preg_match('/=.*&.*=/', $url)) { 607 return $url; 608 } else { 609 return htmlentities($url); 610 } 611 } 612 613 /** 614 * Returns a session-id-ified version of $uri, using the current 615 * application's webroot setting. 616 * 617 * @param string $uri The URI to be modified. 618 * @param boolean $full Generate a full (http://server/path/) 619 * URL. 620 * @param integer $append_session 0 = only if needed, 1 = always, -1 = 621 * never. 622 * 623 * @return string The url with the session id appended. 624 */ 625 function applicationUrl($uri, $full = false, $append_session = 0) 626 { 627 if ($full) { 628 return Horde::url($uri, $full, $append_session); 629 } 630 631 if (substr($uri, 0, 1) != '/') { 632 $webroot = $GLOBALS['registry']->get('webroot'); 633 if (substr($webroot, -1) != '/') { 634 $webroot .= '/'; 635 } 636 $uri = $webroot . $uri; 637 } 638 639 return Horde::url($uri, $full, $append_session); 640 } 641 642 /** 643 * Returns an external link passed through the dereferrer to strip session 644 * IDs from the referrer. 645 * 646 * @param string $url The external URL to link to. 647 * @param boolean $tag If true, a complete <a> tag is returned, only the 648 * url otherwise. 649 * 650 * @return string The correct link to the dereferrer script. 651 */ 652 function externalUrl($url, $tag = false) 653 { 654 if (isset($_COOKIE[session_name()])) { 655 $ext = $url; 656 } else { 657 $ext = Horde::url($GLOBALS['registry']->get('webroot', 'horde') . 658 '/services/go.php', true, -1); 659 660 /* We must make sure there are no &'s in the URL. */ 661 $url = preg_replace(array('/(=?.*?)&(.*?=)/', '/(=?.*?)&(.*?=)/'), '$1&$2', $url); 662 $ext = Util::addParameter($ext, 'url', $url); 663 } 664 if ($tag) { 665 $ext = Horde::link($ext, $url, '', '_blank'); 666 } 667 return $ext; 668 } 669 670 /** 671 * Returns a URL to be used for downloading, that takes into account any 672 * special browser quirks (i.e. IE's broken filename handling). 673 * 674 * @param string $filename The filename of the download data. 675 * @param array $params Any additional parameters needed. 676 * @param string $url The URL to alter. If none passed in, will use 677 * the file 'view.php' located in the current 678 * module's base directory. 679 * 680 * @return string The download URL. 681 */ 682 function downloadUrl($filename, $params = array(), $url = null) 683 { 684 global $browser; 685 686 $horde_url = false; 687 688 if (is_null($url)) { 689 global $registry; 690 $url = Util::addParameter(Horde::url($registry->get('webroot', 'horde') . '/services/download/'), 'module', $registry->getApp()); 691 $horde_url = true; 692 } 693 694 /* Add parameters. */ 695 if (!is_null($params)) { 696 $url = Util::addParameter($url, $params); 697 } 698 699 /* If we are using the default Horde download link, add the 700 * filename to the end of the URL. Although not necessary for 701 * many browsers, this should allow every browser to download 702 * correctly. */ 703 if ($horde_url) { 704 $url = Util::addParameter($url, 'fn', '/' . rawurlencode($filename)); 705 } elseif ($browser->hasQuirk('break_disposition_filename')) { 706 /* Some browsers will only obtain the filename correctly 707 * if the extension is the last argument in the query 708 * string and rest of the filename appears in the 709 * PATH_INFO element. */ 710 $filename = rawurlencode($filename); 711 712 /* Get the webserver ID. */ 713 $server = Horde::webServerID(); 714 715 /* Get the name and extension of the file. Apache 2 does 716 * NOT support PATH_INFO information being passed to the 717 * PHP module by default, so disable that 718 * functionality. */ 719 if (($server != 'apache2')) { 720 if (($pos = strrpos($filename, '.'))) { 721 $name = '/' . preg_replace('/\./', '%2E', substr($filename, 0, $pos)); 722 $ext = substr($filename, $pos); 723 } else { 724 $name = '/' . $filename; 725 $ext = ''; 726 } 727 728 /* Enter the PATH_INFO information. */ 729 if (($pos = strpos($url, '?'))) { 730 $url = substr($url, 0, $pos) . $name . substr($url, $pos); 731 } else { 732 $url .= $name; 733 } 734 } 735 736 /* Append the extension, if it exists. */ 737 if (($server == 'apache2') || !empty($ext)) { 738 $url = Util::addParameter($url, 'fn_ext', '/' . $filename); 739 } 740 } 741 742 return $url; 743 } 744 745 /** 746 * Returns an anchor tag with the relevant parameters 747 * 748 * @param string $url The full URL to be linked to. 749 * @param string $title The link title/description. 750 * @param string $class The CSS class of the link. 751 * @param string $target The window target to point to. 752 * @param string $onclick JavaScript action for the 'onclick' event. 753 * @param string $title2 The link title (tooltip) (deprecated - just 754 * use $title). 755 * @param string $accesskey The access key to use. 756 * @param array $attributes Any other name/value pairs to add to the <a> 757 * tag. 758 * @param boolean $escape Whether to escape special characters in the 759 * title attribute. 760 * 761 * @return string The full <a href> tag. 762 */ 763 function link($url, $title = '', $class = '', $target = '', $onclick = '', 764 $title2 = '', $accesskey = '', $attributes = array(), 765 $escape = true) 766 { 767 static $charset; 768 if (!isset($charset)) { 769 $charset = NLS::getCharset(); 770 } 771 772 if (!empty($title2)) { 773 $title = $title2; 774 } 775 776 $ret = "<a href=\"$url\""; 777 if (!empty($onclick)) { 778 $ret .= " onclick=\"$onclick\""; 779 } 780 if (!empty($class)) { 781 $ret .= " class=\"$class\""; 782 } 783 if (!empty($target)) { 784 $ret .= " target=\"$target\""; 785 } 786 if (!empty($title)) { 787 if ($escape) { 788 $title = nl2br(@htmlspecialchars(@htmlspecialchars($title, ENT_QUOTES, $charset), ENT_QUOTES, $charset)); 789 } 790 $ret .= ' title="' . $title . '"'; 791 } 792 if (!empty($accesskey)) { 793 $ret .= ' accesskey="' . htmlspecialchars($accesskey) . '"'; 794 } 795 796 foreach ($attributes as $name => $value) { 797 $ret .= ' ' . htmlspecialchars($name) . '="' . htmlspecialchars($value) . '"'; 798 } 799 800 return "$ret>"; 801 } 802 803 /** 804 * Uses DOM Tooltips to display the 'title' attribute for 805 * Horde::link() calls. 806 * 807 * @param string $url The full URL to be linked to 808 * @param string $status The JavaScript mouse-over string 809 * @param string $class The CSS class of the link 810 * @param string $target The window target to point to. 811 * @param string $onclick JavaScript action for the 'onclick' event. 812 * @param string $title The link title (tooltip). 813 * @param string $accesskey The access key to use. 814 * @param array $attributes Any other name/value pairs to add to the <a> 815 * tag. 816 * 817 * @return string The full <a href> tag. 818 */ 819 function linkTooltip($url, $status = '', $class = '', $target = '', 820 $onclick = '', $title = '', $accesskey = '', 821 $attributes = array()) 822 { 823 static $charset; 824 if (!isset($charset)) { 825 $charset = NLS::getCharset(); 826 } 827 828 if (!empty($title)) { 829 $title = '<pre>' . preg_replace(array('/\n/', '/((?<!<br)\s{1,}(?<!\/>))/em', '/<br \/><br \/>/', '/<br \/>/'), array('', 'str_repeat(" ", strlen("$1"))', '<br /> <br />', '<br />'), nl2br(@htmlspecialchars(@htmlspecialchars($title, ENT_QUOTES, $charset), ENT_QUOTES, $charset))) . '</pre>'; 830 } 831 return Horde::link($url, $title, $class, $target, $onclick, null, $accesskey, $attributes, false); 832 } 833 834 /** 835 * Returns an anchor sequence with the relevant parameters for a widget 836 * with accesskey and text. 837 * 838 * @access public 839 * 840 * @param string $url The full URL to be linked to. 841 * @param string $title The link title/description. 842 * @param string $class The CSS class of the link 843 * @param string $target The window target to point to. 844 * @param string $onclick JavaScript action for the 'onclick' event. 845 * @param string $title2 The link title (tooltip) (deprecated - just use 846 * $title). 847 * @param boolean $nocheck Don't check if the access key already has been 848 * used. Defaults to false (= check). 849 * 850 * @return string The full <a href>Title</a> sequence. 851 */ 852 function widget($url, $title = '', $class = 'widget', $target = '', 853 $onclick = '', $title2 = '', $nocheck = false) 854 { 855 if (!empty($title2)) { 856 $title = $title2; 857 } 858 859 $ak = Horde::getAccessKey($title, $nocheck); 860 861 return Horde::link($url, '', $class, $target, $onclick, '', $ak) . Horde::highlightAccessKey($title, $ak) . '</a>'; 862 } 863 864 /** 865 * Returns a session-id-ified version of $SCRIPT_NAME resp. $PHP_SELF. 866 * 867 * @param boolean $script_params Include script parameters like QUERY_STRING and PATH_INFO? 868 * @param boolean $nocache Include a nocache parameter in the URL? 869 * @param boolean $full Return a full URL? 870 * 871 * @return string The requested URI. 872 */ 873 function selfUrl($script_params = false, $nocache = true, $full = false, 874 $force_ssl = false) 875 { 876 if (substr(php_sapi_name(), 0, 3) == 'cgi') { 877 // When using CGI PHP, SCRIPT_NAME may contain the path to 878 // the PHP binary instead of the script being run; use 879 // PHP_SELF instead. 880 $url = $_SERVER['PHP_SELF']; 881 } else { 882 $url = isset($_SERVER['SCRIPT_NAME']) ? 883 $_SERVER['SCRIPT_NAME'] : 884 $_SERVER['PHP_SELF']; 885 } 886 887 if ($script_params) { 888 if (!empty($_SERVER['PATH_INFO'])) { 889 $url .= $_SERVER['PATH_INFO']; 890 } 891 if (!empty($_SERVER['QUERY_STRING'])) { 892 $url .= '?' . $_SERVER['QUERY_STRING']; 893 } 894 } 895 896 $url = Horde::url($url, $full, 0, $force_ssl); 897 898 if ($nocache) { 899 return Util::nocacheUrl($url); 900 } else { 901 return $url; 902 } 903 } 904 905 /** 906 * Constructs a correctly-pathed link to an image. 907 * 908 * @param string $src The image file. 909 * @param string $alt Text describing the image. 910 * @param mixed $attr Any additional attributes for the image tag. Can be 911 * a pre-built string or an array of key/value pairs 912 * that will be assembled and html-encoded. 913 * @param string $dir The root graphics directory. 914 * 915 * @return string The full image tag. 916 */ 917 function img($src, $alt = '', $attr = '', $dir = null) 918 { 919 static $charset; 920 if (!isset($charset)) { 921 $charset = NLS::getCharset(); 922 } 923 924 /* If browser does not support images, simply return the ALT text. */ 925 if (!$GLOBALS['browser']->hasFeature('images')) { 926 return @htmlspecialchars($alt, ENT_COMPAT, $charset); 927 } 928 929 /* If no directory has been specified, get it from the registry. */ 930 if ($dir === null) { 931 global $registry; 932 $dir = $registry->getImageDir(); 933 } 934 935 /* If a directory has been provided, prepend it to the image source. */ 936 if (!empty($dir)) { 937 $src = $dir . '/' . $src; 938 } 939 940 /* Build all of the tag attributes. */ 941 $attributes = array('src' => $src, 942 'alt' => $alt); 943 if (is_array($attr)) { 944 $attributes = array_merge($attributes, $attr); 945 } 946 if (empty($attributes['title'])) { 947 $attributes['title'] = ''; 948 } 949 950 $img = '<img'; 951 foreach ($attributes as $attribute => $value) { 952 $img .= ' ' . $attribute . '="' . ($attribute == 'src' ? $value : @htmlspecialchars($value, ENT_COMPAT, $charset)) . '"'; 953 } 954 955 /* If the user supplied a pre-built string of attributes, add that. */ 956 if (is_string($attr) && !empty($attr)) { 957 $img .= ' ' . $attr; 958 } 959 960 /* Return the closed image tag. */ 961 return $img . ' />'; 962 } 963 964 /** 965 * Determines the location of the system temporary directory. If a specific 966 * setting cannot be found, it defaults to /tmp. 967 * 968 * @return string A directory name that can be used for temp files. 969 * Returns false if one could not be found. 970 */ 971 function getTempDir() 972 { 973 global $conf; 974 975 /* If one has been specifically set, then use that */ 976 if (!empty($conf['tmpdir'])) { 977 $tmp = $conf['tmpdir']; 978 } 979 980 /* Next, try Util::getTempDir(). */ 981 if (empty($tmp)) { 982 $tmp = Util::getTempDir(); 983 } 984 985 /* If it is still empty, we have failed, so return false; 986 * otherwise return the directory determined. */ 987 return empty($tmp) ? false : $tmp; 988 } 989 990 /** 991 * Creates a temporary filename for the lifetime of the script, and 992 * (optionally) registers it to be deleted at request shutdown. 993 * 994 * @param string $prefix Prefix to make the temporary name more 995 * recognizable. 996 * @param boolean $delete Delete the file at the end of the request? 997 * @param string $dir Directory to create the temporary file in. 998 * @param boolean $secure If deleting file, should we securely delete the 999 * file? 1000 * 1001 * @return string Returns the full path-name to the temporary file or 1002 * false if a temporary file could not be created. 1003 */ 1004 function getTempFile($prefix = 'Horde', $delete = true, $dir = '', 1005 $secure = false) 1006 { 1007 if (empty($dir) || !is_dir($dir)) { 1008 $dir = Horde::getTempDir(); 1009 } 1010 1011 return Util::getTempFile($prefix, $delete, $dir, $secure); 1012 } 1013 1014 /** 1015 * Starts output compression, if requested. 1016 */ 1017 function compressOutput() 1018 { 1019 static $started; 1020 1021 if (isset($started)) { 1022 return; 1023 } 1024 1025 /* Compress output if requested and possible. */ 1026 if ($GLOBALS['conf']['compress_pages'] && 1027 !$GLOBALS['browser']->hasQuirk('buggy_compression') && 1028 !(bool)ini_get('zlib.output_compression') && 1029 !(bool)ini_get('zend_accelerator.compress_all') && 1030 ini_get('output_handler') != 'ob_gzhandler') { 1031 if (ob_get_level()) { 1032 ob_end_clean(); 1033 } 1034 ob_start('ob_gzhandler'); 1035 } 1036 1037 $started = true; 1038 } 1039 1040 /** 1041 * Determines if output compression can be used. 1042 * 1043 * @return boolean True if output compression can be used, false if not. 1044 */ 1045 function allowOutputCompression() 1046 { 1047 require_once 'Horde/Browser.php'; 1048 $browser = &Browser::singleton(); 1049 1050 /* Turn off compression for buggy browsers. */ 1051 if ($browser->hasQuirk('buggy_compression')) { 1052 return false; 1053 } 1054 1055 return (ini_get('zlib.output_compression') == '' && 1056 ini_get('zend_accelerator.compress_all') == '' && 1057 ini_get('output_handler') != 'ob_gzhandler'); 1058 } 1059 1060 /** 1061 * Returns the Web server being used. 1062 * PHP string list built from the PHP 'configure' script. 1063 * 1064 * @return string A web server identification string. 1065 * <pre> 1066 * 'aolserver' = AOL Server 1067 * 'apache1' = Apache 1.x 1068 * 'apache2' = Apache 2.x 1069 * 'caudium' = Caudium 1070 * 'cgi' = Unknown server - PHP built as CGI program 1071 * 'cli' = Command Line Interface build 1072 * 'embed' = Embedded PHP 1073 * 'isapi' = Zeus ISAPI 1074 * 'milter' = Milter 1075 * 'nsapi' = NSAPI 1076 * 'phttpd' = PHTTPD 1077 * 'pi3web' = Pi3Web 1078 * 'roxen' = Roxen/Pike 1079 * 'servlet' = Servlet 1080 * 'thttpd' = thttpd 1081 * 'tux' = Tux 1082 * 'webjames' = Webjames 1083 * </pre> 1084 */ 1085 function webServerID() 1086 { 1087 $server = php_sapi_name(); 1088 1089 if ($server == 'apache') { 1090 return 'apache1'; 1091 } elseif (($server == 'apache2filter') || 1092 ($server == 'apache2handler')) { 1093 return 'apache2'; 1094 } else { 1095 return $server; 1096 } 1097 } 1098 1099 /** 1100 * Returns the <link> tags for the CSS stylesheets. 1101 * 1102 * @param string|array $app The Horde application(s). 1103 * @param mixed $theme The theme to use; specify an empty value to 1104 * retrieve the theme from user preferences, and 1105 * false for no theme. 1106 * @param boolean $inherit Inherit Horde-wide CSS? 1107 * 1108 * @return string <link> tags for CSS stylesheets. 1109 */ 1110 function stylesheetLink($apps = null, $theme = '', $inherit = true) 1111 { 1112 if ($theme === '' && isset($GLOBALS['prefs'])) { 1113 $theme = $GLOBALS['prefs']->getValue('theme'); 1114 } 1115 1116 $rtl = isset($GLOBALS['nls']['rtl'][$GLOBALS['language']]); 1117 $css = array(); 1118 1119 $themes_fs = $GLOBALS['registry']->get('themesfs', 'horde'); 1120 if ($inherit) { 1121 $themes_uri = Horde::url($GLOBALS['registry']->get('themesuri', 'horde'), false, -1); 1122 $css[] = $themes_uri . '/screen.css'; 1123 if (!empty($theme) && 1124 file_exists($themes_fs . '/' . $theme . '/screen.css')) { 1125 $css[] = $themes_uri . '/' . $theme . '/screen.css'; 1126 } 1127 1128 if ($rtl) { 1129 $css[] = $themes_uri . '/rtl.css'; 1130 if (!empty($theme) && 1131 file_exists($themes_fs . '/' . $theme . '/rtl.css')) { 1132 $css[] = $themes_uri . '/' . $theme . '/rtl.css'; 1133 } 1134 } 1135 } 1136 1137 if (!empty($apps)) { 1138 if (!is_array($apps)) { 1139 $apps = array($apps); 1140 } 1141 1142 foreach ($apps as $app) { 1143 if ($inherit && $app == 'horde') { 1144 continue; 1145 } 1146 1147 $themes_fs = $GLOBALS['registry']->get('themesfs', $app); 1148 $themes_uri = Horde::url($GLOBALS['registry']->get('themesuri', $app), false, -1); 1149 if (file_exists($themes_fs . '/screen.css')) { 1150 $css[] = $themes_uri . '/screen.css'; 1151 } 1152 if (!empty($theme) && 1153 file_exists($themes_fs . '/' . $theme . '/screen.css')) { 1154 $css[] = $themes_uri . '/' . $theme . '/screen.css'; 1155 } 1156 1157 if ($rtl) { 1158 if (file_exists($themes_fs . '/rtl.css')) { 1159 $css[] = $themes_uri . '/rtl.css'; 1160 } 1161 if (!empty($theme) && 1162 file_exists($themes_fs . '/' . $theme . '/rtl.css')) { 1163 $css[] = $themes_uri . '/' . $theme . '/rtl.css'; 1164 } 1165 } 1166 } 1167 } 1168 1169 $html = ''; 1170 foreach ($css as $css_link) { 1171 $html .= '<link href="' . $css_link . '" rel="stylesheet" type="text/css" />' . "\n"; 1172 } 1173 1174 /* Load IE PNG transparency code if needed. */ 1175 if ($GLOBALS['browser']->hasQuirk('png_transparency') && 1176 $GLOBALS['prefs']->getValue('alpha_filter')) { 1177 $url = Horde::url($GLOBALS['registry']->get('jsuri', 'horde') . '/alphaImageLoader.php', true, -1); 1178 $html .= '<style type="text/css"> img { behavior: url("' . $url . '"); } </style>'; 1179 } 1180 1181 /* Load browser specific stylesheets if needed. */ 1182 if ($GLOBALS['browser']->isBrowser('msie') && $GLOBALS['browser']->getMajor() < 7) { 1183 $html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/ie6_or_less.css" rel="stylesheet" type="text/css" />' . "\n"; 1184 if ($GLOBALS['browser']->getPlatform() == 'mac') { 1185 $html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/ie5mac.css" rel="stylesheet" type="text/css" />' . "\n"; 1186 } 1187 } 1188 if ($GLOBALS['browser']->isBrowser('opera')) { 1189 $html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/opera.css" rel="stylesheet" type="text/css" />' . "\n"; 1190 } 1191 if ($GLOBALS['browser']->isBrowser('mozilla') && 1192 $GLOBALS['browser']->getMajor() >= 5 && 1193 preg_match('/rv:(.*)\)/', $GLOBALS['browser']->getAgentString(), $revision) && 1194 $revision[1] <= 1.4) { 1195 $html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/moz14.css" rel="stylesheet" type="text/css" />' . "\n"; 1196 } 1197 if (strpos(strtolower($GLOBALS['browser']->getAgentString()), 'safari') !== false) { 1198 $html .= '<link href="' . $GLOBALS['registry']->get('themesuri', 'horde') . '/safari.css" rel="stylesheet" type="text/css" />' . "\n"; 1199 } 1200 1201 return $html; 1202 } 1203 1204 /** 1205 * Sets a custom session handler up, if there is one. 1206 */ 1207 function setupSessionHandler() 1208 { 1209 global $conf; 1210 1211 ini_set('url_rewriter.tags', 0); 1212 if (!empty($conf['session']['use_only_cookies'])) { 1213 ini_set('session.use_only_cookies', 1); 1214 if (!empty($conf['cookie']['domain']) && 1215 strpos($conf['server']['name'], '.') === false) { 1216 Horde::logMessage('Session cookies will not work without a FQDN and with a non-empty cookie domain.', __FILE__, __LINE__, PEAR_LOG_WARNING); 1217 } 1218 } 1219 session_set_cookie_params($conf['session']['timeout'], 1220 $conf['cookie']['path'], $conf['cookie']['domain'], $conf['use_ssl'] == 1 ? 1 : 0); 1221 session_cache_limiter($conf['session']['cache_limiter']); 1222 session_name(urlencode($conf['session']['name'])); 1223 1224 $type = !empty($conf['sessionhandler']['type']) ? $conf['sessionhandler']['type'] : 'none'; 1225 1226 if ($type == 'external') { 1227 $calls = $conf['sessionhandler']['params']; 1228 session_set_save_handler($calls['open'], 1229 $calls['close'], 1230 $calls['read'], 1231 $calls['write'], 1232 $calls['destroy'], 1233 $calls['gc']); 1234 } elseif ($type != 'none') { 1235 global $_session_handler; 1236 require_once 'Horde/SessionHandler.php'; 1237 $_session_handler = &SessionHandler::singleton($conf['sessionhandler']['type']); 1238 if (!empty($_session_handler) && 1239 !is_a($_session_handler, 'PEAR_Error')) { 1240 ini_set('session.save_handler', 'user'); 1241 session_set_save_handler(array(&$_session_handler, 'open'), 1242 array(&$_session_handler, 'close'), 1243 array(&$_session_handler, 'read'), 1244 array(&$_session_handler, 'write'), 1245 array(&$_session_handler, 'destroy'), 1246 array(&$_session_handler, 'gc')); 1247 } else { 1248 Horde::fatal(PEAR::raiseError('Horde is unable to correctly start the custom session handler.'), __FILE__, __LINE__, false); 1249 } 1250 } 1251 } 1252 1253 /** 1254 * Returns an un-used access key from the label given. 1255 * 1256 * @param string $label The label to choose an access key from. 1257 * @param boolean $nocheck Don't check if the access key already has been 1258 * used? 1259 * 1260 * @return string A single lower case character access key or empty 1261 * string if none can be found 1262 */ 1263 function getAccessKey($label, $nocheck = false, $shutdown = false) 1264 { 1265 /* The access keys already used in this page */ 1266 static $_used = array(); 1267 1268 /* The labels already used in this page */ 1269 static $_labels = array(); 1270 1271 /* Shutdown call for translators? */ 1272 if ($shutdown) { 1273 if (!count($_labels)) { 1274 return; 1275 } 1276 $script = basename($_SERVER['PHP_SELF']); 1277 $labels = array_keys($_labels); 1278 sort($labels); 1279 $used = array_keys($_used); 1280 sort($used); 1281 $remaining = str_replace($used, array(), 'abcdefghijklmnopqrstuvwxyz'); 1282 Horde::logMessage('Access key information for ' . $script, __FILE__, __LINE__); 1283 Horde::logMessage('Used labels: ' . implode(',', $labels), __FILE__, __LINE__); 1284 Horde::logMessage('Used keys: ' . implode('', $used), __FILE__, __LINE__); 1285 Horde::logMessage('Free keys: ' . $remaining, __FILE__, __LINE__); 1286 return; 1287 } 1288 1289 /* Use access keys at all? */ 1290 static $notsupported; 1291 if (!isset($notsupported)) { 1292 $notsupported = !$GLOBALS['browser']->hasFeature('accesskey') || 1293 !$GLOBALS['prefs']->getValue('widget_accesskey'); 1294 } 1295 1296 if ($notsupported || !preg_match('/_([A-Za-z])/', $label, $match)) { 1297 return ''; 1298 } 1299 $key = $match[1]; 1300 1301 /* Has this key already been used? */ 1302 if (isset($_used[strtolower($key)]) && 1303 !($nocheck && isset($_labels[$label]))) { 1304 return ''; 1305 } 1306 1307 /* Save key and label. */ 1308 $_used[strtolower($key)] = true; 1309 $_labels[$label] = true; 1310 1311 return $key; 1312 } 1313 1314 /** 1315 * Strips an access key from a label. 1316 * For multibyte charset strings the access key gets removed completely, 1317 * otherwise only the underscore gets removed. 1318 * 1319 * @param string $label The label containing an access key. 1320 * 1321 * @return string The label with the access key being stripped. 1322 */ 1323 function stripAccessKey($label) 1324 { 1325 include_once HORDE_BASE . '/config/nls.php'; 1326 $multibyte = isset($GLOBALS['nls']['multibyte'][NLS::getCharset(true)]); 1327 1328 return preg_replace('/_([A-Za-z])/', 1329 $multibyte && preg_match('/[\x80-\xff]/', $label) ? '' : '\1', 1330 $label); 1331 } 1332 1333 /** 1334 * Highlights an access key in a label. 1335 * 1336 * @param string $label The label to to highlight the access key in. 1337 * @param string $accessKey The access key to highlight. 1338 * 1339 * @return string The HTML version of the label with the access key 1340 * highlighted. 1341 */ 1342 function highlightAccessKey($label, $accessKey) 1343 { 1344 $stripped_label = Horde::stripAccesskey($label); 1345 1346 if (empty($accessKey)) { 1347 return $stripped_label; 1348 } 1349 1350 if (isset($GLOBALS['nls']['multibyte'][NLS::getCharset(true)])) { 1351 return $stripped_label . '(' . '<span class="accessKey">' . 1352 strtoupper($accessKey) . '</span>' . ')'; 1353 } else { 1354 return str_replace('_' . $accessKey, '<span class="accessKey">' . $accessKey . '</span>', $label); 1355 } 1356 } 1357 1358 /** 1359 * Returns the appropriate "accesskey" and "title" attributes for an HTML 1360 * tag and the given label. 1361 * 1362 * @param string $label The title of an HTML element 1363 * @param boolean $nocheck Don't check if the access key already has been 1364 * used? 1365 * 1366 * @return string The title, and if appropriate, the accesskey attributes 1367 * for the element. 1368 */ 1369 function getAccessKeyAndTitle($label, $nocheck = false) 1370 { 1371 $ak = Horde::getAccessKey($label, $nocheck); 1372 $attributes = 'title="' . Horde::stripAccessKey($label); 1373 if (!empty($ak)) { 1374 $attributes .= sprintf(_(" (Accesskey %s)"), $ak); 1375 $attributes .= '" accesskey="' . $ak; 1376 } 1377 $attributes .= '"'; 1378 return $attributes; 1379 } 1380 1381 /** 1382 * Returns a label element including an access key for usage in conjuction 1383 * with a form field. User preferences regarding access keys are respected. 1384 * 1385 * @param string $for The form field's id attribute. 1386 * @param string $label The label text. 1387 * @param string $ak The access key to use. If null a new access key 1388 * will be generated. 1389 * 1390 * @return string The html code for the label element. 1391 */ 1392 function label($for, $label, $ak = null) 1393 { 1394 global $prefs; 1395 1396 if (is_null($ak)) { 1397 $ak = Horde::getAccesskey($label, 1); 1398 } 1399 $label = Horde::highlightAccessKey($label, $ak); 1400 1401 return sprintf('<label for="%s"%s>%s</label>', 1402 $for, 1403 !empty($ak) ? ' accesskey="' . $ak . '"' : '', 1404 $label); 1405 } 1406 1407 /** 1408 * Redirects to the main Horde login page on authentication failure. 1409 */ 1410 function authenticationFailureRedirect() 1411 { 1412 require_once 'Horde/CLI.php'; 1413 if (Horde_CLI::runningFromCLI()) { 1414 $cli = &Horde_CLI::singleton(); 1415 $cli->fatal(_("You are not authenticated.")); 1416 } 1417 1418 $url = $GLOBALS['registry']->get('webroot', 'horde') . '/login.php'; 1419 $url = Util::addParameter($url, array('url' => Horde::selfUrl(true), 'nosidebar' => 1), null, false); 1420 $url = Auth::addLogoutParameters($url); 1421 header('Location: ' . Horde::url($url, true)); 1422 exit; 1423 } 1424 1425 /** 1426 * Provides a standardised function to call a Horde hook, checking whether 1427 * a hook config file exists and whether the function itself exists. If 1428 * these two conditions are not satisfied it will return the specified 1429 * value (by default a PEAR error). 1430 * 1431 * @param string $hook The function to call. 1432 * @param array $args An array of any arguments to pass to the hook 1433 * function. 1434 * @param string $app If specified look for hooks in the config directory 1435 * of this app. 1436 * @param mixed $error What to return if $app/config/hooks.php or $hook 1437 * does not exist. If this is the string 'PEAR_Error' 1438 * a PEAR error object is returned instead, detailing 1439 * the failure. 1440 * 1441 * @return mixed Either the results of the hook or PEAR error on failure. 1442 */ 1443 function callHook($hook, $args = array(), $app = 'horde', $error = 'PEAR_Error') 1444 { 1445 global $registry; 1446 static $hooks_loaded; 1447 1448 if (!isset($hooks_loaded)) { 1449 if (file_exists($registry->get('fileroot', $app) . '/config/hooks.php')) { 1450 require_once $registry->get('fileroot', $app) . '/config/hooks.php'; 1451 $hooks_loaded = true; 1452 } else { 1453 $hooks_loaded = false; 1454 } 1455 } 1456 if ($hooks_loaded && function_exists($hook)) { 1457 return call_user_func_array($hook, $args); 1458 } 1459 1460 if (is_string($error) && strcmp($error, 'PEAR_Error') == 0) { 1461 $error = PEAR::raiseError(sprintf('Hook %s in application %s not called.', $hook, $app)); 1462 Horde::logMessage($error, __FILE__, __LINE__, PEAR_LOG_DEBUG); 1463 } 1464 1465 return $error; 1466 } 1467 1468 /** 1469 * Returns the specified permission for the current user. 1470 * 1471 * @since Horde 3.1 1472 * 1473 * @param string $permission A permission, currently only 'max_blocks'. 1474 * 1475 * @return mixed The value of the specified permission. 1476 */ 1477 function hasPermission($permission) 1478 { 1479 global $perms; 1480 1481 if (!$perms->exists('horde:' . $permission)) { 1482 return true; 1483 } 1484 1485 $allowed = $perms->getPermissions('horde:' . $permission); 1486 if (is_array($allowed)) { 1487 switch ($permission) { 1488 case 'max_blocks': 1489 $allowed = array_reduce($allowed, create_function('$a, $b', 'return max($a, $b);'), 0); 1490 break; 1491 } 1492 } 1493 1494 return $allowed; 1495 } 1496 1497 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |