[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 3 require_once 'Horde/String.php'; 4 5 /** 6 * The Browser:: class provides capability information for the current 7 * web client. Browser identification is performed by examining the 8 * HTTP_USER_AGENT environmental variable provide by the web server. 9 * 10 * $Horde: framework/Browser/Browser.php,v 1.166 2005/02/22 20:43:58 eraserhd Exp $ 11 * 12 * Copyright 1999-2005 Chuck Hagenbuch <chuck@horde.org> 13 * Copyright 1999-2005 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_Browser 22 */ 23 class Browser { 24 25 /** 26 * Major version number. 27 * 28 * @var integer $_majorVersion 29 */ 30 var $_majorVersion = 0; 31 32 /** 33 * Minor version number. 34 * 35 * @var integer $_minorVersion 36 */ 37 var $_minorVersion = 0; 38 39 /** 40 * Browser name. 41 * 42 * @var string $_browser 43 */ 44 var $_browser = ''; 45 46 /** 47 * Full user agent string. 48 * 49 * @var string $_agent 50 */ 51 var $_agent = ''; 52 53 /** 54 * Lower-case user agent string. 55 * 56 * @var string $_agent 57 */ 58 var $_lowerAgent = ''; 59 60 /** 61 * HTTP_ACCEPT string 62 * 63 * @var string $_accept 64 */ 65 var $_accept = ''; 66 67 /** 68 * Platform the browser is running on. 69 * 70 * @var string $_platform 71 */ 72 var $_platform = ''; 73 74 /** 75 * Known robots. 76 * 77 * @var array $_robots 78 */ 79 var $_robots = array( 80 /* The most common ones. */ 81 'Googlebot', 82 'msnbot', 83 'Slurp', 84 'Yahoo', 85 /* The rest alphabetically. */ 86 'Arachnoidea', 87 'ArchitextSpider', 88 'Ask Jeeves', 89 'B-l-i-t-z-Bot', 90 'ConveraCrawler', 91 'ExtractorPro', 92 'FAST-WebCrawler', 93 'FDSE robot', 94 'fido', 95 'geckobot', 96 'Gigabot', 97 'Girafabot', 98 'grub-client', 99 'Gulliver', 100 'ia_archiver', 101 'InfoSeek', 102 'KIT-Fireball', 103 'LEIA', 104 'Lycos_Spider', 105 'Mediapartners-Google', 106 'MuscatFerret', 107 'NaverBot', 108 'polybot', 109 'Pompos', 110 'Scooter', 111 'Teoma', 112 'TurnitinBot', 113 'Ultraseek', 114 'ViolaBot', 115 'webbandit', 116 'www.almaden.ibm.com/cs/crawler', 117 'ZyBorg', 118 ); 119 120 /** 121 * Is this a mobile browser? 122 * 123 * @var boolean $_mobile 124 */ 125 var $_mobile = false; 126 127 /** 128 * Features. 129 * 130 * @var array $_features 131 */ 132 var $_features = array( 133 'html' => true, 134 'hdml' => false, 135 'wml' => false, 136 'images' => true, 137 'iframes' => false, 138 'frames' => true, 139 'tables' => true, 140 'java' => true, 141 'javascript' => true, 142 'dom' => false, 143 'utf' => false, 144 'rte' => false, 145 'homepage' => false, 146 'accesskey' => false, 147 'optgroup' => false, 148 'xmlhttpreq' => false, 149 'cite' => false, 150 ); 151 152 /** 153 * Quirks 154 * 155 * @var array $_quirks 156 */ 157 var $_quirks = array( 158 'avoid_popup_windows' => false, 159 'break_disposition_header' => false, 160 'break_disposition_filename' => false, 161 'broken_multipart_form' => false, 162 'buggy_compression' => false, 163 'cache_same_url' => false, 164 'cache_ssl_downloads' => false, 165 'double_linebreak_textarea' => false, 166 'empty_file_input_value' => false, 167 'must_cache_forms' => false, 168 'no_filename_spaces' => false, 169 'no_hidden_overflow_tables' => false, 170 'ow_gui_1.3' => false, 171 'png_transparency' => false, 172 'scrollbar_in_way' => false, 173 'scroll_tds' => false, 174 ); 175 176 /** 177 * List of viewable image MIME subtypes. 178 * This list of viewable images works for IE and Netscape/Mozilla. 179 * 180 * @var array $_images 181 */ 182 var $_images = array('jpeg', 'gif', 'png', 'pjpeg', 'x-png', 'bmp'); 183 184 /** 185 186 /** 187 * Returns a reference to the global Browser object, only creating it 188 * if it doesn't already exist. 189 * 190 * This method must be invoked as: 191 * $browser = &Browser::singleton([$userAgent[, $accept]]); 192 * 193 * @access public 194 * 195 * @param optional string $userAgent The browser string to parse. 196 * @param optional string $accept The HTTP_ACCEPT settings to use. 197 * 198 * @return object Browser The Browser object. 199 */ 200 function &singleton($userAgent = null, $accept = null) 201 { 202 static $instances; 203 204 if (!isset($instances)) { 205 $instances = array(); 206 } 207 208 $signature = serialize(array($userAgent, $accept)); 209 if (empty($instances[$signature])) { 210 $instances[$signature] = new Browser($userAgent, $accept); 211 } 212 213 return $instances[$signature]; 214 } 215 216 /** 217 * Create a browser instance (Constructor). 218 * 219 * @access public 220 * 221 * @param optional string $userAgent The browser string to parse. 222 * @param optional string $accept The HTTP_ACCEPT settings to use. 223 */ 224 function Browser($userAgent = null, $accept = null) 225 { 226 $this->match($userAgent, $accept); 227 } 228 229 /** 230 * Parses the user agent string and inititializes the object with 231 * all the known features and quirks for the given browser. 232 * 233 * @access public 234 * 235 * @param optional string $userAgent The browser string to parse. 236 * @param optional string $accept The HTTP_ACCEPT settings to use. 237 */ 238 function match($userAgent = null, $accept = null) 239 { 240 // Set our agent string. 241 if (is_null($userAgent)) { 242 if (isset($_SERVER['HTTP_USER_AGENT'])) { 243 $this->_agent = trim($_SERVER['HTTP_USER_AGENT']); 244 } 245 } else { 246 $this->_agent = $userAgent; 247 } 248 $this->_lowerAgent = String::lower($this->_agent); 249 250 // Set our accept string. 251 if (is_null($accept)) { 252 if (isset($_SERVER['HTTP_ACCEPT'])) { 253 $this->_accept = String::lower(trim($_SERVER['HTTP_ACCEPT'])); 254 } 255 } else { 256 $this->_accept = String::lower($accept); 257 } 258 259 // Check for UTF support. 260 if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) { 261 $this->setFeature('utf', strpos(String::lower($_SERVER['HTTP_ACCEPT_CHARSET']), 'utf') !== false); 262 } 263 264 if (!empty($this->_agent)) { 265 $this->_setPlatform(); 266 267 if (preg_match('|Opera[/ ]([0-9.]+)|', $this->_agent, $version)) { 268 $this->setBrowser('opera'); 269 list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); 270 $this->setFeature('javascript', true); 271 $this->setQuirk('no_filename_spaces'); 272 273 switch ($this->_majorVersion) { 274 case 7: 275 $this->setFeature('dom'); 276 $this->setFeature('iframes'); 277 $this->setFeature('accesskey'); 278 $this->setFeature('optgroup'); 279 $this->setQuirk('double_linebreak_textarea'); 280 break; 281 } 282 } elseif (strpos($this->_lowerAgent, 'elaine/') !== false || 283 strpos($this->_lowerAgent, 'palmsource') !== false || 284 strpos($this->_lowerAgent, 'digital paths') !== false) { 285 $this->setBrowser('palm'); 286 $this->setFeature('images', false); 287 $this->setFeature('frames', false); 288 $this->setFeature('javascript', false); 289 $this->setQuirk('avoid_popup_windows'); 290 $this->_mobile = true; 291 } elseif ((preg_match('|MSIE ([0-9.]+)|', $this->_agent, $version)) || 292 (preg_match('|Internet Explorer/([0-9.]+)|', $this->_agent, $version))) { 293 294 $this->setBrowser('msie'); 295 $this->setQuirk('cache_ssl_downloads'); 296 $this->setQuirk('cache_same_url'); 297 $this->setQuirk('break_disposition_filename'); 298 299 if (strpos($version[1], '.') !== false) { 300 list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); 301 } else { 302 $this->_majorVersion = $version[1]; 303 $this->_minorVersion = 0; 304 } 305 306 /* IE on Windows does not support alpha transparency in PNG 307 * images. */ 308 if (preg_match('/windows/i', $this->_agent)) { 309 $this->setQuirk('png_transparency'); 310 } 311 312 /* IE 6 (pre-SP1) and 5.5 (pre-SP1) has buggy compression. 313 * The versions affected are as follows: 314 * 6.00.2462.0000 Internet Explorer 6 Public Preview (Beta) 315 * 6.00.2479.0006 Internet Explorer 6 Public Preview (Beta) 316 Refresh 317 * 6.00.2600.0000 Internet Explorer 6 (Windows XP) 318 * 5.50.3825.1300 Internet Explorer 5.5 Developer Preview (Beta) 319 * 5.50.4030.2400 Internet Explorer 5.5 & Internet Tools Beta 320 * 5.50.4134.0100 Internet Explorer 5.5 for Windows Me (4.90.3000) 321 * 5.50.4134.0600 Internet Explorer 5.5 322 * 5.50.4308.2900 Internet Explorer 5.5 Advanced Security Privacy Beta 323 * 324 * See: 325 * ==== 326 * http://support.microsoft.com/kb/164539; 327 * http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312496) 328 * http://support.microsoft.com/default.aspx?scid=kb;en-us;Q313712 329 */ 330 $ie_vers = $this->getIEVersion(); 331 $buggy_list = array( 332 '6,00,2462,0000', '6,00,2479,0006', '6,00,2600,0000', 333 '5,50,3825,1300', '5,50,4030,2400', '5,50,4134,0100', 334 '5,50,4134,0600', '5,50,4308,2900' 335 ); 336 if (!is_null($ie_vers) && in_array($ie_vers, $buggy_list)) { 337 $this->setQuirk('buggy_compression'); 338 } 339 340 /* Some Handhelds have their screen resolution in the 341 * user agent string, which we can use to look for 342 * mobile agents. */ 343 if (preg_match('/; (120x160|240x280|240x320)\)/', $this->_agent)) { 344 $this->_mobile = true; 345 } 346 347 switch ($this->_majorVersion) { 348 case 6: 349 $this->setFeature('javascript', 1.4); 350 $this->setFeature('dom'); 351 $this->setFeature('iframes'); 352 $this->setFeature('utf'); 353 $this->setFeature('rte'); 354 $this->setFeature('homepage'); 355 $this->setFeature('accesskey'); 356 $this->setFeature('optgroup'); 357 $this->setFeature('xmlhttpreq'); 358 $this->setQuirk('scrollbar_in_way'); 359 $this->setQuirk('broken_multipart_form'); 360 break; 361 362 case 5: 363 if ($this->getPlatform() == 'mac') { 364 $this->setFeature('javascript', 1.2); 365 $this->setFeature('optgroup'); 366 } else { 367 // MSIE 5 for Windows. 368 $this->setFeature('javascript', 1.4); 369 $this->setFeature('dom'); 370 $this->setFeature('xmlhttpreq'); 371 if ($this->_minorVersion >= 5) { 372 $this->setFeature('rte'); 373 } 374 } 375 $this->setFeature('iframes'); 376 $this->setFeature('utf'); 377 $this->setFeature('homepage'); 378 $this->setFeature('accesskey'); 379 if ($this->_minorVersion == 5) { 380 $this->setQuirk('break_disposition_header'); 381 $this->setQuirk('broken_multipart_form'); 382 } 383 break; 384 385 case 4: 386 $this->setFeature('javascript', 1.2); 387 $this->setFeature('accesskey'); 388 if ($this->_minorVersion > 0) { 389 $this->setFeature('utf'); 390 } 391 break; 392 393 case 3: 394 $this->setFeature('javascript', 1.1); 395 $this->setQuirk('avoid_popup_windows'); 396 break; 397 } 398 } elseif (preg_match('|ANTFresco/([0-9]+)|', $this->_agent, $version)) { 399 $this->setBrowser('fresco'); 400 $this->setFeature('javascript', 1.1); 401 $this->setQuirk('avoid_popup_windows'); 402 } elseif (strpos($this->_lowerAgent, 'avantgo') !== false) { 403 $this->setBrowser('avantgo'); 404 $this->_mobile = true; 405 } elseif (preg_match('|Konqueror/([0-9]+)|', $this->_agent, $version) || 406 preg_match('|Safari/([0-9]+)\.?([0-9]+)?|', $this->_agent, $version)) { 407 // Konqueror and Apple's Safari both use the KHTML 408 // rendering engine. 409 $this->setBrowser('konqueror'); 410 $this->setQuirk('empty_file_input_value'); 411 $this->setQuirk('no_hidden_overflow_tables'); 412 $this->_majorVersion = $version[1]; 413 if (isset($version[2])) { 414 $this->_minorVersion = $version[2]; 415 } 416 417 if (strpos($this->_agent, 'Safari') !== false && 418 $this->_majorVersion >= 60) { 419 // Safari. 420 $this->setFeature('utf'); 421 $this->setFeature('javascript', 1.4); 422 $this->setFeature('dom'); 423 $this->setFeature('iframes'); 424 if ($this->_majorVersion > 125 || 425 ($this->_majorVersion == 125 && 426 $this->_minorVersion >= 1)) { 427 $this->setFeature('utf'); 428 $this->setFeature('accesskey'); 429 $this->setFeature('xmlhttpreq'); 430 } 431 } else { 432 // Konqueror. 433 $this->setFeature('javascript', 1.1); 434 switch ($this->_majorVersion) { 435 case 3: 436 $this->setFeature('dom'); 437 $this->setFeature('iframes'); 438 break; 439 } 440 } 441 } elseif (preg_match('|Mozilla/([0-9.]+)|', $this->_agent, $version)) { 442 $this->setBrowser('mozilla'); 443 $this->setQuirk('must_cache_forms'); 444 445 list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); 446 switch ($this->_majorVersion) { 447 case 5: 448 if ($this->getPlatform() == 'win') { 449 $this->setQuirk('break_disposition_filename'); 450 } 451 $this->setFeature('javascript', 1.4); 452 $this->setFeature('dom'); 453 $this->setFeature('accesskey'); 454 $this->setFeature('optgroup'); 455 $this->setFeature('xmlhttpreq'); 456 $this->setFeature('cite'); 457 if (preg_match('|rv:(.*)\)|', $this->_agent, $revision)) { 458 if ($revision[1] >= 1) { 459 $this->setFeature('iframes'); 460 } 461 if ($revision[1] >= 1.3) { 462 $this->setFeature('rte'); 463 } 464 } 465 break; 466 467 case 4: 468 $this->setFeature('javascript', 1.3); 469 $this->setQuirk('buggy_compression'); 470 break; 471 472 case 3: 473 default: 474 $this->setFeature('javascript', 1); 475 $this->setQuirk('buggy_compression'); 476 break; 477 } 478 } elseif (preg_match('|Lynx/([0-9]+)|', $this->_agent, $version)) { 479 $this->setBrowser('lynx'); 480 $this->setFeature('images', false); 481 $this->setFeature('frames', false); 482 $this->setFeature('javascript', false); 483 $this->setQuirk('avoid_popup_windows'); 484 } elseif (preg_match('|Links \(([0-9]+)|', $this->_agent, $version)) { 485 $this->setBrowser('links'); 486 $this->setFeature('images', false); 487 $this->setFeature('frames', false); 488 $this->setFeature('javascript', false); 489 $this->setQuirk('avoid_popup_windows'); 490 } elseif (preg_match('|HotJava/([0-9]+)|', $this->_agent, $version)) { 491 $this->setBrowser('hotjava'); 492 $this->setFeature('javascript', false); 493 } elseif (strpos($this->_agent, 'UP/') !== false || 494 strpos($this->_agent, 'UP.B') !== false || 495 strpos($this->_agent, 'UP.L') !== false) { 496 $this->setBrowser('up'); 497 $this->setFeature('html', false); 498 $this->setFeature('javascript', false); 499 $this->setFeature('hdml'); 500 $this->setFeature('wml'); 501 502 if (strpos($this->_agent, 'GUI') !== false && 503 strpos($this->_agent, 'UP.Link') !== false) { 504 /* The device accepts Openwave GUI extensions for 505 * WML 1.3. Non-UP.Link gateways sometimes have 506 * problems, so exclude them. */ 507 $this->setQuirk('ow_gui_1.3'); 508 } 509 $this->_mobile = true; 510 } elseif (strpos($this->_agent, 'Xiino/') !== false) { 511 $this->setBrowser('xiino'); 512 $this->setFeature('hdml'); 513 $this->setFeature('wml'); 514 $this->_mobile = true; 515 } elseif (strpos($this->_agent, 'Palmscape/') !== false) { 516 $this->setBrowser('palmscape'); 517 $this->setFeature('javascript', false); 518 $this->setFeature('hdml'); 519 $this->setFeature('wml'); 520 $this->_mobile = true; 521 } elseif (strpos($this->_agent, 'Nokia') !== false) { 522 $this->setBrowser('nokia'); 523 $this->setFeature('html', false); 524 $this->setFeature('wml'); 525 $this->setFeature('xhtml'); 526 $this->_mobile = true; 527 } elseif (strpos($this->_agent, 'Ericsson') !== false) { 528 $this->setBrowser('ericsson'); 529 $this->setFeature('html', false); 530 $this->setFeature('wml'); 531 $this->_mobile = true; 532 } elseif (strpos($this->_lowerAgent, 'wap') !== false) { 533 $this->setBrowser('wap'); 534 $this->setFeature('html', false); 535 $this->setFeature('javascript', false); 536 $this->setFeature('hdml'); 537 $this->setFeature('wml'); 538 $this->_mobile = true; 539 } elseif (strpos($this->_lowerAgent, 'docomo') !== false || 540 strpos($this->_lowerAgent, 'portalmmm') !== false) { 541 $this->setBrowser('imode'); 542 $this->setFeature('images', false); 543 $this->_mobile = true; 544 } elseif (strpos($this->_lowerAgent, 'j-') !== false) { 545 $this->setBrowser('mml'); 546 $this->_mobile = true; 547 } 548 } 549 } 550 551 /** 552 * Match the platform of the browser. 553 * 554 * This is a pretty simplistic implementation, but it's intended 555 * to let us tell what line breaks to send, so it's good enough 556 * for its purpose. 557 * 558 * @access public 559 * 560 * @since Horde 2.2 561 */ 562 function _setPlatform() 563 { 564 if (strpos($this->_lowerAgent, 'wind') !== false) { 565 $this->_platform = 'win'; 566 } elseif (strpos($this->_lowerAgent, 'mac') !== false) { 567 $this->_platform = 'mac'; 568 } else { 569 $this->_platform = 'unix'; 570 } 571 } 572 573 /** 574 * Return the currently matched platform. 575 * 576 * @return string The user's platform. 577 * 578 * @since Horde 2.2 579 */ 580 function getPlatform() 581 { 582 return $this->_platform; 583 } 584 585 /** 586 * Sets the current browser. 587 * 588 * @access public 589 * 590 * @param string $browser The browser to set as current. 591 */ 592 function setBrowser($browser) 593 { 594 $this->_browser = $browser; 595 } 596 597 /** 598 * Determine if the given browser is the same as the current. 599 * 600 * @access public 601 * 602 * @param string $browser The browser to check. 603 * 604 * @return boolean Is the given browser the same as the current? 605 */ 606 function isBrowser($browser) 607 { 608 return ($this->_browser === $browser); 609 } 610 611 /** 612 * Do we consider the current browser to be a mobile device? 613 * 614 * @return boolean True if we do, false if we don't. 615 */ 616 function isMobile() 617 { 618 return $this->_mobile; 619 } 620 621 /** 622 * Determines if the browser is a robot or not. 623 * 624 * @access public 625 * 626 * @return boolean True if browser is a known robot. 627 */ 628 function isRobot() 629 { 630 foreach ($this->_robots as $robot) { 631 if (strpos($this->_agent, $robot) !== false) { 632 return true; 633 } 634 } 635 return false; 636 } 637 638 /** 639 * Retrieve the current browser. 640 * 641 * @access public 642 * 643 * @return string The current browser. 644 */ 645 function getBrowser() 646 { 647 return $this->_browser; 648 } 649 650 /** 651 * Retrieve the current browser's major version. 652 * 653 * @access public 654 * 655 * @return integer The current browser's major version. 656 */ 657 function getMajor() 658 { 659 return $this->_majorVersion; 660 } 661 662 /** 663 * Retrieve the current browser's minor version. 664 * 665 * @access public 666 * 667 * @return integer The current browser's minor version. 668 */ 669 function getMinor() 670 { 671 return $this->_minorVersion; 672 } 673 674 /** 675 * Retrieve the current browser's version. 676 * 677 * @access public 678 * 679 * @return string The current browser's version. 680 */ 681 function getVersion() 682 { 683 return $this->_majorVersion . '.' . $this->_minorVersion; 684 } 685 686 /** 687 * Return the full browser agent string. 688 * 689 * @access public 690 * 691 * @return string The browser agent string. 692 */ 693 function getAgentString() 694 { 695 return $this->_agent; 696 } 697 698 /** 699 * Set unique behavior for the current browser. 700 * 701 * @access public 702 * 703 * @param string $quirk The behavior to set. 704 * @param optional string $value Special behavior parameter. 705 */ 706 function setQuirk($quirk, $value = true) 707 { 708 $this->_quirks[$quirk] = $value; 709 } 710 711 /** 712 * Check unique behavior for the current browser. 713 * 714 * @access public 715 * 716 * @param string $quirk The behavior to check. 717 * 718 * @return boolean Does the browser have the behavior set? 719 */ 720 function hasQuirk($quirk) 721 { 722 return !empty($this->_quirks[$quirk]); 723 } 724 725 /** 726 * Retreive unique behavior for the current browser. 727 * 728 * @access public 729 * 730 * @param string $quirk The behavior to retreive. 731 * 732 * @return string The value for the requested behavior. 733 */ 734 function getQuirk($quirk) 735 { 736 return isset($this->_quirks[$quirk]) 737 ? $this->_quirks[$quirk] 738 : null; 739 } 740 741 /** 742 * Set capabilities for the current browser. 743 * 744 * @access public 745 * 746 * @param string $feature The capability to set. 747 * @param optional string $value Special capability parameter. 748 */ 749 function setFeature($feature, $value = true) 750 { 751 $this->_features[$feature] = $value; 752 } 753 754 /** 755 * Check the current browser capabilities. 756 * 757 * @access public 758 * 759 * @param string $feature The capability to check. 760 * 761 * @return boolean Does the browser have the capability set? 762 */ 763 function hasFeature($feature) 764 { 765 return !empty($this->_features[$feature]); 766 } 767 768 /** 769 * Retreive the current browser capability. 770 * 771 * @access public 772 * 773 * @param string $feature The capability to retreive. 774 * 775 * @return string The value of the requested capability. 776 */ 777 function getFeature($feature) 778 { 779 return isset($this->_features[$feature]) 780 ? $this->_features[$feature] 781 : null; 782 } 783 784 /** 785 * Determine if we are using a secure (SSL) connection. 786 * 787 * @access public 788 * 789 * @return boolean True if using SSL, false if not. 790 */ 791 function usingSSLConnection() 792 { 793 return ((isset($_SERVER['HTTPS']) && 794 ($_SERVER['HTTPS'] == 'on')) || 795 getenv('SSL_PROTOCOL_VERSION')); 796 } 797 798 /** 799 * Returns the server protocol in use on the current server. 800 * 801 * @access public 802 * 803 * @return string The HTTP server protocol version. 804 */ 805 function getHTTPProtocol() 806 { 807 if (isset($_SERVER['SERVER_PROTOCOL'])) { 808 if (($pos = strrpos($_SERVER['SERVER_PROTOCOL'], '/'))) { 809 return substr($_SERVER['SERVER_PROTOCOL'], $pos + 1); 810 } 811 } 812 813 return null; 814 } 815 816 /** 817 * Determine if files can be uploaded to the system. 818 * 819 * @access public 820 * 821 * @return integer If uploads allowed, returns the maximum size of the 822 * upload in bytes. Returns 0 if uploads are not 823 * allowed. 824 */ 825 function allowFileUploads() 826 { 827 if (ini_get('file_uploads')) { 828 if (($dir = ini_get('upload_tmp_dir')) && 829 !is_writable($dir)) { 830 return 0; 831 } 832 $size = ini_get('upload_max_filesize'); 833 switch (strtolower(substr($size, -1, 1))) { 834 case 'k': 835 $size = intval(floatval($size) * 1024); 836 break; 837 838 case 'm': 839 $size = intval(floatval($size) * 1024 * 1024); 840 break; 841 842 default: 843 $size = intval($size); 844 break; 845 } 846 return $size; 847 } else { 848 return 0; 849 } 850 } 851 852 /** 853 * Determines if the file was uploaded or not. If not, will return the 854 * appropriate error message. 855 * 856 * @access public 857 * 858 * @param string $field The name of the field containing the 859 * uploaded file. 860 * @param optional string $name The file description string to use in the 861 * error message. Default: 'file'. 862 * 863 * @return mixed True on success, PEAR_Error on error. 864 */ 865 function wasFileUploaded($field, $name = null) 866 { 867 require_once 'PEAR.php'; 868 869 if (is_null($name)) { 870 $name = _("file"); 871 } 872 873 if (!($uploadSize = Browser::allowFileUploads())) { 874 return PEAR::raiseError(_("File uploads not supported.")); 875 } 876 877 /* Get any index on the field name. */ 878 require_once 'Horde/Array.php'; 879 $index = Horde_Array::getArrayParts($field, $base, $keys); 880 881 if ($index) { 882 /* Index present, fetch the error var to check. */ 883 $keys_path = array_merge(array($base, 'error'), $keys); 884 $error = Horde_Array::getElement($_FILES, $keys_path); 885 886 /* Index present, fetch the tmp_name var to check. */ 887 $keys_path = array_merge(array($base, 'tmp_name'), $keys); 888 $tmp_name = Horde_Array::getElement($_FILES, $keys_path); 889 } else { 890 /* No index, simple set up of vars to check. */ 891 if (!isset($_FILES[$field])) { 892 return PEAR::raiseError(_("No file uploaded"), UPLOAD_ERR_NO_FILE); 893 } 894 $error = $_FILES[$field]['error']; 895 $tmp_name = $_FILES[$field]['tmp_name']; 896 } 897 898 if (!isset($_FILES) || ($error == UPLOAD_ERR_NO_FILE)) { 899 return PEAR::raiseError(sprintf(_("There was a problem with the file upload: No %s was uploaded."), $name), UPLOAD_ERR_NO_FILE); 900 } elseif (($error == UPLOAD_ERR_OK) && is_uploaded_file($tmp_name)) { 901 return true; 902 } elseif (($error == UPLOAD_ERR_INI_SIZE) || 903 ($error == UPLOAD_ERR_FORM_SIZE)) { 904 return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was larger than the maximum allowed size (%d bytes)."), $name, $uploadSize), $error); 905 } elseif ($error == UPLOAD_ERR_PARTIAL) { 906 return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was only partially uploaded."), $name), $error); 907 } 908 } 909 910 /** 911 * Returns the headers for a browser download. 912 * 913 * @access public 914 * 915 * @param optional string $filename The filename of the download. 916 * @param optional string $cType The content-type description of the 917 * file. 918 * @param optional boolean $inline True if inline, false if attachment. 919 * @param optional string $cLength The content-length of this file. 920 * 921 * @since Horde 2.2 922 */ 923 function downloadHeaders($filename = 'unknown', $cType = null, 924 $inline = false, $cLength = null) 925 { 926 /* Some browsers don't like spaces in the filename. */ 927 if ($this->hasQuirk('no_filename_spaces')) { 928 $filename = strtr($filename, ' ', '_'); 929 } 930 931 /* MSIE doesn't like multiple periods in the file name. Convert 932 all periods (except the last one) to underscores. */ 933 if ($this->isBrowser('msie')) { 934 if (($pos = strrpos($filename, '.'))) { 935 $filename = strtr(substr($filename, 0, $pos), '.', '_') . substr($filename, $pos); 936 } 937 } 938 939 /* Content-Type/Content-Disposition Header. */ 940 if ($inline) { 941 if (!is_null($cType)) { 942 header('Content-Type: ' . trim($cType)); 943 } elseif ($this->isBrowser('msie')) { 944 header('Content-Type: application/x-msdownload'); 945 } else { 946 header('Content-Type: application/octet-stream'); 947 } 948 header('Content-Disposition: inline; filename="' . $filename . '"'); 949 } else { 950 if ($this->isBrowser('msie')) { 951 header('Content-Type: application/x-msdownload'); 952 } elseif (!is_null($cType)) { 953 header('Content-Type: ' . trim($cType)); 954 } else { 955 header('Content-Type: application/octet-stream'); 956 } 957 958 if ($this->hasQuirk('break_disposition_header')) { 959 header('Content-Disposition: filename="' . $filename . '"'); 960 } else { 961 header('Content-Disposition: attachment; filename="' . $filename . '"'); 962 } 963 } 964 965 /* Content-Length Header. Don't send Content-Length for 966 * HTTP/1.1 servers. */ 967 if (($this->getHTTPProtocol() != '1.1') && !is_null($cLength)) { 968 header('Content-Length: ' . $cLength); 969 } 970 971 /* Overwrite Pragma: and other caching headers for IE. */ 972 if ($this->hasQuirk('cache_ssl_downloads')) { 973 header('Expires: 0'); 974 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 975 header('Pragma: public'); 976 } 977 } 978 979 /** 980 * Determines if a browser can display a given MIME type. 981 * 982 * @access public 983 * 984 * @param string $mimetype The MIME type to check. 985 * 986 * @return boolean True if the browser can display the MIME type. 987 */ 988 function isViewable($mimetype) 989 { 990 $mimetype = String::lower($mimetype); 991 list($type, $subtype) = explode('/', $mimetype); 992 993 if (!empty($this->_accept)) { 994 $wildcard_match = false; 995 996 if (strpos($this->_accept, $mimetype) !== false) { 997 return true; 998 } 999 1000 if (strpos($this->_accept, '*/*') !== false) { 1001 $wildcard_match = true; 1002 if ($type != 'image') { 1003 return true; 1004 } 1005 } 1006 1007 /* image/jpeg and image/pjpeg *appear* to be the same 1008 * entity, but Mozilla doesn't seem to want to accept the 1009 * latter. For our purposes, we will treat them the 1010 * same. */ 1011 if ($this->isBrowser('mozilla') && 1012 ($mimetype == 'image/pjpeg') && 1013 (strpos($this->_accept, 'image/jpeg') !== false)) { 1014 return true; 1015 } 1016 1017 if (!$wildcard_match) { 1018 return false; 1019 } 1020 } 1021 1022 if (!$this->hasFeature('images') || ($type != 'image')) { 1023 return false; 1024 } 1025 1026 return (in_array($subtype, $this->_images)); 1027 } 1028 1029 /** 1030 * Escape characters in javascript code if the browser requires it. 1031 * %23, %26, and %2B (for IE) and %27 need to be escaped or else 1032 * jscript will interpret it as a single quote, pound sign, or 1033 * ampersand and refuse to work. 1034 * 1035 * @access public 1036 * 1037 * @param string $code The JS code to escape. 1038 * 1039 * @return string The escaped code. 1040 */ 1041 function escapeJSCode($code) 1042 { 1043 $from = $to = array(); 1044 1045 if ($this->isBrowser('msie') || 1046 ($this->isBrowser('mozilla') && ($this->getMajor() >= 5))) { 1047 $from = array('%23', '%26', '%2B'); 1048 $to = array(urlencode('%23'), urlencode('%26'), urlencode('%2B')); 1049 } 1050 $from[] = '%27'; 1051 $to[] = '\%27'; 1052 1053 return str_replace($from, $to, $code); 1054 } 1055 1056 /** 1057 * Set the IE version in the session. 1058 * 1059 * @access public 1060 * 1061 * @param string $ver The IE Version string. 1062 */ 1063 function setIEVersion($ver) 1064 { 1065 $_SESSION['__browser'] = array( 1066 'ie_version' => $ver 1067 ); 1068 } 1069 1070 /** 1071 * Return the IE version stored in the session, if available. 1072 * 1073 * @access public 1074 * 1075 * @return mixed The IE Version string or null if no string is stored. 1076 */ 1077 function getIEVersion() 1078 { 1079 return isset($_SESSION['__browser']['ie_version']) ? $_SESSION['__browser']['ie_version'] : null; 1080 } 1081 1082 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |