php-imap
php-imap copied to clipboard
Attachment names not being parsed
Describe the bug When attempting to store attachments from a retrieved email, the names are returned as 8 characters instead of the original filename.
When checking the headers of the attachment object, you can see the filename is being treated as a separate header and is being split into two sections as the name/value.
Used config Using default.
Code to Reproduce The troubling code section which produces the reported bug.
foreach ($message->getAttachments() as $attachment) {
var_dump($attachment->getName());
}
Expected behavior Expect to see the actual filename, but get an 8 digit code, e.g. 616ca634.
Screenshots If applicable, add screenshots to help explain your problem.
Desktop / Server (please complete the following information):
- OS: [e.g. Debian 10] OSX Ventura
- PHP: [e.g. 5.5.9] 8.2.15
- Version [e.g. v2.3.1] 5.3.0
- Provider [e.g. Gmail, Outlook, Dovecot] Gmail
Additional context Attachment header:
Content-Type: message/rfc822;
Content-Transfer-Encoding: base64
X-Attachment-Id: f_lrosxhxg0
name="xxxxxxxxxxxxxxx Your Reference (ref: xxxxxxxxxx).eml"
filename="xxxxxxxxxxxxxxx Your Reference (ref: xxxxxxxxxx).eml"
Content-ID: <f_lrosxhxg0>
Content-Disposition: attachment;
Parsed header:
["filename="xxxxxxxxxxxxxxx your reference (ref"]=>
object(Webklex\PHPIMAP\Attribute)#2074 (2) {
["name":protected]=>
string(45) "filename="xxxxxxxxxxxxxxx your reference (ref"
["values":protected]=>
array(1) {
[0]=>
string(16) "xxxxxxxxxx).eml""
}
}
As a temporary workaround, I am having to parse the filename myself, however the attachment attachment keys are converted to lowercase, which isn't ideal:
// Loop through attachments and store them.
$backup_filename = false;
foreach ($message->getAttachments() as $attachment) {
$name = $attachment->name;
if ($name === $attachment->hash) {
foreach ($attachment->getAttributes() as $key => $value) {
if (stripos($key, 'filename="') !== false) {
$name = preg_replace('/filename="([^"]+)"/', '$1', sprintf('%s: %s', $key, $value));
}
}
}
if ($name === $attachment->hash) {
$name = $backup_filename;
} else {
$backup_filename = $name;
}
// Do something with the attachment...
}
In the EML with the issue, only one of the attachments has the filename/name headers, the rest are similar to:
Content-Type: message/rfc822;
Content-Transfer-Encoding: base64
X-Attachment-Id: f_lrosxhy12
Content-ID: <f_lrosxhy12>
Content-Disposition: attachment;
Gmail shows the attachments all with the same filename, hence the backup filename.