mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-11-15 04:27:14 +01:00
Ticket system rewrite of ticket import attachment handling, now with application/octet-stream and cid
This commit is contained in:
parent
9a45653eaf
commit
6bb54be5a3
@ -51,9 +51,35 @@ class MailAttachmentData implements MailAttachmentInterface
|
|||||||
$this->cid = $cid;
|
$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
|
* @param MailMessagePartInterface $part
|
||||||
*
|
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*
|
*
|
||||||
* @return MailAttachmentData
|
* @return MailAttachmentData
|
||||||
@ -61,21 +87,22 @@ class MailAttachmentData implements MailAttachmentInterface
|
|||||||
public static function fromMailMessagePart(MailMessagePartInterface $part): MailAttachmentData
|
public static function fromMailMessagePart(MailMessagePartInterface $part): MailAttachmentData
|
||||||
{
|
{
|
||||||
|
|
||||||
$isInline = false;
|
$attachmenttype = MailAttachmentData::getAttachmentPartType($part);
|
||||||
|
|
||||||
$encodingHeader = $part->getHeader('content-transfer-encoding');
|
if ($attachmenttype == null) {
|
||||||
if ($encodingHeader === null) {
|
throw new InvalidArgumentException('object is no attachment');
|
||||||
// Assume this is no error (?) throw new InvalidArgumentException('missing header: "Content-Transfer-Encoding"');
|
|
||||||
$encoding = '';
|
|
||||||
} else {
|
|
||||||
$encoding = $encodingHeader->getValue();
|
|
||||||
}
|
}
|
||||||
$dispositionHeader = $part->getHeader('content-disposition');
|
|
||||||
if ($dispositionHeader === null) {
|
|
||||||
throw new InvalidArgumentException('missing header: "Content-Disposition"');
|
|
||||||
}
|
|
||||||
$disposition = $dispositionHeader->getValue();
|
|
||||||
|
|
||||||
|
$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: inline
|
||||||
Content-Disposition: attachment
|
Content-Disposition: attachment
|
||||||
@ -84,60 +111,29 @@ class MailAttachmentData implements MailAttachmentInterface
|
|||||||
This is not correctly implemented -> only the first string is evaluated
|
This is not correctly implemented -> only the first string is evaluated
|
||||||
Content-Disposition: attachment; filename*0="filename_that_is_"
|
Content-Disposition: attachment; filename*0="filename_that_is_"
|
||||||
Content-Disposition: attachment; filename*1="very_long.jpg"
|
Content-Disposition: attachment; filename*1="very_long.jpg"
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
$filename = 'OpenXE_file.unknown';
|
||||||
if (preg_match('/(.+);\s*filename(?:\*[0-9]){0,1}="([^"]+)".*$/m', $disposition, $matches)) {
|
if (preg_match('/(.+);\s*filename(?:\*[0-9]){0,1}="*([^"]+)"*.*$/m', $disposition, $matches)) { // Filename in disposition
|
||||||
$isInline = strtolower($matches[1]) === 'inline';
|
|
||||||
$filename = $matches[2];
|
|
||||||
}
|
|
||||||
else if ($disposition == 'attachment') {
|
|
||||||
// Filename is given in Content-Type e.g.
|
|
||||||
/* Content-Type: application/pdf; name="Filename.pdf"
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
Content-Disposition: attachment
|
|
||||||
*/
|
|
||||||
|
|
||||||
$contenttypeHeader = $part->getHeader('content-type');
|
|
||||||
if ($contenttypeHeader === null) {
|
|
||||||
throw new InvalidArgumentException('missing header: "Content-Type"');
|
|
||||||
}
|
|
||||||
$contenttype = $contenttypeHeader->getValue();
|
|
||||||
|
|
||||||
if (preg_match('/(.+);\s*name(?:\*[0-9]){0,1}="([^"]+)".*$/m', $contenttype, $matches)) {
|
|
||||||
$isInline = strtolower($matches[1]) === 'inline';
|
|
||||||
$filename = $matches[2];
|
$filename = $matches[2];
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidArgumentException(
|
$contenttype = $part->getHeaderValue('content-type');
|
||||||
sprintf('missing filename in header value "Content-Type" = "%s"', $contenttype)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ($disposition == 'inline') {
|
|
||||||
$isInline = true;
|
|
||||||
$filename = "OpenXE_file.inline";
|
|
||||||
}
|
|
||||||
else if (strpos($disposition,'attachment;\n') == 0) { // No filename, check for content type message/rfc822
|
|
||||||
|
|
||||||
$contenttypeHeader = $part->getHeader('content-type');
|
$contenttype = str_replace(["\n\r", "\n", "\r"], '', $contenttype);
|
||||||
if ($contenttypeHeader === null) {
|
|
||||||
throw new InvalidArgumentException('missing header: "Content-Type"');
|
|
||||||
}
|
|
||||||
$contenttype = $contenttypeHeader->getValue();
|
|
||||||
|
|
||||||
if ($contenttype == 'message/rfc822') {
|
// 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';
|
$filename = 'ForwardedMessage.eml';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$encodingHeader = $part->getHeader('content-transfer-encoding');
|
||||||
|
if ($encodingHeader === null) {
|
||||||
|
$content_transfer_encoding = '';
|
||||||
} else {
|
} else {
|
||||||
/* throw new InvalidArgumentException(
|
$content_transfer_encoding = $encodingHeader->getValue();
|
||||||
sprintf('unexpected header value "Content-Disposition" = "%s"', $disposition)
|
|
||||||
);*/
|
|
||||||
$filename = "OpenXE_file.unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new InvalidArgumentException(
|
|
||||||
sprintf('unexpected header value "Content-Disposition" = "%s", not message/rfc822', $disposition)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thunderbird UTF URL-Format
|
// Thunderbird UTF URL-Format
|
||||||
@ -148,7 +144,6 @@ class MailAttachmentData implements MailAttachmentInterface
|
|||||||
$filename = rawurldecode($filename);
|
$filename = rawurldecode($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$cid = null;
|
$cid = null;
|
||||||
$contentIdHeader = $part->getHeader('content-id');
|
$contentIdHeader = $part->getHeader('content-id');
|
||||||
if ($contentIdHeader !== null) {
|
if ($contentIdHeader !== null) {
|
||||||
@ -157,9 +152,13 @@ class MailAttachmentData implements MailAttachmentInterface
|
|||||||
$cid = $cidMatches[1];
|
$cid = $cidMatches[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($attachmenttype == 'inline' && $cid != null) {
|
||||||
|
$filename = "cid:".$cid;
|
||||||
|
}
|
||||||
|
|
||||||
$content = $part->getContent();
|
$content = $part->getContent();
|
||||||
if ($content === null) { // This should not be
|
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(
|
throw new InvalidArgumentException(
|
||||||
sprintf('content is null "%s"', substr(print_r($part,true),0,1000))
|
sprintf('content is null "%s"', substr(print_r($part,true),0,1000))
|
||||||
);
|
);
|
||||||
@ -169,8 +168,8 @@ class MailAttachmentData implements MailAttachmentInterface
|
|||||||
$filename,
|
$filename,
|
||||||
$content,
|
$content,
|
||||||
$part->getContentType(),
|
$part->getContentType(),
|
||||||
$encoding,
|
$content_transfer_encoding,
|
||||||
$isInline,
|
$attachmenttype == 'inline',
|
||||||
$cid
|
$cid
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,7 @@ final class MailMessageData implements MailMessageInterface, JsonSerializable
|
|||||||
$parts = [];
|
$parts = [];
|
||||||
$this->findAttachmentParts($this->contentPart, $parts);
|
$this->findAttachmentParts($this->contentPart, $parts);
|
||||||
$attachments = [];
|
$attachments = [];
|
||||||
|
|
||||||
foreach ($parts as $part) {
|
foreach ($parts as $part) {
|
||||||
$attachments[] = MailAttachmentData::fromMailMessagePart($part);
|
$attachments[] = MailAttachmentData::fromMailMessagePart($part);
|
||||||
}
|
}
|
||||||
@ -162,18 +163,16 @@ final class MailMessageData implements MailMessageInterface, JsonSerializable
|
|||||||
*/
|
*/
|
||||||
private function findAttachmentParts(MailMessagePartInterface $part, array &$resultArray): void
|
private function findAttachmentParts(MailMessagePartInterface $part, array &$resultArray): void
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
$header = $part->getHeader('content-disposition');
|
|
||||||
$split = explode(';', $header->getValue());
|
|
||||||
if ($split[0] === 'attachment' || $split[0] === 'inline') {
|
|
||||||
$resultArray[] = $part;
|
|
||||||
|
|
||||||
return;
|
if ($part->isMultipart()) {
|
||||||
}
|
// Recurse subparts
|
||||||
} catch (Throwable $e) {
|
|
||||||
for ($i = 0; $i < $part->countParts(); $i++) {
|
for ($i = 0; $i < $part->countParts(); $i++) {
|
||||||
$this->findAttachmentParts($part->getPart($i), $resultArray);
|
$this->findAttachmentParts($part->getPart($i), $resultArray);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (MailAttachmentData::getAttachmentPartType($part) != null) {
|
||||||
|
$resultArray[] = $part;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +83,18 @@ final class MailMessagePartData implements MailMessagePartInterface, JsonSeriali
|
|||||||
return $this->headers[strtolower($name)];
|
return $this->headers[strtolower($name)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getHeaderValue(string $name): ?string
|
||||||
|
{
|
||||||
|
$header = $this->getHeader($name);
|
||||||
|
if ($header == null) {
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
return($header->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
|
@ -495,7 +495,7 @@ class TicketImportHelper
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
// $this->logger->debug('Start import', ['message' => substr(print_r($message,true),1000)]);
|
// $this->logger->debug('Start import', ['message' => substr(print_r($message,true),1000)]);
|
||||||
$this->logger->debug('Start import', []);
|
$this->logger->debug('Start import '.$messageNumber, []);
|
||||||
|
|
||||||
$result = $this->importMessage($message);
|
$result = $this->importMessage($message);
|
||||||
|
|
||||||
@ -507,11 +507,11 @@ class TicketImportHelper
|
|||||||
$this->mailClient->setFlags((int)$messageNumber, ['\\Seen']);
|
$this->mailClient->setFlags((int)$messageNumber, ['\\Seen']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->logger->error('Error during email import', ['message' => substr(print_r($message,true),0,1000)]);
|
$this->logger->error('Error during email import '.$messageNumber, ['message' => substr(print_r($message,true),0,1000)]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$this->logger->error('Error during email import', ['message' => substr(print_r($message,true),0,1000)]);
|
$this->logger->error('Error during email import '.$messageNumber, ['message' => substr(print_r($message,true),0,1000)]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user