[ 'from', 'to', 'cc', 'bcc', 'sender', 'replyto', 'resentfrom', 'resentto', 'resentcc', 'resentbcc', 'resentreplyto', 'returnpath', 'deliveredto', ], DateHeader::class => [ 'date', 'resentdate', 'deliverydate', 'expires', 'expirydate', 'replyby', ], ParameterHeader::class => [ 'contenttype', 'contentdisposition', 'receivedspf', 'authenticationresults', 'dkimsignature', 'autocrypt', ], SubjectHeader::class => [ 'subject', ], IdHeader::class => [ 'messageid', 'contentid', 'inreplyto', 'references' ], ReceivedHeader::class => [ 'received' ] ]; /** * @var string Defines the generic IHeader type to use for headers that * aren't mapped in $types */ protected $genericType = GenericHeader::class; public function __construct( LoggerInterface $logger, MimeTokenPartFactory $mimeTokenPartFactory, AddressBaseConsumerService $addressBaseConsumerService, DateConsumerService $dateConsumerService, GenericConsumerMimeLiteralPartService $genericConsumerMimeLiteralPartService, IdBaseConsumerService $idBaseConsumerService, ParameterConsumerService $parameterConsumerService, ReceivedConsumerService $receivedConsumerService, SubjectConsumerService $subjectConsumerService ) { $this->logger = $logger; $this->mimeTokenPartFactory = $mimeTokenPartFactory; $this->consumerServices = [ AddressBaseConsumerService::class => $addressBaseConsumerService, DateConsumerService::class => $dateConsumerService, GenericConsumerMimeLiteralPartService::class => $genericConsumerMimeLiteralPartService, IdBaseConsumerService::class => $idBaseConsumerService, ParameterConsumerService::class => $parameterConsumerService, ReceivedConsumerService::class => $receivedConsumerService, SubjectConsumerService::class => $subjectConsumerService ]; } /** * Returns the string in lower-case, and with non-alphanumeric characters * stripped out. * * @param string $header The header name * @return string The normalized header name */ public function getNormalizedHeaderName(string $header) : string { return \preg_replace('/[^a-z0-9]/', '', \strtolower($header)); } /** * Returns the name of an IHeader class for the passed header name. * * @param string $name The header name. * @return string The Fully Qualified class name. */ private function getClassFor(string $name) : string { $test = $this->getNormalizedHeaderName($name); foreach ($this->types as $class => $matchers) { foreach ($matchers as $matcher) { if ($test === $matcher) { return $class; } } } return $this->genericType; } /** * Creates an IHeader instance for the passed header name and value, and * returns it. * * @param string $name The header name. * @param string $value The header value. * @return IHeader The created header object. */ public function newInstance(string $name, string $value) : IHeader { $class = $this->getClassFor($name); $this->logger->debug( 'Creating {class} for header with name "{name}" and value "{value}"', ['class' => $class, 'name' => $name, 'value' => $value] ); return $this->newInstanceOf($name, $value, $class); } /** * Creates an IHeader instance for the passed header name and value using * the passed IHeader class, and returns it. * * @param string $name The header name. * @param string $value The header value. * @param string $iHeaderClass The class to use for header creation * @return IHeader The created header object. */ public function newInstanceOf(string $name, string $value, string $iHeaderClass) : IHeader { $ref = new ReflectionClass($iHeaderClass); $params = $ref->getConstructor()->getParameters(); if ($ref->isSubclassOf(MimeEncodedHeader::class)) { return new $iHeaderClass( $name, $value, $this->logger, $this->mimeTokenPartFactory, $this->consumerServices[$params[4]->getType()->getName()] ); } return new $iHeaderClass( $name, $value, $this->logger, $this->consumerServices[$params[3]->getType()->getName()] ); } }