public function getHeaders(string $pid = null) : array
{
// Parses headers
$rawHeaders = $this->getRawHeaders($pid);
if (null === $pid) {
$msgno = imap_msgno($this->connection, $this->uid);
if (0 === $msgno) {
throw new Parser\EmailNotExistException('Email does not exist');
}
$headerInfo = imap_headerinfo($this->connection, $msgno);
} else {
$headerInfo = imap_rfc822_parse_headers($rawHeaders);
}
// Adds a header that the IMAP extension does not support
if (preg_match("~Disposition-Notification-To:(.+?)(?=\r?\n(?:\\S|\r?\n))~is", $rawHeaders, $matches)) {
$addressList = imap_rfc822_parse_adrlist($matches[1], '');
// {''} is used because of CS rules
$headerInfo->{'disposition_notification_toaddress'} = substr(trim($matches[1]), 0, 1024);
$headerInfo->{'disposition_notification_to'} = [$addressList[0]];
}
$headers = [];
static $mimeHeaders = ['toaddress', 'ccaddress', 'bccaddress', 'fromaddress', 'reply_toaddress', 'senderaddress', 'return_pathaddress', 'subject', 'fetchfrom', 'fetchsubject', 'disposition_notification_toaddress'];
foreach ($headerInfo as $key => $value) {
if (!is_object($value) && !is_array($value)) {
if (in_array($key, $mimeHeaders)) {
$headers[$key] = $this->decodeMimeHeader($value);
} else {
$headers[$key] = $this->convertToUtf8((string) $value);
}
}
}
// Adds "udate" if missing
if (!empty($headerInfo->udate)) {
$headers['udate'] = $headerInfo->udate;
} elseif (!empty($headerInfo->date)) {
$headers['udate'] = strtotime($headerInfo->date);
} else {
$headers['udate'] = time();
}
// Parses references
$headers['references'] = isset($headers['references']) ? explode('> <', trim($headers['references'], '<>')) : [];
static $types = ['to', 'cc', 'bcc', 'from', 'reply_to', 'sender', 'return_path', 'disposition_notification_to'];
for ($i = 0; $i < count($types); $i++) {
$type = $types[$i];
$headers[$type] = [];
if (isset($headerInfo->{$type})) {
foreach ($headerInfo->{$type} as $object) {
$newHeader = [];
foreach ($object as $attributeName => $attributeValue) {
if (!empty($attributeValue)) {
$newHeader[$attributeName] = 'personal' === $attributeName ? $this->decodeMimeHeader($attributeValue) : $this->convertToUtf8($attributeValue);
}
}
if (!empty($newHeader)) {
if (isset($newHeader['mailbox'], $newHeader['host'])) {
$newHeader['email'] = $newHeader['mailbox'] . '@' . $newHeader['host'];
} elseif (isset($newHeader['mailbox'])) {
$newHeader['email'] = $newHeader['mailbox'];
} else {
$newHeader['email'] = 'undisclosed-recipients';
}
$headers[$type][] = $newHeader;
}
}
}
}
// Adds X-headers
if (preg_match_all("~(X(?:[\\-]\\w+)+):(.+?)(?=\r?\n(?:\\S|\r?\n))~is", $rawHeaders, $matches) > 0) {
for ($i = 0; $i < count($matches[0]); $i++) {
// Converts to the format used by imap_headerinfo()
$key = str_replace('-', '_', strtolower($matches[1][$i]));
// Removes line endings
$value = strtr(trim($matches[2][$i]), ["\r" => '', "\n" => '', "\t" => ' ']);
$headers[$key] = $value;
}
}
return $headers;
}