1<?php 2 3/* 4 * This file is part of SwiftMailer. 5 * (c) 2004-2009 Chris Corbyn 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11/** 12 * The default email message class. 13 * 14 * @author Chris Corbyn 15 */ 16class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart implements Swift_Mime_Message 17{ 18 const PRIORITY_HIGHEST = 1; 19 const PRIORITY_HIGH = 2; 20 const PRIORITY_NORMAL = 3; 21 const PRIORITY_LOW = 4; 22 const PRIORITY_LOWEST = 5; 23 24 /** 25 * Create a new SimpleMessage with $headers, $encoder and $cache. 26 * 27 * @param Swift_Mime_HeaderSet $headers 28 * @param Swift_Mime_ContentEncoder $encoder 29 * @param Swift_KeyCache $cache 30 * @param Swift_Mime_Grammar $grammar 31 * @param string $charset 32 */ 33 public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $charset = null) 34 { 35 parent::__construct($headers, $encoder, $cache, $grammar, $charset); 36 $this->getHeaders()->defineOrdering(array( 37 'Return-Path', 38 'Received', 39 'DKIM-Signature', 40 'DomainKey-Signature', 41 'Sender', 42 'Message-ID', 43 'Date', 44 'Subject', 45 'From', 46 'Reply-To', 47 'To', 48 'Cc', 49 'Bcc', 50 'MIME-Version', 51 'Content-Type', 52 'Content-Transfer-Encoding', 53 )); 54 $this->getHeaders()->setAlwaysDisplayed(array('Date', 'Message-ID', 'From')); 55 $this->getHeaders()->addTextHeader('MIME-Version', '1.0'); 56 $this->setDate(time()); 57 $this->setId($this->getId()); 58 $this->getHeaders()->addMailboxHeader('From'); 59 } 60 61 /** 62 * Always returns {@link LEVEL_TOP} for a message instance. 63 * 64 * @return int 65 */ 66 public function getNestingLevel() 67 { 68 return self::LEVEL_TOP; 69 } 70 71 /** 72 * Set the subject of this message. 73 * 74 * @param string $subject 75 * 76 * @return $this 77 */ 78 public function setSubject($subject) 79 { 80 if (!$this->_setHeaderFieldModel('Subject', $subject)) { 81 $this->getHeaders()->addTextHeader('Subject', $subject); 82 } 83 84 return $this; 85 } 86 87 /** 88 * Get the subject of this message. 89 * 90 * @return string 91 */ 92 public function getSubject() 93 { 94 return $this->_getHeaderFieldModel('Subject'); 95 } 96 97 /** 98 * Set the date at which this message was created. 99 * 100 * @param int $date 101 * 102 * @return $this 103 */ 104 public function setDate($date) 105 { 106 if (!$this->_setHeaderFieldModel('Date', $date)) { 107 $this->getHeaders()->addDateHeader('Date', $date); 108 } 109 110 return $this; 111 } 112 113 /** 114 * Get the date at which this message was created. 115 * 116 * @return int 117 */ 118 public function getDate() 119 { 120 return $this->_getHeaderFieldModel('Date'); 121 } 122 123 /** 124 * Set the return-path (the bounce address) of this message. 125 * 126 * @param string $address 127 * 128 * @return $this 129 */ 130 public function setReturnPath($address) 131 { 132 if (!$this->_setHeaderFieldModel('Return-Path', $address)) { 133 $this->getHeaders()->addPathHeader('Return-Path', $address); 134 } 135 136 return $this; 137 } 138 139 /** 140 * Get the return-path (bounce address) of this message. 141 * 142 * @return string 143 */ 144 public function getReturnPath() 145 { 146 return $this->_getHeaderFieldModel('Return-Path'); 147 } 148 149 /** 150 * Set the sender of this message. 151 * 152 * This does not override the From field, but it has a higher significance. 153 * 154 * @param string $address 155 * @param string $name optional 156 * 157 * @return $this 158 */ 159 public function setSender($address, $name = null) 160 { 161 if (!is_array($address) && isset($name)) { 162 $address = array($address => $name); 163 } 164 165 if (!$this->_setHeaderFieldModel('Sender', (array) $address)) { 166 $this->getHeaders()->addMailboxHeader('Sender', (array) $address); 167 } 168 169 return $this; 170 } 171 172 /** 173 * Get the sender of this message. 174 * 175 * @return string 176 */ 177 public function getSender() 178 { 179 return $this->_getHeaderFieldModel('Sender'); 180 } 181 182 /** 183 * Add a From: address to this message. 184 * 185 * If $name is passed this name will be associated with the address. 186 * 187 * @param string $address 188 * @param string $name optional 189 * 190 * @return $this 191 */ 192 public function addFrom($address, $name = null) 193 { 194 $current = $this->getFrom(); 195 $current[$address] = $name; 196 197 return $this->setFrom($current); 198 } 199 200 /** 201 * Set the from address of this message. 202 * 203 * You may pass an array of addresses if this message is from multiple people. 204 * 205 * If $name is passed and the first parameter is a string, this name will be 206 * associated with the address. 207 * 208 * @param string|array $addresses 209 * @param string $name optional 210 * 211 * @return $this 212 */ 213 public function setFrom($addresses, $name = null) 214 { 215 if (!is_array($addresses) && isset($name)) { 216 $addresses = array($addresses => $name); 217 } 218 219 if (!$this->_setHeaderFieldModel('From', (array) $addresses)) { 220 $this->getHeaders()->addMailboxHeader('From', (array) $addresses); 221 } 222 223 return $this; 224 } 225 226 /** 227 * Get the from address of this message. 228 * 229 * @return mixed 230 */ 231 public function getFrom() 232 { 233 return $this->_getHeaderFieldModel('From'); 234 } 235 236 /** 237 * Add a Reply-To: address to this message. 238 * 239 * If $name is passed this name will be associated with the address. 240 * 241 * @param string $address 242 * @param string $name optional 243 * 244 * @return $this 245 */ 246 public function addReplyTo($address, $name = null) 247 { 248 $current = $this->getReplyTo(); 249 $current[$address] = $name; 250 251 return $this->setReplyTo($current); 252 } 253 254 /** 255 * Set the reply-to address of this message. 256 * 257 * You may pass an array of addresses if replies will go to multiple people. 258 * 259 * If $name is passed and the first parameter is a string, this name will be 260 * associated with the address. 261 * 262 * @param mixed $addresses 263 * @param string $name optional 264 * 265 * @return $this 266 */ 267 public function setReplyTo($addresses, $name = null) 268 { 269 if (!is_array($addresses) && isset($name)) { 270 $addresses = array($addresses => $name); 271 } 272 273 if (!$this->_setHeaderFieldModel('Reply-To', (array) $addresses)) { 274 $this->getHeaders()->addMailboxHeader('Reply-To', (array) $addresses); 275 } 276 277 return $this; 278 } 279 280 /** 281 * Get the reply-to address of this message. 282 * 283 * @return string 284 */ 285 public function getReplyTo() 286 { 287 return $this->_getHeaderFieldModel('Reply-To'); 288 } 289 290 /** 291 * Add a To: address to this message. 292 * 293 * If $name is passed this name will be associated with the address. 294 * 295 * @param string $address 296 * @param string $name optional 297 * 298 * @return $this 299 */ 300 public function addTo($address, $name = null) 301 { 302 $current = $this->getTo(); 303 $current[$address] = $name; 304 305 return $this->setTo($current); 306 } 307 308 /** 309 * Set the to addresses of this message. 310 * 311 * If multiple recipients will receive the message an array should be used. 312 * Example: array('receiver@domain.org', 'other@domain.org' => 'A name') 313 * 314 * If $name is passed and the first parameter is a string, this name will be 315 * associated with the address. 316 * 317 * @param mixed $addresses 318 * @param string $name optional 319 * 320 * @return $this 321 */ 322 public function setTo($addresses, $name = null) 323 { 324 if (!is_array($addresses) && isset($name)) { 325 $addresses = array($addresses => $name); 326 } 327 328 if (!$this->_setHeaderFieldModel('To', (array) $addresses)) { 329 $this->getHeaders()->addMailboxHeader('To', (array) $addresses); 330 } 331 332 return $this; 333 } 334 335 /** 336 * Get the To addresses of this message. 337 * 338 * @return array 339 */ 340 public function getTo() 341 { 342 return $this->_getHeaderFieldModel('To'); 343 } 344 345 /** 346 * Add a Cc: address to this message. 347 * 348 * If $name is passed this name will be associated with the address. 349 * 350 * @param string $address 351 * @param string $name optional 352 * 353 * @return $this 354 */ 355 public function addCc($address, $name = null) 356 { 357 $current = $this->getCc(); 358 $current[$address] = $name; 359 360 return $this->setCc($current); 361 } 362 363 /** 364 * Set the Cc addresses of this message. 365 * 366 * If $name is passed and the first parameter is a string, this name will be 367 * associated with the address. 368 * 369 * @param mixed $addresses 370 * @param string $name optional 371 * 372 * @return $this 373 */ 374 public function setCc($addresses, $name = null) 375 { 376 if (!is_array($addresses) && isset($name)) { 377 $addresses = array($addresses => $name); 378 } 379 380 if (!$this->_setHeaderFieldModel('Cc', (array) $addresses)) { 381 $this->getHeaders()->addMailboxHeader('Cc', (array) $addresses); 382 } 383 384 return $this; 385 } 386 387 /** 388 * Get the Cc address of this message. 389 * 390 * @return array 391 */ 392 public function getCc() 393 { 394 return $this->_getHeaderFieldModel('Cc'); 395 } 396 397 /** 398 * Add a Bcc: address to this message. 399 * 400 * If $name is passed this name will be associated with the address. 401 * 402 * @param string $address 403 * @param string $name optional 404 * 405 * @return $this 406 */ 407 public function addBcc($address, $name = null) 408 { 409 $current = $this->getBcc(); 410 $current[$address] = $name; 411 412 return $this->setBcc($current); 413 } 414 415 /** 416 * Set the Bcc addresses of this message. 417 * 418 * If $name is passed and the first parameter is a string, this name will be 419 * associated with the address. 420 * 421 * @param mixed $addresses 422 * @param string $name optional 423 * 424 * @return $this 425 */ 426 public function setBcc($addresses, $name = null) 427 { 428 if (!is_array($addresses) && isset($name)) { 429 $addresses = array($addresses => $name); 430 } 431 432 if (!$this->_setHeaderFieldModel('Bcc', (array) $addresses)) { 433 $this->getHeaders()->addMailboxHeader('Bcc', (array) $addresses); 434 } 435 436 return $this; 437 } 438 439 /** 440 * Get the Bcc addresses of this message. 441 * 442 * @return array 443 */ 444 public function getBcc() 445 { 446 return $this->_getHeaderFieldModel('Bcc'); 447 } 448 449 /** 450 * Set the priority of this message. 451 * 452 * The value is an integer where 1 is the highest priority and 5 is the lowest. 453 * 454 * @param int $priority 455 * 456 * @return $this 457 */ 458 public function setPriority($priority) 459 { 460 $priorityMap = array( 461 self::PRIORITY_HIGHEST => 'Highest', 462 self::PRIORITY_HIGH => 'High', 463 self::PRIORITY_NORMAL => 'Normal', 464 self::PRIORITY_LOW => 'Low', 465 self::PRIORITY_LOWEST => 'Lowest', 466 ); 467 $pMapKeys = array_keys($priorityMap); 468 if ($priority > max($pMapKeys)) { 469 $priority = max($pMapKeys); 470 } elseif ($priority < min($pMapKeys)) { 471 $priority = min($pMapKeys); 472 } 473 if (!$this->_setHeaderFieldModel('X-Priority', 474 sprintf('%d (%s)', $priority, $priorityMap[$priority]))) { 475 $this->getHeaders()->addTextHeader('X-Priority', 476 sprintf('%d (%s)', $priority, $priorityMap[$priority])); 477 } 478 479 return $this; 480 } 481 482 /** 483 * Get the priority of this message. 484 * 485 * The returned value is an integer where 1 is the highest priority and 5 486 * is the lowest. 487 * 488 * @return int 489 */ 490 public function getPriority() 491 { 492 list($priority) = sscanf($this->_getHeaderFieldModel('X-Priority'), 493 '%[1-5]' 494 ); 495 496 return isset($priority) ? $priority : 3; 497 } 498 499 /** 500 * Ask for a delivery receipt from the recipient to be sent to $addresses. 501 * 502 * @param array $addresses 503 * 504 * @return $this 505 */ 506 public function setReadReceiptTo($addresses) 507 { 508 if (!$this->_setHeaderFieldModel('Disposition-Notification-To', $addresses)) { 509 $this->getHeaders() 510 ->addMailboxHeader('Disposition-Notification-To', $addresses); 511 } 512 513 return $this; 514 } 515 516 /** 517 * Get the addresses to which a read-receipt will be sent. 518 * 519 * @return string 520 */ 521 public function getReadReceiptTo() 522 { 523 return $this->_getHeaderFieldModel('Disposition-Notification-To'); 524 } 525 526 /** 527 * Attach a {@link Swift_Mime_MimeEntity} such as an Attachment or MimePart. 528 * 529 * @param Swift_Mime_MimeEntity $entity 530 * 531 * @return $this 532 */ 533 public function attach(Swift_Mime_MimeEntity $entity) 534 { 535 $this->setChildren(array_merge($this->getChildren(), array($entity))); 536 537 return $this; 538 } 539 540 /** 541 * Remove an already attached entity. 542 * 543 * @param Swift_Mime_MimeEntity $entity 544 * 545 * @return $this 546 */ 547 public function detach(Swift_Mime_MimeEntity $entity) 548 { 549 $newChildren = array(); 550 foreach ($this->getChildren() as $child) { 551 if ($entity !== $child) { 552 $newChildren[] = $child; 553 } 554 } 555 $this->setChildren($newChildren); 556 557 return $this; 558 } 559 560 /** 561 * Attach a {@link Swift_Mime_MimeEntity} and return it's CID source. 562 * This method should be used when embedding images or other data in a message. 563 * 564 * @param Swift_Mime_MimeEntity $entity 565 * 566 * @return string 567 */ 568 public function embed(Swift_Mime_MimeEntity $entity) 569 { 570 $this->attach($entity); 571 572 return 'cid:'.$entity->getId(); 573 } 574 575 /** 576 * Get this message as a complete string. 577 * 578 * @return string 579 */ 580 public function toString() 581 { 582 if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') { 583 $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); 584 $string = parent::toString(); 585 $this->setChildren($children); 586 } else { 587 $string = parent::toString(); 588 } 589 590 return $string; 591 } 592 593 /** 594 * Returns a string representation of this object. 595 * 596 * @see toString() 597 * 598 * @return string 599 */ 600 public function __toString() 601 { 602 return $this->toString(); 603 } 604 605 /** 606 * Write this message to a {@link Swift_InputByteStream}. 607 * 608 * @param Swift_InputByteStream $is 609 */ 610 public function toByteStream(Swift_InputByteStream $is) 611 { 612 if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') { 613 $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); 614 parent::toByteStream($is); 615 $this->setChildren($children); 616 } else { 617 parent::toByteStream($is); 618 } 619 } 620 621 /** @see Swift_Mime_SimpleMimeEntity::_getIdField() */ 622 protected function _getIdField() 623 { 624 return 'Message-ID'; 625 } 626 627 /** Turn the body of this message into a child of itself if needed */ 628 protected function _becomeMimePart() 629 { 630 $part = new parent($this->getHeaders()->newInstance(), $this->getEncoder(), 631 $this->_getCache(), $this->_getGrammar(), $this->_userCharset 632 ); 633 $part->setContentType($this->_userContentType); 634 $part->setBody($this->getBody()); 635 $part->setFormat($this->_userFormat); 636 $part->setDelSp($this->_userDelSp); 637 $part->_setNestingLevel($this->_getTopNestingLevel()); 638 639 return $part; 640 } 641 642 /** Get the highest nesting level nested inside this message */ 643 private function _getTopNestingLevel() 644 { 645 $highestLevel = $this->getNestingLevel(); 646 foreach ($this->getChildren() as $child) { 647 $childLevel = $child->getNestingLevel(); 648 if ($highestLevel < $childLevel) { 649 $highestLevel = $childLevel; 650 } 651 } 652 653 return $highestLevel; 654 } 655} 656