diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/cdav.php | 186 | ||||
-rw-r--r-- | include/import.php | 67 | ||||
-rw-r--r-- | include/zot.php | 3 |
3 files changed, 256 insertions, 0 deletions
diff --git a/include/cdav.php b/include/cdav.php new file mode 100644 index 000000000..d72caa442 --- /dev/null +++ b/include/cdav.php @@ -0,0 +1,186 @@ +<?php + +/** + * @brief Process CardDAV card + * + * @param array $f fields array + * @param obj $vcard SabreDAV object + * @param bool $edit update card + * + */ + +function process_cdav_card($f, &$vcard, $edit = false) { + + if($f['org']) + $vcard->ORG = $f['org']; + else + if($edit) + unset($vcard->ORG); + + + if($f['title']) + $vcard->TITLE = $f['title']; + else + if($edit) + unset($vcard->TITLE); + + if($edit) + unset($vcard->TEL); + if($f['tel']) { + $i = 0; + foreach($f['tel'] as $item) { + if($item) { + $vcard->add('TEL', $item, ['type' => $f['tel_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->EMAIL); + if($f['email']) { + $i = 0; + foreach($f['email'] as $item) { + if($item) { + $vcard->add('EMAIL', $item, ['type' => $f['email_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->IMPP); + if($f['impp']) { + $i = 0; + foreach($f['impp'] as $item) { + if($item) { + $vcard->add('IMPP', $item, ['type' => $f['impp_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->URL); + if($f['url']) { + $i = 0; + foreach($f['url'] as $item) { + if($item) { + $vcard->add('URL', $item, ['type' => $f['url_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->ADR); + if($f['adr']) { + $i = 0; + foreach($f['adr'] as $item) { + if($item) { + $vcard->add('ADR', $item, ['type' => $f['adr_type'][$i]]); + } + $i++; + } + } + + if($f['note']) { + $vcard->NOTE = $f['note']; + } + else + if($edit) + unset($vcard->NOTE); +} + + +/** + * @brief Import CardDAV or CalDAV card + * + * @param int $id card id + * @param str $ext card extension + * @param str $table name + * @param str $column name + * @param obj $objects + * @param str $profile + * @param obj $backend + * @param array $ids + * @param bool $notice + * + */ + +function import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backend, &$ids, $notice = false) { + + $i = 0; + $newid = (count($ids) ? false : true); + + while ($object = $objects->getNext()) { + + if($_REQUEST['a_upload']) + $object = $object->convert(\Sabre\VObject\Document::VCARD40); + + $ret = $object->validate($profile & \Sabre\VObject\Node::REPAIR); + + //level 3 Means that the document is invalid, + //level 2 means a warning. A warning means it's valid but it could cause interopability issues, + //level 1 means that there was a problem earlier, but the problem was automatically repaired. + + if($ret[0]['level'] < 3) { + + if($newid) { + do { + $duplicate = false; + $objectUri = random_string(40) . '.' . $ext; + + $r = q("SELECT uri FROM $table WHERE $column = %d AND uri = '%s' LIMIT 1", + dbesc($id), + dbesc($objectUri) + ); + if (count($r)) + $duplicate = true; + } while ($duplicate == true); + $ids[$i] = $objectUri; + } + else + $objectUri = $ids[$i]; + + $i++; + + if($ext == 'ics') + $backend->createCalendarObject($id, $objectUri, $object->serialize()); + + if($ext == 'vcf') + $backend->createCard($id, $objectUri, $object->serialize()); + } + else { + if($notice && $ext == 'ics') { + notice( + '<strong>' . t('INVALID EVENT DISMISSED!') . '</strong>' . EOL . + '<strong>' . t('Summary: ') . '</strong>' . (($object->VEVENT->SUMMARY) ? $object->VEVENT->SUMMARY : t('Unknown')) . EOL . + '<strong>' . t('Date: ') . '</strong>' . (($object->VEVENT->DTSTART) ? $object->VEVENT->DTSTART : t('Unknown')) . EOL . + '<strong>' . t('Reason: ') . '</strong>' . $ret[0]['message'] . EOL + ); + } + + if($notice && $exp == 'vcf') { + notice( + '<strong>' . t('INVALID CARD DISMISSED!') . '</strong>' . EOL . + '<strong>' . t('Name: ') . '</strong>' . (($object->FN) ? $object->FN : t('Unknown')) . EOL . + '<strong>' . t('Reason: ') . '</strong>' . $ret[0]['message'] . EOL + ); + } + } + } +} + + +function get_cdav_id($principaluri, $uri, $table) { + + $r = q("SELECT id FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", + dbesc($principaluri), + dbesc($uri) + ); + if(! $r) + return false; + + return $r[0]['id']; +} diff --git a/include/import.php b/include/import.php index 6a3895b9f..0519052d8 100644 --- a/include/import.php +++ b/include/import.php @@ -1504,6 +1504,73 @@ function sync_files($channel, $files) { } /** + * @brief Synchronize addressbooks. + * + * @param array $channel + * @param array $data + */ +function sync_addressbook($channel, $data) { + + if(! \Zotlabs\Lib\Apps::system_app_installed($channel['channel_id'], 'CardDAV')) + return; + + logger("debug: " . print_r($data,true), LOGGER_DEBUG); + + require_once('include/cdav.php'); + + $principalUri = 'principals/' . $channel['channel_address']; + + if($data['action'] !== 'create') { + $id = get_cdav_id($principalUri, $data['uri'], 'addressbooks'); + if(! $id) + return; + } + + $pdo = \DBA::$dba->db; + + $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); + $addressbooks = $carddavBackend->getAddressBooksForUser($principalUri); + + switch($data['action']) { + + case 'create': + $carddavBackend->createAddressBook($principalUri, $data['uri'], $data['properties']); + break; + + case 'drop': + $carddavBackend->deleteAddressBook($id); + break; + + case 'edit': + $patch = new \Sabre\DAV\PropPatch($data['mutations']); + $carddavBackend->updateAddressBook($id, $patch); + $patch->commit(); + break; + + case 'delete_card': + $carddavBackend->deleteCard($id, $data['carduri']); + break; + + case 'update_card': + $vcard = \Sabre\VObject\Reader::read($data['card']); + $object = $vcard->convert(\Sabre\VObject\Document::VCARD40); + $cardData = $vcard->serialize(); + $carddavBackend->updateCard($id, $data['carduri'], $cardData); + break; + + case 'import': + $objects = new \Sabre\VObject\Splitter\VCard($data['card']); + $profile = \Sabre\VObject\Node::PROFILE_CARDDAV; + import_cdav_card($id, 'vcf', 'cards', 'addressbookid', $objects, $profile, $carddavBackend, $data['ids']); + break; + + default: + break; + } +} + + +/** * @brief Rename a key in an array. * * Replaces $old key with $new key in $arr. diff --git a/include/zot.php b/include/zot.php index d08146287..c02dab162 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3611,6 +3611,9 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if(array_key_exists('app',$arr) && $arr['app']) sync_apps($channel,$arr['app']); + if(array_key_exists('addressbook',$arr) && $arr['addressbook']) + sync_addressbook($channel,$arr['addressbook']); + if(array_key_exists('chatroom',$arr) && $arr['chatroom']) sync_chatrooms($channel,$arr['chatroom']); |