composer package updates
[openemr.git] / vendor / zendframework / zend-mail / src / Message.php
blob6d2336e7050544287c2b6c7ed5f1a5e086f0de4e
1 <?php
2 /**
3 * @see https://github.com/zendframework/zend-mail for the canonical source repository
4 * @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (https://www.zend.com)
5 * @license https://github.com/zendframework/zend-mail/blob/master/LICENSE.md New BSD License
6 */
8 namespace Zend\Mail;
10 use Traversable;
11 use Zend\Mail\Header\ContentType;
12 use Zend\Mail\Header\Sender;
13 use Zend\Mime;
15 class Message
17 /**
18 * Content of the message
20 * @var string|object|Mime\Message
22 protected $body;
24 /**
25 * @var Headers
27 protected $headers;
29 /**
30 * Message encoding
32 * Used to determine whether or not to encode headers; defaults to ASCII.
34 * @var string
36 protected $encoding = 'ASCII';
38 /**
39 * Is the message valid?
41 * If we don't any From addresses, we're invalid, according to RFC2822.
43 * @return bool
45 public function isValid()
47 $from = $this->getFrom();
48 if (! $from instanceof AddressList) {
49 return false;
51 return (bool) count($from);
54 /**
55 * Set the message encoding
57 * @param string $encoding
58 * @return Message
60 public function setEncoding($encoding)
62 $this->encoding = $encoding;
63 $this->getHeaders()->setEncoding($encoding);
64 return $this;
67 /**
68 * Get the message encoding
70 * @return string
72 public function getEncoding()
74 return $this->encoding;
77 /**
78 * Compose headers
80 * @param Headers $headers
81 * @return Message
83 public function setHeaders(Headers $headers)
85 $this->headers = $headers;
86 $headers->setEncoding($this->getEncoding());
87 return $this;
90 /**
91 * Access headers collection
93 * Lazy-loads if not already attached.
95 * @return Headers
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
112 * @return Message
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
125 * @return Message
127 public function addFrom($emailOrAddressOrList, $name = null)
129 $addressList = $this->getFrom();
130 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__);
131 return $this;
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
149 * @return Message
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
164 * @return Message
166 public function addTo($emailOrAddressOrList, $name = null)
168 $addressList = $this->getTo();
169 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__);
170 return $this;
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
188 * @return Message
190 public function setCc($emailOrAddressList, $name = null)
192 $this->clearHeaderByName('cc');
193 return $this->addCc($emailOrAddressList, $name);
197 * Add a "Cc" address
199 * @param string|Address|array|AddressList|Traversable $emailOrAddressOrList
200 * @param string|null $name
201 * @return Message
203 public function addCc($emailOrAddressOrList, $name = null)
205 $addressList = $this->getCc();
206 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__);
207 return $this;
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
225 * @return Message
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
238 * @return Message
240 public function addBcc($emailOrAddressOrList, $name = null)
242 $addressList = $this->getBcc();
243 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__);
244 return $this;
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
262 * @return Message
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
277 * @return Message
279 public function addReplyTo($emailOrAddressOrList, $name = null)
281 $addressList = $this->getReplyTo();
282 $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__);
283 return $this;
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');
297 * setSender
299 * @param mixed $emailOrAddress
300 * @param mixed $name
301 * @return Message
303 public function setSender($emailOrAddress, $name = null)
305 /** @var Sender $header */
306 $header = $this->getHeaderByName('sender', __NAMESPACE__ . '\Header\Sender');
307 $header->setAddress($emailOrAddress, $name);
308 return $this;
312 * Retrieve the sender address, if any
314 * @return null|Address\AddressInterface
316 public function getSender()
318 $headers = $this->getHeaders();
319 if (! $headers->has('sender')) {
320 return null;
323 /** @var Sender $header */
324 $header = $this->getHeaderByName('sender', __NAMESPACE__ . '\Header\Sender');
325 return $header->getAddress();
329 * Set the message subject header value
331 * @param string $subject
332 * @return Message
334 public function setSubject($subject)
336 $headers = $this->getHeaders();
337 if (! $headers->has('subject')) {
338 $header = new Header\Subject();
339 $headers->addHeader($header);
340 } else {
341 $header = $headers->get('subject');
343 $header->setSubject($subject);
344 return $this;
348 * Get the message subject header value
350 * @return null|string
352 public function getSubject()
354 $headers = $this->getHeaders();
355 if (! $headers->has('subject')) {
356 return;
358 $header = $headers->get('subject');
359 return $header->getFieldValue();
363 * Set the message body
365 * @param null|string|\Zend\Mime\Message|object $body
366 * @throws Exception\InvalidArgumentException
367 * @return Message
369 public function setBody($body)
371 if (! is_string($body) && $body !== null) {
372 if (! is_object($body)) {
373 throw new Exception\InvalidArgumentException(sprintf(
374 '%s expects a string or object argument; received "%s"',
375 __METHOD__,
376 gettype($body)
379 if (! $body instanceof Mime\Message) {
380 if (! method_exists($body, '__toString')) {
381 throw new Exception\InvalidArgumentException(sprintf(
382 '%s expects object arguments of type Zend\Mime\Message or implementing __toString();'
383 . ' object of type "%s" received',
384 __METHOD__,
385 get_class($body)
390 $this->body = $body;
392 if (! $this->body instanceof Mime\Message) {
393 return $this;
396 // Get headers, and set Mime-Version header
397 $headers = $this->getHeaders();
398 $this->getHeaderByName('mime-version', __NAMESPACE__ . '\Header\MimeVersion');
400 // Multipart content headers
401 if ($this->body->isMultiPart()) {
402 $mime = $this->body->getMime();
404 /** @var ContentType $header */
405 $header = $this->getHeaderByName('content-type', __NAMESPACE__ . '\Header\ContentType');
406 $header->setType('multipart/mixed');
407 $header->addParameter('boundary', $mime->boundary());
408 return $this;
411 // MIME single part headers
412 $parts = $this->body->getParts();
413 if (! empty($parts)) {
414 $part = array_shift($parts);
415 $headers->addHeaders($part->getHeadersArray("\r\n"));
417 return $this;
421 * Return the currently set message body
423 * @return object|string|Mime\Message
425 public function getBody()
427 return $this->body;
431 * Get the string-serialized message body text
433 * @return string
435 public function getBodyText()
437 if ($this->body instanceof Mime\Message) {
438 return $this->body->generateMessage(Headers::EOL);
441 return (string) $this->body;
445 * Retrieve a header by name
447 * If not found, instantiates one based on $headerClass.
449 * @param string $headerName
450 * @param string $headerClass
451 * @return Header\HeaderInterface|\ArrayIterator header instance or collection of headers
453 protected function getHeaderByName($headerName, $headerClass)
455 $headers = $this->getHeaders();
456 if ($headers->has($headerName)) {
457 $header = $headers->get($headerName);
458 } else {
459 $header = new $headerClass();
460 $headers->addHeader($header);
462 return $header;
466 * Clear a header by name
468 * @param string $headerName
470 protected function clearHeaderByName($headerName)
472 $this->getHeaders()->removeHeader($headerName);
476 * Retrieve the AddressList from a named header
478 * Used with To, From, Cc, Bcc, and ReplyTo headers. If the header does not
479 * exist, instantiates it.
481 * @param string $headerName
482 * @param string $headerClass
483 * @throws Exception\DomainException
484 * @return AddressList
486 protected function getAddressListFromHeader($headerName, $headerClass)
488 $header = $this->getHeaderByName($headerName, $headerClass);
489 if (! $header instanceof Header\AbstractAddressList) {
490 throw new Exception\DomainException(sprintf(
491 'Cannot grab address list from header of type "%s"; not an AbstractAddressList implementation',
492 get_class($header)
495 return $header->getAddressList();
499 * Update an address list
501 * Proxied to this from addFrom, addTo, addCc, addBcc, and addReplyTo.
503 * @param AddressList $addressList
504 * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressOrList
505 * @param null|string $name
506 * @param string $callingMethod
507 * @throws Exception\InvalidArgumentException
509 protected function updateAddressList(AddressList $addressList, $emailOrAddressOrList, $name, $callingMethod)
511 if ($emailOrAddressOrList instanceof Traversable) {
512 foreach ($emailOrAddressOrList as $address) {
513 $addressList->add($address);
515 return;
517 if (is_array($emailOrAddressOrList)) {
518 $addressList->addMany($emailOrAddressOrList);
519 return;
521 if (! is_string($emailOrAddressOrList) && ! $emailOrAddressOrList instanceof Address\AddressInterface) {
522 throw new Exception\InvalidArgumentException(sprintf(
523 '%s expects a string, AddressInterface, array, AddressList, or Traversable as its first argument;'
524 . ' received "%s"',
525 $callingMethod,
526 (is_object($emailOrAddressOrList) ? get_class($emailOrAddressOrList) : gettype($emailOrAddressOrList))
530 if (is_string($emailOrAddressOrList) && $name === null) {
531 $addressList->addFromString($emailOrAddressOrList);
532 return;
535 $addressList->add($emailOrAddressOrList, $name);
539 * Serialize to string
541 * @return string
543 public function toString()
545 $headers = $this->getHeaders();
546 return $headers->toString()
547 . Headers::EOL
548 . $this->getBodyText();
552 * Instantiate from raw message string
554 * @todo Restore body to Mime\Message
555 * @param string $rawMessage
556 * @return Message
558 public static function fromString($rawMessage)
560 $message = new static();
562 /** @var Headers $headers */
563 $headers = null;
564 $content = null;
565 Mime\Decode::splitMessage($rawMessage, $headers, $content, Headers::EOL);
566 if ($headers->has('mime-version')) {
567 // todo - restore body to mime\message
569 $message->setHeaders($headers);
570 $message->setBody($content);
571 return $message;