3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
18 * Content of the message
32 * Used to determine whether or not to encode headers; defaults to ASCII.
36 protected $encoding = 'ASCII';
39 * Is the message valid?
41 * If we don't any From addresses, we're invalid, according to RFC2822.
45 public function isValid()
47 $from = $this->getFrom();
48 if (!$from instanceof AddressList
) {
51 return (bool) count($from);
55 * Set the message encoding
57 * @param string $encoding
60 public function setEncoding($encoding)
62 $this->encoding
= $encoding;
63 $this->getHeaders()->setEncoding($encoding);
68 * Get the message encoding
72 public function getEncoding()
74 return $this->encoding
;
80 * @param Headers $headers
83 public function setHeaders(Headers
$headers)
85 $this->headers
= $headers;
86 $headers->setEncoding($this->getEncoding());
91 * Access headers collection
93 * Lazy-loads if not already attached.
97 public function getHeaders()
99 if (null === $this->headers
) {
100 $this->setHeaders(new Headers());
101 $date = Header\Date
::fromString('Date: ' . date('r'));
102 $this->headers
->addHeader($date);
104 return $this->headers
;
108 * Set (overwrite) From addresses
110 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList
111 * @param string|null $name
114 public function setFrom($emailOrAddressList, $name = null)
116 $this->clearHeaderByName('from');
117 return $this->addFrom($emailOrAddressList, $name);
121 * Add a "From" address
123 * @param string|Address|array|AddressList|Traversable $emailOrAddressOrList
124 * @param string|null $name
127 public function addFrom($emailOrAddressOrList, $name = null)
129 $addressList = $this->getFrom();
130 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__
);
135 * Retrieve list of From senders
137 * @return AddressList
139 public function getFrom()
141 return $this->getAddressListFromHeader('from', __NAMESPACE__
. '\Header\From');
145 * Overwrite the address list in the To recipients
147 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList
148 * @param null|string $name
151 public function setTo($emailOrAddressList, $name = null)
153 $this->clearHeaderByName('to');
154 return $this->addTo($emailOrAddressList, $name);
158 * Add one or more addresses to the To recipients
160 * Appends to the list.
162 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressOrList
163 * @param null|string $name
166 public function addTo($emailOrAddressOrList, $name = null)
168 $addressList = $this->getTo();
169 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__
);
174 * Access the address list of the To header
176 * @return AddressList
178 public function getTo()
180 return $this->getAddressListFromHeader('to', __NAMESPACE__
. '\Header\To');
184 * Set (overwrite) CC addresses
186 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList
187 * @param string|null $name
190 public function setCc($emailOrAddressList, $name = null)
192 $this->clearHeaderByName('cc');
193 return $this->addCc($emailOrAddressList, $name);
199 * @param string|Address|array|AddressList|Traversable $emailOrAddressOrList
200 * @param string|null $name
203 public function addCc($emailOrAddressOrList, $name = null)
205 $addressList = $this->getCc();
206 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__
);
211 * Retrieve list of CC recipients
213 * @return AddressList
215 public function getCc()
217 return $this->getAddressListFromHeader('cc', __NAMESPACE__
. '\Header\Cc');
221 * Set (overwrite) BCC addresses
223 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList
224 * @param string|null $name
227 public function setBcc($emailOrAddressList, $name = null)
229 $this->clearHeaderByName('bcc');
230 return $this->addBcc($emailOrAddressList, $name);
234 * Add a "Bcc" address
236 * @param string|Address|array|AddressList|Traversable $emailOrAddressOrList
237 * @param string|null $name
240 public function addBcc($emailOrAddressOrList, $name = null)
242 $addressList = $this->getBcc();
243 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__
);
248 * Retrieve list of BCC recipients
250 * @return AddressList
252 public function getBcc()
254 return $this->getAddressListFromHeader('bcc', __NAMESPACE__
. '\Header\Bcc');
258 * Overwrite the address list in the Reply-To recipients
260 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList
261 * @param null|string $name
264 public function setReplyTo($emailOrAddressList, $name = null)
266 $this->clearHeaderByName('reply-to');
267 return $this->addReplyTo($emailOrAddressList, $name);
271 * Add one or more addresses to the Reply-To recipients
273 * Appends to the list.
275 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressOrList
276 * @param null|string $name
279 public function addReplyTo($emailOrAddressOrList, $name = null)
281 $addressList = $this->getReplyTo();
282 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__
);
287 * Access the address list of the Reply-To header
289 * @return AddressList
291 public function getReplyTo()
293 return $this->getAddressListFromHeader('reply-to', __NAMESPACE__
. '\Header\ReplyTo');
299 * @param mixed $emailOrAddress
303 public function setSender($emailOrAddress, $name = null)
305 $header = $this->getHeaderByName('sender', __NAMESPACE__
. '\Header\Sender');
306 $header->setAddress($emailOrAddress, $name);
311 * Retrieve the sender address, if any
313 * @return null|Address\AddressInterface
315 public function getSender()
317 $header = $this->getHeaderByName('sender', __NAMESPACE__
. '\Header\Sender');
318 return $header->getAddress();
322 * Set the message subject header value
324 * @param string $subject
327 public function setSubject($subject)
329 $headers = $this->getHeaders();
330 if (!$headers->has('subject')) {
331 $header = new Header\
Subject();
332 $headers->addHeader($header);
334 $header = $headers->get('subject');
336 $header->setSubject($subject);
341 * Get the message subject header value
343 * @return null|string
345 public function getSubject()
347 $headers = $this->getHeaders();
348 if (!$headers->has('subject')) {
351 $header = $headers->get('subject');
352 return $header->getFieldValue();
356 * Set the message body
358 * @param null|string|\Zend\Mime\Message|object $body
359 * @throws Exception\InvalidArgumentException
362 public function setBody($body)
364 if (!is_string($body) && $body !== null) {
365 if (!is_object($body)) {
366 throw new Exception\
InvalidArgumentException(sprintf(
367 '%s expects a string or object argument; received "%s"',
372 if (!$body instanceof Mime\Message
) {
373 if (!method_exists($body, '__toString')) {
374 throw new Exception\
InvalidArgumentException(sprintf(
375 '%s expects object arguments of type Zend\Mime\Message or implementing __toString();'
376 . ' object of type "%s" received',
385 if (!$this->body
instanceof Mime\Message
) {
389 // Get headers, and set Mime-Version header
390 $headers = $this->getHeaders();
391 $this->getHeaderByName('mime-version', __NAMESPACE__
. '\Header\MimeVersion');
393 // Multipart content headers
394 if ($this->body
->isMultiPart()) {
395 $mime = $this->body
->getMime();
396 $header = $this->getHeaderByName('content-type', __NAMESPACE__
. '\Header\ContentType');
397 $header->setType('multipart/mixed');
398 $header->addParameter('boundary', $mime->boundary());
402 // MIME single part headers
403 $parts = $this->body
->getParts();
404 if (!empty($parts)) {
405 $part = array_shift($parts);
406 $headers->addHeaders($part->getHeadersArray("\r\n"));
412 * Return the currently set message body
416 public function getBody()
422 * Get the string-serialized message body text
426 public function getBodyText()
428 if ($this->body
instanceof Mime\Message
) {
429 return $this->body
->generateMessage(Headers
::EOL
);
432 return (string) $this->body
;
436 * Retrieve a header by name
438 * If not found, instantiates one based on $headerClass.
440 * @param string $headerName
441 * @param string $headerClass
442 * @return Header\HeaderInterface|\ArrayIterator header instance or collection of headers
444 protected function getHeaderByName($headerName, $headerClass)
446 $headers = $this->getHeaders();
447 if ($headers->has($headerName)) {
448 $header = $headers->get($headerName);
450 $header = new $headerClass();
451 $headers->addHeader($header);
457 * Clear a header by name
459 * @param string $headerName
461 protected function clearHeaderByName($headerName)
463 $this->getHeaders()->removeHeader($headerName);
467 * Retrieve the AddressList from a named header
469 * Used with To, From, Cc, Bcc, and ReplyTo headers. If the header does not
470 * exist, instantiates it.
472 * @param string $headerName
473 * @param string $headerClass
474 * @throws Exception\DomainException
475 * @return AddressList
477 protected function getAddressListFromHeader($headerName, $headerClass)
479 $header = $this->getHeaderByName($headerName, $headerClass);
480 if (!$header instanceof Header\AbstractAddressList
) {
481 throw new Exception\
DomainException(sprintf(
482 'Cannot grab address list from header of type "%s"; not an AbstractAddressList implementation',
486 return $header->getAddressList();
490 * Update an address list
492 * Proxied to this from addFrom, addTo, addCc, addBcc, and addReplyTo.
494 * @param AddressList $addressList
495 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressOrList
496 * @param null|string $name
497 * @param string $callingMethod
498 * @throws Exception\InvalidArgumentException
500 protected function updateAddressList(AddressList
$addressList, $emailOrAddressOrList, $name, $callingMethod)
502 if ($emailOrAddressOrList instanceof Traversable
) {
503 foreach ($emailOrAddressOrList as $address) {
504 $addressList->add($address);
508 if (is_array($emailOrAddressOrList)) {
509 $addressList->addMany($emailOrAddressOrList);
512 if (!is_string($emailOrAddressOrList) && !$emailOrAddressOrList instanceof Address\AddressInterface
) {
513 throw new Exception\
InvalidArgumentException(sprintf(
514 '%s expects a string, AddressInterface, array, AddressList, or Traversable as its first argument;'
517 (is_object($emailOrAddressOrList) ?
get_class($emailOrAddressOrList) : gettype($emailOrAddressOrList))
521 if (is_string($emailOrAddressOrList) && $name === null) {
522 $addressList->addFromString($emailOrAddressOrList);
526 $addressList->add($emailOrAddressOrList, $name);
530 * Serialize to string
534 public function toString()
536 $headers = $this->getHeaders();
537 return $headers->toString()
539 . $this->getBodyText();
543 * Instantiate from raw message string
545 * @todo Restore body to Mime\Message
546 * @param string $rawMessage
549 public static function fromString($rawMessage)
551 $message = new static();
554 Mime\Decode
::splitMessage($rawMessage, $headers, $content);
555 if ($headers->has('mime-version')) {
556 // todo - restore body to mime\message
558 $message->setHeaders($headers);
559 $message->setBody($content);