/** * @return array */ public function getChildren() { $oAccount = $this->getAccount(); $aCards = array(); $oApiCapabilityManager = \CApi::Manager('capability'); if ($oAccount instanceof \CAccount && $oApiCapabilityManager->IsGlobalContactsSupported($oAccount)) { $aContacts = array(); $oApiGcontactManager = \CApi::Manager('gcontacts'); if ($oApiGcontactManager) { $aContacts = $oApiGcontactManager->GetContactItems($oAccount, \EContactSortField::EMail, \ESortOrder::ASC, 0, 9999); } foreach ($aContacts as $oContact) { $sUID = md5($oContact->Email . '-' . $oContact->Id); $vCard = new \Sabre\VObject\Component\VCard(array('VERSION' => '3.0', 'UID' => $sUID, 'FN' => $oContact->Name)); $vCard->add('EMAIL', $oContact->Email, array('type' => array('work'), 'pref' => 1)); $aCards[] = new GCard(array('uri' => md5($oContact->Email . '-' . $oContact->Id) . '.vcf', 'carddata' => $vCard->serialize(), 'lastmodified' => strtotime('2001-01-01 00:00:00'))); } } return $aCards; }
function post() { if (!local_channel() || get_pconfig(local_channel(), 'cdav', 'enabled') != 1) { return; } $channel = \App::get_channel(); $principalUri = 'principals/' . $channel['channel_address']; if (!cdav_principal($principalUri)) { return; } if (\DBA::$dba && \DBA::$dba->connected) { $pdovars = \DBA::$dba->pdo_get(); } else { killme(); } $pdo = new \PDO($pdovars[0], $pdovars[1], $pdovars[2]); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); require_once 'vendor/autoload.php'; if (argc() == 2 && argv(1) === 'calendar') { $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); $calendars = $caldavBackend->getCalendarsForUser($principalUri); //create new calendar if ($_REQUEST['{DAV:}displayname'] && $_REQUEST['create']) { do { $duplicate = false; $calendarUri = random_string(40); $r = q("SELECT uri FROM calendarinstances WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", dbesc($principalUri), dbesc($calendarUri)); if (count($r)) { $duplicate = true; } } while ($duplicate == true); $properties = ['{DAV:}displayname' => $_REQUEST['{DAV:}displayname'], '{http://apple.com/ns/ical/}calendar-color' => $_REQUEST['color'], '{urn:ietf:params:xml:ns:caldav}calendar-description' => $channel['channel_name']]; $id = $caldavBackend->createCalendar($principalUri, $calendarUri, $properties); // set new calendar to be visible set_pconfig(local_channel(), 'cdav_calendar', $id[0], 1); } //create new calendar object via ajax request if ($_REQUEST['submit'] === 'create_event' && $_REQUEST['title'] && $_REQUEST['target'] && $_REQUEST['dtstart']) { $id = explode(':', $_REQUEST['target']); if (!cdav_perms($id[0], $calendars, true)) { return; } $title = $_REQUEST['title']; $dtstart = new \DateTime($_REQUEST['dtstart']); if ($_REQUEST['dtend']) { $dtend = new \DateTime($_REQUEST['dtend']); } $description = $_REQUEST['description']; $location = $_REQUEST['location']; do { $duplicate = false; $objectUri = random_string(40) . '.ics'; $r = q("SELECT uri FROM calendarobjects WHERE calendarid = %s AND uri = '%s' LIMIT 1", intval($id[0]), dbesc($objectUri)); if (count($r)) { $duplicate = true; } } while ($duplicate == true); $vcalendar = new \Sabre\VObject\Component\VCalendar(['VEVENT' => ['SUMMARY' => $title, 'DTSTART' => $dtstart]]); if ($dtend) { $vcalendar->VEVENT->add('DTEND', $dtend); } if ($description) { $vcalendar->VEVENT->add('DESCRIPTION', $description); } if ($location) { $vcalendar->VEVENT->add('LOCATION', $location); } $calendarData = $vcalendar->serialize(); $caldavBackend->createCalendarObject($id, $objectUri, $calendarData); killme(); } //edit calendar name and color if ($_REQUEST['{DAV:}displayname'] && $_REQUEST['edit'] && $_REQUEST['id']) { $id = explode(':', $_REQUEST['id']); if (!cdav_perms($id[0], $calendars)) { return; } $mutations = ['{DAV:}displayname' => $_REQUEST['{DAV:}displayname'], '{http://apple.com/ns/ical/}calendar-color' => $_REQUEST['color']]; $patch = new \Sabre\DAV\PropPatch($mutations); $caldavBackend->updateCalendar($id, $patch); $patch->commit(); } //edit calendar object via ajax request if ($_REQUEST['submit'] === 'update_event' && $_REQUEST['uri'] && $_REQUEST['title'] && $_REQUEST['target'] && $_REQUEST['dtstart']) { $id = explode(':', $_REQUEST['target']); if (!cdav_perms($id[0], $calendars, true)) { return; } $uri = $_REQUEST['uri']; $title = $_REQUEST['title']; $dtstart = new \DateTime($_REQUEST['dtstart']); $dtend = $_REQUEST['dtend'] ? new \DateTime($_REQUEST['dtend']) : ''; $description = $_REQUEST['description']; $location = $_REQUEST['location']; $object = $caldavBackend->getCalendarObject($id, $uri); $vcalendar = \Sabre\VObject\Reader::read($object['calendardata']); if ($title) { $vcalendar->VEVENT->SUMMARY = $title; } if ($dtstart) { $vcalendar->VEVENT->DTSTART = $dtstart; } if ($dtend) { $vcalendar->VEVENT->DTEND = $dtend; } else { unset($vcalendar->VEVENT->DTEND); } if ($description) { $vcalendar->VEVENT->DESCRIPTION = $description; } if ($location) { $vcalendar->VEVENT->LOCATION = $location; } $calendarData = $vcalendar->serialize(); $caldavBackend->updateCalendarObject($id, $uri, $calendarData); killme(); } //delete calendar object via ajax request if ($_REQUEST['delete'] && $_REQUEST['uri'] && $_REQUEST['target']) { $id = explode(':', $_REQUEST['target']); if (!cdav_perms($id[0], $calendars, true)) { return; } $uri = $_REQUEST['uri']; $caldavBackend->deleteCalendarObject($id, $uri); killme(); } //edit calendar object date/timeme via ajax request (drag and drop) if ($_REQUEST['update'] && $_REQUEST['id'] && $_REQUEST['uri']) { $id = [$_REQUEST['id'][0], $_REQUEST['id'][1]]; if (!cdav_perms($id[0], $calendars, true)) { return; } $uri = $_REQUEST['uri']; $dtstart = new \DateTime($_REQUEST['dtstart']); $dtend = $_REQUEST['dtend'] ? new \DateTime($_REQUEST['dtend']) : ''; $object = $caldavBackend->getCalendarObject($id, $uri); $vcalendar = \Sabre\VObject\Reader::read($object['calendardata']); if ($dtstart) { $vcalendar->VEVENT->DTSTART = $dtstart; } if ($dtend) { $vcalendar->VEVENT->DTEND = $dtend; } else { unset($vcalendar->VEVENT->DTEND); } $calendarData = $vcalendar->serialize(); $caldavBackend->updateCalendarObject($id, $uri, $calendarData); killme(); } //share a calendar - this only works on local system (with channels on the same server) if ($_REQUEST['sharee'] && $_REQUEST['share']) { $id = [intval($_REQUEST['calendarid']), intval($_REQUEST['instanceid'])]; if (!cdav_perms($id[0], $calendars)) { return; } $hash = $_REQUEST['sharee']; $sharee_arr = channelx_by_hash($hash); $sharee = new \Sabre\DAV\Xml\Element\Sharee(); $sharee->href = 'mailto:' . $sharee_arr['channel_hash']; $sharee->principal = 'principals/' . $sharee_arr['channel_address']; $sharee->access = intval($_REQUEST['access']); $sharee->properties = ['{DAV:}displayname' => $channel['channel_name']]; $caldavBackend->updateInvites($id, [$sharee]); } } if (argc() >= 2 && argv(1) === 'addressbook') { $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); $addressbooks = $carddavBackend->getAddressBooksForUser($principalUri); //create new addressbook if ($_REQUEST['{DAV:}displayname'] && $_REQUEST['create']) { do { $duplicate = false; $addressbookUri = random_string(20); $r = q("SELECT uri FROM addressbooks WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", dbesc($principalUri), dbesc($addressbookUri)); if (count($r)) { $duplicate = true; } } while ($duplicate == true); $properties = ['{DAV:}displayname' => $_REQUEST['{DAV:}displayname']]; $carddavBackend->createAddressBook($principalUri, $addressbookUri, $properties); } //edit addressbook if ($_REQUEST['{DAV:}displayname'] && $_REQUEST['edit'] && intval($_REQUEST['id'])) { $id = $_REQUEST['id']; if (!cdav_perms($id, $addressbooks)) { return; } $mutations = ['{DAV:}displayname' => $_REQUEST['{DAV:}displayname']]; $patch = new \Sabre\DAV\PropPatch($mutations); $carddavBackend->updateAddressBook($id, $patch); $patch->commit(); } //create addressbook card if ($_REQUEST['create'] && $_REQUEST['target'] && $_REQUEST['fn']) { $id = $_REQUEST['target']; do { $duplicate = false; $uri = random_string(40) . '.vcf'; $r = q("SELECT uri FROM cards WHERE addressbookid = %s AND uri = '%s' LIMIT 1", intval($id), dbesc($uri)); if (count($r)) { $duplicate = true; } } while ($duplicate == true); //TODO: this mostly duplictes the procedure in update addressbook card. should move this part to a function to avoid duplication $fn = $_REQUEST['fn']; $vcard = new \Sabre\VObject\Component\VCard(['FN' => $fn, 'N' => array_reverse(explode(' ', $fn))]); $org = $_REQUEST['org']; if ($org) { $vcard->ORG = $org; } $title = $_REQUEST['title']; if ($title) { $vcard->TITLE = $title; } $tel = $_REQUEST['tel']; $tel_type = $_REQUEST['tel_type']; if ($tel) { $i = 0; foreach ($tel as $item) { if ($item) { $vcard->add('TEL', $item, ['type' => $tel_type[$i]]); } $i++; } } $email = $_REQUEST['email']; $email_type = $_REQUEST['email_type']; if ($email) { $i = 0; foreach ($email as $item) { if ($item) { $vcard->add('EMAIL', $item, ['type' => $email_type[$i]]); } $i++; } } $impp = $_REQUEST['impp']; $impp_type = $_REQUEST['impp_type']; if ($impp) { $i = 0; foreach ($impp as $item) { if ($item) { $vcard->add('IMPP', $item, ['type' => $impp_type[$i]]); } $i++; } } $url = $_REQUEST['url']; $url_type = $_REQUEST['url_type']; if ($url) { $i = 0; foreach ($url as $item) { if ($item) { $vcard->add('URL', $item, ['type' => $url_type[$i]]); } $i++; } } $adr = $_REQUEST['adr']; $adr_type = $_REQUEST['adr_type']; if ($adr) { $i = 0; foreach ($adr as $item) { if ($item) { $vcard->add('ADR', $item, ['type' => $adr_type[$i]]); } $i++; } } $note = $_REQUEST['note']; if ($note) { $vcard->NOTE = $note; } $cardData = $vcard->serialize(); $carddavBackend->createCard($id, $uri, $cardData); } //edit addressbook card if ($_REQUEST['update'] && $_REQUEST['uri'] && $_REQUEST['target']) { $id = $_REQUEST['target']; if (!cdav_perms($id, $addressbooks)) { return; } $uri = $_REQUEST['uri']; $object = $carddavBackend->getCard($id, $uri); $vcard = \Sabre\VObject\Reader::read($object['carddata']); $fn = $_REQUEST['fn']; if ($fn) { $vcard->FN = $fn; $vcard->N = array_reverse(explode(' ', $fn)); } $org = $_REQUEST['org']; if ($org) { $vcard->ORG = $org; } else { unset($vcard->ORG); } $title = $_REQUEST['title']; if ($title) { $vcard->TITLE = $title; } else { unset($vcard->TITLE); } $tel = $_REQUEST['tel']; $tel_type = $_REQUEST['tel_type']; if ($tel) { $i = 0; unset($vcard->TEL); foreach ($tel as $item) { if ($item) { $vcard->add('TEL', $item, ['type' => $tel_type[$i]]); } $i++; } } else { unset($vcard->TEL); } $email = $_REQUEST['email']; $email_type = $_REQUEST['email_type']; if ($email) { $i = 0; unset($vcard->EMAIL); foreach ($email as $item) { if ($item) { $vcard->add('EMAIL', $item, ['type' => $email_type[$i]]); } $i++; } } else { unset($vcard->EMAIL); } $impp = $_REQUEST['impp']; $impp_type = $_REQUEST['impp_type']; if ($impp) { $i = 0; unset($vcard->IMPP); foreach ($impp as $item) { if ($item) { $vcard->add('IMPP', $item, ['type' => $impp_type[$i]]); } $i++; } } else { unset($vcard->IMPP); } $url = $_REQUEST['url']; $url_type = $_REQUEST['url_type']; if ($url) { $i = 0; unset($vcard->URL); foreach ($url as $item) { if ($item) { $vcard->add('URL', $item, ['type' => $url_type[$i]]); } $i++; } } else { unset($vcard->URL); } $adr = $_REQUEST['adr']; $adr_type = $_REQUEST['adr_type']; if ($adr) { $i = 0; unset($vcard->ADR); foreach ($adr as $item) { if ($item) { $vcard->add('ADR', $item, ['type' => $adr_type[$i]]); } $i++; } } else { unset($vcard->ADR); } $note = $_REQUEST['note']; if ($note) { $vcard->NOTE = $note; } else { unset($vcard->NOTE); } $cardData = $vcard->serialize(); $carddavBackend->updateCard($id, $uri, $cardData); } //delete addressbook card if ($_REQUEST['delete'] && $_REQUEST['uri'] && $_REQUEST['target']) { $id = $_REQUEST['target']; if (!cdav_perms($id, $addressbooks)) { return; } $uri = $_REQUEST['uri']; $carddavBackend->deleteCard($id, $uri); } } //Import calendar or addressbook if ($_FILES && array_key_exists('userfile', $_FILES) && intval($_FILES['userfile']['size']) && $_REQUEST['target']) { $src = @file_get_contents($_FILES['userfile']['tmp_name']); if ($src) { if ($_REQUEST['c_upload']) { $id = explode(':', $_REQUEST['target']); $ext = 'ics'; $table = 'calendarobjects'; $column = 'calendarid'; $objects = new \Sabre\VObject\Splitter\ICalendar($src); $profile = \Sabre\VObject\Node::PROFILE_CALDAV; $backend = new \Sabre\CalDAV\Backend\PDO($pdo); } if ($_REQUEST['a_upload']) { $id[] = intval($_REQUEST['target']); $ext = 'vcf'; $table = 'cards'; $column = 'addressbookid'; $objects = new \Sabre\VObject\Splitter\VCard($src); $profile = \Sabre\VObject\Node::PROFILE_CARDDAV; $backend = new \Sabre\CardDAV\Backend\PDO($pdo); } 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) { do { $duplicate = false; $objectUri = random_string(40) . '.' . $ext; $r = q("SELECT uri FROM {$table} WHERE {$column} = %d AND uri = '%s' LIMIT 1", dbesc($id[0]), dbesc($objectUri)); if (count($r)) { $duplicate = true; } } while ($duplicate == true); if ($_REQUEST['c_upload']) { $backend->createCalendarObject($id, $objectUri, $object->serialize()); } if ($_REQUEST['a_upload']) { $backend->createCard($id[0], $objectUri, $object->serialize()); } } else { if ($_REQUEST['c_upload']) { 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 ($_REQUEST['a_upload']) { 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); } } } } @unlink($src); } }
/** * @return string */ public function ToVCard($sPreVCard = '') { $this->UpdateDependentValues(); $oVCard = null; if (0 < \strlen($sPreVCard)) { try { $oVCard = \Sabre\VObject\Reader::read($sPreVCard); } catch (\Exception $oExc) { } } if (!$oVCard) { $oVCard = new \Sabre\VObject\Component\VCard(); } $oVCard->VERSION = '3.0'; $oVCard->PRODID = '-//RainLoop//' . APP_VERSION . '//EN'; unset($oVCard->FN, $oVCard->EMAIL, $oVCard->TEL, $oVCard->URL, $oVCard->NICKNAME, $oVCard->CATEGORIES, $oVCard->{'X-RL-TAGS'}); $sFirstName = $sLastName = $sMiddleName = $sSuffix = $sPrefix = ''; foreach ($this->Properties as &$oProperty) { if ($oProperty) { $sAddKey = ''; switch ($oProperty->Type) { case PropertyType::FULLNAME: $oVCard->FN = $oProperty->Value; break; case PropertyType::NICK_NAME: $oVCard->NICKNAME = $oProperty->Value; break; case PropertyType::NOTE: $oVCard->NOTE = $oProperty->Value; break; case PropertyType::FIRST_NAME: $sFirstName = $oProperty->Value; break; case PropertyType::LAST_NAME: $sLastName = $oProperty->Value; break; case PropertyType::MIDDLE_NAME: $sMiddleName = $oProperty->Value; break; case PropertyType::NAME_SUFFIX: $sSuffix = $oProperty->Value; break; case PropertyType::NAME_PREFIX: $sPrefix = $oProperty->Value; break; case PropertyType::EMAIl: if (empty($sAddKey)) { $sAddKey = 'EMAIL'; } case PropertyType::WEB_PAGE: if (empty($sAddKey)) { $sAddKey = 'URL'; } case PropertyType::PHONE: if (empty($sAddKey)) { $sAddKey = 'TEL'; } $aTypes = $oProperty->TypesAsArray(); $oVCard->add($sAddKey, $oProperty->Value, \is_array($aTypes) && 0 < \count($aTypes) ? array('TYPE' => $aTypes) : null); break; } } } $oVCard->UID = $this->IdContactStr; $oVCard->N = array($sLastName, $sFirstName, $sMiddleName, $sPrefix, $sSuffix); $oVCard->REV = \gmdate('Ymd', $this->Changed) . 'T' . \gmdate('His', $this->Changed) . 'Z'; if (0 < \count($this->Tags)) { $oVCard->CATEGORIES = $this->Tags; } return (string) $oVCard->serialize(); }
public function createCard($moduleName, $record) { $this->log->debug(__CLASS__ . '::' . __METHOD__ . ' | Start CRM ID:' . $record['crmid']); $vcard = new Sabre\VObject\Component\VCard(); $vcard->PRODID = self::PRODID; if ($moduleName == 'Contacts') { $name = $record['firstname'] . ' ' . $record['lastname']; $vcard->N = [$record['lastname'], $record['firstname']]; $org = Vtiger_Functions::getCRMRecordLabel($record['parentid']); if ($org != '') { $vcard->ORG = $org; } } if ($moduleName == 'OSSEmployees') { $name = $record['name'] . ' ' . $record['last_name']; $vcard->N = [$record['last_name'], $record['name']]; $vcard->ORG = Vtiger_CompanyDetails_Model::getInstanceById()->get('organizationname'); } $vcard->add('FN', $name); foreach ($this->telFields[$moduleName] as $key => $val) { if ($record[$key] != '') { $vcard->add('TEL', $record[$key], ['type' => explode(',', $val)]); } } foreach ($this->mailFields[$moduleName] as $key => $val) { if ($record[$key] != '') { $vcard->add('EMAIL', $record[$key], ['type' => explode(',', $val)]); } } $cardUri = $record['crmid'] . '.vcf'; $cardData = Sabre\DAV\StringUtil::ensureUTF8($vcard->serialize()); $etag = md5($cardData); $modifiedtime = strtotime($record['modifiedtime']); $stmt = $this->pdo->prepare('INSERT INTO dav_cards (carddata, uri, lastmodified, addressbookid, size, etag, crmid) VALUES (?, ?, ?, ?, ?, ?, ?)'); $stmt->execute([$cardData, $cardUri, $modifiedtime, $this->addressBookId, strlen($cardData), $etag, $record['crmid']]); $this->addChange($cardUri, 1); $this->log->debug(__CLASS__ . '::' . __METHOD__ . ' | End'); }