Overview

Packages

  • awl
    • caldav-client-v2
    • RRule
  • davical
    • authentication
      • drivers
    • caldav
    • DAViCalSession
    • DAVTicket
    • external-bind
    • feed
    • HTTPAuthSession
    • iSchedule
    • iSchedule-POST
    • logging
    • metrics
    • Principal
    • propfind
    • PublicSession
    • Request
    • Resource
    • tzservice
  • None
  • PHP

Functions

  • add_failure
  • check_for_expansion
  • component_to_xml
  • controlRequestContainer
  • delete_collection
  • deliverItipCancel
  • display_status
  • do_scheduling_for_delete
  • do_scheduling_reply
  • do_scheduling_requests
  • doImipMessage
  • doItipAttendeeReply
  • doItipOrganizerCancel
  • export_iCalendar
  • GetItip
  • GetTZID
  • handle_cancel_request
  • handle_freebusy_request
  • handle_schedule_reply
  • handle_schedule_request
  • import_addressbook_collection
  • import_calendar_collection
  • import_collection
  • late_catch_fatal_error
  • logRequestHeaders
  • obfuscated_event
  • process_ace
  • processItipCancel
  • property_response
  • public_events_only
  • rollback
  • rollback_on_error
  • send_dav_header
  • simple_write_resource
  • write_alarms
  • write_attendees
  • write_resource
  • Overview
  • Package
  • Function
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3: * CalDAV Server - functions used by GET method handler
  4: *
  5: * @package   davical
  6: * @subpackage   caldav
  7: * @author    Andrew McMillan <andrew@mcmillan.net.nz>
  8: * @copyright Catalyst .Net Ltd, Morphoss Ltd <http://www.morphoss.com/>
  9: * @license   http://gnu.org/copyleft/gpl.html GNU GPL v2 or later
 10: */
 11: 
 12: require_once("iCalendar.php");
 13: require_once("DAVResource.php");
 14: 
 15: function obfuscated_event( $icalendar ) {
 16:   // The user is not admin / owner of this calendar looking at his calendar and can not admin the other cal,
 17:   // or maybe they don't have *read* access but they got here, so they must at least have free/busy access
 18:   // so we will present an obfuscated version of the event that just says "Busy" (translated :-)
 19:   $confidential = new iCalComponent();
 20:   $confidential->SetType($icalendar->GetType());
 21:   $confidential->AddProperty( 'SUMMARY', translate('Busy') );
 22:   $confidential->AddProperty( 'CLASS', 'CONFIDENTIAL' );
 23:   $confidential->SetProperties( $icalendar->GetProperties('DTSTART'), 'DTSTART' );
 24:   $confidential->SetProperties( $icalendar->GetProperties('RRULE'), 'RRULE' );
 25:   $confidential->SetProperties( $icalendar->GetProperties('DURATION'), 'DURATION' );
 26:   $confidential->SetProperties( $icalendar->GetProperties('DTEND'), 'DTEND' );
 27:   $confidential->SetProperties( $icalendar->GetProperties('UID'), 'UID' );
 28:   $confidential->SetProperties( $icalendar->GetProperties('CREATED'), 'CREATED' );
 29: 
 30:   return $confidential;
 31: }
 32: 
 33: function export_iCalendar( DAVResource $dav_resource ) {
 34:   global $session, $c, $request;
 35:   if ( ! $dav_resource->IsCalendar() && !(isset($c->get_includes_subcollections) && $c->get_includes_subcollections) ) {
 36:     /** RFC2616 says we must send an Allow header if we send a 405 */
 37:     header("Allow: PROPFIND,PROPPATCH,OPTIONS,MKCOL,REPORT,DELETE");
 38:     $request->DoResponse( 405, translate("GET requests on collections are only supported for calendars.") );
 39:   }
 40: 
 41:   /**
 42:   * The CalDAV specification does not define GET on a collection, but typically this is
 43:   * used as a .ics download for the whole collection, which is what we do also.
 44:   */
 45:   if ( isset($c->get_includes_subcollections) && $c->get_includes_subcollections ) {
 46:     $where = 'caldav_data.collection_id IN ';
 47:     $where .= '(SELECT bound_source_id FROM dav_binding WHERE dav_binding.dav_name ~ :path_match ';
 48:     $where .= 'UNION ';
 49:     $where .= 'SELECT collection_id FROM collection WHERE collection.dav_name ~ :path_match) ';
 50:     $params = array( ':path_match' => '^'.$dav_resource->dav_name() );
 51:     $distinct = 'DISTINCT ON (calendar_item.uid) ';
 52:   }
 53:   else {
 54:     $where = 'caldav_data.collection_id = :collection_id ';
 55:     $params = array( ':collection_id' => $dav_resource->resource_id() );
 56:     $distinct = '';
 57:   }
 58:   $sql = 'SELECT '.$distinct.' caldav_data, class, caldav_type, calendar_item.user_no, logged_user ';
 59:   $sql .= 'FROM collection INNER JOIN caldav_data USING(collection_id) ';
 60:   $sql .= 'INNER JOIN calendar_item USING ( dav_id ) WHERE '.$where;
 61:   if ( isset($c->strict_result_ordering) && $c->strict_result_ordering ) $sql .= ' ORDER BY calendar_item.uid, calendar_item.dav_id';
 62: 
 63:   $qry = new AwlQuery( $sql, $params );
 64:   if ( !$qry->Exec("GET",__LINE__,__FILE__) ) {
 65:     $request->DoResponse( 500, translate("Database Error") );
 66:   }
 67: 
 68:   /**
 69:   * Here we are constructing a whole calendar response for this collection, including
 70:   * the timezones that are referred to by the events we have selected.
 71:   */
 72:   $vcal = new iCalComponent();
 73:   $vcal->VCalendar();
 74:   $displayname = $dav_resource->GetProperty('displayname');
 75:   if ( isset($displayname) ) {
 76:     $vcal->AddProperty("X-WR-CALNAME", $displayname);
 77:   }
 78:   if ( !empty($c->auto_refresh_duration) ) {
 79:     $vcal->AddProperty("X-APPLE-AUTO-REFRESH-INTERVAL", $c->auto_refresh_duration);
 80:     $vcal->AddProperty("AUTO-REFRESH", $c->auto_refresh_duration);
 81:     $vcal->AddProperty("X-PUBLISHED-TTL", $c->auto_refresh_duration);
 82:   }
 83: 
 84:   $need_zones = array();
 85:   $timezones = array();
 86:   while( $event = $qry->Fetch() ) {
 87:     $ical = new iCalComponent( $event->caldav_data );
 88: 
 89:     /** Save the timezone component(s) into a minimal set for inclusion later */
 90:     $event_zones = $ical->GetComponents('VTIMEZONE',true);
 91:     foreach( $event_zones AS $k => $tz ) {
 92:       $tzid = $tz->GetPValue('TZID');
 93:       if ( !isset($tzid) ) continue ;
 94:       if ( $tzid != '' && !isset($timezones[$tzid]) ) {
 95:         $timezones[$tzid] = $tz;
 96:       }
 97:     }
 98: 
 99:     /** Work out which ones are actually used here */
100:     $comps = $ical->GetComponents('VTIMEZONE',false);
101:     foreach( $comps AS $k => $comp ) {
102:       $tzid = $comp->GetPParamValue('DTSTART', 'TZID');      if ( isset($tzid) && !isset($need_zones[$tzid]) ) $need_zones[$tzid] = 1;
103:       $tzid = $comp->GetPParamValue('DUE',     'TZID');      if ( isset($tzid) && !isset($need_zones[$tzid]) ) $need_zones[$tzid] = 1;
104:       $tzid = $comp->GetPParamValue('DTEND',   'TZID');      if ( isset($tzid) && !isset($need_zones[$tzid]) ) $need_zones[$tzid] = 1;
105: 
106:       if ( $dav_resource->HavePrivilegeTo('all',false) || $session->user_no == $event->user_no || $session->user_no == $event->logged_user
107:             || ( isset($session->email) && $c->allow_get_email_visibility && $comp->IsAttendee($session->email) ) ) {
108:         /**
109:         * These people get to see all of the event, and they should always
110:         * get any alarms as well.
111:         */
112:         $vcal->AddComponent($comp);
113:         continue;
114:       }
115:       /** No visibility even of the existence of these events if they aren't admin/owner/attendee */
116:       if ( $event->class == 'PRIVATE' ) continue;
117: 
118:       if ( ! $dav_resource->HavePrivilegeTo('DAV::read') || $event->class == 'CONFIDENTIAL' ) {
119:        $vcal->AddComponent(obfuscated_event($comp));
120:       }
121:       elseif ( isset($c->hide_alarm) && $c->hide_alarm ) {
122:         // Otherwise we hide the alarms (if configured to)
123:         $comp->ClearComponents('VALARM');
124:         $vcal->AddComponent($comp);
125:       }
126:       else {
127:         $vcal->AddComponent($comp);
128:       }
129:     }
130:   }
131: 
132:   /** Put the timezones on there that we need */
133:   foreach( $need_zones AS $tzid => $v ) {
134:     if ( isset($timezones[$tzid]) ) $vcal->AddComponent($timezones[$tzid]);
135:   }
136: 
137:   return $vcal->Render();
138: }
139: 
DAViCal API documentation generated by ApiGen 2.8.0