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); } }
<?php /** * @var Termin[] $alle_termine */ Header("Content-Type: text/calendar"); $vcalendar = new \Sabre\VObject\Component\VCalendar(); foreach ($alle_termine as $curr_termin) { $vcalendar->add('VEVENT', $curr_termin->getVEventParams()); } echo $vcalendar->serialize();
/** * generate VTimezone for given folder * * @param string|Tinebase_Model_Application $applicationName * @return string */ public static function getCalendarVTimezone($applicationName) { $timezone = Tinebase_Core::getPreference()->getValueForUser(Tinebase_Preference::TIMEZONE, Tinebase_Core::getUser()->getId()); $application = $applicationName instanceof Tinebase_Model_Application ? $applicationName : Tinebase_Application::getInstance()->getApplicationByName($applicationName); // create vcalendar object with timezone information $vcalendar = new \Sabre\VObject\Component\VCalendar(array('PRODID' => "-//tine20.org//Tine 2.0 {$application->name} V{$application->version}//EN", 'VERSION' => '2.0', 'CALSCALE' => 'GREGORIAN')); $vcalendar->add(new Sabre_VObject_Component_VTimezone($timezone)); // Taking out \r to not screw up the xml output return str_replace("\r", "", $vcalendar->serialize()); }
public function addEvent($calendar, $titulo, $descripcion, $fecha) { //FIXME esto debería ser una variable $location = "Uroges Cruces"; echo "Vamos a crear {$calendar},{$titulo},{$descripcion},{$fecha} "; $uid = strtoupper(\Rhumsaa\Uuid\Uuid::uuid4()); $inicio = new \DateTime($fecha); $inicio = "VALUE=DATE:" . $fecha; //$inicio = $inicio->setTimezone(new DateTimezone("europe/madrid")); $now = new DateTime("now"); //$now = $now->setTimezone(new DateTimezone("europe/madrid")); $vcalendar = new \Sabre\VObject\Component\VCalendar(); $event = $vcalendar->add('VEVENT', ['CREATED' => $now, 'UID' => $uid, 'SUMMARY' => $titulo, 'DESCRIPTION' => $descripcion, 'DTSTART' => $fecha, 'DTSTAMP' => $now, 'LAST-MODIFIED' => $now, 'TRANSP' => "TRANSPARENT", 'SEQUENCE' => 0]); //$vcalendar->add($event); $etag = md5($vcalendar->serialize()); $startdate = $event->DTSTART->getDateTime()->getTimeStamp(); $enddate = $startdate; $size = strlen($vcalendar->serialize()); //echo "Tenemos el vclandera:<pre>"; //echo $vcalendar->serialize(); //echo "</pre>"; //echo "Vamos a introducir en BBDD el etag $etag el size $size y el tiempo $startdate"; $ret = $this->db->insert('oc_clndr_objects', array('calendardata' => $vcalendar->serialize(), 'uri' => $uid . ".ics", 'calendarid' => $calendar, 'startdate' => $startdate, 'enddate' => $enddate, 'lastmodified' => $now->getTimestamp())); $id = $this->db->lastInsertId(); //Actualizamos el ctag del calendario $this->updateSyncToken($calendar); //echo "Insercion hecha con ID: ".$id; //echo "Vamos a introducir en BBDD el etag $etag el size $size y el tiempo $startdate"; return $id; }
public function createCalendar() { $record = $this->record; $this->log->debug(__CLASS__ . '::' . __METHOD__ . ' | Start CRM ID:' . $record['crmid']); $calType = $record['activitytype'] == 'Task' ? 'VTODO' : 'VEVENT'; $endField = $this->getEndFieldName($calType); $vcalendar = new Sabre\VObject\Component\VCalendar(); $vcalendar->PRODID = '-//' . self::PRODID . ' V' . vglobal('YetiForce_current_version') . '//'; $start = $record['date_start'] . ' ' . $record['time_start']; $end = $record['due_date'] . ' ' . $record['time_end']; if ($record['allday']) { $DTSTART = $vcalendar->createProperty('DTSTART', new DateTime($start)); $endTime = new DateTime($end); $endTime->modify('+1 day'); $DTEND = $vcalendar->createProperty($endField, $endTime); $DTEND['VALUE'] = 'DATE'; $DTSTART['VALUE'] = 'DATE'; } else { $DTSTART = new \DateTime($start); $DTEND = new \DateTime($end); } $cal = $vcalendar->createComponent($calType); $cal->add($vcalendar->createProperty('CREATED', new \DateTime($record['createdtime']))); $cal->add($vcalendar->createProperty('LAST-MODIFIED', new \DateTime($record['modifiedtime']))); $cal->add($vcalendar->createProperty('SUMMARY', $record['subject'])); $cal->add($vcalendar->createProperty('DTSTART', $DTSTART)); $cal->add($vcalendar->createProperty($endField, $DTEND)); $cal->add($vcalendar->createProperty('CLASS', $record['visibility'] == 'Private' ? 'PRIVATE' : 'PUBLIC')); $cal->add($vcalendar->createProperty('PRIORITY', $this->getPriority($record['priority'], FALSE))); $state = $this->getState($record['state']); if ($state) { $cal->add($vcalendar->createProperty('TRANSP', $state, FALSE)); } if (!empty($record['location'])) { $cal->add($vcalendar->createProperty('LOCATION', $record['location'])); } if (!empty($record['description'])) { $cal->add($vcalendar->createProperty('DESCRIPTION', $record['description'])); } $vcalendar->add($cal); $calendarData = $vcalendar->serialize(); $modifiedtime = strtotime($record['modifiedtime']); $extraData = $this->getDenormalizedData($calendarData); $calUri = $extraData['uid'] . '.ics'; $stmt = $this->pdo->prepare('INSERT INTO dav_calendarobjects (calendarid, uri, calendardata, lastmodified, etag, size, componenttype, firstoccurence, lastoccurence, uid, crmid) VALUES (?,?,?,?,?,?,?,?,?,?,?)'); $stmt->execute([$this->calendarId, $calUri, $calendarData, $modifiedtime, $extraData['etag'], $extraData['size'], $extraData['componentType'], $extraData['firstOccurence'], $extraData['lastOccurence'], $extraData['uid'], $record['crmid']]); $this->addChange($calUri, 1); $this->log->debug(__CLASS__ . '::' . __METHOD__ . ' | End'); }
/** * Returns a list of calendar objects. * * This method should work identical to getCalendarObject, but instead * return all the calendar objects in the list as an array. * * If the backend supports this, it may allow for some speed-ups. * * @param mixed $calendarId * @param array $uris * @return array * @throws DAV\Exception\NotFound */ function getMultipleCalendarObjects($calendarId, array $uris) { $return = []; foreach ($uris as $uri) { /** @var Termin $termin */ $termin = Termin::model()->findByPk($uri); if (!$termin) { throw new \Sabre\DAV\Exception\NotFound('Calendar not found'); } $vcalendar = new \Sabre\VObject\Component\VCalendar(); $vcalendar->add('VEVENT', $termin->getVEventParams()); $calendardata = $vcalendar->serialize(); $return[] = ['id' => $termin->id, 'uri' => $termin->id, 'lastmodified' => $termin->datum_letzte_aenderung, 'etag' => rand(0, 999999999999), 'calendarid' => $calendarId, 'calendardata' => $calendardata, 'size' => strlen($calendardata), 'component' => 'VEVENT']; } return $return; }