[ Index ]
 

Code source de Horde 3.1.3

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

title

Body

[fermer]

/lib/Horde/ -> MIME.php (source)

   1  <?php
   2  
   3  /* We need to (unfortunately) hard code these constants because they reside in
   4   * the imap module, which is not required for Horde.
   5   * These constants are found in the UW-imap c-client distribution:
   6   *   ftp://ftp.cac.washington.edu/imap/
   7   * The constants appear in the file include/mail.h */
   8  require_once  'Horde/Util.php';
   9  if (!Util::extensionExists('imap')) {
  10      /* Primary body types */
  11      define('TYPETEXT', 0);
  12      define('TYPEMULTIPART', 1);
  13      define('TYPEMESSAGE', 2);
  14      define('TYPEAPPLICATION', 3);
  15      define('TYPEAUDIO', 4);
  16      define('TYPEIMAGE', 5);
  17      define('TYPEVIDEO', 6);
  18      define('TYPEOTHER', 8);
  19  
  20      /* Body encodings */
  21      define('ENC7BIT', 0);
  22      define('ENC8BIT', 1);
  23      define('ENCBINARY', 2);
  24      define('ENCBASE64', 3);
  25      define('ENCQUOTEDPRINTABLE', 4);
  26      define('ENCOTHER', 5);
  27  }
  28  
  29  /**
  30   * Older versions of PHP's imap extension don't define TYPEMODEL.
  31   */
  32  if (!defined('TYPEMODEL')) {
  33      define('TYPEMODEL', 7);
  34  }
  35  
  36  /**
  37   * Return a code for type()/encoding().
  38   */
  39  define('MIME_CODE', 1);
  40  
  41  /**
  42   * Return a string for type()/encoding().
  43   */
  44  define('MIME_STRING', 2);
  45  
  46  
  47  /**
  48   * The MIME:: class provides methods for dealing with MIME standards.
  49   *
  50   * $Horde: framework/MIME/MIME.php,v 1.139.4.20 2006/03/24 04:29:52 chuck Exp $
  51   *
  52   * Copyright 1999-2006 Chuck Hagenbuch <chuck@horde.org>
  53   *
  54   * See the enclosed file COPYING for license information (LGPL). If you
  55   * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  56   *
  57   * @author  Chuck Hagenbuch <chuck@horde.org>
  58   * @since   Horde 1.3
  59   * @package Horde_MIME
  60   */
  61  class MIME {
  62  
  63      /**
  64       * A listing of the allowed MIME types.
  65       *
  66       * @var array
  67       */
  68      var $mime_types = array(
  69          TYPETEXT => 'text',
  70          TYPEMULTIPART => 'multipart',
  71          TYPEMESSAGE => 'message',
  72          TYPEAPPLICATION => 'application',
  73          TYPEAUDIO => 'audio',
  74          TYPEIMAGE => 'image',
  75          TYPEVIDEO => 'video',
  76          TYPEMODEL => 'model',
  77          TYPEOTHER => 'other'
  78      );
  79  
  80      /**
  81       * A listing of the allowed MIME encodings.
  82       *
  83       * @var array
  84       */
  85      var $mime_encodings = array(
  86          ENC7BIT => '7bit',
  87          ENC8BIT => '8bit',
  88          ENCBINARY => 'binary',
  89          ENCBASE64 => 'base64',
  90          ENCQUOTEDPRINTABLE => 'quoted-printable',
  91          ENCOTHER => 'unknown'
  92      );
  93  
  94      /**
  95       * Filter for RFC822.
  96       *
  97       * @var string
  98       */
  99      var $rfc822_filter = "()<>@,;:\\\"[]\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\177";
 100  
 101      /**
 102       * Determines if a string contains 8-bit characters.
 103       *
 104       * @param string $string  The string to check.
 105       *
 106       * @return boolean  True if it does, false if it doesn't.
 107       */
 108      function is8bit($string)
 109      {
 110          return (is_string($string) && preg_match('/[\x80-\xff]/', $string));
 111      }
 112  
 113      /**
 114       * Encodes a string containing non-ASCII characters according to RFC 2047.
 115       *
 116       * @param string $text     The text to encode.
 117       * @param string $charset  The character set of the text.
 118       *
 119       * @return string  The text, encoded only if it contains non-ASCII
 120       *                 characters.
 121       */
 122      function encode($text, $charset = null)
 123      {
 124          /* Return if nothing needs to be encoded. */
 125          if (!MIME::is8bit($text)) {
 126              return $text;
 127          }
 128  
 129          if (is_null($charset)) {
 130              $charset = NLS::getCharset();
 131          }
 132  
 133          $charset = String::lower($charset);
 134          $line = '';
 135  
 136          /* Get the list of elements in the string. */
 137          $size = preg_match_all('/([^\s]+)([\s]*)/', $text, $matches, PREG_SET_ORDER);
 138  
 139          foreach ($matches as $key => $val) {
 140              if (MIME::is8bit($val[1])) {
 141                  if ((($key + 1) < $size) &&
 142                      MIME::is8bit($matches[$key + 1][1])) {
 143                      $line .= MIME::_encode($val[1] . $val[2], $charset) . ' ';
 144                  } else {
 145                      $line .= MIME::_encode($val[1], $charset) . $val[2];
 146                  }
 147              } else {
 148                  $line .= $val[1] . $val[2];
 149              }
 150          }
 151  
 152          return rtrim($line);
 153      }
 154  
 155      /**
 156       * Internal recursive function to RFC 2047 encode a string.
 157       *
 158       * @access private
 159       *
 160       * @param string $text     The text to encode.
 161       * @param string $charset  The character set of the text.
 162       *
 163       * @return string  The text, encoded only if it contains non-ASCII
 164       *                 characters.
 165       */
 166      function _encode($text, $charset)
 167      {
 168          $char_len = strlen($charset);
 169          $txt_len = strlen($text) * 2;
 170  
 171          /* RFC 2047 [2] states that no encoded word can be more than 75
 172             characters long. If longer, you must split the word. */
 173          if (($txt_len + $char_len + 7) > 75) {
 174              $pos = intval((68 - $char_len) / 2);
 175              return MIME::_encode(substr($text, 0, $pos), $charset) . ' ' . MIME::_encode(substr($text, $pos), $charset);
 176          } else {
 177              return '=?' . $charset . '?b?' . trim(base64_encode($text)) . '?=';
 178          }
 179      }
 180  
 181      /**
 182       * Encodes a line via quoted-printable encoding.
 183       * Wraps lines at 76 characters.
 184       *
 185       * @param string $text  The text to encode.
 186       * @param string $eol   The EOL sequence to use.
 187       *
 188       * @return string  The quoted-printable encoded string.
 189       */
 190      function quotedPrintableEncode($text, $eol)
 191      {
 192          $output = '';
 193  
 194          foreach (preg_split("/\r?\n/", $text) as $line) {
 195              /* We need to go character by character through the line. */
 196              $length = strlen($line);
 197              $current_line = '';
 198              $current_length = 0;
 199  
 200              for ($i = 0; $i < $length; $i++) {
 201                  $char = substr($line, $i, 1);
 202                  $ascii = ord($char);
 203  
 204                  /* Spaces or tabs at the end of the line are NOT allowed.
 205                   * Also, Characters in ASCII below 32 or above 126 AND 61
 206                   * must be encoded. */
 207                  if (((($ascii === 9) || ($ascii === 32)) && ($i == ($length - 1))) ||
 208                      (($ascii < 32) || ($ascii > 126) || ($ascii === 61))) {
 209                      $char = '=' . String::upper(sprintf('%02s', dechex($ascii)));
 210                  }
 211  
 212                  /* Lines must be 76 characters or less. */
 213                  $char_length = strlen($char);
 214                  $current_length += $char_length;
 215                  if ($current_length > 76) {
 216                      $output .= $current_line . '=' . $eol;
 217                      $current_line = '';
 218                      $current_length = $char_length;
 219                  }
 220                  $current_line .= $char;
 221              }
 222              $output .= $current_line . $eol;
 223          }
 224  
 225          return $output;
 226      }
 227  
 228      /**
 229       * Encodes a string containing email addresses according to RFC 2047.
 230       *
 231       * This differs from MIME::encode() because it keeps email addresses legal,
 232       * only encoding the personal information.
 233       *
 234       * @param string $addresses  The email addresses to encode.
 235       * @param string $charset    The character set of the text.
 236       * @param string $defserver  The default domain to append to mailboxes.
 237       *
 238       * @return string  The text, encoded only if it contains non-ascii
 239       *                 characters.
 240       */
 241      function encodeAddress($addresses, $charset = null, $defserver = null)
 242      {
 243          if (is_array($addresses)) {
 244              $addr_arr = $addresses;
 245          } else {
 246              /* parseAddressList() does not process the null entry
 247               * 'undisclosed-recipients:;' correctly. */
 248              if (preg_match('/undisclosed-recipients:\s*;/i', trim($addresses))) {
 249                  return $addresses;
 250              }
 251  
 252              require_once 'Mail/RFC822.php';
 253              $parser = &new Mail_RFC822();
 254              $addr_arr = $parser->parseAddressList($addresses, $defserver, true, false);
 255              if (is_a($addr_arr, 'PEAR_Error')) {
 256                  return $addr_arr;
 257              }
 258          }
 259  
 260          $text = '';
 261          if (is_array($addr_arr)) {
 262              foreach ($addr_arr as $addr) {
 263                  // Check for groups.
 264                  if (!empty($addr->groupname)) {
 265                      $text .= MIME::encode($addr->groupname, $charset) . ': ' . MIME::encodeAddress($addr->addresses) . ';';
 266                      continue;
 267                  }
 268  
 269                  if (empty($addr->personal)) {
 270                      $personal = '';
 271                  } else {
 272                      if ((substr($addr->personal, 0, 1) == '"') &&
 273                          (substr($addr->personal, -1) == '"')) {
 274                          $addr->personal = substr($addr->personal, 1, -1);
 275                      }
 276                      $personal = MIME::encode($addr->personal, $charset);
 277                  }
 278                  if (strlen($text) != 0) {
 279                      $text .= ', ';
 280                  }
 281                  $text .= MIME::trimEmailAddress(MIME::rfc822WriteAddress($addr->mailbox, $addr->host, $personal));
 282              }
 283          }
 284  
 285          return $text;
 286      }
 287  
 288      /**
 289       * Decodes an RFC 2047-encoded string.
 290       *
 291       * @param string $string      The text to decode.
 292       * @param string $to_charset  The charset that the text should be decoded
 293       *                            to.
 294       *
 295       * @return string  The decoded text.
 296       */
 297      function decode($string, $to_charset = null)
 298      {
 299          if (($pos = strpos($string, '=?')) === false) {
 300              return $string;
 301          }
 302  
 303          /* Take out any spaces between multiple encoded words. */
 304          $string = preg_replace('|\?=\s=\?|', '?==?', $string);
 305  
 306          /* Save any preceding text. */
 307          $preceding = substr($string, 0, $pos);
 308  
 309          $search = substr($string, $pos + 2);
 310          $d1 = strpos($search, '?');
 311          if ($d1 === false) {
 312              return $string;
 313          }
 314  
 315          $charset = substr($string, $pos + 2, $d1);
 316          $search = substr($search, $d1 + 1);
 317  
 318          $d2 = strpos($search, '?');
 319          if ($d2 === false) {
 320              return $string;
 321          }
 322  
 323          $encoding = substr($search, 0, $d2);
 324          $search = substr($search, $d2 + 1);
 325  
 326          $end = strpos($search, '?=');
 327          if ($end === false) {
 328              $end = strlen($search);
 329          }
 330  
 331          $encoded_text = substr($search, 0, $end);
 332          $rest = substr($string, (strlen($preceding . $charset . $encoding . $encoded_text) + 6));
 333  
 334          if (!isset($to_charset)) {
 335              $to_charset = NLS::getCharset();
 336          }
 337  
 338          switch ($encoding) {
 339          case 'Q':
 340          case 'q':
 341              $encoded_text = str_replace('_', ' ', $encoded_text);
 342              $decoded = preg_replace('/=([0-9a-f]{2})/ie', 'chr(0x\1)', $encoded_text);
 343              $decoded = String::convertCharset($decoded, $charset, $to_charset);
 344              break;
 345  
 346          case 'B':
 347          case 'b':
 348              $decoded = base64_decode($encoded_text);
 349              $decoded = String::convertCharset($decoded, $charset, $to_charset);
 350              break;
 351  
 352          default:
 353              $decoded = '=?' . $charset . '?' . $encoding . '?' . $encoded_text . '?=';
 354              break;
 355          }
 356  
 357          return $preceding . $decoded . MIME::decode($rest, $to_charset);
 358      }
 359  
 360      /**
 361       * Decodes an RFC 2231-encoded string.
 362       *
 363       * @param string $string   The entire string to decode, including the
 364       *                         parameter name.
 365       * @param string $charset  The charset that the text should be decoded to.
 366       *
 367       * @return array  The decoded text, or the original string if it was not
 368       *                encoded.
 369       */
 370      function decodeRFC2231($string, $to_charset = null)
 371      {
 372          if (($pos = strpos($string, '*')) === false) {
 373              return false;
 374          }
 375  
 376          if (!isset($to_charset)) {
 377              $to_charset = NLS::getCharset();
 378          }
 379  
 380          $attribute = substr($string, 0, $pos);
 381          $charset = $lang = null;
 382          $output = '';
 383  
 384          /* Get the character set and language used in the encoding, if
 385           * any. */
 386          if (preg_match("/^[^=]+\*\=([^']*)'([^']*)'/", $string, $matches)) {
 387              $charset = $matches[1];
 388              $lang = $matches[2];
 389              $string = str_replace($charset . "'" . $lang . "'", '', $string);
 390          }
 391  
 392          $lines = preg_split('/' . preg_quote($attribute) . '(?:\*\d)*/', $string);
 393          foreach ($lines as $line) {
 394              $pos = strpos($line, '*=');
 395              if ($pos === 0) {
 396                  $line = substr($line, 2);
 397                  $line = str_replace('_', '%20', $line);
 398                  $line = str_replace('=', '%', $line);
 399                  $output .= urldecode($line);
 400              } else {
 401                  $line = substr($line, 1);
 402                  $output .= $line;
 403              }
 404          }
 405  
 406          /* RFC 2231 uses quoted printable encoding. */
 407          if (!is_null($charset)) {
 408              $output = String::convertCharset($output, $charset, $to_charset);
 409          }
 410  
 411          return array(
 412              'attribute' => $attribute,
 413              'value' => $output
 414          );
 415      }
 416  
 417      /**
 418       * If an email address has no personal information, get rid of any angle
 419       * brackets (<>) around it.
 420       *
 421       * @param string $address  The address to trim.
 422       *
 423       * @return string  The trimmed address.
 424       */
 425      function trimEmailAddress($address)
 426      {
 427          $address = trim($address);
 428  
 429          if ((substr($address, 0, 1) == '<') && (substr($address, -1) == '>')) {
 430              $address = substr($address, 1, -1);
 431          }
 432  
 433          return $address;
 434      }
 435  
 436      /**
 437       * Builds an RFC 822 compliant email address.
 438       *
 439       * @param string $mailbox   Mailbox name.
 440       * @param string $host      Domain name of mailbox's host.
 441       * @param string $personal  Personal name phrase.
 442       *
 443       * @return string  The correctly escaped and quoted
 444       *                 "$personal <$mailbox@$host>" string.
 445       */
 446      function rfc822WriteAddress($mailbox, $host = null, $personal = '')
 447      {
 448          $address = '';
 449  
 450          if (!empty($personal)) {
 451              $vars = get_class_vars('MIME');
 452              $address .= MIME::_rfc822Encode($personal, $vars['rfc822_filter'] . '.');
 453              $address .= ' <';
 454          }
 455  
 456          if (!is_null($host)) {
 457              $address .= MIME::_rfc822Encode($mailbox);
 458              if (substr($host, 0, 1) != '@') {
 459                  $address .= '@' . $host;
 460              }
 461          }
 462  
 463          if (!empty($personal)) {
 464              $address .= '>';
 465          }
 466  
 467          return $address;
 468      }
 469  
 470      /**
 471       * Explodes a RFC 822 string, ignoring a delimiter if preceded by a "\"
 472       * character, or if delimiter is inside single or double quotes.
 473       *
 474       * @param string $str        The RFC 822 string.
 475       * @param string $delimiter  The delimter.
 476       *
 477       * @return array  The exploded string in an array.
 478       */
 479      function rfc822Explode($str, $delimiter)
 480      {
 481          $arr = array();
 482          $match = 0;
 483          $quotes = array('"', "'");
 484          $in_quote = null;
 485          $in_group = false;
 486          $prev = null;
 487  
 488          if (empty($str)) {
 489              return array($str);
 490          }
 491  
 492          if (in_array($str{0}, $quotes)) {
 493              $in_quote = $str{0};
 494          } elseif ($str{0} == ':') {
 495              $in_group = true;
 496          } elseif ($str{0} == $delimiter) {
 497              $arr[] = '';
 498              $match = 1;
 499          }
 500  
 501          for ($i = 1; $i < strlen($str); $i++) {
 502              $char = $str{$i};
 503              if (in_array($char, $quotes)) {
 504                  if ($prev !== '\\') {
 505                      if ($in_quote === $char) {
 506                          $in_quote = null;
 507                      } elseif (is_null($in_quote)) {
 508                          $in_quote = $char;
 509                      }
 510                  }
 511              } elseif ($in_group) {
 512                  if ($char == ';') {
 513                      $arr[] = substr($str, $match, $i - $match + 1);
 514                      $match = $i + 1;
 515                      $in_group = false;
 516                  }
 517              } elseif ($char == ':') {
 518                  $in_group = true;
 519              } elseif ($char == $delimiter &&
 520                        $prev !== '\\' &&
 521                        is_null($in_quote)) {
 522                  $arr[] = substr($str, $match, $i - $match);
 523                  $match = $i + 1;
 524              }
 525              $prev = $char;
 526          }
 527  
 528          if ($match != $i) {
 529              /* The string ended without a $delimiter. */
 530              $arr[] = substr($str, $match, $i - $match);
 531          }
 532  
 533          return $arr;
 534      }
 535  
 536      /**
 537       * Takes an address object, as returned by imap_header() for example, and
 538       * formats it as a string.
 539       *
 540       * Object format for the address "John Doe <john_doe@example.com>" is:
 541       * <pre>
 542       *   $object->personal = Personal name ("John Doe")
 543       *   $object->mailbox  = The user's mailbox ("john_doe")
 544       *   $object->host     = The host the mailbox is on ("example.com")
 545       * </pre>
 546       *
 547       * @param stdClass $ob   The address object to be turned into a string.
 548       * @param mixed $filter  A user@example.com style bare address to ignore.
 549       *                       Either single string or an array of strings.  If
 550       *                       the address matches $filter, an empty string will
 551       *                       be returned.
 552       *
 553       * @return string  The formatted address (Example: John Doe
 554       *                 <john_doe@example.com>).
 555       */
 556      function addrObject2String($ob, $filter = '')
 557      {
 558          /* If the personal name is set, decode it. */
 559          $ob->personal = isset($ob->personal) ? MIME::decode($ob->personal) : '';
 560  
 561          /* If both the mailbox and the host are empty, return an empty
 562             string.  If we just let this case fall through, the call to
 563             MIME::rfc822WriteAddress() will end up return just a '@', which
 564             is undesirable. */
 565          if (empty($ob->mailbox) && empty($ob->host)) {
 566              return '';
 567          }
 568  
 569          /* Make sure these two variables have some sort of value. */
 570          if (!isset($ob->mailbox)) {
 571              $ob->mailbox = '';
 572          } elseif ($ob->mailbox == 'undisclosed-recipients') {
 573              return '';
 574          }
 575          if (!isset($ob->host)) {
 576              $ob->host = '';
 577          }
 578  
 579          /* Filter out unwanted addresses based on the $filter string. */
 580          if ($filter) {
 581              if (!is_array($filter)) {
 582                  $filter = array($filter);
 583              }
 584              foreach ($filter as $f) {
 585                  if (strcasecmp($f, $ob->mailbox . '@' . $ob->host) == 0) {
 586                      return '';
 587                  }
 588              }
 589          }
 590  
 591          /* Return the trimmed, formatted email address. */
 592          return MIME::trimEmailAddress(MIME::rfc822WriteAddress($ob->mailbox, $ob->host, $ob->personal));
 593      }
 594  
 595      /**
 596       * Takes an array of address objects, as returned by imap_headerinfo(),
 597       * for example, and passes each of them through MIME::addrObject2String().
 598       *
 599       * @param array $addresses  The array of address objects.
 600       * @param mixed $filter     A user@example.com style bare address to
 601       *                          ignore.  If any address matches $filter, it
 602       *                          will not be included in the final string.
 603       *
 604       * @return string  All of the addresses in a comma-delimited string.
 605       *                 Returns the empty string on error/no addresses found.
 606       */
 607      function addrArray2String($addresses, $filter = '')
 608      {
 609          $addrList = array();
 610  
 611          if (!is_array($addresses)) {
 612              return '';
 613          }
 614  
 615          foreach ($addresses as $addr) {
 616              $val = MIME::addrObject2String($addr, $filter);
 617              if (!empty($val)) {
 618                  $bareAddr = String::lower(MIME::bareAddress($val));
 619                  if (!isset($addrList[$bareAddr])) {
 620                      $addrList[$bareAddr] = $val;
 621                  }
 622              }
 623          }
 624  
 625          if (empty($addrList)) {
 626              return '';
 627          } else {
 628              return implode(', ', $addrList);
 629          }
 630      }
 631  
 632      /**
 633       * Returns the bare address.
 634       *
 635       * @param string $address    The address string.
 636       * @param string $defserver  The default domain to append to mailboxes.
 637       * @param boolean $multiple  Should we return multiple results?
 638       *
 639       * @return mixed  If $multiple is false, returns the mailbox@host e-mail
 640       *                address.  If $multiple is true, returns an array of
 641       *                these addresses.
 642       */
 643      function bareAddress($address, $defserver = null, $multiple = false)
 644      {
 645          $addressList = array();
 646  
 647          /* Use built-in IMAP function only if available and if not parsing
 648           * distribution lists because it doesn't parse distribution lists
 649           * properly. */
 650          if (Util::extensionExists('imap') && strpos($address, ':') === false) {
 651              $from = imap_rfc822_parse_adrlist($address, $defserver);
 652          } else {
 653              require_once 'Mail/RFC822.php';
 654              $parser = new Mail_RFC822();
 655              $from = $parser->parseAddressList($address, $defserver, false, false);
 656              if (is_a($from, 'PEAR_Error')) {
 657                  return $multiple ? array() : '';
 658              }
 659          }
 660  
 661          foreach ($from as $entry) {
 662              if (isset($entry->mailbox) &&
 663                  $entry->mailbox != 'undisclosed-recipients' &&
 664                  $entry->mailbox != 'UNEXPECTED_DATA_AFTER_ADDRESS') {
 665                  if (isset($entry->host)) {
 666                      $addressList[] = $entry->mailbox . '@' . $entry->host;
 667                  } else {
 668                      $addressList[] = $entry->mailbox;
 669                  }
 670              }
 671          }
 672  
 673          return $multiple ? $addressList : array_pop($addressList);
 674      }
 675  
 676      /**
 677       * Quotes and escapes the given string if necessary.
 678       *
 679       * @access private
 680       *
 681       * @param string $str     The string to be quoted and escaped.
 682       * @param string $filter  A list of characters that make it necessary to
 683       *                        quote the string if they occur.
 684       *
 685       * @return string  The correctly quoted and escaped string.
 686       */
 687      function _rfc822Encode($str, $filter = '')
 688      {
 689          if (empty($filter)) {
 690              $vars = get_class_vars('MIME');
 691              $filter = $vars['rfc822_filter'] . ' ';
 692          }
 693  
 694          // Strip double quotes if they are around the string already.
 695          if (substr($str, 0, 1) == '"' && substr($str, -1) == '"') {
 696              $str = substr($str, 1, -1);
 697          }
 698  
 699          if (strcspn($str, $filter) != strlen($str)) {
 700              $str = str_replace('\"', '"', $str);
 701              return '"' . str_replace('"', '\\"', str_replace('\\', '\\\\', $str)) . '"';
 702          } else {
 703              return $str;
 704          }
 705      }
 706  
 707      /**
 708       * Returns the MIME type for the given input.
 709       *
 710       * @param mixed $input     Either the MIME code or type string.
 711       * @param integer $format  If MIME_CODE, return code.
 712       *                         If MIME_STRING, returns lowercase string.
 713       *
 714       * @return mixed  See above.
 715       */
 716      function type($input, $format = null)
 717      {
 718          return MIME::_getCode($input, $format, 'mime_types');
 719      }
 720  
 721      /**
 722       * Returns the MIME encoding for the given input.
 723       *
 724       * @param mixed $input     Either the MIME code or encoding string.
 725       * @param integer $format  If MIME_CODE, return code.
 726       *                         If MIME_STRING, returns lowercase string.
 727       *                         If not set, returns the opposite value.
 728       *
 729       * @return mixed  See above.
 730       */
 731      function encoding($input, $format = null)
 732      {
 733          return MIME::_getCode($input, $format, 'mime_encodings');
 734      }
 735  
 736      /**
 737       * Retrieves MIME encoding/type data from the internal arrays.
 738       *
 739       * @access private
 740       *
 741       * @param mixed $input    Either the MIME code or encoding string.
 742       * @param string $format  If MIME_CODE, returns code.
 743       *                        If MIME_STRING, returns lowercase string.
 744       *                        If null, returns the oppposite value.
 745       * @param string $type    The name of the internal array.
 746       *
 747       * @return mixed  See above.
 748       */
 749      function _getCode($input, $format, $type)
 750      {
 751          $numeric = is_numeric($input);
 752          if (!$numeric) {
 753              $input = String::lower($input);
 754          }
 755  
 756          switch ($format) {
 757          case MIME_CODE:
 758              if ($numeric) return $input;
 759              break;
 760  
 761          case MIME_STRING:
 762              if (!$numeric) return $input;
 763              break;
 764          }
 765  
 766          $vars = get_class_vars('MIME');
 767  
 768          if ($numeric) {
 769              if (isset($vars[$type][$input])) {
 770                  return $vars[$type][$input];
 771              }
 772          } else {
 773              if (($search = array_search($input, $vars[$type]))) {
 774                  return $search;
 775              }
 776          }
 777  
 778          return null;
 779      }
 780  
 781      /**
 782       * Generates a Message-ID string conforming to RFC 2822 [3.6.4] and the
 783       * standards outlined in 'draft-ietf-usefor-message-id-01.txt'.
 784       *
 785       * @param string  A message ID string.
 786       */
 787      function generateMessageID()
 788      {
 789          return '<' . date('YmdHis') . '.' .
 790              substr(base_convert(microtime() . mt_rand(), 10, 36), -16) .
 791              '@' . $_SERVER['SERVER_NAME'] . '>';
 792      }
 793  
 794      /**
 795       * Adds proper linebreaks to a header string.
 796       * RFC 2822 [2.2.3] says that headers SHOULD be wrapped at 78 characters.
 797       * However, since we may be dealing with quoted text that contains spaces,
 798       * strict wrapping at 78 characters may add unwanted newlines and tabs to
 799       * the quoted parameter.  The correct way to get around this is to encode
 800       * paraeters according to RFC 2231.  However, since most mailers do not
 801       * seem to support this, we will instead simply use long lines.  RFC 2822
 802       * says headers SHOULD only be 78 characters a line, but also says that
 803       * a header line MUST not be more than 998 characters.  Therefore, the
 804       * compromise is to put each parameter on a separate line and chop it
 805       * only if it is longer than 998 characters.
 806       *
 807       * @param string $header  The header name.
 808       * @param string $text    The text of the header field.
 809       * @param string $eol     The EOL string to use.
 810       *
 811       * @return string  The header text, with linebreaks inserted.
 812       */
 813      function wrapHeaders($header, $text, $eol = "\r\n")
 814      {
 815          $header = rtrim($header);
 816  
 817          /* Remove any existing linebreaks. */
 818          $text = preg_replace("/\r?\n\s?/", ' ', $text);
 819          $text = $header . ': ' . rtrim($text);
 820  
 821          $eollength = strlen($eol);
 822          $header_lower = strtolower($header);
 823  
 824          if (($header_lower != 'content-type') &&
 825              ($header_lower != 'content-disposition')) {
 826              /* Wrap the line. */
 827              $line = wordwrap($text, 75, $eol . "\t");
 828  
 829              /* Make sure there are no empty lines. */
 830              $line = preg_replace('/' . $eol . "\t\s*" . $eol . "\t/", '/' . $eol . "\t/", $line);
 831  
 832              return substr($line, strlen($header) + 2);
 833          }
 834  
 835          /* Split the line by the RFC parameter separator ';'. */
 836          $params = preg_split("/\s*;\s*/", $text);
 837  
 838          $line = '';
 839          $length = 1000 - $eollength;
 840          $paramcount = count($params);
 841  
 842          foreach ($params as $count => $val) {
 843              /* If longer than RFC allows, then simply chop off the excess. */
 844              $moreparams = (($count + 1) != $paramcount);
 845              $maxlength = $length - (!empty($line) ? 1 : 0) - (($moreparams) ? 1 : 0);
 846              if (strlen($val) > $maxlength) {
 847                  $val = substr($val, 0, $maxlength);
 848  
 849                  /* If we have an opening quote, add a closing quote after
 850                   * chopping the rest of the text. */
 851                  if (strpos($val, '"') !== false) {
 852                      $val = substr($val, 0, -1);
 853                      $val .= '"';
 854                  }
 855  
 856              }
 857  
 858              if (!empty($line)) {
 859                  $line .= "\t";
 860              }
 861              $line .= $val . (($moreparams) ? ';' : '') . $eol;
 862          }
 863  
 864          return substr($line, strlen($header) + 2, ($eollength * -1));
 865      }
 866  
 867  }


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