vendor/symfony/mime/Address.php line 25

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;
  11. use Egulias\EmailValidator\EmailValidator;
  12. use Egulias\EmailValidator\Validation\MessageIDValidation;
  13. use Egulias\EmailValidator\Validation\RFCValidation;
  14. use Symfony\Component\Mime\Encoder\IdnAddressEncoder;
  15. use Symfony\Component\Mime\Exception\InvalidArgumentException;
  16. use Symfony\Component\Mime\Exception\LogicException;
  17. use Symfony\Component\Mime\Exception\RfcComplianceException;
  18. /**
  19.  * @author Fabien Potencier <fabien@symfony.com>
  20.  */
  21. final class Address
  22. {
  23.     /**
  24.      * A regex that matches a structure like 'Name <email@address.com>'.
  25.      * It matches anything between the first < and last > as email address.
  26.      * This allows to use a single string to construct an Address, which can be convenient to use in
  27.      * config, and allows to have more readable config.
  28.      * This does not try to cover all edge cases for address.
  29.      */
  30.     private const FROM_STRING_PATTERN '~(?<displayName>[^<]*)<(?<addrSpec>.*)>[^>]*~';
  31.     private static $validator;
  32.     private static $encoder;
  33.     private $address;
  34.     private $name;
  35.     public function __construct(string $addressstring $name '')
  36.     {
  37.         if (!class_exists(EmailValidator::class)) {
  38.             throw new LogicException(sprintf('The "%s" class cannot be used as it needs "%s"; try running "composer require egulias/email-validator".'__CLASS__EmailValidator::class));
  39.         }
  40.         if (null === self::$validator) {
  41.             self::$validator = new EmailValidator();
  42.         }
  43.         $this->address trim($address);
  44.         $this->name trim(str_replace(["\n""\r"], ''$name));
  45.         if (!self::$validator->isValid($this->addressclass_exists(MessageIDValidation::class) ? new MessageIDValidation() : new RFCValidation())) {
  46.             throw new RfcComplianceException(sprintf('Email "%s" does not comply with addr-spec of RFC 2822.'$address));
  47.         }
  48.     }
  49.     public function getAddress(): string
  50.     {
  51.         return $this->address;
  52.     }
  53.     public function getName(): string
  54.     {
  55.         return $this->name;
  56.     }
  57.     public function getEncodedAddress(): string
  58.     {
  59.         if (null === self::$encoder) {
  60.             self::$encoder = new IdnAddressEncoder();
  61.         }
  62.         return self::$encoder->encodeString($this->address);
  63.     }
  64.     public function toString(): string
  65.     {
  66.         return ($n $this->getEncodedName()) ? $n.' <'.$this->getEncodedAddress().'>' $this->getEncodedAddress();
  67.     }
  68.     public function getEncodedName(): string
  69.     {
  70.         if ('' === $this->getName()) {
  71.             return '';
  72.         }
  73.         return sprintf('"%s"'preg_replace('/"/u''\"'$this->getName()));
  74.     }
  75.     /**
  76.      * @param Address|string $address
  77.      */
  78.     public static function create($address): self
  79.     {
  80.         if ($address instanceof self) {
  81.             return $address;
  82.         }
  83.         if (!\is_string($address)) {
  84.             throw new InvalidArgumentException(sprintf('An address can be an instance of Address or a string ("%s" given).'get_debug_type($address)));
  85.         }
  86.         if (false === strpos($address'<')) {
  87.             return new self($address);
  88.         }
  89.         if (!preg_match(self::FROM_STRING_PATTERN$address$matches)) {
  90.             throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.'$addressself::class));
  91.         }
  92.         return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"'));
  93.     }
  94.     /**
  95.      * @param array<Address|string> $addresses
  96.      *
  97.      * @return Address[]
  98.      */
  99.     public static function createArray(array $addresses): array
  100.     {
  101.         $addrs = [];
  102.         foreach ($addresses as $address) {
  103.             $addrs[] = self::create($address);
  104.         }
  105.         return $addrs;
  106.     }
  107.     /**
  108.      * @deprecated since Symfony 5.2, use "create()" instead.
  109.      */
  110.     public static function fromString(string $string): self
  111.     {
  112.         trigger_deprecation('symfony/mime''5.2''"%s()" is deprecated, use "%s::create()" instead.'__METHOD____CLASS__);
  113.         if (!str_contains($string'<')) {
  114.             return new self($string'');
  115.         }
  116.         if (!preg_match(self::FROM_STRING_PATTERN$string$matches)) {
  117.             throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.'$stringself::class));
  118.         }
  119.         return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"'));
  120.     }
  121. }