Changeset View
Changeset View
Standalone View
Standalone View
plugins/kolab_addressbook/lib/rcube_kolab_contacts.php
Show All 28 Lines | |||||
class rcube_kolab_contacts extends rcube_addressbook | class rcube_kolab_contacts extends rcube_addressbook | ||||
{ | { | ||||
public $primary_key = 'ID'; | public $primary_key = 'ID'; | ||||
public $rights = 'lrs'; | public $rights = 'lrs'; | ||||
public $readonly = true; | public $readonly = true; | ||||
public $undelete = true; | public $undelete = true; | ||||
public $groups = true; | public $groups = true; | ||||
public $coltypes = array( | public $coltypes = array( | ||||
'name' => array('limit' => 1), | 'name' => array('limit' => 1), | ||||
'firstname' => array('limit' => 1), | 'firstname' => array('limit' => 1), | ||||
'surname' => array('limit' => 1), | 'surname' => array('limit' => 1), | ||||
'middlename' => array('limit' => 1), | 'middlename' => array('limit' => 1), | ||||
'prefix' => array('limit' => 1), | 'prefix' => array('limit' => 1), | ||||
'suffix' => array('limit' => 1), | 'suffix' => array('limit' => 1), | ||||
'nickname' => array('limit' => 1), | 'nickname' => array('limit' => 1), | ||||
'jobtitle' => array('limit' => 1), | 'jobtitle' => array('limit' => 1), | ||||
'organization' => array('limit' => 1), | 'organization' => array('limit' => 1), | ||||
'department' => array('limit' => 1), | 'department' => array('limit' => 1), | ||||
'email' => array('subtypes' => array('home','work','other')), | 'email' => array('subtypes' => array('home','work','other')), | ||||
'phone' => array(), | 'phone' => array(), | ||||
'address' => array('subtypes' => array('home','work','office')), | 'address' => array('subtypes' => array('home','work','office')), | ||||
'website' => array('subtypes' => array('homepage','blog')), | 'website' => array('subtypes' => array('homepage','blog')), | ||||
'im' => array('subtypes' => null), | 'im' => array('subtypes' => null), | ||||
'gender' => array('limit' => 1), | 'gender' => array('limit' => 1), | ||||
'birthday' => array('limit' => 1), | 'birthday' => array('limit' => 1), | ||||
'anniversary' => array('limit' => 1), | 'anniversary' => array('limit' => 1), | ||||
'profession' => array('type' => 'text', 'size' => 40, 'maxlength' => 80, 'limit' => 1, | 'profession' => array( | ||||
'label' => 'kolab_addressbook.profession', 'category' => 'personal'), | 'type' => 'text', | ||||
'size' => 40, | |||||
'maxlength' => 80, | |||||
'limit' => 1, | |||||
'label' => 'kolab_addressbook.profession', | |||||
'category' => 'personal' | |||||
), | |||||
'manager' => array('limit' => null), | 'manager' => array('limit' => null), | ||||
'assistant' => array('limit' => null), | 'assistant' => array('limit' => null), | ||||
'spouse' => array('limit' => 1), | 'spouse' => array('limit' => 1), | ||||
'children' => array('type' => 'text', 'size' => 40, 'maxlength' => 80, 'limit' => null, | 'children' => array( | ||||
'label' => 'kolab_addressbook.children', 'category' => 'personal'), | 'type' => 'text', | ||||
'freebusyurl' => array('type' => 'text', 'size' => 40, 'limit' => 1, | 'size' => 40, | ||||
'label' => 'kolab_addressbook.freebusyurl'), | 'maxlength' => 80, | ||||
'pgppublickey' => array('type' => 'textarea', 'size' => 70, 'rows' => 10, 'limit' => 1, | 'limit' => null, | ||||
'label' => 'kolab_addressbook.pgppublickey'), | 'label' => 'kolab_addressbook.children', | ||||
'pkcs7publickey' => array('type' => 'textarea', 'size' => 70, 'rows' => 10, 'limit' => 1, | 'category' => 'personal' | ||||
'label' => 'kolab_addressbook.pkcs7publickey'), | ), | ||||
'freebusyurl' => array( | |||||
'type' => 'text', | |||||
'size' => 40, | |||||
'limit' => 1, | |||||
'label' => 'kolab_addressbook.freebusyurl' | |||||
), | |||||
'pgppublickey' => array( | |||||
'type' => 'textarea', | |||||
'size' => 70, | |||||
'rows' => 10, | |||||
'limit' => 1, | |||||
'label' => 'kolab_addressbook.pgppublickey' | |||||
), | |||||
'pkcs7publickey' => array( | |||||
'type' => 'textarea', | |||||
'size' => 70, | |||||
'rows' => 10, | |||||
'limit' => 1, | |||||
'label' => 'kolab_addressbook.pkcs7publickey' | |||||
), | |||||
'notes' => array('limit' => 1), | 'notes' => array('limit' => 1), | ||||
'photo' => array('limit' => 1), | 'photo' => array('limit' => 1), | ||||
// TODO: define more Kolab-specific fields such as: language, latitude, longitude, crypto settings | // TODO: define more Kolab-specific fields such as: language, latitude, longitude, crypto settings | ||||
); | ); | ||||
/** | /** | ||||
* vCard additional fields mapping | * vCard additional fields mapping | ||||
*/ | */ | ||||
public $vcard_map = array( | public $vcard_map = array( | ||||
'profession' => 'X-PROFESSION', | 'profession' => 'X-PROFESSION', | ||||
'officelocation' => 'X-OFFICE-LOCATION', | 'officelocation' => 'X-OFFICE-LOCATION', | ||||
'initials' => 'X-INITIALS', | 'initials' => 'X-INITIALS', | ||||
'children' => 'X-CHILDREN', | 'children' => 'X-CHILDREN', | ||||
'freebusyurl' => 'X-FREEBUSY-URL', | 'freebusyurl' => 'X-FREEBUSY-URL', | ||||
'pgppublickey' => 'KEY', | 'pgppublickey' => 'KEY', | ||||
); | ); | ||||
/** | /** | ||||
* List of date type fields | * List of date type fields | ||||
*/ | */ | ||||
public $date_cols = array('birthday', 'anniversary'); | public $date_cols = array('birthday', 'anniversary'); | ||||
private $gid; | private $gid; | ||||
private $storagefolder; | private $storagefolder; | ||||
private $dataset; | private $dataset; | ||||
private $sortindex; | private $sortindex; | ||||
private $contacts; | private $contacts; | ||||
private $distlists; | private $distlists; | ||||
private $groupmembers; | private $groupmembers; | ||||
private $filter; | private $filter; | ||||
private $result; | private $result; | ||||
private $namespace; | private $namespace; | ||||
private $imap_folder = 'INBOX/Contacts'; | private $imap_folder = 'INBOX/Contacts'; | ||||
private $action; | private $action; | ||||
// list of fields used for searching in "All fields" mode | // list of fields used for searching in "All fields" mode | ||||
private $search_fields = array( | private $search_fields = array( | ||||
'name', | 'name', | ||||
'firstname', | 'firstname', | ||||
'surname', | 'surname', | ||||
'middlename', | 'middlename', | ||||
'prefix', | 'prefix', | ||||
'suffix', | 'suffix', | ||||
'nickname', | 'nickname', | ||||
'jobtitle', | 'jobtitle', | ||||
'organization', | 'organization', | ||||
'department', | 'department', | ||||
'email', | 'email', | ||||
'phone', | 'phone', | ||||
'address', | 'address', | ||||
'profession', | 'profession', | ||||
'manager', | 'manager', | ||||
'assistant', | 'assistant', | ||||
'spouse', | 'spouse', | ||||
'children', | 'children', | ||||
'notes', | 'notes', | ||||
); | ); | ||||
public function __construct($imap_folder = null) | public function __construct($imap_folder = null) | ||||
{ | { | ||||
if ($imap_folder) { | if ($imap_folder) { | ||||
$this->imap_folder = $imap_folder; | $this->imap_folder = $imap_folder; | ||||
} | } | ||||
// extend coltypes configuration | // extend coltypes configuration | ||||
$format = kolab_format::factory('contact'); | $format = kolab_format::factory('contact'); | ||||
$this->coltypes['phone']['subtypes'] = array_keys($format->phonetypes); | $this->coltypes['phone']['subtypes'] = array_keys($format->phonetypes); | ||||
$this->coltypes['address']['subtypes'] = array_keys($format->addresstypes); | $this->coltypes['address']['subtypes'] = array_keys($format->addresstypes); | ||||
$rcube = rcube::get_instance(); | $rcube = rcube::get_instance(); | ||||
// set localized labels for proprietary cols | // set localized labels for proprietary cols | ||||
foreach ($this->coltypes as $col => $prop) { | foreach ($this->coltypes as $col => $prop) { | ||||
if (is_string($prop['label'])) | if (is_string($prop['label'])) { | ||||
$this->coltypes[$col]['label'] = $rcube->gettext($prop['label']); | $this->coltypes[$col]['label'] = $rcube->gettext($prop['label']); | ||||
} | } | ||||
} | |||||
// fetch objects from the given IMAP folder | // fetch objects from the given IMAP folder | ||||
$this->storagefolder = kolab_storage::get_folder($this->imap_folder); | $this->storagefolder = kolab_storage::get_folder($this->imap_folder); | ||||
$this->ready = $this->storagefolder && !PEAR::isError($this->storagefolder); | $this->ready = $this->storagefolder && !PEAR::isError($this->storagefolder); | ||||
// Set readonly and rights flags according to folder permissions | // Set readonly and rights flags according to folder permissions | ||||
if ($this->ready) { | if ($this->ready) { | ||||
if ($this->storagefolder->get_owner() == $_SESSION['username']) { | if ($this->storagefolder->get_owner() == $_SESSION['username']) { | ||||
$this->readonly = false; | $this->readonly = false; | ||||
$this->rights = 'lrswikxtea'; | $this->rights = 'lrswikxtea'; | ||||
} | } | ||||
else { | else { | ||||
$rights = $this->storagefolder->get_myrights(); | $rights = $this->storagefolder->get_myrights(); | ||||
if ($rights && !PEAR::isError($rights)) { | if ($rights && !PEAR::isError($rights)) { | ||||
$this->rights = $rights; | $this->rights = $rights; | ||||
if (strpos($rights, 'i') !== false && strpos($rights, 't') !== false) | if (strpos($rights, 'i') !== false && strpos($rights, 't') !== false) { | ||||
$this->readonly = false; | $this->readonly = false; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | |||||
$this->action = rcube::get_instance()->action; | $this->action = rcube::get_instance()->action; | ||||
} | } | ||||
/** | /** | ||||
* Getter for the address book name to be displayed | * Getter for the address book name to be displayed | ||||
* | * | ||||
* @return string Name of this address book | * @return string Name of this address book | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | public function is_subscribed() | ||||
return kolab_storage::folder_is_subscribed($this->imap_folder); | return kolab_storage::folder_is_subscribed($this->imap_folder); | ||||
} | } | ||||
/** | /** | ||||
* Compose an URL for CardDAV access to this address book (if configured) | * Compose an URL for CardDAV access to this address book (if configured) | ||||
*/ | */ | ||||
public function get_carddav_url() | public function get_carddav_url() | ||||
{ | { | ||||
$rcmail = rcmail::get_instance(); | $rcmail = rcmail::get_instance(); | ||||
if ($template = $rcmail->config->get('kolab_addressbook_carddav_url', null)) { | if ($template = $rcmail->config->get('kolab_addressbook_carddav_url', null)) { | ||||
return strtr($template, array( | return strtr($template, array( | ||||
'%h' => $_SERVER['HTTP_HOST'], | '%h' => $_SERVER['HTTP_HOST'], | ||||
'%u' => urlencode($rcmail->get_user_name()), | '%u' => urlencode($rcmail->get_user_name()), | ||||
'%i' => urlencode($this->storagefolder->get_uid()), | '%i' => urlencode($this->storagefolder->get_uid()), | ||||
'%n' => urlencode($this->imap_folder), | '%n' => urlencode($this->imap_folder), | ||||
)); | )); | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Setter for the current group | * Setter for the current group | ||||
*/ | */ | ||||
public function set_group($gid) | public function set_group($gid) | ||||
{ | { | ||||
$this->gid = $gid; | $this->gid = $gid; | ||||
} | } | ||||
/** | /** | ||||
* Save a search string for future listings | * Save a search string for future listings | ||||
* | * | ||||
* @param mixed Search params to use in listing method, obtained by get_search_set() | * @param mixed Search params to use in listing method, obtained by get_search_set() | ||||
*/ | */ | ||||
public function set_search_set($filter) | public function set_search_set($filter) | ||||
{ | { | ||||
$this->filter = $filter; | $this->filter = $filter; | ||||
} | } | ||||
/** | /** | ||||
* Getter for saved search properties | * Getter for saved search properties | ||||
* | * | ||||
* @return mixed Search properties used by this class | * @return mixed Search properties used by this class | ||||
*/ | */ | ||||
public function get_search_set() | public function get_search_set() | ||||
{ | { | ||||
return $this->filter; | return $this->filter; | ||||
} | } | ||||
/** | /** | ||||
* Reset saved results and search parameters | * Reset saved results and search parameters | ||||
*/ | */ | ||||
public function reset() | public function reset() | ||||
{ | { | ||||
$this->result = null; | $this->result = null; | ||||
$this->filter = null; | $this->filter = null; | ||||
} | } | ||||
/** | /** | ||||
* List all active contact groups of this source | * List all active contact groups of this source | ||||
* | * | ||||
* @param string Optional search string to match group name | * @param string Optional search string to match group name | ||||
* @param int Search mode. Sum of self::SEARCH_* | * @param int Search mode. Sum of self::SEARCH_* | ||||
* | * | ||||
* @return array Indexed list of contact groups, each a hash array | * @return array Indexed list of contact groups, each a hash array | ||||
*/ | */ | ||||
function list_groups($search = null, $mode = 0) | function list_groups($search = null, $mode = 0) | ||||
{ | { | ||||
$this->_fetch_groups(); | $this->_fetch_groups(); | ||||
$groups = array(); | $groups = array(); | ||||
foreach ((array)$this->distlists as $group) { | foreach ((array)$this->distlists as $group) { | ||||
if (!$search || strstr(mb_strtolower($group['name']), mb_strtolower($search))) { | if (!$search || strstr(mb_strtolower($group['name']), mb_strtolower($search))) { | ||||
$groups[$group['ID']] = array('ID' => $group['ID'], 'name' => $group['name']); | $groups[$group['ID']] = array('ID' => $group['ID'], 'name' => $group['name']); | ||||
} | } | ||||
} | } | ||||
// sort groups by name | // sort groups by name | ||||
uasort($groups, function($a, $b) { return strcoll($a['name'], $b['name']); }); | uasort($groups, function($a, $b) { return strcoll($a['name'], $b['name']); }); | ||||
return array_values($groups); | return array_values($groups); | ||||
} | } | ||||
/** | /** | ||||
* List the current set of contact records | * List the current set of contact records | ||||
* | * | ||||
* @param array List of cols to show | * @param array List of cols to show | ||||
* @param int Only return this number of records, use negative values for tail | * @param int Only return this number of records, use negative values for tail | ||||
* @param boolean True to skip the count query (select only) | * @param bool True to skip the count query (select only) | ||||
* | * | ||||
* @return array Indexed list of contact records, each a hash array | * @return array Indexed list of contact records, each a hash array | ||||
*/ | */ | ||||
public function list_records($cols = null, $subset = 0, $nocount = false) | public function list_records($cols = null, $subset = 0, $nocount = false) | ||||
{ | { | ||||
$this->result = new rcube_result_set(0, ($this->list_page-1) * $this->page_size); | $this->result = new rcube_result_set(0, ($this->list_page-1) * $this->page_size); | ||||
$fetch_all = false; | $fetch_all = false; | ||||
$fast_mode = !empty($cols) && is_array($cols); | $fast_mode = !empty($cols) && is_array($cols); | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | public function list_records($cols = null, $subset = 0, $nocount = false) | ||||
for ($i = $start_row; $i < $last_row; $i++) { | for ($i = $start_row; $i < $last_row; $i++) { | ||||
$this->result->add($this->_to_rcube_contact($this->dataset[$i])); | $this->result->add($this->_to_rcube_contact($this->dataset[$i])); | ||||
} | } | ||||
} | } | ||||
return $this->result; | return $this->result; | ||||
} | } | ||||
/** | /** | ||||
* Search records | * Search records | ||||
* | * | ||||
* @param mixed $fields The field name of array of field names to search in | * @param mixed $fields The field name of array of field names to search in | ||||
* @param mixed $value Search value (or array of values when $fields is array) | * @param mixed $value Search value (or array of values when $fields is array) | ||||
* @param int $mode Matching mode: | * @param int $mode Matching mode: | ||||
* 0 - partial (*abc*), | * 0 - partial (*abc*), | ||||
* 1 - strict (=), | * 1 - strict (=), | ||||
* 2 - prefix (abc*) | * 2 - prefix (abc*) | ||||
* 4 - include groups (if supported) | * 4 - include groups (if supported) | ||||
* @param boolean $select True if results are requested, False if count only | * @param bool $select True if results are requested, False if count only | ||||
* @param boolean $nocount True to skip the count query (select only) | * @param bool $nocount True to skip the count query (select only) | ||||
* @param array $required List of fields that cannot be empty | * @param array $required List of fields that cannot be empty | ||||
* | * | ||||
* @return object rcube_result_set List of contact records and 'count' value | * @return rcube_result_set List of contact records and 'count' value | ||||
*/ | */ | ||||
public function search($fields, $value, $mode=0, $select=true, $nocount=false, $required=array()) | public function search($fields, $value, $mode=0, $select=true, $nocount=false, $required=array()) | ||||
{ | { | ||||
// search by ID | // search by ID | ||||
if ($fields == $this->primary_key) { | if ($fields == $this->primary_key) { | ||||
$ids = !is_array($value) ? explode(',', $value) : $value; | $ids = !is_array($value) ? explode(',', $value) : $value; | ||||
$result = new rcube_result_set(); | $result = new rcube_result_set(); | ||||
foreach ($ids as $id) { | foreach ($ids as $id) { | ||||
if ($rec = $this->get_record($id, true)) { | if ($rec = $this->get_record($id, true)) { | ||||
$result->add($rec); | $result->add($rec); | ||||
$result->count++; | $result->count++; | ||||
} | } | ||||
} | } | ||||
return $result; | return $result; | ||||
} | } | ||||
else if ($fields == '*') { | else if ($fields == '*') { | ||||
$fields = $this->search_fields; | $fields = $this->search_fields; | ||||
} | } | ||||
if (!is_array($fields)) | if (!is_array($fields)) { | ||||
$fields = array($fields); | $fields = array($fields); | ||||
if (!is_array($required) && !empty($required)) | } | ||||
if (!is_array($required) && !empty($required)) { | |||||
$required = array($required); | $required = array($required); | ||||
} | |||||
// advanced search | // advanced search | ||||
if (is_array($value)) { | if (is_array($value)) { | ||||
$advanced = true; | $advanced = true; | ||||
$value = array_map('mb_strtolower', $value); | $value = array_map('mb_strtolower', $value); | ||||
} | } | ||||
else | else { | ||||
$value = mb_strtolower($value); | $value = mb_strtolower($value); | ||||
} | |||||
$scount = count($fields); | $scount = count($fields); | ||||
// build key name regexp | // build key name regexp | ||||
$regexp = '/^(' . implode('|', $fields) . ')(?:.*)$/'; | $regexp = '/^(' . implode('|', $fields) . ')(?:.*)$/'; | ||||
// pass query to storage if only indexed cols are involved | // pass query to storage if only indexed cols are involved | ||||
// NOTE: this is only some rough pre-filtering but probably includes false positives | // NOTE: this is only some rough pre-filtering but probably includes false positives | ||||
$squery = $this->_search_query($fields, $value, $mode); | $squery = $this->_search_query($fields, $value, $mode); | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | public function search($fields, $value, $mode=0, $select=true, $nocount=false, $required=array()) | ||||
if (!$select) { | if (!$select) { | ||||
return new rcube_result_set(count($this->filter['ids']), ($this->list_page-1) * $this->page_size); | return new rcube_result_set(count($this->filter['ids']), ($this->list_page-1) * $this->page_size); | ||||
} | } | ||||
// list records (now limited by $this->filter) | // list records (now limited by $this->filter) | ||||
return $this->list_records(); | return $this->list_records(); | ||||
} | } | ||||
/** | /** | ||||
* Refresh saved search results after data has changed | * Refresh saved search results after data has changed | ||||
*/ | */ | ||||
public function refresh_search() | public function refresh_search() | ||||
{ | { | ||||
if ($this->filter) | if ($this->filter) { | ||||
$this->search($this->filter['fields'], $this->filter['value'], $this->filter['mode']); | $this->search($this->filter['fields'], $this->filter['value'], $this->filter['mode']); | ||||
} | |||||
return $this->get_search_set(); | return $this->get_search_set(); | ||||
} | } | ||||
/** | /** | ||||
* Count number of available contacts in database | * Count number of available contacts in database | ||||
* | * | ||||
* @return rcube_result_set Result set with values for 'count' and 'first' | * @return rcube_result_set Result set with values for 'count' and 'first' | ||||
*/ | */ | ||||
public function count() | public function count() | ||||
{ | { | ||||
if ($this->gid) { | if ($this->gid) { | ||||
$this->_fetch_groups(); | $this->_fetch_groups(); | ||||
$count = count($this->distlists[$this->gid]['member']); | $count = count($this->distlists[$this->gid]['member']); | ||||
} | } | ||||
else if (is_array($this->filter['ids'])) { | else if (is_array($this->filter['ids'])) { | ||||
$count = count($this->filter['ids']); | $count = count($this->filter['ids']); | ||||
} | } | ||||
else { | else { | ||||
$count = $this->storagefolder->count('contact'); | $count = $this->storagefolder->count('contact'); | ||||
} | } | ||||
return new rcube_result_set($count, ($this->list_page-1) * $this->page_size); | return new rcube_result_set($count, ($this->list_page-1) * $this->page_size); | ||||
} | } | ||||
/** | /** | ||||
* Return the last result set | * Return the last result set | ||||
* | * | ||||
* @return rcube_result_set Current result set or NULL if nothing selected yet | * @return rcube_result_set Current result set or NULL if nothing selected yet | ||||
*/ | */ | ||||
public function get_result() | public function get_result() | ||||
{ | { | ||||
return $this->result; | return $this->result; | ||||
} | } | ||||
/** | /** | ||||
* Get a specific contact record | * Get a specific contact record | ||||
* | * | ||||
* @param mixed record identifier(s) | * @param mixed Record identifier(s) | ||||
* @param boolean True to return record as associative array, otherwise a result set is returned | * @param bool True to return record as associative array, otherwise a result set is returned | ||||
* | |||||
* @return mixed Result object with all record fields or False if not found | * @return mixed Result object with all record fields or False if not found | ||||
*/ | */ | ||||
public function get_record($id, $assoc=false) | public function get_record($id, $assoc = false) | ||||
{ | { | ||||
$rec = null; | $rec = null; | ||||
$uid = $this->id2uid($id); | $uid = $this->id2uid($id); | ||||
$rev = rcube_utils::get_input_value('_rev', rcube_utils::INPUT_GPC); | $rev = rcube_utils::get_input_value('_rev', rcube_utils::INPUT_GPC); | ||||
if (strpos($uid, 'mailto:') === 0) { | if (strpos($uid, 'mailto:') === 0) { | ||||
$this->_fetch_groups(true); | $this->_fetch_groups(true); | ||||
$rec = $this->contacts[$id]; | $rec = $this->contacts[$id]; | ||||
Show All 16 Lines | public function get_record($id, $assoc = false) | ||||
$this->result = new rcube_result_set(1); | $this->result = new rcube_result_set(1); | ||||
$this->result->add($rec); | $this->result->add($rec); | ||||
return $assoc ? $rec : $this->result; | return $assoc ? $rec : $this->result; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Get group assignments of a specific contact record | * Get group assignments of a specific contact record | ||||
* | * | ||||
* @param mixed Record identifier | * @param mixed Record identifier | ||||
* | |||||
* @return array List of assigned groups as ID=>Name pairs | * @return array List of assigned groups as ID=>Name pairs | ||||
*/ | */ | ||||
public function get_record_groups($id) | public function get_record_groups($id) | ||||
{ | { | ||||
$out = array(); | $out = array(); | ||||
$this->_fetch_groups(); | $this->_fetch_groups(); | ||||
if (!empty($this->groupmembers[$id])) { | |||||
foreach ((array)$this->groupmembers[$id] as $gid) { | foreach ((array) $this->groupmembers[$id] as $gid) { | ||||
if ($group = $this->distlists[$gid]) | if (!empty($this->distlists[$gid])) { | ||||
$group = $this->distlists[$gid]; | |||||
$out[$gid] = $group['name']; | $out[$gid] = $group['name']; | ||||
} | } | ||||
} | |||||
} | |||||
return $out; | return $out; | ||||
} | } | ||||
/** | /** | ||||
* Create a new contact record | * Create a new contact record | ||||
* | * | ||||
* @param array Assoziative array with save data | * @param array Associative array with save data | ||||
* Keys: Field name with optional section in the form FIELD:SECTION | * Keys: Field name with optional section in the form FIELD:SECTION | ||||
* Values: Field value. Can be either a string or an array of strings for multiple values | * Values: Field value. Can be either a string or an array of strings for multiple values | ||||
* @param boolean True to check for duplicates first | * @param bool True to check for duplicates first | ||||
* | |||||
* @return mixed The created record ID on success, False on error | * @return mixed The created record ID on success, False on error | ||||
*/ | */ | ||||
public function insert($save_data, $check=false) | public function insert($save_data, $check=false) | ||||
{ | { | ||||
if (!is_array($save_data)) | if (!is_array($save_data)) { | ||||
return false; | return false; | ||||
} | |||||
$insert_id = $existing = false; | $insert_id = $existing = false; | ||||
// check for existing records by e-mail comparison | // check for existing records by e-mail comparison | ||||
if ($check) { | if ($check) { | ||||
foreach ($this->get_col_values('email', $save_data, true) as $email) { | foreach ($this->get_col_values('email', $save_data, true) as $email) { | ||||
if (($res = $this->search('email', $email, true, false)) && $res->count) { | if (($res = $this->search('email', $email, true, false)) && $res->count) { | ||||
$existing = true; | $existing = true; | ||||
Show All 20 Lines | public function insert($save_data, $check=false) | ||||
else { | else { | ||||
$insert_id = $this->uid2id($object['uid']); | $insert_id = $this->uid2id($object['uid']); | ||||
} | } | ||||
} | } | ||||
return $insert_id; | return $insert_id; | ||||
} | } | ||||
/** | /** | ||||
* Update a specific contact record | * Update a specific contact record | ||||
* | * | ||||
* @param mixed Record identifier | * @param mixed Record identifier | ||||
* @param array Assoziative array with save data | * @param array Associative array with save data | ||||
* Keys: Field name with optional section in the form FIELD:SECTION | * Keys: Field name with optional section in the form FIELD:SECTION | ||||
* Values: Field value. Can be either a string or an array of strings for multiple values | * Values: Field value. Can be either a string or an array of strings for multiple values | ||||
* @return boolean True on success, False on error | * | ||||
* @return bool True on success, False on error | |||||
*/ | */ | ||||
public function update($id, $save_data) | public function update($id, $save_data) | ||||
{ | { | ||||
$updated = false; | $updated = false; | ||||
if ($old = $this->storagefolder->get_object($this->id2uid($id))) { | if ($old = $this->storagefolder->get_object($this->id2uid($id))) { | ||||
$object = $this->_from_rcube_contact($save_data, $old); | $object = $this->_from_rcube_contact($save_data, $old); | ||||
if (!$this->storagefolder->save($object, 'contact', $old['uid'])) { | if (!$this->storagefolder->save($object, 'contact', $old['uid'])) { | ||||
rcube::raise_error(array( | rcube::raise_error(array( | ||||
'code' => 600, 'type' => 'php', | 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, | ||||
'file' => __FILE__, 'line' => __LINE__, | 'message' => "Error saving contact object to Kolab server" | ||||
'message' => "Error saving contact object to Kolab server"), | ), | ||||
true, false); | true, false | ||||
); | |||||
} | } | ||||
else { | else { | ||||
$updated = true; | $updated = true; | ||||
// TODO: update data in groups this contact is member of | // TODO: update data in groups this contact is member of | ||||
} | } | ||||
} | } | ||||
return $updated; | return $updated; | ||||
} | } | ||||
/** | /** | ||||
* Mark one or more contact records as deleted | * Mark one or more contact records as deleted | ||||
* | * | ||||
* @param array Record identifiers | * @param array Record identifiers | ||||
* @param boolean Remove record(s) irreversible (mark as deleted otherwise) | * @param bool Remove record(s) irreversible (mark as deleted otherwise) | ||||
* | * | ||||
* @return int Number of records deleted | * @return int Number of records deleted | ||||
*/ | */ | ||||
public function delete($ids, $force=true) | public function delete($ids, $force=true) | ||||
{ | { | ||||
$this->_fetch_groups(); | $this->_fetch_groups(); | ||||
if (!is_array($ids)) | if (!is_array($ids)) { | ||||
$ids = explode(',', $ids); | $ids = explode(',', $ids); | ||||
} | |||||
$count = 0; | $count = 0; | ||||
foreach ($ids as $id) { | foreach ($ids as $id) { | ||||
if ($uid = $this->id2uid($id)) { | if ($uid = $this->id2uid($id)) { | ||||
$is_mailto = strpos($uid, 'mailto:') === 0; | $is_mailto = strpos($uid, 'mailto:') === 0; | ||||
$deleted = $is_mailto || $this->storagefolder->delete($uid, $force); | $deleted = $is_mailto || $this->storagefolder->delete($uid, $force); | ||||
if (!$deleted) { | if (!$deleted) { | ||||
rcube::raise_error(array( | rcube::raise_error(array( | ||||
'code' => 600, 'type' => 'php', | 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, | ||||
'file' => __FILE__, 'line' => __LINE__, | 'message' => "Error deleting a contact object $uid from the Kolab server" | ||||
'message' => "Error deleting a contact object $uid from the Kolab server"), | ), | ||||
true, false); | true, false | ||||
); | |||||
} | } | ||||
else { | else { | ||||
// remove from distribution lists | // remove from distribution lists | ||||
foreach ((array)$this->groupmembers[$id] as $gid) { | foreach ((array) $this->groupmembers[$id] as $gid) { | ||||
if (!$is_mailto || $gid == $this->gid) | if (!$is_mailto || $gid == $this->gid) { | ||||
$this->remove_from_group($gid, $id); | $this->remove_from_group($gid, $id); | ||||
} | } | ||||
} | |||||
// clear internal cache | // clear internal cache | ||||
unset($this->groupmembers[$id]); | unset($this->groupmembers[$id]); | ||||
$count++; | $count++; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return $count; | return $count; | ||||
} | } | ||||
/** | /** | ||||
* Undelete one or more contact records. | * Undelete one or more contact records. | ||||
* Only possible just after delete (see 2nd argument of delete() method). | * Only possible just after delete (see 2nd argument of delete() method). | ||||
* | * | ||||
* @param array Record identifiers | * @param array Record identifiers | ||||
* | * | ||||
* @return int Number of records restored | * @return int Number of records restored | ||||
*/ | */ | ||||
public function undelete($ids) | public function undelete($ids) | ||||
{ | { | ||||
if (!is_array($ids)) | if (!is_array($ids)) { | ||||
$ids = explode(',', $ids); | $ids = explode(',', $ids); | ||||
} | |||||
$count = 0; | $count = 0; | ||||
foreach ($ids as $id) { | foreach ($ids as $id) { | ||||
$uid = $this->id2uid($id); | $uid = $this->id2uid($id); | ||||
if ($this->storagefolder->undelete($uid)) { | if ($this->storagefolder->undelete($uid)) { | ||||
$count++; | $count++; | ||||
} | } | ||||
else { | else { | ||||
rcube::raise_error(array( | rcube::raise_error(array( | ||||
'code' => 600, 'type' => 'php', | 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, | ||||
'file' => __FILE__, 'line' => __LINE__, | 'message' => "Error undeleting a contact object $uid from the Kolab server" | ||||
'message' => "Error undeleting a contact object $uid from the Kolab server"), | ), | ||||
true, false); | true, false | ||||
); | |||||
} | } | ||||
} | } | ||||
return $count; | return $count; | ||||
} | } | ||||
/** | /** | ||||
* Remove all records from the database | * Remove all records from the database | ||||
* | * | ||||
* @param bool $with_groups Remove also groups | * @param bool $with_groups Remove also groups | ||||
*/ | */ | ||||
public function delete_all($with_groups = false) | public function delete_all($with_groups = false) | ||||
{ | { | ||||
if ($this->storagefolder->delete_all()) { | if ($this->storagefolder->delete_all()) { | ||||
$this->contacts = array(); | $this->contacts = array(); | ||||
$this->sortindex = array(); | $this->sortindex = array(); | ||||
$this->dataset = null; | $this->dataset = null; | ||||
$this->result = null; | $this->result = null; | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Close connection to source | * Close connection to source | ||||
* Called on script shutdown | * Called on script shutdown | ||||
*/ | */ | ||||
public function close() | public function close() | ||||
{ | { | ||||
} | } | ||||
/** | /** | ||||
* Create a contact group with the given name | * Create a contact group with the given name | ||||
* | * | ||||
* @param string The group name | * @param string The group name | ||||
* | |||||
* @return mixed False on error, array with record props in success | * @return mixed False on error, array with record props in success | ||||
*/ | */ | ||||
function create_group($name) | function create_group($name) | ||||
{ | { | ||||
$this->_fetch_groups(); | $this->_fetch_groups(); | ||||
$result = false; | $result = false; | ||||
$list = array( | $list = array( | ||||
'name' => $name, | 'name' => $name, | ||||
'member' => array(), | 'member' => array(), | ||||
); | ); | ||||
$saved = $this->storagefolder->save($list, 'distribution-list'); | $saved = $this->storagefolder->save($list, 'distribution-list'); | ||||
if (!$saved) { | if (!$saved) { | ||||
rcube::raise_error(array( | rcube::raise_error(array( | ||||
'code' => 600, 'type' => 'php', | 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, | ||||
'file' => __FILE__, 'line' => __LINE__, | 'message' => "Error saving distribution-list object to Kolab server" | ||||
'message' => "Error saving distribution-list object to Kolab server"), | ), | ||||
true, false); | true, false | ||||
); | |||||
return false; | return false; | ||||
} | } | ||||
else { | else { | ||||
$id = $this->uid2id($list['uid']); | $id = $this->uid2id($list['uid']); | ||||
$this->distlists[$id] = $list; | $this->distlists[$id] = $list; | ||||
$result = array('id' => $id, 'name' => $name); | $result = array('id' => $id, 'name' => $name); | ||||
} | } | ||||
return $result; | return $result; | ||||
} | } | ||||
/** | /** | ||||
* Delete the given group and all linked group members | * Delete the given group and all linked group members | ||||
* | * | ||||
* @param string Group identifier | * @param string Group identifier | ||||
* @return boolean True on success, false if no data was changed | * | ||||
* @return bool True on success, false if no data was changed | |||||
*/ | */ | ||||
function delete_group($gid) | function delete_group($gid) | ||||
{ | { | ||||
$this->_fetch_groups(); | $this->_fetch_groups(); | ||||
$result = false; | $result = false; | ||||
if ($list = $this->distlists[$gid]) { | if ($list = $this->distlists[$gid]) { | ||||
$deleted = $this->storagefolder->delete($list['uid']); | $deleted = $this->storagefolder->delete($list['uid']); | ||||
} | } | ||||
if (!$deleted) { | if (!$deleted) { | ||||
rcube::raise_error(array( | rcube::raise_error(array( | ||||
'code' => 600, 'type' => 'php', | 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, | ||||
'file' => __FILE__, 'line' => __LINE__, | 'message' => "Error deleting distribution-list object from the Kolab server" | ||||
'message' => "Error deleting distribution-list object from the Kolab server"), | ), | ||||
true, false); | true, false | ||||
); | |||||
} | } | ||||
else { | else { | ||||
$result = true; | $result = true; | ||||
} | } | ||||
return $result; | return $result; | ||||
} | } | ||||
/** | /** | ||||
* Rename a specific contact group | * Rename a specific contact group | ||||
* | * | ||||
* @param string Group identifier | * @param string Group identifier | ||||
* @param string New name to set for this group | * @param string New name to set for this group | ||||
* @param string New group identifier (if changed, otherwise don't set) | * @param string New group identifier (if changed, otherwise don't set) | ||||
* | * | ||||
* @return boolean New name on success, false if no data was changed | * @return bool New name on success, false if no data was changed | ||||
*/ | */ | ||||
function rename_group($gid, $newname, &$newid) | function rename_group($gid, $newname, &$newid) | ||||
{ | { | ||||
$this->_fetch_groups(); | $this->_fetch_groups(); | ||||
$list = $this->distlists[$gid]; | $list = $this->distlists[$gid]; | ||||
if ($newname != $list['name']) { | if ($newname != $list['name']) { | ||||
$list['name'] = $newname; | $list['name'] = $newname; | ||||
$saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']); | $saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']); | ||||
} | } | ||||
if (!$saved) { | if (!$saved) { | ||||
rcube::raise_error(array( | rcube::raise_error(array( | ||||
'code' => 600, 'type' => 'php', | 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, | ||||
'file' => __FILE__, 'line' => __LINE__, | 'message' => "Error saving distribution-list object to Kolab server" | ||||
'message' => "Error saving distribution-list object to Kolab server"), | ), | ||||
true, false); | true, false | ||||
); | |||||
return false; | return false; | ||||
} | } | ||||
return $newname; | return $newname; | ||||
} | } | ||||
/** | /** | ||||
* Add the given contact records the a certain group | * Add the given contact records the a certain group | ||||
* | * | ||||
* @param string Group identifier | * @param string Group identifier | ||||
* @param array List of contact identifiers to be added | * @param array List of contact identifiers to be added | ||||
* @return int Number of contacts added | * @return int Number of contacts added | ||||
*/ | */ | ||||
function add_to_group($gid, $ids) | function add_to_group($gid, $ids) | ||||
{ | { | ||||
if (!is_array($ids)) { | if (!is_array($ids)) { | ||||
$ids = explode(',', $ids); | $ids = explode(',', $ids); | ||||
} | } | ||||
$this->_fetch_groups(true); | $this->_fetch_groups(true); | ||||
Show All 30 Lines | function add_to_group($gid, $ids) | ||||
if (!empty($uids)) { | if (!empty($uids)) { | ||||
foreach ($uids as $uid => $contact_id) { | foreach ($uids as $uid => $contact_id) { | ||||
$list['member'][] = array('uid' => $uid); | $list['member'][] = array('uid' => $uid); | ||||
$this->groupmembers[$contact_id][] = $gid; | $this->groupmembers[$contact_id][] = $gid; | ||||
$added++; | $added++; | ||||
} | } | ||||
} | } | ||||
if ($added) | if ($added) { | ||||
$saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']); | $saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']); | ||||
else | } | ||||
else { | |||||
$saved = true; | $saved = true; | ||||
} | |||||
if (!$saved) { | if (!$saved) { | ||||
rcube::raise_error(array( | rcube::raise_error(array( | ||||
'code' => 600, 'type' => 'php', | 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, | ||||
'file' => __FILE__, 'line' => __LINE__, | 'message' => "Error saving distribution-list to Kolab server" | ||||
'message' => "Error saving distribution-list to Kolab server"), | ), | ||||
true, false); | true, false | ||||
); | |||||
$added = false; | $added = false; | ||||
$this->set_error(self::ERROR_SAVING, 'errorsaving'); | $this->set_error(self::ERROR_SAVING, 'errorsaving'); | ||||
} | } | ||||
else { | else { | ||||
$this->distlists[$gid] = $list; | $this->distlists[$gid] = $list; | ||||
} | } | ||||
return $added; | return $added; | ||||
} | } | ||||
/** | /** | ||||
* Remove the given contact records from a certain group | * Remove the given contact records from a certain group | ||||
* | * | ||||
* @param string Group identifier | * @param string Group identifier | ||||
* @param array List of contact identifiers to be removed | * @param array List of contact identifiers to be removed | ||||
* @return int Number of deleted group members | * @return int Number of deleted group members | ||||
*/ | */ | ||||
function remove_from_group($gid, $ids) | function remove_from_group($gid, $ids) | ||||
{ | { | ||||
if (!is_array($ids)) | if (!is_array($ids)) { | ||||
$ids = explode(',', $ids); | $ids = explode(',', $ids); | ||||
} | |||||
$this->_fetch_groups(); | $this->_fetch_groups(); | ||||
if (!($list = $this->distlists[$gid])) | if (!($list = $this->distlists[$gid])) { | ||||
return false; | return false; | ||||
} | |||||
$new_member = array(); | $new_member = array(); | ||||
foreach ((array)$list['member'] as $member) { | foreach ((array)$list['member'] as $member) { | ||||
if (!in_array($member['ID'], $ids)) | if (!in_array($member['ID'], $ids)) { | ||||
$new_member[] = $member; | $new_member[] = $member; | ||||
} | } | ||||
} | |||||
// write distribution list back to server | // write distribution list back to server | ||||
$list['member'] = $new_member; | $list['member'] = $new_member; | ||||
$saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']); | $saved = $this->storagefolder->save($list, 'distribution-list', $list['uid']); | ||||
if (!$saved) { | if (!$saved) { | ||||
rcube::raise_error(array( | rcube::raise_error(array( | ||||
'code' => 600, 'type' => 'php', | 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, | ||||
'file' => __FILE__, 'line' => __LINE__, | 'message' => "Error saving distribution-list object to Kolab server" | ||||
'message' => "Error saving distribution-list object to Kolab server"), | ), | ||||
true, false); | true, false | ||||
); | |||||
} | } | ||||
else { | else { | ||||
// remove group assigments in local cache | // remove group assigments in local cache | ||||
foreach ($ids as $id) { | foreach ($ids as $id) { | ||||
$j = array_search($gid, $this->groupmembers[$id]); | $j = array_search($gid, $this->groupmembers[$id]); | ||||
unset($this->groupmembers[$id][$j]); | unset($this->groupmembers[$id][$j]); | ||||
} | } | ||||
$this->distlists[$gid] = $list; | $this->distlists[$gid] = $list; | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Check the given data before saving. | * Check the given data before saving. | ||||
* If input not valid, the message to display can be fetched using get_error() | * If input not valid, the message to display can be fetched using get_error() | ||||
* | * | ||||
* @param array Associative array with contact data to save | * @param array Associative array with contact data to save | ||||
* @param bool Attempt to fix/complete data automatically | * @param bool Attempt to fix/complete data automatically | ||||
* | * | ||||
* @return boolean True if input is valid, False if not. | * @return bool True if input is valid, False if not. | ||||
*/ | */ | ||||
public function validate(&$save_data, $autofix = false) | public function validate(&$save_data, $autofix = false) | ||||
{ | { | ||||
// validate e-mail addresses | // validate e-mail addresses | ||||
$valid = parent::validate($save_data); | $valid = parent::validate($save_data); | ||||
// require at least one e-mail address if there's no name | // require at least one e-mail address if there's no name | ||||
// (syntax check is already done) | // (syntax check is already done) | ||||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | private function _to_rcube_contact($record) | ||||
'zipcode' => $adr['code'], | 'zipcode' => $adr['code'], | ||||
'region' => $adr['region'], | 'region' => $adr['region'], | ||||
'country' => $adr['country'], | 'country' => $adr['country'], | ||||
); | ); | ||||
} | } | ||||
} | } | ||||
// photo is stored as separate attachment | // photo is stored as separate attachment | ||||
if ($record['photo'] && strlen($record['photo']) < 255 && ($att = $record['_attachments'][$record['photo']])) { | if ($record['photo'] && strlen($record['photo']) < 255 && !empty($record['_attachments'][$record['photo']])) { | ||||
$att = $record['_attachments'][$record['photo']]; | |||||
// only fetch photo content if requested | // only fetch photo content if requested | ||||
if ($this->action == 'photo') | if ($this->action == 'photo') { | ||||
$record['photo'] = $att['content'] ? $att['content'] : $this->storagefolder->get_attachment($record['uid'], $att['id']); | if (!empty($att['content'])) { | ||||
$record['photo'] = $att['content']; | |||||
} | |||||
else { | |||||
$record['photo'] = $this->storagefolder->get_attachment($record['uid'], $att['id']); | |||||
} | |||||
} | |||||
} | } | ||||
// truncate publickey value for display | // truncate publickey value for display | ||||
if ($record['pgppublickey'] && $this->action == 'show') | if (!empty($record['pgppublickey']) && $this->action == 'show') { | ||||
$record['pgppublickey'] = substr($record['pgppublickey'], 0, 140) . '...'; | $record['pgppublickey'] = substr($record['pgppublickey'], 0, 140) . '...'; | ||||
} | |||||
// remove empty fields | // remove empty fields | ||||
$record = array_filter($record); | $record = array_filter($record); | ||||
// remove kolab_storage internal data | // remove kolab_storage internal data | ||||
unset($record['_msguid'], $record['_formatobj'], $record['_mailbox'], $record['_type'], $record['_size']); | unset($record['_msguid'], $record['_formatobj'], $record['_mailbox'], $record['_type'], $record['_size']); | ||||
return $record; | return $record; | ||||
} | } | ||||
/** | /** | ||||
* Map fields from Roundcube format to internal kolab_format_contact properties | * Map fields from Roundcube format to internal kolab_format_contact properties | ||||
*/ | */ | ||||
private function _from_rcube_contact($contact, $old = array()) | private function _from_rcube_contact($contact, $old = array()) | ||||
{ | { | ||||
if (!$contact['uid'] && $contact['ID']) | if (!$contact['uid'] && $contact['ID']) { | ||||
$contact['uid'] = $this->id2uid($contact['ID']); | $contact['uid'] = $this->id2uid($contact['ID']); | ||||
else if (!$contact['uid'] && $old['uid']) | } | ||||
else if (!$contact['uid'] && $old['uid']) { | |||||
$contact['uid'] = $old['uid']; | $contact['uid'] = $old['uid']; | ||||
} | |||||
$contact['im'] = array_filter($this->get_col_values('im', $contact, true)); | $contact['im'] = array_filter($this->get_col_values('im', $contact, true)); | ||||
// convert email, website, phone values | // convert email, website, phone values | ||||
foreach (array('email'=>'address', 'website'=>'url', 'phone'=>'number') as $col => $propname) { | foreach (array('email'=>'address', 'website'=>'url', 'phone'=>'number') as $col => $propname) { | ||||
$col_values = $this->get_col_values($col, $contact); | $col_values = $this->get_col_values($col, $contact); | ||||
$contact[$col] = array(); | $contact[$col] = array(); | ||||
foreach ($col_values as $type => $values) { | foreach ($col_values as $type => $values) { | ||||
foreach ((array)$values as $val) { | foreach ((array)$values as $val) { | ||||
if (!empty($val)) { | if (!empty($val)) { | ||||
$contact[$col][] = array($propname => $val, 'type' => $type); | $contact[$col][] = array($propname => $val, 'type' => $type); | ||||
} | } | ||||
} | } | ||||
unset($contact[$col.':'.$type]); | unset($contact[$col.':'.$type]); | ||||
} | } | ||||
} | } | ||||
$addresses = array(); | $addresses = array(); | ||||
foreach ($this->get_col_values('address', $contact) as $type => $values) { | foreach ($this->get_col_values('address', $contact) as $type => $values) { | ||||
foreach ((array)$values as $adr) { | foreach ((array)$values as $adr) { | ||||
// skip empty address | // skip empty address | ||||
$adr = array_filter($adr); | $adr = array_filter($adr); | ||||
if (empty($adr)) | if (empty($adr)) { | ||||
continue; | continue; | ||||
} | |||||
$addresses[] = array( | $addresses[] = array( | ||||
'type' => $type, | 'type' => $type, | ||||
'street' => $adr['street'], | 'street' => $adr['street'], | ||||
'locality' => $adr['locality'], | 'locality' => $adr['locality'], | ||||
'code' => $adr['zipcode'], | 'code' => $adr['zipcode'], | ||||
'region' => $adr['region'], | 'region' => $adr['region'], | ||||
'country' => $adr['country'], | 'country' => $adr['country'], | ||||
); | ); | ||||
} | } | ||||
unset($contact['address:'.$type]); | unset($contact['address:'.$type]); | ||||
} | } | ||||
$contact['address'] = $addresses; | $contact['address'] = $addresses; | ||||
// categories are not supported in the web client but should be preserved (#2608) | // categories are not supported in the web client but should be preserved (#2608) | ||||
$contact['categories'] = $old['categories']; | $contact['categories'] = $old['categories']; | ||||
// copy meta data (starting with _) from old object | // copy meta data (starting with _) from old object | ||||
foreach ((array)$old as $key => $val) { | foreach ((array)$old as $key => $val) { | ||||
if (!isset($contact[$key]) && $key[0] == '_') | if (!isset($contact[$key]) && $key[0] == '_') { | ||||
$contact[$key] = $val; | $contact[$key] = $val; | ||||
} | } | ||||
} | |||||
// convert one-item-array elements into string element | // convert one-item-array elements into string element | ||||
// this is needed e.g. to properly import birthday field | // this is needed e.g. to properly import birthday field | ||||
foreach ($this->coltypes as $type => $col_def) { | foreach ($this->coltypes as $type => $col_def) { | ||||
if ($col_def['limit'] == 1 && is_array($contact[$type])) { | if ($col_def['limit'] == 1 && is_array($contact[$type])) { | ||||
$contact[$type] = array_shift(array_filter($contact[$type])); | $contact[$type] = array_shift(array_filter($contact[$type])); | ||||
} | } | ||||
} | } | ||||
// When importing contacts 'vcard' data is added, we don't need it (Bug #1711) | // When importing contacts 'vcard' data is added, we don't need it (Bug #1711) | ||||
unset($contact['vcard']); | unset($contact['vcard']); | ||||
// add empty values for some fields which can be removed in the UI | // add empty values for some fields which can be removed in the UI | ||||
return array_filter($contact) + array('nickname' => '', 'birthday' => '', 'anniversary' => '', 'freebusyurl' => '', 'photo' => $contact['photo']); | return array_filter($contact) + array( | ||||
'nickname' => '', | |||||
'birthday' => '', | |||||
'anniversary' => '', | |||||
'freebusyurl' => '', | |||||
'photo' => $contact['photo'] | |||||
); | |||||
} | } | ||||
} | } |