/**
  * 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;
 }
Beispiel #2
0
 $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}");