/** * Synchronize CardDAV-Addressbook * * @param array $server CardDAV server array * @param integer $carddav_contact_id CardDAV contact id * @param string $vcard_id vCard id * @return boolean if no error occurred "true" else "false" */ function carddav_addressbook_sync($server, $carddav_contact_id = null, $vcard_id = null, $start = 0, $timeout = 29) { $any_data_synced = false; $this->write_log('Starting CardDAV-Addressbook synchronization'); $carddav_backend = new carddav_backend($server['url']); if ($this->rc->decrypt($server['password']) == '%p') { $server['password'] = $this->rcpassword; } $carddav_backend->set_auth($server['username'], $this->rc->decrypt($server['password']), $server['authtype']); if ($carddav_backend->check_connection()) { $this->write_log('Connected to the CardDAV-Server ' . $server['url']); if ($vcard_id !== null) { // server does not support REPORT request $noreport = $this->rc->config->get('carddav_noreport', array()); if ($noreport[$server['url']]) { $elements = $carddav_backend->get_xml_vcard($vcard_id); } else { $elements = false; } try { $xml = new SimpleXMLElement($elements); if (count($xml->element) < 1) { $elements = false; } } catch (Exception $e) { $elements = false; } if ($elements === false) { $elements = $carddav_backend->get(false); $this->filter = null; $carddav_addressbook_contacts = $this->get_carddav_addressbook_contacts(); if (!isset($noreport[$server['url']])) { $a_prefs['carddav_noreport'][$server['url']] = 1; $this->rc->user->save_prefs($a_prefs); } } else { if ($carddav_contact_id) { $carddav_addressbook_contact = $this->get_carddav_addressbook_contact($carddav_contact_id); $carddav_addressbook_contacts = array($carddav_addressbook_contact['vcard_id'] => $carddav_addressbook_contact); } } } else { $elements = $carddav_backend->get(false); $carddav_addressbook_contacts = $this->get_carddav_addressbook_contacts(); } try { $xml = new SimpleXMLElement($elements); if (!empty($xml->element)) { foreach ($xml->element as $element) { if ($start != 0 && time() - $start >= $timeout) { return null; } $element_id = (string) $element->id; $element_etag = (string) $element->etag; $element_last_modified = (string) $element->last_modified; if (isset($carddav_addressbook_contacts[$element_id])) { if ($carddav_addressbook_contacts[$element_id]['etag'] != $element_etag || $carddav_addressbook_contacts[$element_id]['last_modified'] != $element_last_modified) { $carddav_content = array('vcard' => $carddav_backend->get_vcard($element_id), 'vcard_id' => $element_id, 'etag' => $element_etag, 'last_modified' => $element_last_modified); if ($this->carddav_addressbook_update($carddav_content)) { $any_data_synced = true; } } } else { $carddav_content = array('vcard' => $carddav_backend->get_vcard($element_id), 'vcard_id' => $element_id, 'etag' => $element_etag, 'last_modified' => $element_last_modified); if (!empty($carddav_content['vcard'])) { if ($this->carddav_addressbook_add($carddav_content)) { $any_data_synced = true; } } } unset($carddav_addressbook_contacts[$element_id]); } } else { $logging_message = 'No CardDAV XML-Element found!'; if ($carddav_contact_id !== null && $vcard_id !== null) { $this->write_log($logging_message . ' The CardDAV-Server does not have a contact with the vCard id ' . $vcard_id); } else { $this->write_log($logging_message . ' The CardDAV-Server seems to have no contacts'); } } if (!empty($carddav_addressbook_contacts)) { foreach ($carddav_addressbook_contacts as $vcard_id => $etag) { if ($this->carddav_addressbook_delete($vcard_id)) { $any_data_synced = true; } } } if ($any_data_synced === false) { $this->write_log('all CardDAV-Data are synchronous, nothing todo!'); } $this->write_log('Syncronization complete!'); } catch (Exception $e) { $this->write_log('CardDAV-Server XML-Response is malformed. Synchronization aborted!'); return false; } } else { $this->write_log('Couldn\'t connect to the CardDAV-Server ' . $server['url']); return false; } return true; }
$address_list_total_update = count($address_list_update); unset($address_list_xml); unset($address_list_array); unset($address_list_all); $log->info("[contacts] Total of {$address_list_total_all} contacts, need to update/fetch {$address_list_total_update} of them"); /* Fetch any new contacts */ if (!empty($address_list_update)) { $i = 0; foreach ($address_list_update as $id) { $i++; $log->info("[contacts] Fetching contact {$id} ({$i}/{$address_list_total_all})"); // download vcard to offline space. We use touch to set the mtime of the file // so that we can check if it's changed without re-downloading if (!($vcard = $carddav->get_vcard($id))) { $log->error("[contacts] Error reading contact {$id}, skipping"); } else { $vcard_array = split("\r\n", $vcard); $timestamp = null; $name = null; foreach ($vcard_array as $line) { if (preg_match("/^REV:([0-9]*)-([0-9]*)-([0-9]*)T([0-9]*):([0-9]*):([0-9]*)/", $line, $matches)) { $timestamp = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]); } if (preg_match("/^FN:([\\S\\s]*)/", $line, $matches)) { $name = $matches[1]; } } $log->debug("[contacts] Downloaded Vcard for {$name}"); $log->debug("[contacts] Last modified at {$timestamp}");