[ Index ]
 

Code source de Horde 3.1.3

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

title

Body

[fermer]

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

   1  <?php
   2  /**
   3   * The description of Horde to use in the 'User-Agent:' header.
   4   */
   5  define('HORDE_AGENT_HEADER', 'Horde Application Framework 3.1');
   6  
   7  /**
   8   * The MIME_Headers:: class contains generic functions related to
   9   * handling the headers of mail messages.
  10   *
  11   * The default character set to use for headers should be defined in the
  12   * variable $GLOBALS['mime_headers']['default_charset'] (defaults to US-ASCII
  13   * per RFC 2045).
  14   *
  15   * $Horde: framework/MIME/MIME/Headers.php,v 1.29.10.20 2006/04/15 17:24:19 slusarz Exp $
  16   *
  17   * Copyright 2002-2006 Michael Slusarz <slusarz@bigworm.colorado.edu>
  18   *
  19   * See the enclosed file COPYING for license information (LGPL). If you
  20   * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  21   *
  22   * @author  Michael Slusarz <slusarz@bigworm.colorado.edu>
  23   * @since   Horde 3.0
  24   * @package Horde_MIME
  25   */
  26  class MIME_Headers {
  27  
  28      /**
  29       * The internal headers array.
  30       *
  31       * @var array
  32       */
  33      var $_headers = array();
  34  
  35      /**
  36       * Cached output of the MIME_Structure::parseMIMEHeaders() command.
  37       *
  38       * @var array
  39       */
  40      var $_allHeaders;
  41  
  42      /**
  43       * Cached output of the imap_fetchheader() command.
  44       *
  45       * @var string
  46       */
  47      var $_headerText;
  48  
  49      /**
  50       * The header object returned from imap_headerinfo().
  51       *
  52       * @var stdClass
  53       */
  54      var $_headerObject;
  55  
  56      /**
  57       * The internal flags array.
  58       *
  59       * @var array
  60       */
  61      var $_flags = array();
  62  
  63      /**
  64       * The User-Agent string to use.
  65       * THIS VALUE SHOULD BE OVERRIDEN BY ALL SUBCLASSES.
  66       *
  67       * @var string
  68       */
  69      var $_agent = HORDE_AGENT_HEADER;
  70  
  71      /**
  72       * The sequence to use as EOL for the headers.
  73       * The default is currently to output the EOL sequence internally as
  74       * just "\n" instead of the canonical "\r\n" required in RFC 822 & 2045.
  75       * To be RFC complaint, the full <CR><LF> EOL combination should be used
  76       * when sending a message.
  77       *
  78       * @var string
  79       */
  80      var $_eol = "\n";
  81  
  82      /**
  83       * The index of the message.
  84       *
  85       * @var integer
  86       */
  87      var $_index;
  88  
  89      /**
  90       * Constructor.
  91       *
  92       * @param integer $index  The message index to parse headers.
  93       */
  94      function MIME_Headers($index = null)
  95      {
  96          $this->_index = $index;
  97      }
  98  
  99      /**
 100       * Returns a reference to a currently open IMAP stream.
 101       * THIS VALUE SHOULD BE OVERRIDEN BY ALL SUBCLASSES.
 102       *
 103       * @return resource  An IMAP resource stream.
 104       */
 105      function &_getStream()
 106      {
 107          return false;
 108      }
 109  
 110      /**
 111       * Return the full list of headers from the imap_fetchheader() function.
 112       *
 113       * @return string  See imap_fetchheader().
 114       */
 115      function getHeaderText()
 116      {
 117          if (!is_null($this->_index) && empty($this->_headerText)) {
 118              $this->_headerText = @imap_fetchheader($this->_getStream(), $this->_index, FT_UID);
 119              if (!empty($GLOBALS['mime_headers']['default_charset'])) {
 120                  $this->_headerText = String::convertCharset($this->_headerText, $GLOBALS['mime_headers']['default_charset']);
 121              }
 122          }
 123  
 124          return $this->_headerText;
 125      }
 126  
 127      /**
 128       * Return the full list of headers.
 129       *
 130       * @param boolean $decode  Decode the headers?
 131       *
 132       * @return array  See MIME_Structure::parseMIMEHeaders().
 133       */
 134      function getAllHeaders($decode = true)
 135      {
 136          require_once 'Horde/MIME/Structure.php';
 137  
 138          if (!is_null($this->_index) && empty($this->_allHeaders)) {
 139              $this->_allHeaders = MIME_Structure::parseMIMEHeaders($this->getHeaderText(), $decode);
 140          }
 141  
 142          return $this->_allHeaders;
 143      }
 144  
 145      /**
 146       * Return the header object from imap_headerinfo().
 147       *
 148       * @return stdClass  See imap_headerinfo().
 149       */
 150      function getHeaderObject()
 151      {
 152          if (!is_null($this->_index) && empty($this->_headerObject)) {
 153              $stream = $this->_getStream();
 154              $this->_headerObject = @imap_headerinfo($stream, @imap_msgno($stream, $this->_index));
 155          }
 156  
 157          return $this->_headerObject;
 158      }
 159  
 160      /**
 161       * Build the header array.
 162       *
 163       * @param boolean $decode  MIME decode the headers?
 164       */
 165      function buildHeaders($decode = true)
 166      {
 167          if (!empty($this->_headers)) {
 168              return;
 169          }
 170  
 171          /* Parse through the list of all headers. */
 172          foreach ($this->getAllHeaders($decode) as $key => $val) {
 173              $this->addHeader($key, $val);
 174          }
 175      }
 176  
 177      /**
 178       * Build the flags array.
 179       */
 180      function buildFlags()
 181      {
 182          if (!empty($this->_flags)) {
 183              return;
 184          }
 185  
 186          /* Get the IMAP header object. */
 187          $ob = $this->getHeaderObject();
 188          if (!is_object($ob)) {
 189              return;
 190          }
 191  
 192          /* Unseen flag */
 193          if (($ob->Unseen == 'U') || ($ob->Recent == 'N')) {
 194              $this->_flags['unseen'] = true;
 195          }
 196  
 197          /* Recent flag */
 198          if (($ob->Recent == 'N') || ($ob->Recent == 'R')) {
 199              $this->_flags['recent'] = true;
 200          }
 201  
 202          /* Answered flag */
 203          if ($ob->Answered == 'A') {
 204              $this->_flags['answered'] = true;
 205          }
 206  
 207          /* Draft flag */
 208          if (isset($ob->Draft) && ($ob->Draft == 'X')) {
 209              $this->_flags['draft'] = true;
 210          }
 211  
 212          /* Flagged flag */
 213          if ($ob->Flagged == 'F') {
 214              $this->_flags['flagged'] = true;
 215          }
 216  
 217          /* Deleted flag */
 218          if ($ob->Deleted == 'D') {
 219              $this->_flags['deleted'] = true;
 220          }
 221      }
 222  
 223      /**
 224       * Returns the internal header array in array format.
 225       *
 226       * @return array  The headers in array format.
 227       */
 228      function toArray()
 229      {
 230          $return_array = array();
 231  
 232          foreach ($this->_headers as $ob) {
 233              $eol = $this->getEOL();
 234              $header = $ob['header'];
 235              if (is_array($ob['value'])) {
 236                  require_once dirname(__FILE__) . '/../MIME.php';
 237                  $return_array[$header] = MIME::wrapHeaders($header, reset($ob['value']));
 238                  next($ob['value']);
 239                  while (list(,$val) = each($ob['value'])) {
 240                      $return_array[$header] .= $eol . $header . ': ' . MIME::wrapHeaders($header, $val, $eol);
 241                  }
 242              } else {
 243                  $return_array[$header] = $ob['value'];
 244              }
 245          }
 246  
 247          return $return_array;
 248      }
 249  
 250      /**
 251       * Returns the internal header array in string format.
 252       *
 253       * @return string  The headers in string format.
 254       */
 255      function toString()
 256      {
 257          $eol = $this->getEOL();
 258          $text = '';
 259  
 260          foreach ($this->_headers as $ob) {
 261              if (!is_array($ob['value'])) {
 262                  $ob['value'] = array($ob['value']);
 263              }
 264              foreach ($ob['value'] as $entry) {
 265                  $text .= $ob['header'] . ': ' . $entry . $eol;
 266              }
 267          }
 268  
 269          return $text . $eol;
 270      }
 271  
 272      /**
 273       * Generate the 'Received' header for the Web browser->Horde hop
 274       * (attempts to conform to guidelines in RFC 2821).
 275       */
 276      function addReceivedHeader()
 277      {
 278          if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
 279              /* This indicates the user is connecting through a proxy. */
 280              $remote_path = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
 281              $remote_addr = $remote_path[0];
 282              $remote = @gethostbyaddr($remote_addr);
 283          } else {
 284              $remote_addr = $_SERVER['REMOTE_ADDR'];
 285              if (empty($_SERVER['REMOTE_HOST'])) {
 286                  $remote = @gethostbyaddr($remote_addr);
 287              } else {
 288                  $remote = $_SERVER['REMOTE_HOST'];
 289              }
 290          }
 291          $received = 'from ' . $remote . ' (';
 292  
 293          if (!empty($_SERVER['REMOTE_IDENT'])) {
 294              $received .= $_SERVER['REMOTE_IDENT'] . '@' . $remote . ' ';
 295          } elseif ($remote != $_SERVER['REMOTE_ADDR']) {
 296              $received .= $remote . ' ';
 297          }
 298          $received .= '[' . $remote_addr . ']) ';
 299  
 300          if (!empty($GLOBALS['conf']['server']['name'])) {
 301              $server_name = $GLOBALS['conf']['server']['name'];
 302          } elseif (!empty($_SERVER['SERVER_NAME'])) {
 303              $server_name = $_SERVER['SERVER_NAME'];
 304          } elseif (!empty($_SERVER['HTTP_HOST'])) {
 305              $server_name = $_SERVER['HTTP_HOST'];
 306          } else {
 307              $server_name = 'unknown';
 308          }
 309          $received .= 'by ' . $server_name . ' (Horde MIME library) with HTTP; ';
 310  
 311          $received .= date('r');
 312  
 313          $this->addHeader('Received', $received);
 314      }
 315  
 316      /**
 317       * Generate the 'Message-ID' header.
 318       */
 319      function addMessageIdHeader()
 320      {
 321          require_once dirname(__FILE__) . '/../MIME.php';
 322          $this->addHeader('Message-ID', MIME::generateMessageID());
 323      }
 324  
 325      /**
 326       * Generate the 'Resent' headers (conforms to guidelines in
 327       * RFC 2822 [3.6.6]).
 328       *
 329       * @param string $from  The address to use for 'Resent-From'.
 330       * @param string $to    The address to use for 'Resent-To'.
 331       */
 332      function addResentHeaders($from, $to)
 333      {
 334          require_once dirname(__FILE__) . '/../MIME.php';
 335  
 336          /* We don't set Resent-Sender, Resent-Cc, or Resent-Bcc. */
 337          $this->addHeader('Resent-Date', date('r'));
 338          $this->addHeader('Resent-From', $from);
 339          $this->addHeader('Resent-To', $to);
 340          $this->addHeader('Resent-Message-ID', MIME::generateMessageID());
 341      }
 342  
 343      /**
 344       * Generate delivery receipt headers.
 345       *
 346       * @param string $to  The address the receipt should be mailed to.
 347       */
 348      function addDeliveryReceiptHeaders($to)
 349      {
 350          /* This is old sendmail (pre-8.7) behavior. */
 351          $this->addHeader('Return-Receipt-To', $to);
 352      }
 353  
 354      /**
 355       * Generate the user agent description header.
 356       */
 357      function addAgentHeader()
 358      {
 359          $this->addHeader('User-Agent', $this->_agent);
 360      }
 361  
 362      /**
 363       * Returns the user agent description header.
 364       *
 365       * @return string  The user agent header.
 366       */
 367      function getAgentHeader()
 368      {
 369          return $this->_agent;
 370      }
 371  
 372      /**
 373       * Add a header to the header array.
 374       *
 375       * @param string $header  The header name.
 376       * @param string $value   The header value.
 377       */
 378      function addHeader($header, $value)
 379      {
 380          $header = trim($header);
 381          $lcHeader = String::lower($header);
 382  
 383          if (!isset($this->_headers[$lcHeader])) {
 384              $this->_headers[$lcHeader] = array();
 385          }
 386          $this->_headers[$lcHeader]['header'] = $header;
 387          $this->_headers[$lcHeader]['value'] = $value;
 388          $this->_headers[$lcHeader]['_alter'] = false;
 389      }
 390  
 391      /**
 392       * Remove a header from the header array.
 393       *
 394       * @param string $header  The header name.
 395       */
 396      function removeHeader($header)
 397      {
 398          $header = trim($header);
 399          $lcHeader = String::lower($header);
 400          unset($this->_headers[$lcHeader]);
 401      }
 402  
 403      /**
 404       * Set a value for a particular header ONLY if that header is set.
 405       *
 406       * @param string $header  The header name.
 407       * @param string $value   The header value.
 408       *
 409       * @return boolean  True if value was set, false if not.
 410       */
 411      function setValue($header, $value)
 412      {
 413          $lcHeader = String::lower($header);
 414          if (isset($this->_headers[$lcHeader])) {
 415              $this->_headers[$lcHeader]['value'] = $value;
 416              $this->_headers[$lcHeader]['_alter'] = true;
 417              return true;
 418          } else {
 419              return false;
 420          }
 421      }
 422  
 423      /**
 424       * Attempts to return the header in the correct case.
 425       *
 426       * @param string $header  The header to search for.
 427       *
 428       * @return string  The value for the given header.
 429       *                 If the header is not found, returns null.
 430       */
 431      function getString($header)
 432      {
 433          $lcHeader = String::lower($header);
 434          return (isset($this->_headers[$lcHeader])) ? $this->_headers[$lcHeader]['header'] : null;
 435      }
 436  
 437      /**
 438       * Attempt to return the value for a given header.
 439       * The following header fields can only have 1 entry, so if duplicate
 440       * entries exist, the first value will be used:
 441       *   * To, From, Cc, Bcc, Date, Sender, Reply-to, Message-ID, In-Reply-To,
 442       *     References, Subject (RFC 2822 [3.6])
 443       *   * All List Headers (RFC 2369 [3])
 444       *
 445       * @param string $header  The header to search for.
 446       *
 447       * @return mixed  The value for the given header.
 448       *                If the header is not found, returns null.
 449       */
 450      function getValue($header)
 451      {
 452          $header = String::lower($header);
 453  
 454          if (isset($this->_headers[$header])) {
 455              $single = array('to', 'from', 'cc', 'bcc', 'date', 'sender',
 456                              'reply-to', 'message-id', 'in-reply-to',
 457                              'references', 'subject', 'x-priority');
 458              $single = array_merge($single, array_keys($this->listHeaders()));
 459              if (is_array($this->_headers[$header]['value']) &&
 460                  in_array($header, $single)) {
 461                  return $this->_headers[$header]['value'][0];
 462              } else {
 463                  return $this->_headers[$header]['value'];
 464              }
 465          } else {
 466              return null;
 467          }
 468      }
 469  
 470      /**
 471       * Has the header been altered from the original?
 472       *
 473       * @param string $header  The header to analyze.
 474       *
 475       * @return boolean  True if the header has been altered.
 476       */
 477      function alteredHeader($header)
 478      {
 479          $lcHeader = String::lower($header);
 480          return (isset($this->_headers[$lcHeader])) ? $this->_headers[$lcHeader]['_alter'] : false;
 481      }
 482  
 483      /**
 484       * Transforms a Header value using the list of functions provided.
 485       *
 486       * @param string $header  The header to alter.
 487       * @param mixed $funcs    A function, or an array of functions.
 488       *                        The functions will be performed from right to
 489       *                        left.
 490       */
 491      function setValueByFunction($header, $funcs)
 492      {
 493          $header = String::lower($header);
 494  
 495          if (is_array($funcs)) {
 496              $funcs = array_reverse($funcs);
 497          } else {
 498              $funcs = array($funcs);
 499          }
 500  
 501          if (isset($this->_headers[$header])) {
 502              $val = $this->getValue($header);
 503              if (is_array($val)) {
 504                  $val = implode("\n", $val);
 505              }
 506              foreach ($funcs as $func) {
 507                  $val = call_user_func($func, $val);
 508              }
 509              $this->setValue($header, $val);
 510          }
 511      }
 512  
 513      /**
 514       * Add any MIME headers required for the MIME_Part.
 515       *
 516       * @param MIME_Part &$mime_part  The MIME_Part object.
 517       */
 518      function addMIMEHeaders(&$mime_part)
 519      {
 520          foreach ($mime_part->header(array()) as $head => $val) {
 521              $this->addHeader($head, $val);
 522          }
 523      }
 524  
 525      /**
 526       * Return the list of addresses for a header object.
 527       *
 528       * @param array $obs  An array of header objects (See imap_headerinfo()
 529       *                    for the object structure).
 530       *
 531       * @return array  An array of objects.
 532       * <pre>
 533       * Object elements:
 534       * 'address'   -  Full address
 535       * 'host'      -  Host name
 536       * 'inner'     -  Trimmed, bare address
 537       * 'personal'  -  Personal string
 538       * </pre>
 539       */
 540      function getAddressesFromObject($obs)
 541      {
 542          $retArray = array();
 543  
 544          if (!is_array($obs) || empty($obs)) {
 545              return $retArray;
 546          }
 547  
 548          foreach ($obs as $ob) {
 549              /* Ensure we're working with initialized values. */
 550              if (isset($ob->personal)) {
 551                  $ob->personal = MIME::decode($ob->personal);
 552                  if ((substr($ob->personal, 0, 1) == '"') &&
 553                      (substr($ob->personal, -1) == '"')) {
 554                      $ob->personal = substr($ob->personal, 1, -1);
 555                  }
 556              } else {
 557                  $ob->personal = '';
 558              }
 559  
 560              if (isset($ob->mailbox)) {
 561                  /* Don't process invalid addresses. */
 562                  if (strpos($ob->mailbox, 'UNEXPECTED_DATA_AFTER_ADDRESS') !== false ||
 563                      strpos($ob->mailbox, 'INVALID_ADDRESS') !== false) {
 564                      continue;
 565                  }
 566              } else {
 567                  $ob->mailbox = '';
 568              }
 569  
 570              if (!isset($ob->host)) {
 571                  $ob->host = '';
 572              }
 573  
 574              /* Generate the new object. */
 575              $newOb = &new stdClass;
 576              $newOb->address = MIME::addrObject2String($ob, array('undisclosed-recipients@', 'Undisclosed recipients@'));
 577              $newOb->host = $ob->host;
 578              $newOb->inner = MIME::trimEmailAddress(MIME::rfc822WriteAddress($ob->mailbox, $ob->host, ''));
 579              $newOb->personal = $ob->personal;
 580  
 581              $retArray[] = &$newOb;
 582          }
 583  
 584          return $retArray;
 585      }
 586  
 587      /**
 588       * Returns the list of valid mailing list headers.
 589       *
 590       * @return array  The list of valid mailing list headers.
 591       */
 592      function listHeaders()
 593      {
 594          return array(
 595              /* RFC 2369 */
 596              'list-help'         =>  _("List-Help"),
 597              'list-unsubscribe'  =>  _("List-Unsubscribe"),
 598              'list-subscribe'    =>  _("List-Subscribe"),
 599              'list-owner'        =>  _("List-Owner"),
 600              'list-post'         =>  _("List-Post"),
 601              'list-archive'      =>  _("List-Archive"),
 602              /* RFC 2919 */
 603              'list-id'           =>  _("List-Id")
 604          );
 605      }
 606  
 607      /**
 608       * Do any mailing list headers exist?
 609       *
 610       * @return boolean  True if any mailing list headers exist.
 611       */
 612      function listHeadersExist()
 613      {
 614          foreach ($this->listHeaders() as $val => $str) {
 615              if (isset($this->_headers[$val])) {
 616                  return true;
 617              }
 618          }
 619  
 620          return false;
 621      }
 622  
 623      /**
 624       * Sets a new string to use for EOLs.
 625       *
 626       * @param string $eol  The string to use for EOLs.
 627       */
 628      function setEOL($eol)
 629      {
 630          $this->_eol = $eol;
 631      }
 632  
 633      /**
 634       * Get the string to use for EOLs.
 635       *
 636       * @return string  The string to use for EOLs.
 637       */
 638      function getEOL()
 639      {
 640          return $this->_eol;
 641      }
 642  
 643      /**
 644       * Returns the flag status.
 645       *
 646       * @param string $flag  Is this flag set?
 647       *                      Flags: recent, unseen, answered, draft, important,
 648       *                             deleted
 649       *
 650       * @return boolean  True if the flag has been set, false if not.
 651       */
 652      function getFlag($flag)
 653      {
 654          if (!empty($this->_flags[String::lower($flag)])) {
 655              return true;
 656          } else {
 657              return false;
 658          }
 659      }
 660  
 661      /**
 662       * Get the primary from address (first address in the From: header).
 663       *
 664       * @return string  The from address (user@host).
 665       */
 666      function getFromAddress()
 667      {
 668          if (!($ob = $this->getOb('from'))) {
 669              return null;
 670          }
 671  
 672          require_once 'Horde/MIME.php';
 673  
 674          return trim(MIME::trimEmailAddress(MIME::rfc822WriteAddress($ob[0]->mailbox, (isset($ob[0]->host)) ? $ob[0]->host : '', '')));
 675      }
 676  
 677      /**
 678       * Get a header from the header object.
 679       *
 680       * @todo Replace with getOb() from IMP's IMP_Headers for Horde 4.0.
 681       *
 682       * @param string $field    The object field to retrieve (see
 683       *                         imap_headerinfo() for the list of fields).
 684       * @param boolean $decode  Should the return value be MIME decoded?
 685       *                         It will only be decoded if it is not an object
 686       *                         itself.
 687       *
 688       * @return mixed  The field requested.
 689       */
 690      function getOb($field, $decode = false)
 691      {
 692          $data = array();
 693  
 694          $ob = $this->getHeaderObject();
 695          if (!is_object($ob)) {
 696              return $data;
 697          }
 698  
 699          if (isset($ob->$field)) {
 700              $data = $ob->$field;
 701              if (!empty($decode) && !is_object($data) && !is_array($data)) {
 702                  include_once 'Horde/MIME.php';
 703                  if (!empty($GLOBALS['mime_headers']['default_charset'])) {
 704                      $data = String::convertCharset($data, $GLOBALS['mime_headers']['default_charset']);
 705                  }
 706                  $data = MIME::decode($data);
 707              }
 708          }
 709  
 710          return (is_string($data)) ? strtr($data, "\t", ' ') : $data;
 711      }
 712  
 713  }


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