[ Index ] |
|
Code source de IMP H3 (4.1.5) |
1 <?php 2 3 require_once 'Horde/MIME/Contents.php'; 4 // TODO: for BC - Remove for Horde 4.0 5 require IMP_BASE . '/config/mime_drivers.php'; 6 7 /** 8 * The IMP_Contents:: class extends the MIME_Contents:: class and contains 9 * all functions related to handling the content and output of mail messages 10 * in IMP. 11 * 12 * $Horde: imp/lib/MIME/Contents.php,v 1.153.4.45 2007/08/07 19:53:40 slusarz Exp $ 13 * 14 * Copyright 2002-2007 Michael Slusarz <slusarz@bigworm.colorado.edu> 15 * 16 * See the enclosed file COPYING for license information (GPL). If you 17 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. 18 * 19 * @author Michael Slusarz <slusarz@bigworm.colorado.edu> 20 * @since IMP 4.0 21 * @package IMP 22 */ 23 class IMP_Contents extends MIME_Contents { 24 25 /** 26 * The text of the body of the message. 27 * 28 * @var string 29 */ 30 var $_body = ''; 31 32 /** 33 * The MIME part id of the message body. 34 * 35 * @var integer 36 */ 37 var $_body_id; 38 39 /** 40 * The text of various MIME body parts. 41 * 42 * @var array 43 */ 44 var $_bodypart = array(); 45 46 /** 47 * The IMAP index of the message. 48 * 49 * @var integer 50 */ 51 var $_index; 52 53 /** 54 * The mailbox of the current message. 55 * 56 * @var string 57 */ 58 var $_mailbox; 59 60 /** 61 * Should attachment stripping links be generated? 62 * 63 * @var boolean 64 */ 65 var $_strip = false; 66 67 /** 68 * Attempts to return a reference to a concrete IMP_Contents instance. 69 * If an IMP_Contents object is currently stored in the local cache, 70 * recreate that object. Else, create a new instance. 71 * Ensures that only one IMP_Contents instance for any given message is 72 * available at any one time. 73 * 74 * This method must be invoked as: 75 * $imp_contents = &IMP_Contents::singleton($index); 76 * 77 * @param string $index The IMAP message mailbox/index. The index should 78 * be in the following format: 79 * <pre> 80 * msg_id IMP_IDX_SEP msg_folder 81 * msg_id = Message index of the message 82 * IMP_IDX_SEP = IMP constant used to separate index/folder 83 * msg_folder = The full folder name containing the message index 84 * </pre> 85 * 86 * @return IMP_Contents The IMP_Contents object or null. 87 */ 88 function &singleton($index) 89 { 90 static $instance = array(); 91 92 $signature = IMP_Contents::_createCacheID($index); 93 if (isset($instance[$signature])) { 94 return $instance[$signature]; 95 } 96 97 $instance[$signature] = &IMP_Contents::getCache($signature); 98 if (empty($instance[$signature])) { 99 $instance[$signature] = &new IMP_Contents($index); 100 } 101 102 return $instance[$signature]; 103 } 104 105 /** 106 * Constructor 107 * 108 * @param mixed $in Either an index string (see IMP_Contents::singleton() 109 * for the format) or a MIME_Message object. 110 */ 111 function IMP_Contents($in) 112 { 113 if (is_a($in, 'MIME_Message')) { 114 $ob = $in; 115 } else { 116 list($this->_index, $this->_mailbox) = explode(IMP_IDX_SEP, $in); 117 118 /* Get the MIME_Structure object for the given index. */ 119 require_once IMP_BASE . '/lib/IMAP.php'; 120 $imp_imap = &IMP_IMAP::singleton(); 121 $imp_imap->changeMbox($this->_mailbox); 122 $structure = @imap_fetchstructure($_SESSION['imp']['stream'], $this->_index, FT_UID); 123 if (!is_object($structure)) { 124 return; 125 } 126 require_once 'Horde/MIME/Structure.php'; 127 $ob = &MIME_Structure::parse($structure); 128 } 129 130 switch ($GLOBALS['prefs']->getValue('attachment_display')) { 131 case 'list': 132 $this->_displayType = MIME_CONTENTS_DISPLAY_TYPE_LIST; 133 break; 134 135 case 'inline': 136 $this->_displayType = MIME_CONTENTS_DISPLAY_TYPE_INLINE; 137 break; 138 139 case 'both': 140 $this->_displayType = MIME_CONTENTS_DISPLAY_TYPE_BOTH; 141 break; 142 } 143 144 parent::MIME_Contents($ob, array('download' => 'download_attach', 'view' => 'view_attach')); 145 } 146 147 /** 148 * Returns the entire body of the message. 149 * 150 * @return string The text of the body of the message. 151 */ 152 function getBody() 153 { 154 if (empty($this->_body)) { 155 $this->_body = @imap_body($_SESSION['imp']['stream'], $this->_index, FT_UID | FT_PEEK); 156 $this->_body = str_replace("\r\n", "\n", $this->_body); 157 } 158 159 return $this->_body; 160 } 161 162 /** 163 * Gets the raw text for one section of the message. 164 * 165 * @param integer $id The ID of the MIME_Part. 166 * 167 * @return string The text of the part. 168 */ 169 function getBodyPart($id) 170 { 171 if (!isset($this->_bodypart[$id])) { 172 $this->_bodypart[$id] = @imap_fetchbody($_SESSION['imp']['stream'], $this->_index, $id, FT_UID | FT_PEEK); 173 $this->_bodypart[$id] = str_replace("\r\n", "\n", $this->_bodypart[$id]); 174 } 175 176 return isset($this->_bodypart[$id]) ? $this->_bodypart[$id] : ''; 177 } 178 179 /** 180 * Allow attachments to be stripped by providing a link in summary view? 181 * 182 * @param boolean $strip Should the strip links be generated? 183 */ 184 function setStripLink($strip = false) 185 { 186 $this->_strip = $strip; 187 } 188 189 /** 190 * Returns an array summarizing a part of a MIME message. 191 * 192 * @param MIME_Part &$mime_part See MIME_Contents::partSummary(). 193 * @param boolean $guess See MIME_Contents::partSummary(). 194 * 195 * @return array See MIME_Contents::partSummary(). 196 * Adds the following key to that return: 197 * [6] = Compressed Download Link 198 * [7] = Image Save link (if allowed) 199 * [8] = Strip Attachment Link (if allowed) 200 */ 201 function partSummary(&$mime_part, $guess = false) 202 { 203 global $conf, $registry; 204 205 $summary = parent::partSummary($mime_part, $guess); 206 207 /* Don't add extra links if not requested or if this is a guessed 208 part. */ 209 if ($guess || !$this->_links) { 210 return $summary; 211 } 212 213 /* Display the compressed download link only if size is greater 214 than 200 KB. */ 215 if (($mime_part->getBytes() > 204800) && 216 Util::extensionExists('zlib') && 217 ($mime_part->getType() != 'application/zip') && 218 ($mime_part->getType() != 'application/x-zip-compressed')) { 219 $summary[] = $this->linkView($mime_part, 'download_attach', Horde::img('compressed.png', _("Download in .zip Format"), null, $registry->getImageDir('horde') . '/mime'), array('jstext' => sprintf(_("Download %s in .zip Format"), $mime_part->getDescription(true, true)), 'viewparams' => array('zip' => 1)), true); 220 } else { 221 $summary[] = null; 222 } 223 224 /* Display the image save link if the required registry calls are 225 * present. */ 226 if (($mime_part->getPrimaryType() == 'image') && 227 $registry->hasMethod('images/selectGalleries') && 228 ($image_app = $registry->hasMethod('images/saveImage'))) { 229 Horde::addScriptFile('popup.js'); 230 $url = Util::addParameter(Horde::applicationUrl('saveimage.php'), array('index' => ($this->_index . IMP_IDX_SEP . $this->_mailbox), 'id' => $mime_part->getMIMEId())); 231 $summary[] = Horde::link('#', _("Save Image in Gallery"), null, null, "popup_imp('" . $url . "',450,200); return false;") . '<img src="' . $registry->get('icon', $image_app) . '" alt="' . _("Save Image in Gallery") . '" title="' . _("Save Image in Gallery") . '" /></a>'; 232 } else { 233 $summary[] = null; 234 } 235 236 /* Strip the Attachment? */ 237 if ($this->_strip && 238 !$mime_part->getInformation('rfc822_part')) { 239 $url = Horde::selfUrl(true); 240 $url = Util::removeParameter($url, array('actionID', 'imapid', 'index')); 241 $url = Util::addParameter($url, array('actionID' => 'strip_attachment', 'imapid' => $this->_getMIMEKey($mime_part, false), 'index' => $this->getMessageIndex())); 242 $summary[] = Horde::link($url, _("Strip Attachment"), null, null, "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete this attachment?")) . "');") . Horde::img('delete.png', _("Strip Attachment"), null, $registry->getImageDir('horde')) . '</a>'; 243 } else { 244 $summary[] = null; 245 } 246 247 return $summary; 248 } 249 250 /** 251 * Return the URL to the view.php page. 252 * 253 * @param MIME_Part &$mime_part See MIME_Contents::urlView(). 254 * @param integer $actionID See MIME_Contents::urlView(). 255 * @param array $params See MIME_Contents::urlView(). 256 * @param boolean $dload See MIME_Contents::urlView(). 257 * The following parameter names will be overwritten by this function: 258 * id, index, mailbox 259 * 260 * @return string The URL to view.php. 261 */ 262 function urlView(&$mime_part, $actionID, $params = array(), $dload = false) 263 { 264 require_once IMP_BASE . '/lib/Search.php'; 265 266 /* Add the necessary local parameters. */ 267 $params = array_merge($params, IMP::getSearchParameters($_SESSION['imp']['thismailbox'])); 268 $params['index'] = $this->_index; 269 if (!isset($params['mailbox'])) { 270 $params['mailbox'] = $_SESSION['imp']['mailbox']; 271 } 272 273 /* Should this be a download link? */ 274 $dload = (($actionID == 'download_attach') || 275 ($actionID == 'download_render') || 276 ($actionID == 'save_message')); 277 278 return parent::urlView($mime_part, $actionID, $params, $dload); 279 } 280 281 /** 282 * Generate a link to the view.php page. 283 * 284 * @param MIME_Part &$mime_part See MIME_Contents::linkView(). 285 * @param integer $actionID See MIME_Contents::linkView(). 286 * @param string $text See MIME_Contents::linkView(). 287 * @param array $params See MIME_Contents::linkView(). 288 * 289 * @return string See MIME_Contents::linkView(). 290 */ 291 function linkView(&$mime_part, $actionID, $text, $params = array()) 292 { 293 if ($mime_part->getInformation('actionID')) { 294 $actionID = $mime_part->getInformation('actionID'); 295 } 296 297 /* If this is a 'download_attach or 'download_render' link, we do not 298 want to show in a new window. */ 299 $dload = (($actionID == 'download_attach') || 300 ($actionID == 'download_render')); 301 302 /* If download attachment, add the 'thismailbox' param. */ 303 if ($actionID == 'download_attach') { 304 $params['viewparams']['thismailbox'] = $_SESSION['imp']['thismailbox']; 305 } 306 307 if ($mime_part->getInformation('viewparams')) { 308 foreach ($mime_part->getInformation('viewparams') as $key => $val) { 309 $params['viewparams'][$key] = $val; 310 } 311 } 312 313 return parent::linkView($mime_part, $actionID, $text, $params, $dload); 314 } 315 316 /** 317 * Returns the full message text. 318 * 319 * @return string The full message text. 320 */ 321 function fullMessageText() 322 { 323 $imp_headers = &$this->getHeaderOb(); 324 return $imp_headers->getHeaderText() . $this->getBody(); 325 } 326 327 /** 328 * Returns the header object. 329 * 330 * @return IMP_Headers The IMP_Headers object. 331 */ 332 function &getHeaderOb() 333 { 334 require_once IMP_BASE . '/lib/MIME/Headers.php'; 335 $imp_headers = &new IMP_Headers($this->_index); 336 return $imp_headers; 337 } 338 339 /** 340 * Returns the IMAP index for the current message. 341 * 342 * @return integer The message index. 343 */ 344 function getMessageIndex() 345 { 346 return $this->_index; 347 } 348 349 /** 350 * Rebuild the MIME_Part structure of a message from IMAP data. 351 * This will store IMAP data in all parts of the message - for example, 352 * all data for a multipart/mixed part will be stored in the base part, 353 * and each part will contain its own data. Note that if you want to 354 * build a message string from the MIME_Part data after calling 355 * rebuildMessage(), you should use IMP_Contents::toString() instead of 356 * MIME_Part::toString(). 357 * 358 * @return MIME_Message A MIME_Message object with all of the body text 359 * stored in the individual MIME_Parts. 360 */ 361 function rebuildMessage() 362 { 363 $part = $this->_message->getBasePart(); 364 $this->_rebuildMessage($part); 365 return $this->_message; 366 } 367 368 /** 369 * Recursive function used to rebuild the MIME_Part structure of a 370 * message. 371 * 372 * @access private 373 * 374 * @param MIME_Part $part A MIME_Part object. 375 */ 376 function _rebuildMessage($part) 377 { 378 $id = $part->getMIMEId(); 379 380 $mime_part = $this->getMIMEPart($id); 381 $this->_setContents($mime_part, true); 382 if ($this->_message->getPart($id) === $this->_message) { 383 $this->_message = &$mime_part; 384 } else { 385 $this->_message->alterPart($id, $mime_part); 386 } 387 388 if ($part->getPrimaryType() == 'multipart') { 389 /* Recursively process any subparts. */ 390 foreach ($part->getParts() as $mime) { 391 $this->_rebuildMessage($mime); 392 } 393 } 394 } 395 396 /** 397 * Render a MIME Part. 398 * 399 * @param MIME_Part &$mime_part A MIME_Part object. 400 * 401 * @return string The rendered data. 402 */ 403 function renderMIMEPart(&$mime_part) 404 { 405 $this->_setContents($mime_part); 406 $text = parent::renderMIMEPart($mime_part); 407 408 /* Convert textual emoticons into graphical ones - but only for 409 * text parts. */ 410 if (($mime_part->getPrimaryType() == 'text') && 411 $GLOBALS['prefs']->getValue('emoticons')) { 412 require_once 'Horde/Text/Filter.php'; 413 $text = Text_Filter::filter($text, 'emoticons', array('entities' => true)); 414 } 415 416 return $text; 417 } 418 419 /** 420 * Saves a copy of the MIME_Contents object at the end of a request. 421 * 422 * @access private 423 */ 424 function _addCacheShutdown() 425 { 426 /* Don't cache the $_bodypart array since we most likely will not use 427 * them in the cached object (since the cache will generally be used 428 * to view parts that weren't displayed originally). 429 * However, we will lose the benefit of not having to 430 * make calls to the mail server on subsequent page loads, so allow 431 * users to change this behavior. Only cache small messages as 432 * storing large messages will make the session size too large and 433 * will tax storage and performance on the server. */ 434 if (empty($GLOBALS['conf']['server']['cache_msgbody'])) { 435 $this->_bodypart = array(); 436 } else { 437 $size = 0; 438 foreach ($this->_bodypart as $key => $val) { 439 $part_size = strlen($val); 440 if (($size + $part_size) < 10240) { 441 $size += $part_size; 442 } else { 443 unset($this->_bodypart[$key]); 444 } 445 } 446 } 447 448 /* Never cache the full body part as we use this item much less 449 * often than specific message body parts. */ 450 $this->_body = null; 451 452 parent::_addCacheShutdown(); 453 } 454 455 /** 456 * Get the from address of the message. 457 * 458 * @return string The from address of the message. 459 */ 460 function getFromAddress() 461 { 462 require_once IMP_BASE . '/lib/MIME/Headers.php'; 463 $headers = &new IMP_Headers($this->getMessageIndex()); 464 return $headers->getFromAddress(); 465 } 466 467 /** 468 * Generate the list of MIME IDs to use for download all. 469 * 470 * @param boolean $forward Generate a list of items that can be forwarded, 471 * rather than downloaded. 472 * 473 * @return array The list of MIME IDs that should be downloaded when 474 * downloading all attachments. 475 */ 476 function getDownloadAllList($forward = false) 477 { 478 $downloads = array(); 479 480 $bodyid = $this->findBody(); 481 482 /* Here is what we consider 'forwardable': 483 * All parts > 0 484 * Part 0 if not multipart/mixed 485 * NOT the body part (if one exists) 486 * 487 * Here is what we consider 'downloadable': 488 * All parts not 'multipart/*' and 'message/*' except for 489 * 'message/rfc822' 490 * All parts that are not PGP or S/MIME signature information 491 * NOT the body part (if one exists) */ 492 foreach ($this->_message->contentTypeMap() as $key => $val) { 493 if ($key == $bodyid) { 494 continue; 495 } 496 497 if ($forward) { 498 if ($key == 0) { 499 if ($val != 'multipart/mixed') { 500 $downloads[] = $key; 501 break; 502 } 503 } elseif (strpos($key, '.') === false) { 504 $downloads[] = $key; 505 } 506 } else { 507 if (strpos($val, 'message/') === 0) { 508 if (strpos($val, 'message/rfc822') === 0) { 509 $downloads[] = $key; 510 } 511 } elseif (((intval($key) != 1) && (strpos($val, '1.') === false)) && 512 ((strpos($val, 'multipart/') === false)) && 513 (strpos($val, 'application/x-pkcs7-signature') === false) && 514 (strpos($val, 'application/pkcs7-signature') === false)) { 515 $downloads[] = $key; 516 } 517 } 518 } 519 520 return $downloads; 521 } 522 523 /** 524 * Generate a download all link, if possible. 525 * 526 * @return string The download link. 527 */ 528 function getDownloadAllLink() 529 { 530 $url = null; 531 532 $downloads_list = $this->getDownloadAllList(); 533 if (!empty($downloads_list)) { 534 /* Create a dummy variable to pass to urlView() since we don't 535 have a MIME_Part and we can't pass null by reference. */ 536 $dummy = 0; 537 $url = $this->urlView($dummy, 'download_all', array('id' => 1)); 538 $url = Util::removeParameter($url, array('id')); 539 } 540 541 return $url; 542 } 543 544 /** 545 * Prints out the status message for a given MIME Part. 546 * 547 * @param mixed $msg See MIME_Contents::formatStatusMsg(). 548 * @param string $img See MIME_Contents::formatStatusMsg(). 549 * @param boolean $print Output this message when in a print view? 550 * 551 * @return string The formatted status message. 552 */ 553 function formatStatusMsg($msg, $img = null, $printable = true) 554 { 555 if (!$printable && IMP::printMode()) { 556 return ''; 557 } else { 558 return parent::formatStatusMsg($msg, $img); 559 } 560 } 561 562 /** 563 * Finds the main "body" text part (if any) in a message. 564 * "Body" data is the first text part in the base MIME part. 565 * 566 * @return string The MIME ID of the main "body" part. 567 */ 568 function findBody() 569 { 570 if (isset($this->_body_id)) { 571 return $this->_body_id; 572 } 573 574 if (!is_null($this->_message)) { 575 /* Look for potential body parts. */ 576 $part = $this->_message->getBasePart(); 577 $primary_type = $part->getPrimaryType(); 578 if (($primary_type == MIME::type(TYPEMULTIPART)) || 579 ($primary_type == MIME::type(TYPETEXT))) { 580 $this->_body_id = $this->_findBody($part); 581 return $this->_body_id; 582 } 583 } 584 585 return null; 586 } 587 588 /** 589 * Processes a MIME Part and looks for "body" data. 590 * 591 * @access private 592 * 593 * @return string The MIME ID of the main "body" part. 594 */ 595 function _findBody($mime_part) 596 { 597 if (intval($mime_part->getMIMEId()) < 2 || 598 $mime_part->getInformation('alternative') === 0) { 599 if ($mime_part->getPrimaryType() == MIME::type(TYPEMULTIPART)) { 600 foreach ($mime_part->getParts() as $part) { 601 if (($partid = $this->_findBody($part))) { 602 return $partid; 603 } 604 } 605 } elseif ($mime_part->getPrimaryType() == MIME::type(TYPETEXT)) { 606 if ($mime_part->getBytes() || 607 $this->getBodyPart($mime_part->getMIMEId())) { 608 return $mime_part->getMIMEId(); 609 } 610 } 611 } 612 613 return null; 614 } 615 616 /** 617 * Creates a unique cache ID for this object. 618 * 619 * @access private 620 * 621 * @param integer $index The IMAP index of the current message. 622 * 623 * @return string A unique cache ID. 624 */ 625 function _createCacheID($index = null) 626 { 627 if (is_null($index)) { 628 if (isset($this)) { 629 $index = $this->_index; 630 } else { 631 return parent::_createCacheID(); 632 } 633 } 634 return md5(implode('|', array($index, $_SESSION['imp']['thismailbox']))); 635 } 636 637 /** 638 * Make sure the contents of the current part are set from IMAP server 639 * data. 640 * 641 * @access private 642 * @since IMP 3.1 643 * 644 * @param MIME_Part &$mime_part The MIME_Part object to work with. 645 * @param boolean $all Download the entire parts contents? 646 */ 647 function _setContents(&$mime_part, $all = false) 648 { 649 if (!$mime_part->getInformation('imp_contents_set') && 650 !$mime_part->getContents()) { 651 $id = $mime_part->getMIMEId(); 652 if ($all && ($mime_part->getType() == 'message/rfc822')) { 653 $id = substr($mime_part->getMIMEId(), 0, -2); 654 } 655 $mime_part->setContents($this->getBodyPart($id)); 656 } 657 $mime_part->setInformation('imp_contents_set', true); 658 } 659 660 /** 661 * Fetch part of a MIME message. 662 * 663 * @since IMP 3.1 664 * 665 * @param integer $id The MIME ID of the part requested. 666 * @param boolean $all If this is a header part, should we return all text 667 * in the body? 668 * 669 * @return MIME_Part The MIME_Part. 670 */ 671 function &getRawMIMEPart($id, $all = false) 672 { 673 $mime_part = $this->getMIMEPart($id); 674 if (!is_a($mime_part, 'MIME_Part')) { 675 $mime_part = null; 676 return $mime_part; 677 } 678 $this->_setContents($mime_part, true); 679 return $mime_part; 680 } 681 682 /** 683 * Create a message string from a MIME message that has used 684 * rebuildMessage() to build the data from the IMAP server. 685 * 686 * @since IMP 4.1 687 * 688 * @param MIME_Message $message A MIME_Message object. 689 * @param boolean $canonical Return a canonical string? 690 * 691 * @return string The contents of the MIME_Message object. 692 */ 693 function toString($message, $canonical = false) 694 { 695 $text = ''; 696 697 $part = $message->getBasePart(); 698 foreach ($part->contentTypeMap() as $key => $val) { 699 if (($key != 0) && (strpos($val, 'multipart/') === 0)) { 700 $old = $part->getPart($key); 701 $old->setContents(''); 702 $part->alterPart($key, $old); 703 } 704 } 705 706 if ($message->getMIMEId() == 0) { 707 $part->setContents(''); 708 } 709 710 return ($canonical) ? $part->toCanonicalString() : $part->toString(); 711 } 712 713 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 12:30:07 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |