vendor/symfony/mime/Header/Headers.php line 22

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Mime\Header;
  11. use Symfony\Component\Mime\Address;
  12. use Symfony\Component\Mime\Exception\LogicException;
  13. /**
  14.  * A collection of headers.
  15.  *
  16.  * @author Fabien Potencier <fabien@symfony.com>
  17.  */
  18. final class Headers
  19. {
  20.     private const UNIQUE_HEADERS = [
  21.         'date''from''sender''reply-to''to''cc''bcc',
  22.         'message-id''in-reply-to''references''subject',
  23.     ];
  24.     private const HEADER_CLASS_MAP = [
  25.         'date' => DateHeader::class,
  26.         'from' => MailboxListHeader::class,
  27.         'sender' => MailboxHeader::class,
  28.         'reply-to' => MailboxListHeader::class,
  29.         'to' => MailboxListHeader::class,
  30.         'cc' => MailboxListHeader::class,
  31.         'bcc' => MailboxListHeader::class,
  32.         'message-id' => IdentificationHeader::class,
  33.         '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 ...
  34.         'references' => UnstructuredHeader::class, // ... `Message-ID`, even if that is no valid `msg-id`
  35.         'return-path' => PathHeader::class,
  36.     ];
  37.     /**
  38.      * @var HeaderInterface[][]
  39.      */
  40.     private $headers = [];
  41.     private $lineLength 76;
  42.     public function __construct(HeaderInterface ...$headers)
  43.     {
  44.         foreach ($headers as $header) {
  45.             $this->add($header);
  46.         }
  47.     }
  48.     public function __clone()
  49.     {
  50.         foreach ($this->headers as $name => $collection) {
  51.             foreach ($collection as $i => $header) {
  52.                 $this->headers[$name][$i] = clone $header;
  53.             }
  54.         }
  55.     }
  56.     public function setMaxLineLength(int $lineLength)
  57.     {
  58.         $this->lineLength $lineLength;
  59.         foreach ($this->all() as $header) {
  60.             $header->setMaxLineLength($lineLength);
  61.         }
  62.     }
  63.     public function getMaxLineLength(): int
  64.     {
  65.         return $this->lineLength;
  66.     }
  67.     /**
  68.      * @param array<Address|string> $addresses
  69.      *
  70.      * @return $this
  71.      */
  72.     public function addMailboxListHeader(string $name, array $addresses): self
  73.     {
  74.         return $this->add(new MailboxListHeader($nameAddress::createArray($addresses)));
  75.     }
  76.     /**
  77.      * @param Address|string $address
  78.      *
  79.      * @return $this
  80.      */
  81.     public function addMailboxHeader(string $name$address): self
  82.     {
  83.         return $this->add(new MailboxHeader($nameAddress::create($address)));
  84.     }
  85.     /**
  86.      * @param string|array $ids
  87.      *
  88.      * @return $this
  89.      */
  90.     public function addIdHeader(string $name$ids): self
  91.     {
  92.         return $this->add(new IdentificationHeader($name$ids));
  93.     }
  94.     /**
  95.      * @param Address|string $path
  96.      *
  97.      * @return $this
  98.      */
  99.     public function addPathHeader(string $name$path): self
  100.     {
  101.         return $this->add(new PathHeader($name$path instanceof Address $path : new Address($path)));
  102.     }
  103.     /**
  104.      * @return $this
  105.      */
  106.     public function addDateHeader(string $name, \DateTimeInterface $dateTime): self
  107.     {
  108.         return $this->add(new DateHeader($name$dateTime));
  109.     }
  110.     /**
  111.      * @return $this
  112.      */
  113.     public function addTextHeader(string $namestring $value): self
  114.     {
  115.         return $this->add(new UnstructuredHeader($name$value));
  116.     }
  117.     /**
  118.      * @return $this
  119.      */
  120.     public function addParameterizedHeader(string $namestring $value, array $params = []): self
  121.     {
  122.         return $this->add(new ParameterizedHeader($name$value$params));
  123.     }
  124.     /**
  125.      * @return $this
  126.      */
  127.     public function addHeader(string $name$argument, array $more = []): self
  128.     {
  129.         $parts explode('\\'self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class);
  130.         $method 'add'.ucfirst(array_pop($parts));
  131.         if ('addUnstructuredHeader' === $method) {
  132.             $method 'addTextHeader';
  133.         } elseif ('addIdentificationHeader' === $method) {
  134.             $method 'addIdHeader';
  135.         }
  136.         return $this->$method($name$argument$more);
  137.     }
  138.     public function has(string $name): bool
  139.     {
  140.         return isset($this->headers[strtolower($name)]);
  141.     }
  142.     /**
  143.      * @return $this
  144.      */
  145.     public function add(HeaderInterface $header): self
  146.     {
  147.         self::checkHeaderClass($header);
  148.         $header->setMaxLineLength($this->lineLength);
  149.         $name strtolower($header->getName());
  150.         if (\in_array($nameself::UNIQUE_HEADERStrue) && isset($this->headers[$name]) && \count($this->headers[$name]) > 0) {
  151.             throw new LogicException(sprintf('Impossible to set header "%s" as it\'s already defined and must be unique.'$header->getName()));
  152.         }
  153.         $this->headers[$name][] = $header;
  154.         return $this;
  155.     }
  156.     public function get(string $name): ?HeaderInterface
  157.     {
  158.         $name strtolower($name);
  159.         if (!isset($this->headers[$name])) {
  160.             return null;
  161.         }
  162.         $values array_values($this->headers[$name]);
  163.         return array_shift($values);
  164.     }
  165.     public function all(?string $name null): iterable
  166.     {
  167.         if (null === $name) {
  168.             foreach ($this->headers as $name => $collection) {
  169.                 foreach ($collection as $header) {
  170.                     yield $name => $header;
  171.                 }
  172.             }
  173.         } elseif (isset($this->headers[strtolower($name)])) {
  174.             foreach ($this->headers[strtolower($name)] as $header) {
  175.                 yield $header;
  176.             }
  177.         }
  178.     }
  179.     public function getNames(): array
  180.     {
  181.         return array_keys($this->headers);
  182.     }
  183.     public function remove(string $name): void
  184.     {
  185.         unset($this->headers[strtolower($name)]);
  186.     }
  187.     public static function isUniqueHeader(string $name): bool
  188.     {
  189.         return \in_array(strtolower($name), self::UNIQUE_HEADERStrue);
  190.     }
  191.     /**
  192.      * @throws LogicException if the header name and class are not compatible
  193.      */
  194.     public static function checkHeaderClass(HeaderInterface $header): void
  195.     {
  196.         $name strtolower($header->getName());
  197.         if (($c self::HEADER_CLASS_MAP[$name] ?? null) && !$header instanceof $c) {
  198.             throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").'$header->getName(), $cget_debug_type($header)));
  199.         }
  200.     }
  201.     public function toString(): string
  202.     {
  203.         $string '';
  204.         foreach ($this->toArray() as $str) {
  205.             $string .= $str."\r\n";
  206.         }
  207.         return $string;
  208.     }
  209.     public function toArray(): array
  210.     {
  211.         $arr = [];
  212.         foreach ($this->all() as $header) {
  213.             if ('' !== $header->getBodyAsString()) {
  214.                 $arr[] = $header->toString();
  215.             }
  216.         }
  217.         return $arr;
  218.     }
  219.     /**
  220.      * @internal
  221.      */
  222.     public function getHeaderBody(string $name)
  223.     {
  224.         return $this->has($name) ? $this->get($name)->getBody() : null;
  225.     }
  226.     /**
  227.      * @internal
  228.      */
  229.     public function setHeaderBody(string $typestring $name$body): void
  230.     {
  231.         if ($this->has($name)) {
  232.             $this->get($name)->setBody($body);
  233.         } else {
  234.             $this->{'add'.$type.'Header'}($name$body);
  235.         }
  236.     }
  237.     public function getHeaderParameter(string $namestring $parameter): ?string
  238.     {
  239.         if (!$this->has($name)) {
  240.             return null;
  241.         }
  242.         $header $this->get($name);
  243.         if (!$header instanceof ParameterizedHeader) {
  244.             throw new LogicException(sprintf('Unable to get parameter "%s" on header "%s" as the header is not of class "%s".'$parameter$nameParameterizedHeader::class));
  245.         }
  246.         return $header->getParameter($parameter);
  247.     }
  248.     /**
  249.      * @internal
  250.      */
  251.     public function setHeaderParameter(string $namestring $parameter, ?string $value): void
  252.     {
  253.         if (!$this->has($name)) {
  254.             throw new LogicException(sprintf('Unable to set parameter "%s" on header "%s" as the header is not defined.'$parameter$name));
  255.         }
  256.         $header $this->get($name);
  257.         if (!$header instanceof ParameterizedHeader) {
  258.             throw new LogicException(sprintf('Unable to set parameter "%s" on header "%s" as the header is not of class "%s".'$parameter$nameParameterizedHeader::class));
  259.         }
  260.         $header->setParameter($parameter$value);
  261.     }
  262. }