| [ Index ] |
|
Code source de Horde 3.1.3 |
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 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |