Improve attachments handling:
- use Content-ID as key in _attachments list; new attachments have numeric keys - generate a unique Content-ID for new/changed attachments in libkolab - bugfix: don't cache empty attachment entries
This commit is contained in:
parent
f678e8f16a
commit
d5c2f15ccb
5 changed files with 60 additions and 29 deletions
|
@ -220,7 +220,7 @@ function rcube_calendar_ui(settings)
|
|||
// check if the event has 'real' attendees, excluding the current user
|
||||
var has_attendees = function(event)
|
||||
{
|
||||
return (event.attendees && (event.attendees.length > 1 || event.attendees[0].email != settings.identity.email));
|
||||
return (event.attendees && event.attendees.length && (event.attendees.length > 1 || event.attendees[0].email != settings.identity.email));
|
||||
};
|
||||
|
||||
// check if the current user is an attendee of this event
|
||||
|
|
|
@ -429,9 +429,10 @@ class kolab_calendar
|
|||
$record['end'] = $record['start'] + 3600;
|
||||
|
||||
if (!empty($record['_attachments'])) {
|
||||
foreach ($record['_attachments'] as $name => $attachment) {
|
||||
foreach ($record['_attachments'] as $key => $attachment) {
|
||||
if ($attachment !== false) {
|
||||
$attachment['name'] = $name;
|
||||
if (!$attachment['name'])
|
||||
$attachment['name'] = $key;
|
||||
$attachments[] = $attachment;
|
||||
}
|
||||
}
|
||||
|
@ -460,29 +461,34 @@ class kolab_calendar
|
|||
{
|
||||
$object = &$event;
|
||||
|
||||
// in Horde attachments are indexed by name
|
||||
// in kolab_storage attachments are indexed by content-id
|
||||
$object['_attachments'] = array();
|
||||
if (is_array($event['attachments'])) {
|
||||
$collisions = array();
|
||||
foreach ($event['attachments'] as $idx => $attachment) {
|
||||
// Roundcube ID has nothing to do with Horde ID, remove it
|
||||
if ($attachment['content'])
|
||||
$key = null;
|
||||
// Roundcube ID has nothing to do with the storage ID, remove it
|
||||
if ($attachment['content']) {
|
||||
unset($attachment['id']);
|
||||
}
|
||||
else {
|
||||
foreach ((array)$old['_attachments'] as $cid => $oldatt) {
|
||||
if ($attachment['id'] == $oldatt['id'])
|
||||
$key = $cid;
|
||||
}
|
||||
}
|
||||
|
||||
// flagged for deletion => set to false
|
||||
if ($attachment['_deleted']) {
|
||||
$object['_attachments'][$attachment['name']] = false;
|
||||
$object['_attachments'][$key] = false;
|
||||
}
|
||||
// replace existing entry
|
||||
else if ($key) {
|
||||
$object['_attachments'][$key] = $attachment;
|
||||
}
|
||||
// append as new attachment
|
||||
else {
|
||||
// Horde code assumes that there will be no more than
|
||||
// one file with the same name: make filenames unique
|
||||
$filename = $attachment['name'];
|
||||
if ($collisions[$filename]++) {
|
||||
$ext = preg_match('/(\.[a-z0-9]{1,6})$/i', $filename, $m) ? $m[1] : null;
|
||||
$attachment['name'] = basename($filename, $ext) . '-' . $collisions[$filename] . $ext;
|
||||
}
|
||||
|
||||
$object['_attachments'][$attachment['name']] = $attachment;
|
||||
$object['_attachments'][] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -582,6 +582,7 @@ class kolab_driver extends calendar_driver
|
|||
}
|
||||
}
|
||||
}
|
||||
unset($event['deleted_attachments']);
|
||||
}
|
||||
|
||||
// handle attachments to add
|
||||
|
|
|
@ -77,12 +77,12 @@ class kolab_format_event extends kolab_format_xcal
|
|||
|
||||
// save attachments
|
||||
$vattach = new vectorattachment;
|
||||
foreach ((array)$object['_attachments'] as $name => $attr) {
|
||||
foreach ((array)$object['_attachments'] as $cid => $attr) {
|
||||
if (empty($attr))
|
||||
continue;
|
||||
$attach = new Attachment;
|
||||
$attach->setLabel($name);
|
||||
$attach->setUri('cid:' . $name, $attr['mimetype']);
|
||||
$attach->setLabel((string)$attr['name']);
|
||||
$attach->setUri('cid:' . $cid, $attr['mimetype']);
|
||||
$vattach->push($attach);
|
||||
}
|
||||
$this->obj->setAttachments($vattach);
|
||||
|
@ -148,6 +148,7 @@ class kolab_format_event extends kolab_format_xcal
|
|||
$name = $attach->label();
|
||||
$data = $attach->data();
|
||||
$object['_attachments'][$name] = array(
|
||||
'name' => $name,
|
||||
'mimetype' => $attach->mimetype(),
|
||||
'size' => strlen($data),
|
||||
'content' => $data,
|
||||
|
|
|
@ -415,6 +415,7 @@ class kolab_storage_folder
|
|||
$key = $part->content_id ? trim($part->content_id, '<>') : $part->filename;
|
||||
$attachments[$key] = array(
|
||||
'id' => $part->mime_id,
|
||||
'name' => $part->filename,
|
||||
'mimetype' => $part->mimetype,
|
||||
'size' => $part->size,
|
||||
);
|
||||
|
@ -509,14 +510,35 @@ class kolab_storage_folder
|
|||
|
||||
// copy attachments from old message
|
||||
if (!empty($object['_msguid']) && ($old = $this->cache->get($object['_msguid'], $type, $object['_mailbox']))) {
|
||||
foreach ((array)$old['_attachments'] as $name => $att) {
|
||||
if (!isset($object['_attachments'][$name])) {
|
||||
$object['_attachments'][$name] = $old['_attachments'][$name];
|
||||
foreach ((array)$old['_attachments'] as $key => $att) {
|
||||
if (!isset($object['_attachments'][$key])) {
|
||||
$object['_attachments'][$key] = $old['_attachments'][$key];
|
||||
}
|
||||
// unset deleted attachment entries
|
||||
if ($object['_attachments'][$key] == false) {
|
||||
unset($object['_attachments'][$key]);
|
||||
}
|
||||
// load photo.attachment from old Kolab2 format to be directly embedded in xcard block
|
||||
if ($name == 'photo.attachment' && !isset($object['photo']) && !$object['_attachments'][$name]['content'] && $att['id']) {
|
||||
else if ($key == 'photo.attachment' && !isset($object['photo']) && !$object['_attachments'][$key]['content'] && $att['id']) {
|
||||
$object['photo'] = $this->get_attachment($object['_msguid'], $att['id'], $object['_mailbox']);
|
||||
unset($object['_attachments'][$name]);
|
||||
unset($object['_attachments'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generate unique keys (used as content-id) for attachments
|
||||
if (is_array($object['_attachments'])) {
|
||||
$numatt = count($object['_attachments']);
|
||||
foreach ($object['_attachments'] as $key => $attachment) {
|
||||
if (is_numeric($key) && $key < $numatt) {
|
||||
// derrive content-id from attachment file name
|
||||
$ext = preg_match('/(\.[a-z0-9]{1,6})$/i', $attachment['name'], $m) ? $m[1] : null;
|
||||
$basename = preg_replace('/[^a-z0-9_.-]/i', '', basename($attachment['name'], $ext)); // to 7bit ascii
|
||||
if (!$basename) $basename = 'noname';
|
||||
$cid = $basename . '.' . microtime(true) . $ext;
|
||||
|
||||
$object['_attachments'][$cid] = $attachment;
|
||||
unset($object['_attachments'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -685,24 +707,25 @@ class kolab_storage_folder
|
|||
|
||||
// save object attachments as separate parts
|
||||
// TODO: optimize memory consumption by using tempfiles for transfer
|
||||
foreach ((array)$object['_attachments'] as $name => $att) {
|
||||
foreach ((array)$object['_attachments'] as $key => $att) {
|
||||
if (empty($att['content']) && !empty($att['id'])) {
|
||||
$msguid = !empty($object['_msguid']) ? $object['_msguid'] : $object['uid'];
|
||||
$att['content'] = $this->get_attachment($msguid, $att['id'], $object['_mailbox']);
|
||||
}
|
||||
|
||||
$headers = array('Content-ID' => Mail_mimePart::encodeHeader('Content-ID', '<' . $name . '>', RCMAIL_CHARSET, 'quoted-printable'));
|
||||
$headers = array('Content-ID' => Mail_mimePart::encodeHeader('Content-ID', '<' . $key . '>', RCMAIL_CHARSET, 'quoted-printable'));
|
||||
$name = !empty($att['name']) ? $att['name'] : $key;
|
||||
|
||||
if (!empty($att['content'])) {
|
||||
$mime->addAttachment($att['content'], $att['mimetype'], $name, false, 'base64', 'attachment', '', '', '', null, null, '', null, $headers);
|
||||
$mime->addAttachment($att['content'], $att['mimetype'], $name, false, 'base64', 'attachment', '', '', '', null, null, '', RCMAIL_CHARSET, $headers);
|
||||
$part_id++;
|
||||
}
|
||||
else if (!empty($att['path'])) {
|
||||
$mime->addAttachment($att['path'], $att['mimetype'], $name, true, 'base64', 'attachment', '', '', '', null, null, '', null, $headers);
|
||||
$mime->addAttachment($att['path'], $att['mimetype'], $name, true, 'base64', 'attachment', '', '', '', null, null, '', RCMAIL_CHARSET, $headers);
|
||||
$part_id++;
|
||||
}
|
||||
|
||||
$object['_attachments'][$name]['id'] = $part_id;
|
||||
$object['_attachments'][$key]['id'] = $part_id;
|
||||
}
|
||||
|
||||
return $mime->getMessage();
|
||||
|
|
Loading…
Add table
Reference in a new issue