[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/phpgwapi/inc/horde/Horde/ -> Browser.php (source)

   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  }


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7