Adapt to recent changes in libkolabxml:
- store manager, assistant, spouse and children in Related objects - add support for both uid and mailto distlist members - fix contact photo transition from old Kolab2 format
This commit is contained in:
parent
824c89b326
commit
88d6ce9500
4 changed files with 140 additions and 58 deletions
|
@ -47,8 +47,8 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
'email' => array('subtypes' => null),
|
||||
'phone' => array(),
|
||||
'address' => array('subtypes' => array('home','work')),
|
||||
'officelocation' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1,
|
||||
'label' => 'kolab_addressbook.officelocation', 'category' => 'main'),
|
||||
// 'officelocation' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1,
|
||||
// 'label' => 'kolab_addressbook.officelocation', 'category' => 'main'),
|
||||
'website' => array('subtypes' => null),
|
||||
'im' => array('subtypes' => null),
|
||||
'gender' => array('limit' => 1),
|
||||
|
@ -58,10 +58,10 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
'anniversary' => array('limit' => 1),
|
||||
'profession' => array('type' => 'text', 'size' => 40, 'maxlength' => 80, 'limit' => 1,
|
||||
'label' => 'kolab_addressbook.profession', 'category' => 'personal'),
|
||||
'manager' => array('limit' => 1),
|
||||
'assistant' => array('limit' => 1),
|
||||
'manager' => array('limit' => null),
|
||||
'assistant' => array('limit' => null),
|
||||
'spouse' => array('limit' => 1),
|
||||
'children' => array('type' => 'text', 'size' => 40, 'maxlength' => 80, 'limit' => 1,
|
||||
'children' => array('type' => 'text', 'size' => 40, 'maxlength' => 80, 'limit' => null,
|
||||
'label' => 'kolab_addressbook.children', 'category' => 'personal'),
|
||||
'pgppublickey' => array('type' => 'text', 'size' => 40, 'limit' => 1,
|
||||
'label' => 'kolab_addressbook.pgppublickey'),
|
||||
|
@ -69,7 +69,7 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
'label' => 'kolab_addressbook.freebusyurl'),
|
||||
'notes' => array(),
|
||||
'photo' => array(),
|
||||
// TODO: define more Kolab-specific fields such as: role, language, latitude, longitude
|
||||
// TODO: define more Kolab-specific fields such as: language, latitude, longitude
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -257,11 +257,14 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
if (is_array($this->filter['ids']) && array_search($member['ID'], $this->filter['ids']) === false)
|
||||
continue;
|
||||
|
||||
$contact = $this->storagefolder->get_object($member['uid']);
|
||||
if ($contact && !$seen[$member['ID']]++) {
|
||||
if ($member['uid'] && ($contact = $this->storagefolder->get_object($member['uid'])) && !$seen[$member['ID']]++) {
|
||||
$this->contacts[$member['ID']] = $this->_to_rcube_contact($contact);
|
||||
$this->result->count++;
|
||||
}
|
||||
else if ($member['email'] && !$seen[$member['ID']]++) {
|
||||
$this->contacts[$member['ID']] = $member;
|
||||
$this->result->count++;
|
||||
}
|
||||
}
|
||||
$ids = array_keys($seen);
|
||||
}
|
||||
|
@ -458,8 +461,18 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
*/
|
||||
public function get_record($id, $assoc=false)
|
||||
{
|
||||
if ($object = $this->storagefolder->get_object($this->_id2uid($id))) {
|
||||
$rec = null;
|
||||
$uid = $this->_id2uid($id);
|
||||
if (strpos($uid, 'mailto:') === 0) {
|
||||
$this->_fetch_groups(true);
|
||||
$rec = $this->contacts[$id];
|
||||
$this->readonly = true; // set source to read-only
|
||||
}
|
||||
else if ($object = $this->storagefolder->get_object($uid)) {
|
||||
$rec = $this->_to_rcube_contact($object);
|
||||
}
|
||||
|
||||
if ($rec) {
|
||||
$this->result = new rcube_result_set(1);
|
||||
$this->result->add($rec);
|
||||
return $assoc ? $rec : $this->result;
|
||||
|
@ -592,19 +605,22 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
$count = 0;
|
||||
foreach ($ids as $id) {
|
||||
if ($uid = $this->_id2uid($id)) {
|
||||
$deleted = $this->storagefolder->delete($uid, $force);
|
||||
$is_mailto = strpos($uid, 'mailto:') === 0;
|
||||
$deleted = $is_mailto || $this->storagefolder->delete($uid, $force);
|
||||
|
||||
if (!$deleted) {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error deleting a contact object from the Kolab server"),
|
||||
'message' => "Error deleting a contact object $uid from the Kolab server"),
|
||||
true, false);
|
||||
}
|
||||
else {
|
||||
// remove from distribution lists
|
||||
foreach ((array)$this->groupmembers[$id] as $gid)
|
||||
$this->remove_from_group($gid, $id);
|
||||
foreach ((array)$this->groupmembers[$id] as $gid) {
|
||||
if (!$is_mailto || $gid == $this->gid)
|
||||
$this->remove_from_group($gid, $id);
|
||||
}
|
||||
|
||||
// clear internal cache
|
||||
unset($this->contacts[$id], $this->groupmembers[$id]);
|
||||
|
@ -776,7 +792,7 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
$added = 0;
|
||||
$exists = array();
|
||||
|
||||
$this->_fetch_groups();
|
||||
$this->_fetch_groups(true);
|
||||
$list = $this->distlists[$gid];
|
||||
|
||||
foreach ((array)$list['member'] as $i => $member)
|
||||
|
@ -786,16 +802,24 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
$ids = array_diff($ids, $exists);
|
||||
|
||||
foreach ($ids as $contact_id) {
|
||||
if ($uid = $this->_id2uid($contact_id)) {
|
||||
$contact = $this->storagefolder->get_object($uid);
|
||||
foreach ($this->get_col_values('email', $contact, true) as $email) {
|
||||
$list['member'][] = array(
|
||||
'uid' => $uid,
|
||||
'mailto' => $email,
|
||||
'name' => $contact['name'],
|
||||
);
|
||||
$uid = $this->_id2uid($contact_id);
|
||||
if ($contact = $this->storagefolder->get_object($uid)) {
|
||||
foreach ($this->get_col_values('email', $contact, true) as $email)
|
||||
break;
|
||||
}
|
||||
|
||||
$list['member'][] = array(
|
||||
'uid' => $uid,
|
||||
'email' => $email,
|
||||
'name' => $contact['name'],
|
||||
);
|
||||
$this->groupmembers[$contact_id][] = $gid;
|
||||
$added++;
|
||||
}
|
||||
else if (strpos($uid, 'mailto:') === 0 && ($contact = $this->contacts[$contact_id])) {
|
||||
$list['member'][] = array(
|
||||
'email' => $contact['email'],
|
||||
'name' => $contact['name'],
|
||||
);
|
||||
$this->groupmembers[$contact_id][] = $gid;
|
||||
$added++;
|
||||
}
|
||||
|
@ -953,16 +977,20 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
/**
|
||||
* Read distribution-lists AKA groups from server
|
||||
*/
|
||||
private function _fetch_groups()
|
||||
private function _fetch_groups($with_contacts = false)
|
||||
{
|
||||
if (!isset($this->distlists)) {
|
||||
$this->distlists = $this->groupmembers = array();
|
||||
foreach ((array)$this->storagefolder->get_objects('distribution-list') as $record) {
|
||||
$record['ID'] = $this->_uid2id($record['uid']);
|
||||
foreach ((array)$record['member'] as $i => $member) {
|
||||
$mid = $this->_uid2id($member['uid']);
|
||||
$mid = $this->_uid2id($member['uid'] ? $member['uid'] : 'mailto:' . $member['email']);
|
||||
$record['member'][$i]['ID'] = $mid;
|
||||
$record['member'][$i]['readonly'] = empty($member['uid']);
|
||||
$this->groupmembers[$mid][] = $record['ID'];
|
||||
|
||||
if ($with_contacts && empty($member['uid']))
|
||||
$this->contacts[$mid] = $record['member'][$i];
|
||||
}
|
||||
$this->distlists[$record['ID']] = $record;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,14 @@ class kolab_format_contact extends kolab_format
|
|||
|
||||
private $gendermap = array(
|
||||
'female' => Contact::Female,
|
||||
'male' => Contact::Male,
|
||||
'male' => Contact::Male,
|
||||
);
|
||||
|
||||
private $relatedmap = array(
|
||||
'manager' => Related::Manager,
|
||||
'assistant' => Related::Assistant,
|
||||
'spouse' => Related::Spouse,
|
||||
'children' => Related::Child,
|
||||
);
|
||||
|
||||
// old Kolab 2 format field map
|
||||
|
@ -160,15 +167,23 @@ class kolab_format_contact extends kolab_format
|
|||
$org = new Affiliation;
|
||||
if ($object['organization'])
|
||||
$org->setOrganisation($object['organization']);
|
||||
if ($object['department'])
|
||||
$org->setOrganisationalUnits(self::array2vector($object['department']));
|
||||
if ($object['jobtitle'])
|
||||
$org->setTitles(self::array2vector($object['jobtitle']));
|
||||
if ($object['officelocation'])
|
||||
$org->setOffices(self::array2vector($object['officelocation']));
|
||||
if ($object['manager'])
|
||||
$org->setManagers(self::array2vector($object['manager']));
|
||||
if ($object['assistant'])
|
||||
$org->setAssistants(self::array2vector($object['assistant']));
|
||||
// department ?
|
||||
$org->setRoles(self::array2vector($object['jobtitle']));
|
||||
// if ($object['officelocation'])
|
||||
// $org->setOffices(self::array2vector($object['officelocation']));
|
||||
|
||||
$rels = new vectorrelated;
|
||||
if ($object['manager']) {
|
||||
foreach ((array)$object['manager'] as $manager)
|
||||
$rels->push(new Related(Related::Text, $manager, Related::Manager));
|
||||
}
|
||||
if ($object['assistant']) {
|
||||
foreach ((array)$object['assistant'] as $assistant)
|
||||
$rels->push(new Related(Related::Text, $assistant, Related::Assistant));
|
||||
}
|
||||
$org->setRelateds($rels);
|
||||
|
||||
$orgs = new vectoraffiliation;
|
||||
$orgs->push($org);
|
||||
|
@ -226,21 +241,26 @@ class kolab_format_contact extends kolab_format
|
|||
$this->obj->setAnniversary(self::get_datetime($object['anniversary'], null, true));
|
||||
|
||||
if (!empty($object['photo'])) {
|
||||
if (strlen($object['photo']) < 255 && ($att = $object['_attachments'][$object['photo']])) {
|
||||
if ($att['content'])
|
||||
$this->obj->setPhoto($att['content'], $att['type']);
|
||||
$object['_attachments'][$object['photo']] = false;
|
||||
}
|
||||
else if ($type = rc_image_content_type($object['photo'])) {
|
||||
if ($type = rc_image_content_type($object['photo']))
|
||||
$this->obj->setPhoto($object['photo'], $type);
|
||||
$object['_attachments']['photo.attachment'] = false;
|
||||
}
|
||||
}
|
||||
else if (isset($object['photo'])) {
|
||||
$this->obj->setPhoto('','');
|
||||
}
|
||||
|
||||
// TODO: handle spouse, children, profession, initials, pgppublickey, etc.
|
||||
// spouse and children are relateds
|
||||
$rels = new vectorrelated;
|
||||
if ($object['spouse']) {
|
||||
$rels->push(new Related(Related::Text, $object['spouse'], Related::Spouse));
|
||||
}
|
||||
if ($object['children']) {
|
||||
foreach ((array)$object['children'] as $child)
|
||||
$rels->push(new Related(Related::Text, $child, Related::Child));
|
||||
}
|
||||
$this->obj->setRelateds($rels);
|
||||
|
||||
// TODO: handle profession, language, pgppublickey, etc.
|
||||
|
||||
|
||||
// cache this data
|
||||
$this->data = $object;
|
||||
|
@ -285,10 +305,10 @@ class kolab_format_contact extends kolab_format
|
|||
if ($orgs->size()) {
|
||||
$org = $orgs->get(0);
|
||||
$object['organization'] = $org->organisation();
|
||||
$object['jobtitle'] = join(' ', self::vector2array($org->titles()));
|
||||
$object['manager'] = join(' ', self::vector2array($org->managers()));
|
||||
$object['assistant'] = join(' ', self::vector2array($org->assistants()));
|
||||
$object['officelocation'] = join(' ', self::vector2array($org->offices()));
|
||||
$object['jobtitle'] = join(' ', self::vector2array($org->roles()));
|
||||
// $object['officelocation'] = join(' ', self::vector2array($org->offices()));
|
||||
$object['department'] = join(' ', self::vector2array($org->organisationalUnits()));
|
||||
$this->read_relateds($org->relateds(), $object);
|
||||
}
|
||||
|
||||
$object['email'] = self::vector2array($this->obj->emailAddresses());
|
||||
|
@ -334,6 +354,9 @@ class kolab_format_contact extends kolab_format
|
|||
if ($this->obj->photoMimetype())
|
||||
$object['photo'] = $this->obj->photo();
|
||||
|
||||
// relateds -> spouse, children
|
||||
$this->read_relateds($this->obj->relateds(), $object);
|
||||
|
||||
$this->data = $object;
|
||||
return $this->data;
|
||||
}
|
||||
|
@ -381,4 +404,26 @@ class kolab_format_contact extends kolab_format
|
|||
// remove empty fields
|
||||
$this->data = array_filter($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to map contents of a Related vector to the contact data object
|
||||
*/
|
||||
private function read_relateds($rels, &$object)
|
||||
{
|
||||
$typemap = array_flip($this->relatedmap);
|
||||
|
||||
for ($i=0; $i < $rels->size(); $i++) {
|
||||
$rel = $rels->get($i);
|
||||
if ($rel->type() != Related::Text) // we can't handle UID relations yet
|
||||
continue;
|
||||
|
||||
$types = $rel->relationTypes();
|
||||
foreach ($typemap as $t => $field) {
|
||||
if ($types & $t) {
|
||||
$object[$field][] = $rel->text();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,14 +61,21 @@ class kolab_format_distributionlist extends kolab_format
|
|||
|
||||
$this->obj->setName($object['name']);
|
||||
|
||||
$members = new vectormember;
|
||||
$seen = array();
|
||||
$members = new vectorcontactref;
|
||||
foreach ($object['member'] as $member) {
|
||||
$m = new Member;
|
||||
if ($member['uid'])
|
||||
$m = new ContactReference(ContactReference::UidReference, $member['uid']);
|
||||
else if ($member['email'])
|
||||
$m = new ContactReference(ContactReference::EmailReference, $member['email']);
|
||||
else
|
||||
continue;
|
||||
|
||||
$m->setName($member['name']);
|
||||
$m->setEmail($member['mailto']);
|
||||
$m->setUid($member['uid']);
|
||||
$members->push($m);
|
||||
$seen[$member['email']]++;
|
||||
}
|
||||
|
||||
$this->obj->setMembers($members);
|
||||
}
|
||||
|
||||
|
@ -91,7 +98,7 @@ class kolab_format_distributionlist extends kolab_format
|
|||
|
||||
foreach ($record['member'] as $member) {
|
||||
$object['member'][] = array(
|
||||
'mailto' => $member['smtp-address'],
|
||||
'email' => $member['smtp-address'],
|
||||
'name' => $member['display-name'],
|
||||
'uid' => $member['uid'],
|
||||
);
|
||||
|
@ -122,11 +129,11 @@ class kolab_format_distributionlist extends kolab_format
|
|||
$members = $this->obj->members();
|
||||
for ($i=0; $i < $members->size(); $i++) {
|
||||
$member = $members->get($i);
|
||||
if ($mailto = $member->email())
|
||||
# if ($member->type() == ContactReference::UidReference && ($uid = $member->uid()))
|
||||
$object['member'][] = array(
|
||||
'mailto' => $mailto,
|
||||
'name' => $member->name(),
|
||||
'uid' => $member->uid(),
|
||||
'email' => $member->email(),
|
||||
'name' => $member->name(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -338,9 +338,11 @@ class kolab_storage_folder
|
|||
if (!isset($object['_attachments'][$name])) {
|
||||
$object['_attachments'][$name] = $old['_attachments'][$name];
|
||||
}
|
||||
// load photo.attachment contents to be directly embedded in xcard block
|
||||
if ($name == 'photo.attachment' && !$object['_attachments'][$name]['content'] && $att['key'])
|
||||
$object['_attachments'][$name]['content'] = $this->get_attachment($object['_msguid'], $att['key'], $object['_mailbox']);
|
||||
// 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['key']) {
|
||||
$object['photo'] = $this->get_attachment($object['_msguid'], $att['key'], $object['_mailbox']);
|
||||
unset($object['_attachments'][$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue