filename = $filename; $this->content = $content; $this->contentType = $contentType; $this->encoding = $encoding; $this->isInlineAttachment = $isInlineAttachment; $this->cid = $cid; } /* Check the type of Attachment Possible results: application/octet-stream, attachment, inline */ public static function getAttachmentPartType(MailMessagePartInterface $part): ?string { if (!$part->isMultipart()) { $header = $part->getHeader('content-disposition'); if ($header !== null) { $split = explode(';', $header->getValue()); if ($split[0] === 'attachment') { return ('attachment'); } else if ($split[0] === 'inline') { return ('inline'); } } else { // Check for application/octet-stream $content_type = $part->getContentType(); if ($content_type == 'application/octet-stream') { return('application/octet-stream'); } } } return(null); } /** * @param MailMessagePartInterface $part * @throws InvalidArgumentException * * @return MailAttachmentData */ public static function fromMailMessagePart(MailMessagePartInterface $part): MailAttachmentData { $attachmenttype = MailAttachmentData::getAttachmentPartType($part); if ($attachmenttype == null) { throw new InvalidArgumentException('object is no attachment'); } $disposition = $part->getHeaderValue('content-disposition'); if ($disposition == null) { $disposition = ''; } $disposition = str_replace(["\n\r", "\n", "\r"], '', $disposition); // file_put_contents('debug.txt',date("HH:mm:ss")."\nDispo: ".$disposition); // FILE_APPEND // Determine filename /* Content-Disposition: inline Content-Disposition: attachment Content-Disposition: attachment; filename="filename.jpg" This is not correctly implemented -> only the first string is evaluated Content-Disposition: attachment; filename*0="filename_that_is_" Content-Disposition: attachment; filename*1="very_long.jpg" */ $filename = 'OpenXE_file.unknown'; if (preg_match('/(.+);\s*filename(?:\*[0-9]){0,1}="*([^"]+)"*.*$/m', $disposition, $matches)) { // Filename in disposition $filename = $matches[2]; } else { $contenttype = $part->getHeaderValue('content-type'); $contenttype = str_replace(["\n\r", "\n", "\r"], '', $contenttype); // file_put_contents('debug.txt',date("HH:mm:ss")."\nConttype: ".$contenttype,FILE_APPEND); // FILE_APPEND if (preg_match('/(.+);\s*name(?:\*[0-9]){0,1}="*([^"]+)"*.*$/m', $contenttype, $matches)) { // Name in content-type $filename = $matches[2]; } else if ($contenttype == 'message/rfc822') { // RFC822 message $filename = 'ForwardedMessage.eml'; } } $encodingHeader = $part->getHeader('content-transfer-encoding'); if ($encodingHeader === null) { $content_transfer_encoding = ''; } else { $content_transfer_encoding = $encodingHeader->getValue(); } // Thunderbird UTF URL-Format $UTF_pos = strpos($filename,'UTF-8\'\''); if ($UTF_pos !== false) { $wasUTF = "JA"; $filename = substr($filename,$UTF_pos); $filename = rawurldecode($filename); } $cid = null; $contentIdHeader = $part->getHeader('content-id'); if ($contentIdHeader !== null) { $cid = $contentIdHeader->getValue(); if (preg_match('/[<]?([^<>]+)[>]?$/', $cid, $cidMatches)) { $cid = $cidMatches[1]; } } if ($attachmenttype == 'inline' && $cid != null) { $filename = "cid:".$cid; } $content = $part->getContent(); if ($content === null) { // This should not be // file_put_contents('debug.txt',date("HH:mm:ss")."\n".print_r($part,true)); // FILE_APPEND throw new InvalidArgumentException( sprintf('content is null "%s"', substr(print_r($part,true),0,1000)) ); } return new self( $filename, $content, $part->getContentType(), $content_transfer_encoding, $attachmenttype == 'inline', $cid ); } /** * @return string */ public function getFileName(): string { return $this->filename; } /** * @return string */ public function getContent(): string { switch ($this->encoding) { case 'base64': return base64_decode($this->content); default: return $this->content; } } /** * @return string */ public function getContentType(): string { return $this->contentType; } /** * @return string */ public function getTransferEncoding(): string { return $this->encoding; } /** * @return bool */ public function isInlineAttachment(): bool { return $this->isInlineAttachment; } /** * @return string|null */ public function getCid(): ?string { return $this->cid; } }