diff --git a/inc/CalDAVPrincipal.php b/inc/CalDAVPrincipal.php index d86fc460..512a7fb4 100644 --- a/inc/CalDAVPrincipal.php +++ b/inc/CalDAVPrincipal.php @@ -65,27 +65,27 @@ class CalDAVPrincipal /** * @var RFC3744: The groups in which the principal is directly a member. */ - var $group_membership; + protected $group_membership; /** * @var caldav-cu-proxy-02: The principals which this one has read permissions on. */ - var $read_proxy_for; + protected $read_proxy_for; /** * @var caldav-cu-proxy-02: The principals which this one has read-write prmissions for. */ - var $write_proxy_for; + protected $write_proxy_for; /** * @var caldav-cu-proxy-02: The principals which have read permissions on this one. */ - var $read_proxy_group; + protected $read_proxy_group; /** * @var caldav-cu-proxy-02: The principals which have write permissions on this one. */ - var $write_proxy_group; + protected $write_proxy_group; /** * Constructor @@ -196,6 +196,34 @@ class CalDAVPrincipal } } + $this->group_membership = null; + $this->read_proxy_group = null; + $this->write_proxy_group = null; + $this->write_proxy_for = null; + $this->read_proxy_for = null; + + /** + * calendar-free-busy-set has been dropped from draft 5 of the scheduling extensions for CalDAV + * but we'll keep replying to it for a while longer since iCal appears to want it... + */ + $qry = new PgQuery('SELECT dav_name FROM collection WHERE user_no = ? AND is_calendar', $this->user_no); + $this->calendar_free_busy_set = array(); + if( $qry->Exec('CalDAVPrincipal',__LINE__,__FILE__) && $qry->rows > 0 ) { + while( $calendar = $qry->Fetch() ) { + $this->calendar_free_busy_set[] = ConstructURL($calendar->dav_name, true); + } + } + + dbg_error_log( 'principal', ' User: %s (%d) URL: %s, Home: %s, By Email: %d', $this->username, $this->user_no, $this->url, $this->calendar_home_set, $this->by_email ); + } + + + /** + * Split this out so we do it as infrequently as possible, given the cost. + */ + function FetchProxyGroups() { + global $c; + $this->group_membership = array(); $qry = new PgQuery('SELECT * FROM relationship LEFT JOIN usr ON (to_user = user_no) LEFT JOIN role_member USING (user_no) LEFT JOIN roles USING (role_no) WHERE from_user = ? AND role_name = '."'Group'", $this->user_no ); if ( $qry->Exec('CalDAVPrincipal') && $qry->rows > 0 ) { @@ -241,20 +269,51 @@ class CalDAVPrincipal } } } + } - /** - * calendar-free-busy-set has been dropped from draft 5 of the scheduling extensions for CalDAV - * but we'll keep replying to it for a while longer since iCal appears to want it... - */ - $qry = new PgQuery('SELECT dav_name FROM collection WHERE user_no = ? AND is_calendar', $this->user_no); - $this->calendar_free_busy_set = array(); - if( $qry->Exec('CalDAVPrincipal',__LINE__,__FILE__) && $qry->rows > 0 ) { - while( $calendar = $qry->Fetch() ) { - $this->calendar_free_busy_set[] = ConstructURL($calendar->dav_name, true); - } - } - dbg_error_log( 'principal', ' User: %s (%d) URL: %s, Home: %s, By Email: %d', $this->username, $this->user_no, $this->url, $this->calendar_home_set, $this->by_email ); + /** + * Accessor for the read proxy group + */ + function ReadProxyGroup() { + if ( !isset($this->read_proxy_group) ) $this->FetchProxyGroups(); + return $this->read_proxy_group; + } + + + /** + * Accessor for the write proxy group + */ + function WriteProxyGroup() { + if ( !isset($this->write_proxy_group) ) $this->FetchProxyGroups(); + return $this->write_proxy_group; + } + + + /** + * Accessor for the read proxy for + */ + function ReadProxyFor() { + if ( !isset($this->read_proxy_for) ) $this->FetchProxyGroups(); + return $this->read_proxy_for; + } + + + /** + * Accessor for the write proxy for + */ + function WriteProxyFor() { + if ( !isset($this->write_proxy_for) ) $this->FetchProxyGroups(); + return $this->write_proxy_for; + } + + + /** + * Accessor for the group membership + */ + function GroupMembership() { + if ( !isset($this->group_membership) ) $this->FetchProxyGroups(); + return $this->group_membership; } @@ -403,7 +462,7 @@ class CalDAVPrincipal break; case 'DAV::group-membership': - $prop->NewElement('group-membership', $reply->href($this->group_membership) ); + $prop->NewElement('group-membership', $reply->href($this->GroupMembership()) ); break; case 'urn:ietf:params:xml:ns:caldav:schedule-inbox-URL': diff --git a/inc/caldav-PROPFIND.php b/inc/caldav-PROPFIND.php index 8c24ae94..35617828 100644 --- a/inc/caldav-PROPFIND.php +++ b/inc/caldav-PROPFIND.php @@ -260,9 +260,9 @@ function add_general_properties( &$prop, &$denied, $record ) { // TODO: this duplicates code below. if possible, do said code only once. if ( preg_match('#/[^/]+/calendar-proxy-(read|write)/?#', $record->dav_displayname, $matches) && isset($prop_list['DAV::group-member-set']) ) { if ($matches[1] == 'read') { - $reply->DAVElement($prop, 'group-member-set', href_set_from_paths( $request->principal->read_proxy_group ) ); + $reply->DAVElement($prop, 'group-member-set', href_set_from_paths( $request->principal->ReadProxyGroup() ) ); } else /* if ($matches[1] == 'write') */ { - $reply->DAVElement($prop, 'group-member-set', href_set_from_paths( $request->principal->write_proxy_group ) ); + $reply->DAVElement($prop, 'group-member-set', href_set_from_paths( $request->principal->WriteProxyGroup() ) ); } } @@ -365,16 +365,17 @@ function build_propstat_response( $prop, $denied, $url ) { function add_proxy_response( &$responses, $which, $parent_path ) { global $request, $c, $session; - $collection = (object) ''; - if ( $which == 'read' ) { - $proxy_group = $request->principal->read_proxy_group; - } else if ( $which == 'write' ) { - $proxy_group = $request->principal->write_proxy_group; - } if ($parent_path != '/'.$request->principal->username.'/') { return; // Nothing to proxy for } + $collection = (object) ''; + if ( $which == 'read' ) { + $proxy_group = $request->principal->ReadProxyGroup(); + } else if ( $which == 'write' ) { + $proxy_group = $request->principal->WriteProxyGroup(); + } + $collection->dav_name = $parent_path.'calendar-proxy-'.$which.'/'; $collection->is_calendar = 'f'; $collection->is_principal = 't'; @@ -474,24 +475,24 @@ function collection_to_xml( $collection ) { // Caldav proxy (not described in rfc, but CalendarServer has it) if ( isset($prop_list['http://calendarserver.org/ns/:calendar-proxy-'.$collection->proxy_type.'-for'] ) ) { if ( $collection->proxy_type == 'read' ) { - $proxy_group = $request->principal->read_proxy_for; + $proxy_group = $request->principal->ReadProxyFor(); } else if ( $collection->proxy_type == 'write' ) { - $proxy_group = $request->principal->write_proxy_for; + $proxy_group = $request->principal->WriteProxyFor(); } $reply->CalendarserverElement($prop, 'calendar-proxy-'.$collection->proxy_type.'-for', $reply->href( $proxy_group ) ); } if ( isset($prop_list['DAV::group-member-set']) ) { if ( $collection->proxy_type == 'read' ) { - $proxy_group = $request->principal->read_proxy_group; + $proxy_group = $request->principal->ReadProxyGroup(); } else if ( $collection->proxy_type == 'write' ) { - $proxy_group = $request->principal->write_proxy_group; + $proxy_group = $request->principal->WriteProxyGroup(); } $reply->DAVElement($prop, 'group-member-set', $reply->href( $proxy_group ) ); } if (isset($prop_list['DAV::group-membership'])) { - $reply->DAVElement($prop, 'group-membership', $reply->href( $request->principal->group_membership )); + $reply->DAVElement($prop, 'group-membership', $reply->href( $request->principal->GroupMembership() )); } }