Merge branch 'dev/kolab3' of ssh://git.kolabsys.com/git/roundcube into dev/kolab3
This commit is contained in:
commit
12e59189cb
9 changed files with 239 additions and 93 deletions
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* @author Aleksander Machniak <machniak@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com>
|
||||
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
@ -156,7 +156,7 @@ class kolab_addressbook_ui
|
|||
);
|
||||
|
||||
if (!empty($options) && ($options['norename'] || $options['protected'])) {
|
||||
$foldername = Q(str_replace($delimiter, ' » ', rcube_kolab::object_name($folder)));
|
||||
$foldername = Q(str_replace($delimiter, ' » ', kolab_storage::object_name($folder)));
|
||||
}
|
||||
else {
|
||||
$foldername = new html_inputfield(array('name' => '_name', 'id' => '_name', 'size' => 30));
|
||||
|
@ -178,7 +178,7 @@ class kolab_addressbook_ui
|
|||
$hidden_fields[] = array('name' => '_parent', 'value' => $path_imap);
|
||||
}
|
||||
else {
|
||||
$select = rcube_kolab::folder_selector('contact', array('name' => '_parent'), $folder);
|
||||
$select = kolab_storage::folder_selector('contact', array('name' => '_parent'), $folder);
|
||||
|
||||
$form['props']['fieldsets']['location']['content']['path'] = array(
|
||||
'label' => $this->plugin->gettext('parentbook'),
|
||||
|
|
|
@ -46,7 +46,7 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
'department' => array('limit' => 1),
|
||||
'email' => array('subtypes' => null),
|
||||
'phone' => array(),
|
||||
'address' => array('subtypes' => array('home','business')),
|
||||
'address' => array('subtypes' => array('home','work')),
|
||||
'officelocation' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1,
|
||||
'label' => 'kolab_addressbook.officelocation', 'category' => 'main'),
|
||||
'website' => array('subtypes' => null),
|
||||
|
@ -249,6 +249,7 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
|
||||
// list member of the selected group
|
||||
if ($this->gid) {
|
||||
$this->_fetch_groups();
|
||||
$seen = array();
|
||||
$this->result->count = 0;
|
||||
foreach ((array)$this->distlists[$this->gid]['member'] as $member) {
|
||||
|
@ -256,8 +257,11 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
if (is_array($this->filter['ids']) && array_search($member['ID'], $this->filter['ids']) === false)
|
||||
continue;
|
||||
|
||||
if ($this->contacts[$member['ID']] && !$seen[$member['ID']]++)
|
||||
$contact = $this->storagefolder->get_object($member['uid']);
|
||||
if ($contact && !$seen[$member['ID']]++) {
|
||||
$this->contacts[$member['ID']] = $this->_to_rcube_contact($contact);
|
||||
$this->result->count++;
|
||||
}
|
||||
}
|
||||
$ids = array_keys($seen);
|
||||
}
|
||||
|
@ -518,11 +522,11 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
|
||||
$saved = $this->storagefolder->save($object, 'contact');
|
||||
|
||||
if (PEAR::isError($saved)) {
|
||||
if (!$saved) {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving contact object to Kolab server:" . $saved->getMessage()),
|
||||
'message' => "Error saving contact object to Kolab server"),
|
||||
true, false);
|
||||
}
|
||||
else {
|
||||
|
@ -553,7 +557,7 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
$object = array_merge($old, $this->_from_rcube_contact($save_data));
|
||||
|
||||
$saved = $this->storagefolder->save($object, 'contact', $uid);
|
||||
if (!$saved || PEAR::isError($saved)) {
|
||||
if (!$saved) {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
|
@ -563,6 +567,8 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
else {
|
||||
$this->contacts[$id] = $this->_to_rcube_contact($object);
|
||||
$updated = true;
|
||||
|
||||
// TODO: update data in groups this contact is member of
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -717,16 +723,16 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
);
|
||||
$saved = $this->storagefolder->save($list, 'distribution-list');
|
||||
|
||||
if (PEAR::isError($saved)) {
|
||||
if (!$saved) {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
|
||||
'message' => "Error saving distribution-list object to Kolab server"),
|
||||
true, false);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
$id = md5($list['uid']);
|
||||
$id = $this->_uid2id($list['uid']);
|
||||
$this->distlists[$id] = $list;
|
||||
$result = array('id' => $id, 'name' => $name);
|
||||
}
|
||||
|
@ -748,11 +754,11 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
if ($list = $this->distlists[$gid])
|
||||
$deleted = $this->storagefolder->delete($list['uid']);
|
||||
|
||||
if (PEAR::isError($deleted)) {
|
||||
if (!$deleted) {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error deleting distribution-list object from the Kolab server:" . $deleted->getMessage()),
|
||||
'message' => "Error deleting distribution-list object from the Kolab server"),
|
||||
true, false);
|
||||
}
|
||||
else
|
||||
|
@ -778,11 +784,11 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
$saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']);
|
||||
}
|
||||
|
||||
if (PEAR::isError($saved)) {
|
||||
if (!$saved) {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
|
||||
'message' => "Error saving distribution-list object to Kolab server"),
|
||||
true, false);
|
||||
return false;
|
||||
}
|
||||
|
@ -806,7 +812,6 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
$exists = array();
|
||||
|
||||
$this->_fetch_groups();
|
||||
$this->_fetch_contacts();
|
||||
$list = $this->distlists[$gid];
|
||||
|
||||
foreach ((array)$list['member'] as $i => $member)
|
||||
|
@ -817,13 +822,14 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
|
||||
foreach ($ids as $contact_id) {
|
||||
if ($uid = $this->_id2uid($contact_id)) {
|
||||
$contact = $this->contacts[$contact_id];
|
||||
$contact = $this->storagefolder->get_object($uid);
|
||||
foreach ($this->get_col_values('email', $contact, true) as $email) {
|
||||
$list['member'][] = array(
|
||||
'uid' => $uid,
|
||||
'display-name' => $contact['name'],
|
||||
'smtp-address' => $email,
|
||||
'mailto' => $email,
|
||||
'name' => $contact['name'],
|
||||
);
|
||||
break;
|
||||
}
|
||||
$this->groupmembers[$contact_id][] = $gid;
|
||||
$added++;
|
||||
|
@ -833,11 +839,11 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
if ($added)
|
||||
$saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']);
|
||||
|
||||
if (PEAR::isError($saved)) {
|
||||
if (!$saved) {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving distribution-list to Kolab server:" . $saved->getMessage()),
|
||||
'message' => "Error saving distribution-list to Kolab server"),
|
||||
true, false);
|
||||
$added = false;
|
||||
}
|
||||
|
@ -874,11 +880,11 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
$list['member'] = $new_member;
|
||||
$saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']);
|
||||
|
||||
if (PEAR::isError($saved)) {
|
||||
if (!$saved) {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
|
||||
'message' => "Error saving distribution-list object to Kolab server"),
|
||||
true, false);
|
||||
}
|
||||
else {
|
||||
|
@ -1046,8 +1052,10 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
}
|
||||
|
||||
// photo is stored as separate attachment
|
||||
if ($record['photo'] && ($att = $record['_attachments'][$record['photo']])) {
|
||||
$out['photo'] = $att['content'] ? $att['content'] : $this->storagefolder->get_attachment($record['uid'], $att['key']);
|
||||
if ($record['photo'] && strlen($record['photo']) < 255 && ($att = $record['_attachments'][$record['photo']])) {
|
||||
// only fetch photo content if requested
|
||||
if (rcmail::get_instance()->action == 'photo')
|
||||
$record['photo'] = $att['content'] ? $att['content'] : $this->storagefolder->get_attachment($record['uid'], $att['key']);
|
||||
}
|
||||
|
||||
// remove empty fields
|
||||
|
@ -1062,13 +1070,6 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
if (!$contact['uid'] && $contact['ID'])
|
||||
$contact['uid'] = $this->_id2uid($contact['ID']);
|
||||
|
||||
/*
|
||||
// format dates
|
||||
if ($object['birthday'] && ($date = @strtotime($object['birthday'])))
|
||||
$object['birthday'] = date('Y-m-d', $date);
|
||||
if ($object['anniversary'] && ($date = @strtotime($object['anniversary'])))
|
||||
$object['anniversary'] = date('Y-m-d', $date);
|
||||
*/
|
||||
$contact['email'] = array_filter($this->get_col_values('email', $contact, true));
|
||||
$contact['website'] = array_filter($this->get_col_values('website', $contact, true));
|
||||
$contact['im'] = array_filter($this->get_col_values('im', $contact, true));
|
||||
|
@ -1112,6 +1113,10 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
);
|
||||
$contact['photo'] = $attkey;
|
||||
}
|
||||
else if (isset($contact['photo']) && empty($contact['photo'])) {
|
||||
// unset photo attachment
|
||||
$contact['_attachments']['photo.attachment'] = false;
|
||||
}
|
||||
|
||||
return $contact;
|
||||
}
|
||||
|
|
28
plugins/kolab_addressbook/skins/larry/kolab_addressbook.css
Normal file
28
plugins/kolab_addressbook/skins/larry/kolab_addressbook.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
#directorylist li.addressbook.readonly,
|
||||
#directorylist li.addressbook.shared,
|
||||
#directorylist li.addressbook.other {
|
||||
/* background-image: url(kolab_folders.png); */
|
||||
background-position: 5px -1000px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#directorylist li.addressbook.readonly {
|
||||
background-position: 5px 0px;
|
||||
}
|
||||
|
||||
#directorylist li.addressbook.shared {
|
||||
background-position: 5px -54px;
|
||||
}
|
||||
|
||||
#directorylist li.addressbook.shared.readonly {
|
||||
background-position: 5px -72px;
|
||||
}
|
||||
|
||||
#directorylist li.addressbook.other {
|
||||
background-position: 5px -18px;
|
||||
}
|
||||
|
||||
#directorylist li.addressbook.other.readonly {
|
||||
background-position: 5px -36px;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<roundcube:object name="doctype" value="html5" />
|
||||
<html>
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
</head>
|
||||
<body class="iframe">
|
||||
|
||||
<h1 class="boxtitle"><roundcube:label name="kolab_addressbook.bookproperties" /></h1>
|
||||
|
||||
<div class="boxcontent">
|
||||
<roundcube:object name="bookdetails" class="propform" />
|
||||
</div>
|
||||
|
||||
<div id="formfooter">
|
||||
<div class="footerleft formbuttons">
|
||||
<roundcube:button command="book-save" type="input" class="button mainaction" label="save" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<roundcube:include file="/includes/footer.html" />
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -45,33 +45,33 @@ abstract class kolab_format
|
|||
/**
|
||||
* Generate random UID for Kolab objects
|
||||
*
|
||||
* @return string MD5 hash with a unique value
|
||||
* @return string UUID with a unique MD5 value
|
||||
*/
|
||||
public static function generate_uid()
|
||||
{
|
||||
return md5(uniqid(mt_rand(), true));
|
||||
return 'urn:uuid:' . md5(uniqid(mt_rand(), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given date/time value into a c_DateTime object
|
||||
* Convert the given date/time value into a cDateTime object
|
||||
*
|
||||
* @param mixed Date/Time value either as unix timestamp, date string or PHP DateTime object
|
||||
* @param DateTimeZone The timezone the date/time is in. Use global default if empty
|
||||
* @param boolean True of the given date has no time component
|
||||
* @return c_DateTime The libkolabxml date/time object or null on error
|
||||
* @return object The libkolabxml date/time object or null on error
|
||||
*/
|
||||
public static function getDateTime($datetime, $tz = null, $dateonly = false)
|
||||
public static function get_datetime($datetime, $tz = null, $dateonly = false)
|
||||
{
|
||||
if (!$tz) $tz = self::$timezone;
|
||||
$result = null;
|
||||
|
||||
if (is_numeric($datetime))
|
||||
$datetime = new DateTime('@'.$datetime, $tz);
|
||||
else if (is_string($datetime))
|
||||
else if (is_string($datetime) && strlen($datetime))
|
||||
$datetime = new DateTime($datetime, $tz);
|
||||
|
||||
if (is_a($datetime, 'DateTime')) {
|
||||
$result = new KolabDateTime();
|
||||
$result = new cDateTime();
|
||||
$result->setDate($datetime->format('Y'), $datetime->format('n'), $datetime->format('j'));
|
||||
|
||||
if (!$dateonly)
|
||||
|
@ -83,6 +83,41 @@ abstract class kolab_format
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given cDateTime into a PHP DateTime object
|
||||
*
|
||||
* @param object cDateTime The libkolabxml datetime object
|
||||
* @return object DateTime PHP datetime instance
|
||||
*/
|
||||
public static function php_datetime($cdt)
|
||||
{
|
||||
if (!is_object($cdt) || !$cdt->isValid())
|
||||
return null;
|
||||
|
||||
$d = new DateTime;
|
||||
$d->setTimezone(self::$timezone);
|
||||
|
||||
try {
|
||||
if ($tzs = $cdt->timezone()) {
|
||||
$tz = new DateTimeZone($tzs);
|
||||
$d->setTimezone($tz);
|
||||
}
|
||||
}
|
||||
catch (Exception $e) { }
|
||||
|
||||
$d->setDate($cdt->year(), $cdt->month(), $cdt->day());
|
||||
|
||||
if ($cdt->isDateOnly()) {
|
||||
$d->_dateonly = true;
|
||||
$d->setTime(12, 0, 0); // set time to noon to avoid timezone troubles
|
||||
}
|
||||
else {
|
||||
$d->setTime($cdt->hour(), $cdt->minute(), $cdt->second());
|
||||
}
|
||||
|
||||
return $d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a libkolabxml vector to a PHP array
|
||||
*
|
||||
|
|
|
@ -55,6 +55,7 @@ class kolab_format_contact extends kolab_format
|
|||
'body' => 'notes',
|
||||
'pgp-publickey' => 'pgppublickey',
|
||||
'free-busy-url' => 'freebusyurl',
|
||||
'picture' => 'photo',
|
||||
);
|
||||
private $kolab2_phonetypes = array(
|
||||
'home1' => 'home',
|
||||
|
@ -114,7 +115,7 @@ class kolab_format_contact extends kolab_format
|
|||
if (false && !$this->obj->created()) {
|
||||
if (!empty($object['created']))
|
||||
$object['created'] = new DateTime('now', self::$timezone);
|
||||
$this->obj->setCreated(self::getDateTime($object['created']));
|
||||
$this->obj->setCreated(self::get_datetime($object['created']));
|
||||
}
|
||||
|
||||
// do the hard work of setting object values
|
||||
|
@ -196,10 +197,10 @@ class kolab_format_contact extends kolab_format
|
|||
$this->obj->setNote($object['notes']);
|
||||
if ($object['freebusyurl'])
|
||||
$this->obj->setFreeBusyUrl($object['freebusyurl']);
|
||||
// if ($object['birthday'])
|
||||
// $this->obj->setBDay(self::getDateTime($object['birthday'], null, true));
|
||||
// if ($object['anniversary'])
|
||||
// $this->obj->setAnniversary(self::getDateTime($object['anniversary'], null, true));
|
||||
if ($object['birthday'])
|
||||
$this->obj->setBDay(self::get_datetime($object['birthday'], null, true));
|
||||
if ($object['anniversary'])
|
||||
$this->obj->setAnniversary(self::get_datetime($object['anniversary'], null, true));
|
||||
|
||||
// handle spouse, children, profession, initials, pgppublickey, etc.
|
||||
|
||||
|
@ -281,7 +282,13 @@ class kolab_format_contact extends kolab_format
|
|||
|
||||
$object['notes'] = $this->obj->note();
|
||||
$object['freebusyurl'] = $this->obj->freeBusyUrl();
|
||||
|
||||
|
||||
if ($bday = self::php_datetime($this->obj->bDay()))
|
||||
$object['birthday'] = $bday->format('c');
|
||||
|
||||
if ($anniversary = self::php_datetime($this->obj->anniversary()))
|
||||
$object['anniversary'] = $anniversary->format('c');
|
||||
|
||||
if ($g = $this->obj->gender())
|
||||
$object['gender'] = $g == Contact::Female ? 'female' : 'male';
|
||||
|
||||
|
@ -327,11 +334,6 @@ class kolab_format_contact extends kolab_format
|
|||
}
|
||||
}
|
||||
|
||||
// photo is stored as separate attachment
|
||||
if ($record['picture'] && ($att = $record['_attachments'][$record['picture']])) {
|
||||
$object['photo'] = $att['content'] ? $att['content'] : $this->contactstorage->getAttachment($att['key']);
|
||||
}
|
||||
|
||||
// remove empty fields
|
||||
$this->data = array_filter($object);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class kolab_format_distributionlist extends kolab_format
|
|||
|
||||
function __construct()
|
||||
{
|
||||
$obj = new DistList;
|
||||
$this->obj = new DistList;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,12 +35,28 @@ class kolab_format_distributionlist extends kolab_format
|
|||
|
||||
public function set(&$object)
|
||||
{
|
||||
// TODO: do the hard work of setting object values
|
||||
// set some automatic values if missing
|
||||
if (empty($object['uid']))
|
||||
$object['uid'] = self::generate_uid();
|
||||
|
||||
// do the hard work of setting object values
|
||||
$this->obj->setUid($object['uid']);
|
||||
$this->obj->setName($object['name']);
|
||||
|
||||
$members = new vectormember;
|
||||
foreach ($object['member'] as $member) {
|
||||
$m = new Member;
|
||||
$m->setName($member['name']);
|
||||
$m->setEmail($member['mailto']);
|
||||
$m->setUid($member['uid']);
|
||||
$members->push($m);
|
||||
}
|
||||
$this->obj->setMembers($members);
|
||||
}
|
||||
|
||||
public function is_valid()
|
||||
{
|
||||
return $this->data || (is_object($this->obj) && true /*$this->obj->isValid()*/);
|
||||
return $this->data || (is_object($this->obj) && $this->obj->isValid());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,40 +103,17 @@ class kolab_format_distributionlist extends kolab_format
|
|||
|
||||
$members = $this->obj->members();
|
||||
for ($i=0; $i < $members->size(); $i++) {
|
||||
$adr = self::decode_member($members->get($i));
|
||||
if ($adr[0]['mailto'])
|
||||
$member = $members->get($i);
|
||||
if ($mailto = $member->email())
|
||||
$object['member'][] = array(
|
||||
'mailto' => $adr[0]['mailto'],
|
||||
'name' => $adr[0]['name'],
|
||||
'uid' => '????',
|
||||
'mailto' => $mailto,
|
||||
'name' => $member->name(),
|
||||
'uid' => $member->uid(),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data = $object;
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a valid Mailto URL according to RFC 822
|
||||
*
|
||||
* @param string E-mail address
|
||||
* @param string Person name
|
||||
* @return string Formatted string
|
||||
*/
|
||||
public static function format_member($email, $name = '')
|
||||
{
|
||||
// let Roundcube internals do the job
|
||||
return 'mailto:' . format_email_recipient($email, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a mailto: url into a structured member component
|
||||
*
|
||||
* @param string RFC 822 mailto: string
|
||||
* @return array Hash array with member properties
|
||||
*/
|
||||
public static function decode_member($str)
|
||||
{
|
||||
$adr = rcube_mime::decode_address_list(preg_replace('/^mailto:/', '', $str));
|
||||
return $adr[0];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,4 +203,25 @@ class kolab_storage
|
|||
return $folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SELECT field with folders list
|
||||
*
|
||||
* @param string $type Folder type
|
||||
* @param array $attrs SELECT field attributes (e.g. name)
|
||||
* @param string $current The name of current folder (to skip it)
|
||||
*
|
||||
* @return html_select SELECT object
|
||||
*/
|
||||
public static function folder_selector($type, $attrs, $current = '')
|
||||
{
|
||||
// TODO: implement this
|
||||
|
||||
|
||||
// Build SELECT field of parent folder
|
||||
$select = new html_select($attrs);
|
||||
$select->add('---', '');
|
||||
|
||||
|
||||
return $select;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,16 +202,19 @@ class kolab_storage_folder
|
|||
* Fetch a Kolab object attachment which is stored in a separate part
|
||||
* of the mail MIME message that represents the Kolab record.
|
||||
*
|
||||
* @param string Object's UID
|
||||
* @param string The attachment key stored in the Kolab XML
|
||||
* @return mixed The attachment content as binary string
|
||||
* @param string Object's UID
|
||||
* @param string The attachment's mime number
|
||||
* @param string IMAP folder where message is stored;
|
||||
* If set, that also implies that the given UID is an IMAP UID
|
||||
* @return mixed The attachment content as binary string
|
||||
*/
|
||||
public function get_attachment($uid, $key)
|
||||
public function get_attachment($uid, $part, $mailbox = null)
|
||||
{
|
||||
// TODO: implement this
|
||||
if ($msguid = ($mailbox ? $uid : $this->uid2msguid($uid))) {
|
||||
if ($mailbox)
|
||||
$this->imap->set_folder($mailbox);
|
||||
|
||||
if ($msguid = $this->uid2msguid($uid)) {
|
||||
$message = new rcube_message($msguid);
|
||||
return $this->imap->get_message_part($msguid, $part);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -219,21 +222,34 @@ class kolab_storage_folder
|
|||
|
||||
|
||||
/**
|
||||
* Fetch the mime message from the storage server and extract
|
||||
* the Kolab groupware object from it
|
||||
*
|
||||
* @param string The IMAP message UID to fetch
|
||||
* @param string The object type expected
|
||||
* @return array Hash array representing the Kolab object
|
||||
*/
|
||||
private function read_object($msguid, $type = null)
|
||||
private function read_object($msguid, $type = null, $folder = null)
|
||||
{
|
||||
if (!$type) $type = $this->type;
|
||||
if (!$folder) $folder = $this->name;
|
||||
$ctype= self::KTYPE_PREFIX . $type;
|
||||
|
||||
$this->imap->set_folder($this->name);
|
||||
$this->imap->set_folder($folder);
|
||||
$message = new rcube_message($msguid);
|
||||
$attachments = array();
|
||||
|
||||
// get XML part
|
||||
foreach ((array)$message->attachments as $part) {
|
||||
if ($part->mimetype == $ctype || preg_match('!application/([a-z]+\+)?xml!', $part->mimetype)) {
|
||||
if (!$xml && ($part->mimetype == $ctype || preg_match('!application/([a-z]+\+)?xml!', $part->mimetype))) {
|
||||
$xml = $part->body ? $part->body : $message->get_part_content($part->mime_id);
|
||||
break;
|
||||
}
|
||||
else if ($part->filename) {
|
||||
$attachments[$part->filename] = array(
|
||||
'key' => $part->mime_id,
|
||||
'type' => $part->mimetype,
|
||||
'size' => $part->size,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,6 +287,7 @@ class kolab_storage_folder
|
|||
$object = $format->to_array();
|
||||
$object['_msguid'] = $msguid;
|
||||
$object['_mailbox'] = $this->name;
|
||||
$object['_attachments'] = $attachments;
|
||||
return $object;
|
||||
}
|
||||
|
||||
|
@ -291,6 +308,15 @@ class kolab_storage_folder
|
|||
if (!$type)
|
||||
$type = $this->type;
|
||||
|
||||
// copy attachments from old message
|
||||
if (!empty($object['_msguid']) && ($old = $this->read_object($object['_msguid'], $type, $object['_mailbox']))) {
|
||||
foreach ($old['_attachments'] as $name => $att) {
|
||||
if (!isset($object['_attachments'][$name])) {
|
||||
$object['_attachments'][$name] = $old['_attachments'][$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($raw_msg = $this->build_message($object, $type)) {
|
||||
$result = $this->imap->save_message($this->name, $raw_msg, '', false);
|
||||
|
||||
|
@ -415,6 +441,18 @@ class kolab_storage_folder
|
|||
'', RCMAIL_CHARSET
|
||||
);
|
||||
|
||||
// save object attachments as separate parts
|
||||
// TODO: optimize memory consumption by using tempfiles for transfer
|
||||
foreach ((array)$object['_attachments'] as $name => $att) {
|
||||
if (empty($att['content']) && !empty($att['key'])) {
|
||||
$msguid = !empty($object['_msguid']) ? $object['_msguid'] : $object['uid'];
|
||||
$att['content'] = $this->get_attachment($msguid, $att['key'], $object['_mailbox']);
|
||||
}
|
||||
if (!empty($att['content'])) {
|
||||
$mime->addAttachment($att['content'], $att['type'], $name, false);
|
||||
}
|
||||
}
|
||||
|
||||
return $mime->getMessage();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue