Пример #1
0
function obfuscated_event($icalendar)
{
    // The user is not admin / owner of this calendar looking at his calendar and can not admin the other cal,
    // or maybe they don't have *read* access but they got here, so they must at least have free/busy access
    // so we will present an obfuscated version of the event that just says "Busy" (translated :-)
    $confidential = new iCalComponent();
    $confidential->SetType($icalendar->GetType());
    $confidential->AddProperty('SUMMARY', translate('Busy'));
    $confidential->AddProperty('CLASS', 'CONFIDENTIAL');
    $confidential->SetProperties($icalendar->GetProperties('DTSTART'), 'DTSTART');
    $confidential->SetProperties($icalendar->GetProperties('RRULE'), 'RRULE');
    $confidential->SetProperties($icalendar->GetProperties('DURATION'), 'DURATION');
    $confidential->SetProperties($icalendar->GetProperties('DTEND'), 'DTEND');
    $confidential->SetProperties($icalendar->GetProperties('UID'), 'UID');
    $confidential->SetProperties($icalendar->GetProperties('CREATED'), 'CREATED');
    return $confidential;
}
Пример #2
0
/**
* Return XML for a single component from the DB
*
* @param array $properties The properties for this component
* @param string $item The DB row data for this component
*
* @return string An XML document which is the response for the component
*/
function component_to_xml($properties, $item)
{
    global $session, $c, $request, $reply;
    dbg_error_log("REPORT", "Building XML Response for item '%s'", $item->dav_name);
    $denied = array();
    $unsupported = array();
    $caldav_data = $item->caldav_data;
    $displayname = preg_replace('{^.*/}', '', $item->dav_name);
    $type = 'unknown';
    $contenttype = 'text/plain';
    switch ($item->caldav_type) {
        case 'VJOURNAL':
        case 'VEVENT':
        case 'VTODO':
            $displayname = $item->summary;
            $type = 'calendar';
            $contenttype = 'text/calendar';
            break;
        case 'VCARD':
            $displayname = $item->fn;
            $type = 'vcard';
            $contenttype = 'text/vcard';
            break;
    }
    if (isset($properties['calendar-data']) || isset($properties['displayname'])) {
        if (!$request->AllowedTo('all') && $session->user_no != $item->user_no) {
            // the user is not admin / owner of this calendarlooking at his calendar and can not admin the other cal
            /** @todo We should examine the ORGANIZER and ATTENDEE fields in the event.  If this person is there then they should see this */
            if ($type == 'calendar' && $item->class == 'CONFIDENTIAL' || !$request->AllowedTo('read')) {
                $ical = new iCalComponent($caldav_data);
                $resources = $ical->GetComponents('VTIMEZONE', false);
                $first = $resources[0];
                // if the event is confidential we fake one that just says "Busy"
                $confidential = new iCalComponent();
                $confidential->SetType($first->GetType());
                $confidential->AddProperty('SUMMARY', translate('Busy'));
                $confidential->AddProperty('CLASS', 'CONFIDENTIAL');
                $confidential->SetProperties($first->GetProperties('DTSTART'), 'DTSTART');
                $confidential->SetProperties($first->GetProperties('RRULE'), 'RRULE');
                $confidential->SetProperties($first->GetProperties('DURATION'), 'DURATION');
                $confidential->SetProperties($first->GetProperties('DTEND'), 'DTEND');
                $confidential->SetProperties($first->GetProperties('UID'), 'UID');
                $ical->SetComponents(array($confidential), $confidential->GetType());
                $caldav_data = $ical->Render();
                $displayname = translate('Busy');
            }
        }
    }
    $url = ConstructURL($item->dav_name);
    $prop = new XMLElement("prop");
    foreach ($properties as $k => $v) {
        switch ($k) {
            case 'getcontentlength':
                $contentlength = strlen($caldav_data);
                $prop->NewElement($k, $contentlength);
                break;
            case 'getlastmodified':
                $prop->NewElement($k, ISODateToHTTPDate($item->modified));
                break;
            case 'calendar-data':
                if ($type == 'calendar') {
                    $reply->CalDAVElement($prop, $k, $caldav_data);
                } else {
                    $unsupported[] = $k;
                }
                break;
            case 'address-data':
                if ($type == 'vcard') {
                    $reply->CardDAVElement($prop, $k, $caldav_data);
                } else {
                    $unsupported[] = $k;
                }
                break;
            case 'getcontenttype':
                $prop->NewElement($k, $contenttype);
                break;
            case 'current-user-principal':
                $prop->NewElement("current-user-principal", $request->current_user_principal_xml);
                break;
            case 'displayname':
                $prop->NewElement($k, $displayname);
                break;
            case 'resourcetype':
                $prop->NewElement($k);
                // Just an empty resourcetype for a non-collection.
                break;
            case 'getetag':
                $prop->NewElement($k, '"' . $item->dav_etag . '"');
                break;
            case '"current-user-privilege-set"':
                $prop->NewElement($k, privileges($request->permissions));
                break;
            case 'SOME-DENIED-PROPERTY':
                /** indicating the style for future expansion */
                $denied[] = $k;
                break;
            default:
                dbg_error_log('REPORT', "Request for unsupported property '%s' of calendar item.", $v);
                $unsupported[] = $k;
        }
    }
    $status = new XMLElement("status", "HTTP/1.1 200 OK");
    $propstat = new XMLElement("propstat", array($prop, $status));
    $href = new XMLElement("href", $url);
    $elements = array($href, $propstat);
    if (count($denied) > 0) {
        $status = new XMLElement("status", "HTTP/1.1 403 Forbidden");
        $noprop = new XMLElement("prop");
        foreach ($denied as $k => $v) {
            $noprop->NewElement(strtolower($v));
        }
        $elements[] = new XMLElement("propstat", array($noprop, $status));
    }
    if (count($unsupported) > 0) {
        $status = new XMLElement("status", "HTTP/1.1 404 Not Found");
        $noprop = new XMLElement("prop");
        foreach ($unsupported as $k => $v) {
            $noprop->NewElement(strtolower($v));
        }
        $elements[] = new XMLElement("propstat", array($noprop, $status));
    }
    $response = new XMLElement("response", $elements);
    return $response;
}
Пример #3
0
 /**
  * Generate a VTODO from a SyncAppointment(Exception)
  * @param string $data
  * @param string $id
  * @return iCalComponent
  */
 private function _ParseASTaskToVTodo($data, $id)
 {
     $vtodo = new iCalComponent();
     $vtodo->SetType("VTODO");
     if (isset($data->body)) {
         $vtodo->AddProperty("DESCRIPTION", $data->body);
     }
     if (isset($data->asbody->data)) {
         if (isset($data->nativebodytype) && $data->nativebodytype == SYNC_BODYPREFERENCE_RTF) {
             $rtfparser = new rtf();
             $rtfparser->loadrtf(base64_decode($data->asbody->data));
             $rtfparser->output("ascii");
             $rtfparser->parse();
             $vtodo->AddProperty("DESCRIPTION", $rtfparser->out);
         } else {
             $vtodo->AddProperty("DESCRIPTION", $data->asbody->data);
         }
     }
     if (isset($data->complete)) {
         if ($data->complete == "0") {
             $vtodo->AddProperty("STATUS", "NEEDS-ACTION");
         } else {
             $vtodo->AddProperty("STATUS", "COMPLETED");
         }
     }
     if (isset($data->datecompleted)) {
         $vtodo->AddProperty("COMPLETED", gmdate("Ymd\\THis\\Z", $data->datecompleted));
     }
     if ($data->utcduedate) {
         $vtodo->AddProperty("DUE", gmdate("Ymd\\THis\\Z", $data->utcduedate));
     }
     if (isset($data->importance)) {
         if ($data->importance == "1") {
             $vtodo->AddProperty("PRIORITY", 6);
         } elseif ($data->importance == "2") {
             $vtodo->AddProperty("PRIORITY", 9);
         } else {
             $vtodo->AddProperty("PRIORITY", 1);
         }
     }
     if (isset($data->recurrence)) {
         $vtodo->AddProperty("RRULE", $this->_GenerateRecurrence($data->recurrence));
     }
     if ($data->reminderset && $data->remindertime) {
         $valarm = new iCalComponent();
         $valarm->SetType("VALARM");
         $valarm->AddProperty("ACTION", "DISPLAY");
         $valarm->AddProperty("TRIGGER;VALUE=DATE-TIME", gmdate("Ymd\\THis\\Z", $data->remindertime));
         $vtodo->AddComponent($valarm);
     }
     if (isset($data->sensitivity)) {
         switch ($data->sensitivity) {
             case "0":
                 $vtodo->AddProperty("CLASS", "PUBLIC");
                 break;
             case "2":
                 $vtodo->AddProperty("CLASS", "PRIVATE");
                 break;
             case "3":
                 $vtodo->AddProperty("CLASS", "CONFIDENTIAL");
                 break;
         }
     }
     if (isset($data->utcstartdate)) {
         $vtodo->AddProperty("DTSTART", gmdate("Ymd\\THis\\Z", $data->utcstartdate));
     }
     if (isset($data->subject)) {
         $vtodo->AddProperty("SUMMARY", $data->subject);
     }
     if (isset($data->rtf)) {
         $rtfparser = new rtf();
         $rtfparser->loadrtf(base64_decode($data->rtf));
         $rtfparser->output("ascii");
         $rtfparser->parse();
         $vtodo->AddProperty("DESCRIPTION", $rtfparser->out);
     }
     if (isset($data->categories) && is_array($data->categories)) {
         $vtodo->AddProperty("CATEGORIES", implode(",", $data->categories));
     }
     return $vtodo;
 }
Пример #4
0
 /**
  * The constructor takes an array of args.  If there is an element called 'icalendar'
  * then that will be parsed into the iCalendar object.  Otherwise the array elements
  * are converted into properties of the iCalendar object directly.
  */
 function iRemoteCalendar($args)
 {
     global $c;
     $this->tz_locn = "";
     if (!isset($args) || !(is_array($args) || is_object($args))) {
         return;
     }
     if (is_object($args)) {
         settype($args, 'array');
     }
     $this->component = new iCalComponent();
     if (isset($args['icalendar'])) {
         $this->component->ParseFrom($args['icalendar']);
         $this->lines = preg_split('/\\r?\\n/', $args['icalendar']);
         $this->SaveTimeZones();
         $first =& $this->component->FirstNonTimezone();
         if ($first) {
             $this->type = $first->GetType();
             $this->properties = $first->GetProperties();
         } else {
             $this->properties = array();
         }
         $this->properties['VCALENDAR'] = array('***ERROR*** This class is being referenced in an unsupported way!');
         return;
     }
     if (isset($args['type'])) {
         $this->type = $args['type'];
         unset($args['type']);
     } else {
         $this->type = 'VEVENT';
         // Default to event
     }
     $this->component->SetType('VCALENDAR');
     $this->component->SetProperties(array(new iCalProp('PRODID:-//davical.org//NONSGML AWL Calendar//EN'), new iCalProp('VERSION:2.0'), new iCalProp('CALSCALE:GREGORIAN')));
     $first = new iCalComponent();
     $first->SetType($this->type);
     $this->properties = array();
     foreach ($args as $k => $v) {
         dbg_error_log("iCalendar", ":Initialise: %s to >>>%s<<<", $k, $v);
         $property = new iCalProp();
         $property->Name($k);
         $property->Value($v);
         $this->properties[] = $property;
     }
     $first->SetProperties($this->properties);
     $this->component->SetComponents(array($first));
     $this->properties['VCALENDAR'] = array('***ERROR*** This class is being referenced in an unsupported way!');
     /**
      * @todo Need to handle timezones!!!
      */
     if ($this->tz_locn == "") {
         $this->tz_locn = $this->Get("tzid");
         if ((!isset($this->tz_locn) || $this->tz_locn == "") && isset($c->local_tzid)) {
             $this->tz_locn = $c->local_tzid;
         }
     }
 }
Пример #5
0
function get_freebusy($path_match, $range_start, $range_end, $bin_privs = null)
{
    global $request;
    //  printf( "Path: %s\n", $path_match);
    //  print_r($range_start);
    //  print_r($range_end);
    if (!isset($bin_privs)) {
        $bin_privs = $request->Privileges();
    }
    if (!isset($range_start) || !isset($range_end)) {
        $request->DoResponse(400, 'All valid freebusy requests MUST contain a time-range filter');
    }
    $params = array(':path_match' => $path_match, ':start' => $range_start->UTC(), ':end' => $range_end->UTC());
    $where = ' WHERE caldav_data.dav_name ~ :path_match ';
    $where .= 'AND rrule_event_overlaps( dtstart, dtend, rrule, :start, :end) ';
    $where .= "AND caldav_data.caldav_type IN ( 'VEVENT', 'VTODO' ) ";
    $where .= "AND (calendar_item.transp != 'TRANSPARENT' OR calendar_item.transp IS NULL) ";
    $where .= "AND (calendar_item.status != 'CANCELLED' OR calendar_item.status IS NULL) ";
    $where .= "AND collection.is_calendar AND collection.schedule_transp = 'opaque' ";
    if ($bin_privs != privilege_to_bits('all')) {
        $where .= "AND (calendar_item.class != 'PRIVATE' OR calendar_item.class IS NULL) ";
    }
    // $debugging = true;
    $fbtimes = array();
    $sql = 'SELECT caldav_data.caldav_data, calendar_item.rrule, calendar_item.transp, calendar_item.status, ';
    $sql .= "to_char(calendar_item.dtstart at time zone 'GMT'," . iCalendar::SqlUTCFormat() . ') AS start, ';
    $sql .= "to_char(calendar_item.dtend at time zone 'GMT'," . iCalendar::SqlUTCFormat() . ') AS finish, ';
    $sql .= "calendar_item.class, calendar_item.dav_id ";
    $sql .= 'FROM caldav_data INNER JOIN calendar_item USING(dav_id,user_no,dav_name,collection_id) ';
    $sql .= 'INNER JOIN collection USING(collection_id)';
    $sql .= $where;
    if (isset($c->strict_result_ordering) && $c->strict_result_ordering) {
        $sql .= ' ORDER BY dav_id';
    }
    $qry = new AwlQuery($sql, $params);
    if ($qry->Exec("REPORT", __LINE__, __FILE__) && $qry->rows() > 0) {
        while ($calendar_object = $qry->Fetch()) {
            $extra = '';
            if ($calendar_object->status == 'TENTATIVE') {
                $extra = ';BUSY-TENTATIVE';
            }
            //      else if ( $debugging ) {
            //        $extra = ';'.$calendar_object->dav_id;
            //      }
            dbg_error_log("REPORT", " FreeBusy: Not transparent, tentative or cancelled: %s, %s, %s", $calendar_object->start, $calendar_object->finish, $calendar_object->class);
            $ics = new vComponent($calendar_object->caldav_data);
            $expanded = expand_event_instances($ics, $range_start, $range_end);
            $expansion = $expanded->GetComponents(array('VEVENT' => true, 'VTODO' => true, 'VJOURNAL' => true));
            foreach ($expansion as $k => $v) {
                //        echo "=====================================================\n";
                //        printf( "Type: %s\n", $v->GetType());
                //        print_r($v);
                //        echo "-----------------------------------------------------\n";
                $start_date = $v->GetProperty('DTSTART');
                if (!isset($start_date)) {
                    continue;
                }
                $start_date = new RepeatRuleDateTime($start_date);
                $duration = $v->GetProperty('DURATION');
                $duration = !isset($duration) ? 'P1D' : $duration->Value();
                $end_date = clone $start_date;
                $end_date->modify($duration);
                if ($end_date == $start_date || $end_date < $range_start || $start_date > $range_end) {
                    continue;
                }
                $thisfb = $start_date->UTC() . '/' . $end_date->UTC() . $extra;
                array_push($fbtimes, $thisfb);
            }
        }
    }
    $freebusy = new iCalComponent();
    $freebusy->SetType('VFREEBUSY');
    $freebusy->AddProperty('DTSTAMP', date('Ymd\\THis\\Z'));
    $freebusy->AddProperty('DTSTART', $range_start->UTC());
    $freebusy->AddProperty('DTEND', $range_end->UTC());
    sort($fbtimes);
    foreach ($fbtimes as $k => $v) {
        $text = explode(';', $v, 2);
        $freebusy->AddProperty('FREEBUSY', $text[0], isset($text[1]) ? array('FBTYPE' => $text[1]) : null);
    }
    return $freebusy;
}