123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- <?php
- /*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Symfony\Component\Mime\Header;
- use Symfony\Component\Mime\Address;
- use Symfony\Component\Mime\Exception\LogicException;
- /**
- * A collection of headers.
- *
- * @author Fabien Potencier <fabien@symfony.com>
- */
- final class Headers
- {
- private const UNIQUE_HEADERS = [
- 'date', 'from', 'sender', 'reply-to', 'to', 'cc', 'bcc',
- 'message-id', 'in-reply-to', 'references', 'subject',
- ];
- private $headers = [];
- private $lineLength = 76;
- public function __construct(HeaderInterface ...$headers)
- {
- foreach ($headers as $header) {
- $this->add($header);
- }
- }
- public function __clone()
- {
- foreach ($this->headers as $name => $collection) {
- foreach ($collection as $i => $header) {
- $this->headers[$name][$i] = clone $header;
- }
- }
- }
- public function setMaxLineLength(int $lineLength)
- {
- $this->lineLength = $lineLength;
- foreach ($this->all() as $header) {
- $header->setMaxLineLength($lineLength);
- }
- }
- public function getMaxLineLength(): int
- {
- return $this->lineLength;
- }
- /**
- * @param array<Address|string> $addresses
- *
- * @return $this
- */
- public function addMailboxListHeader(string $name, array $addresses): self
- {
- return $this->add(new MailboxListHeader($name, Address::createArray($addresses)));
- }
- /**
- * @param Address|string $address
- *
- * @return $this
- */
- public function addMailboxHeader(string $name, $address): self
- {
- return $this->add(new MailboxHeader($name, Address::create($address)));
- }
- /**
- * @param string|array $ids
- *
- * @return $this
- */
- public function addIdHeader(string $name, $ids): self
- {
- return $this->add(new IdentificationHeader($name, $ids));
- }
- /**
- * @param Address|string $path
- *
- * @return $this
- */
- public function addPathHeader(string $name, $path): self
- {
- return $this->add(new PathHeader($name, $path instanceof Address ? $path : new Address($path)));
- }
- /**
- * @return $this
- */
- public function addDateHeader(string $name, \DateTimeInterface $dateTime): self
- {
- return $this->add(new DateHeader($name, $dateTime));
- }
- /**
- * @return $this
- */
- public function addTextHeader(string $name, string $value): self
- {
- return $this->add(new UnstructuredHeader($name, $value));
- }
- /**
- * @return $this
- */
- public function addParameterizedHeader(string $name, string $value, array $params = []): self
- {
- return $this->add(new ParameterizedHeader($name, $value, $params));
- }
- public function has(string $name): bool
- {
- return isset($this->headers[strtolower($name)]);
- }
- /**
- * @return $this
- */
- public function add(HeaderInterface $header): self
- {
- static $map = [
- 'date' => DateHeader::class,
- 'from' => MailboxListHeader::class,
- 'sender' => MailboxHeader::class,
- 'reply-to' => MailboxListHeader::class,
- 'to' => MailboxListHeader::class,
- 'cc' => MailboxListHeader::class,
- 'bcc' => MailboxListHeader::class,
- 'message-id' => IdentificationHeader::class,
- 'in-reply-to' => UnstructuredHeader::class, // `In-Reply-To` and `References` are less strict than RFC 2822 (3.6.4) to allow users entering the original email's ...
- 'references' => UnstructuredHeader::class, // ... `Message-ID`, even if that is no valid `msg-id`
- 'return-path' => PathHeader::class,
- ];
- $header->setMaxLineLength($this->lineLength);
- $name = strtolower($header->getName());
- if (isset($map[$name]) && !$header instanceof $map[$name]) {
- throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), $map[$name], \get_class($header)));
- }
- if (\in_array($name, self::UNIQUE_HEADERS, true) && isset($this->headers[$name]) && \count($this->headers[$name]) > 0) {
- throw new LogicException(sprintf('Impossible to set header "%s" as it\'s already defined and must be unique.', $header->getName()));
- }
- $this->headers[$name][] = $header;
- return $this;
- }
- public function get(string $name): ?HeaderInterface
- {
- $name = strtolower($name);
- if (!isset($this->headers[$name])) {
- return null;
- }
- $values = array_values($this->headers[$name]);
- return array_shift($values);
- }
- public function all(string $name = null): iterable
- {
- if (null === $name) {
- foreach ($this->headers as $name => $collection) {
- foreach ($collection as $header) {
- yield $name => $header;
- }
- }
- } elseif (isset($this->headers[strtolower($name)])) {
- foreach ($this->headers[strtolower($name)] as $header) {
- yield $header;
- }
- }
- }
- public function getNames(): array
- {
- return array_keys($this->headers);
- }
- public function remove(string $name): void
- {
- unset($this->headers[strtolower($name)]);
- }
- public static function isUniqueHeader(string $name): bool
- {
- return \in_array(strtolower($name), self::UNIQUE_HEADERS, true);
- }
- public function toString(): string
- {
- $string = '';
- foreach ($this->toArray() as $str) {
- $string .= $str."\r\n";
- }
- return $string;
- }
- public function toArray(): array
- {
- $arr = [];
- foreach ($this->all() as $header) {
- if ('' !== $header->getBodyAsString()) {
- $arr[] = $header->toString();
- }
- }
- return $arr;
- }
- /**
- * @internal
- */
- public function getHeaderBody(string $name)
- {
- return $this->has($name) ? $this->get($name)->getBody() : null;
- }
- /**
- * @internal
- */
- public function setHeaderBody(string $type, string $name, $body): void
- {
- if ($this->has($name)) {
- $this->get($name)->setBody($body);
- } else {
- $this->{'add'.$type.'Header'}($name, $body);
- }
- }
- /**
- * @internal
- */
- public function getHeaderParameter(string $name, string $parameter): ?string
- {
- if (!$this->has($name)) {
- return null;
- }
- $header = $this->get($name);
- if (!$header instanceof ParameterizedHeader) {
- throw new LogicException(sprintf('Unable to get parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class));
- }
- return $header->getParameter($parameter);
- }
- /**
- * @internal
- */
- public function setHeaderParameter(string $name, string $parameter, ?string $value): void
- {
- if (!$this->has($name)) {
- throw new LogicException(sprintf('Unable to set parameter "%s" on header "%s" as the header is not defined.', $parameter, $name));
- }
- $header = $this->get($name);
- if (!$header instanceof ParameterizedHeader) {
- throw new LogicException(sprintf('Unable to set parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class));
- }
- $header->setParameter($parameter, $value);
- }
- }
|