mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-05-26 02:44:29 +00:00
Merge remote branch 'origin/master' into sched
This commit is contained in:
commit
f4e561412f
@ -7,7 +7,7 @@ written in Python.</p>
|
||||
|
||||
<ol>
|
||||
<li>Select "Subscribe" from the "Share" menu (or in older builds it was in the "Collection" menu).</li>
|
||||
<li>Enter a URL like: "http://calendar.example.net/caldav.php/username/home/" (click "Subscribe") <img src="clients/Chandler-dialog1.png" /> <br /> </li>
|
||||
<li>Enter a URL like: "http://calendar.example.net/caldav.php/username/calendar/" (click "Subscribe") <img src="clients/Chandler-dialog1.png" /> <br /> </li>
|
||||
<li>You will then be prompted for a username/password with in an expanded dialog. Enter these and click "Subscribe" again. <img src="clients/Chandler-dialog2.png" /> <br /> </li>
|
||||
<li>You should now have a new calendar showing.</li>
|
||||
</ol>
|
||||
|
||||
@ -5,7 +5,7 @@ was little in the way of a repository available to test against until recently.<
|
||||
|
||||
<ol>
|
||||
<li>Select "File" then "New" then "Calendar" from the menus.</li>
|
||||
<li>Choose a type of "CalDAV", enter a name, and a URL such as <code>caldav://server.domain.name/caldav.php/username/home/</code>, enter your user name for DAViCal and click "OK".<img src="clients/Evolution-dialog1.png" /> <br /> </li>
|
||||
<li>Choose a type of "CalDAV", enter a name, and a URL such as <code>caldav://server.domain.name/caldav.php/username/calendar/</code>, enter your user name for DAViCal and click "OK".<img src="clients/Evolution-dialog1.png" /> <br /> </li>
|
||||
<li>You should now be prompted for a password for that username. Enter the password and your calendar should now show.</li>
|
||||
</ol>
|
||||
|
||||
|
||||
@ -10,13 +10,25 @@ that Mulberry does it.</p>
|
||||
<li>Calendar namespace</li>
|
||||
</ul>
|
||||
|
||||
<p>The host name is, of course, up to you. The 'root path' should be <code>/caldav.php/</code> and anything following that is the calendar namespace.</p>
|
||||
<p>Within the calendar namespace DAViCal uses the first element of the path as the user or resource name, so that a client connecting at the root path
|
||||
can see all of the (accessible) users and resources available to them (Mulberry displays this hierarchy) with any calendars below that.</p>
|
||||
<p>Effectively this means that in Evolution, Sunbird and Lightning you should really specify a calendar URL which is something like:</p>
|
||||
<p>The host name is, of course, up to you. The 'root path' should be
|
||||
<code>/caldav.php/</code> and anything following that is the calendar
|
||||
namespace.</p>
|
||||
|
||||
<p>Within the calendar namespace DAViCal uses the first element of the
|
||||
path as the user or 'princpal' name, so that a client connecting at the
|
||||
root path can see all of the (accessible) users and resources available
|
||||
to them (Mulberry displays this hierarchy) with any calendars below that.</p>
|
||||
|
||||
<p>This means that in Evolution, Lightning and other software wanting a
|
||||
'calendar' URL you should specify a URL which is something like:</p>
|
||||
<pre>
|
||||
http://calendar.example.net/caldav.php/username/home/
|
||||
http://calendar.example.net/caldav.php/username/calendar/
|
||||
</pre>
|
||||
<p>Then, when more calendar client software sees it as useful to be able to browse that hierarchy, you won't be up for any heavy database manipulation.</p>
|
||||
<p>I may well enforce this standard in some way before release 1.0, as well as auto-creating the <code>collection</code> records when Evolution, Lightning
|
||||
or Sunbird attempt to store to a non-existent collection.</p>
|
||||
|
||||
<p>DAViCal creates two collections automatically when a user is created. In
|
||||
recent versions these are called 'calendar' and 'addressbook'. Some software
|
||||
also makes it easy to create more calendars and addressbooks, or you can create
|
||||
more through DAViCal's web interface, also.</p>
|
||||
|
||||
<p>In older versions of DAViCal (pre 0.9.9.5) the default calendar was named 'home'
|
||||
and there was no default addressbook.</p>
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
<ol>
|
||||
<li>Select "New Calendar" from the "File" menu.</li>
|
||||
<li>Choose "On the Network" (click "Next")<img src="clients/Mozilla-dialog1.png" /> <br /> </li>
|
||||
<li>Choose a format of "CalDAV" and enter a URL like: "http://calendar.example.net/caldav.php/username/home/" (click "Next")<img src="clients/Mozilla-dialog2.png" /> <br /> </li>
|
||||
<li>Choose a format of "CalDAV" and enter a URL like: "http://calendar.example.net/caldav.php/username/calendar/" (click "Next")<img src="clients/Mozilla-dialog2.png" /> <br /> </li>
|
||||
<li>Give the calendar an appropriate display name, and choose a colour for events on this calendar. (click "Next")<img src="clients/Mozilla-dialog3.png" /> <br /> </li>
|
||||
<li>click "Finish"</li>
|
||||
</ol>
|
||||
|
||||
@ -6,3 +6,24 @@ against, but so far these are the only ones I have access to.</p>
|
||||
<p>If you want to point me at more free software that supports CalDAV, or
|
||||
send me free copies of such proprietary software, then I will add it to
|
||||
the list as well as make DAViCal work with it.</p>
|
||||
|
||||
<p>In the general CalDAV terminology, client software will want to know
|
||||
several facts about the CalDAV server. Some (like iCal and iOS) will try
|
||||
and discover these facts for themselves, and others (like Lightning and
|
||||
Evolution) will require you to enter some information. When they ask for
|
||||
that information they will be asking for the following things:</p>
|
||||
<ol>
|
||||
<li>Where is the user's "home" collection?</li>
|
||||
<li>Where is the user's "calendar" collection?</li>
|
||||
<li>What is the server's domain name</li>
|
||||
</ol>
|
||||
|
||||
<p>Typically the answers, in DAViCal's case, are:</p>
|
||||
<ol>
|
||||
<li>.../caldav.php/username/</li>
|
||||
<li>.../caldav.php/username/calendar/ (although in older versions the default calendar was called 'home' rather than 'calendar')</li>
|
||||
<li>I can't help here - whatever you called it, I guess!</li>
|
||||
</ol>
|
||||
|
||||
<p>There could well be a wider range of information about many and varied client
|
||||
software on the <a href="http://wiki.davical.org/" title="The DAViCal CalDAV Server Wiki">DAViCal Wiki</a> as well.
|
||||
@ -24,7 +24,7 @@ if ( ! @include_once( $code_file ) ) {
|
||||
$c->messages[] = sprintf('No page found to %s %s%s%s', $action, ($action == 'browse' ? '' : 'a '), $component, ($action == 'browse' ? 's' : ''));
|
||||
include('page-header.php');
|
||||
include('page-footer.php');
|
||||
exit(0);
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
|
||||
include('page-header.php');
|
||||
|
||||
@ -26,6 +26,7 @@ function early_exception_handler($e) {
|
||||
foreach( $trace AS $k => $v ) {
|
||||
printf( "%s[%d] %s%s%s()\n", $v['file'], $v['line'], (isset($v['class'])?$v['class']:''), (isset($v['type'])?$v['type']:''), (isset($v['function'])?$v['function']:'') );
|
||||
}
|
||||
@ob_flush();
|
||||
}
|
||||
set_exception_handler('early_exception_handler');
|
||||
|
||||
@ -89,7 +90,7 @@ if ( ! @include_once('AWLUtilities.php') ) {
|
||||
}
|
||||
if ( ! @include_once('AWLUtilities.php') ) {
|
||||
echo "Could not find the AWL libraries. Are they installed? Check your include_path in php.ini!\n";
|
||||
exit;
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +146,7 @@ else if ( @file_exists('config/config.php') ) {
|
||||
}
|
||||
else {
|
||||
include('davical_configuration_missing.php');
|
||||
exit;
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
$config_warnings = trim(ob_get_contents());
|
||||
ob_end_clean();
|
||||
|
||||
@ -17,17 +17,17 @@ if ( isset($_SERVER['PATH_INFO']) && preg_match( '{^(/favicon.ico|davical.css|(i
|
||||
else {
|
||||
fpassthru($fh);
|
||||
}
|
||||
exit(0);
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
require_once('./always.php');
|
||||
|
||||
if ( isset($_SERVER['PATH_INFO']) && preg_match( '{^/\.well-known/(.+)$}', $_SERVER['PATH_INFO'], $matches ) ) {
|
||||
require ('well-known.php');
|
||||
exit(0);
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
elseif ( isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] == '/autodiscover/autodiscover.xml' ) {
|
||||
require ('autodiscover-handler.php');
|
||||
exit(0);
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
|
||||
function logRequestHeaders() {
|
||||
@ -102,7 +102,7 @@ if ( ! ($request->IsPrincipal() || isset($request->collection) || $request->meth
|
||||
$redirect_url = ConstructURL('/caldav.php'.$matches[1]);
|
||||
dbg_error_log( 'LOG WARNING', 'Redirecting %s for "%s" to "%s"', $request->method, $request->path, $redirect_url );
|
||||
header('Location: '.$redirect_url );
|
||||
exit(0);
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ if ( $_SERVER['REQUEST_METHOD'] != "GET" && $_SERVER['REQUEST_METHOD'] != "POST"
|
||||
* If the request is not a GET or POST then they must really want caldav.php!
|
||||
*/
|
||||
include("./caldav.php");
|
||||
exit; // Not that it should return from that!
|
||||
@ob_flush(); exit(0); // Not that it should return from that!
|
||||
}
|
||||
|
||||
include("./always.php");
|
||||
|
||||
@ -21,7 +21,7 @@ require_once("caldav-PUT-functions.php");
|
||||
include_once('check_UTF8.php');
|
||||
|
||||
if ( !$session->AllowedTo("Admin" ) )
|
||||
exit;
|
||||
@ob_flush(); exit(0);
|
||||
|
||||
if( function_exists("sync_LDAP") && isset($_POST['Sync_LDAP'])){
|
||||
sync_LDAP();
|
||||
|
||||
@ -1201,8 +1201,7 @@ EOSQL;
|
||||
@dbg_error_log("statistics", "Method: %s, Status: %d, Script: %5.3lfs, Queries: %5.3lfs, URL: %s",
|
||||
$this->method, $status, $script_time, $c->total_query_time, $this->path);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -283,6 +283,17 @@ class DAVResource
|
||||
$this->resource->location = null;
|
||||
$this->resource->url = null;
|
||||
}
|
||||
else if ( isset($c->hide_alarm) && $c->hide_alarm && !$this->HavePrivilegeTo('write') ) {
|
||||
$vcal1 = new iCalComponent($this->resource->caldav_data);
|
||||
$comps = $vcal1->GetComponents();
|
||||
$vcal2 = new iCalComponent();
|
||||
$vcal2->VCalendar();
|
||||
foreach( $comps AS $comp ) {
|
||||
$comp->ClearComponents('VALARM');
|
||||
$vcal2->AddComponent($comp);
|
||||
}
|
||||
$this->resource->caldav_data = $vcal2->Render();
|
||||
}
|
||||
}
|
||||
else if ( strtoupper(substr($this->resource->caldav_data,0,11)) == 'BEGIN:VCARD' ) {
|
||||
$this->contenttype = 'text/vcard';
|
||||
@ -1048,8 +1059,8 @@ EOQRY;
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether this resource is a calendar
|
||||
* @param string $type The type of scheduling collection, 'read', 'write' or 'any'
|
||||
* Checks whether this resource is a scheduling inbox/outbox collection
|
||||
* @param string $type The type of scheduling collection, 'inbox', 'outbox' or 'any'
|
||||
*/
|
||||
function IsSchedulingCollection( $type = 'any' ) {
|
||||
if ( $this->_is_collection && preg_match( '{schedule-(inbox|outbox)}', $this->collection->type, $matches ) ) {
|
||||
@ -1059,6 +1070,18 @@ EOQRY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether this resource is IN a scheduling inbox/outbox collection
|
||||
* @param string $type The type of scheduling collection, 'inbox', 'outbox' or 'any'
|
||||
*/
|
||||
function IsInSchedulingCollection( $type = 'any' ) {
|
||||
if ( !$this->_is_collection && preg_match( '{schedule-(inbox|outbox)}', $this->collection->type, $matches ) ) {
|
||||
return ($type == 'any' || $type == $matches[1]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether this resource is an addressbook
|
||||
*/
|
||||
@ -1245,6 +1268,14 @@ EOQRY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the target collection is for public events only
|
||||
*/
|
||||
function IsPublicOnly() {
|
||||
return ( isset($this->collection->publicly_events_only) && $this->collection->publicly_events_only == 't' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the type of whatever contains this resource, or would if it existed.
|
||||
*/
|
||||
@ -1371,6 +1402,11 @@ EOQRY;
|
||||
return clone($this->resource);
|
||||
break;
|
||||
|
||||
case 'dav-data':
|
||||
if ( !isset($this->resource) ) $this->FetchResource();
|
||||
return $this->resource->caldav_data;
|
||||
break;
|
||||
|
||||
case 'principal':
|
||||
if ( !isset($this->principal) ) $this->FetchPrincipal();
|
||||
return clone($this->principal);
|
||||
|
||||
@ -113,7 +113,7 @@ class DAViCalSession extends Session
|
||||
|| (isset($c->restrict_admin_port) && $c->restrict_admin_port != $_SERVER['SERVER_PORT'] ) ) {
|
||||
header('Location: caldav.php');
|
||||
dbg_error_log( 'LOG WARNING', 'Access to "%s" via "%s:%d" rejected.', $_SERVER['REQUEST_URI'], $current_domain, $_SERVER['SERVER_PORT'] );
|
||||
exit(0);
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
if ( isset($c->restrict_admin_roles) && $roles == '' ) $roles = $c->restrict_admin_roles;
|
||||
if ( $this->logged_in && $roles == '' ) return;
|
||||
@ -156,7 +156,7 @@ class DAViCalSession extends Session
|
||||
}
|
||||
|
||||
include('page-footer.php');
|
||||
exit;
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ class HTTPAuthSession {
|
||||
header( $auth_header );
|
||||
echo 'Please log in for access to this system.';
|
||||
dbg_error_log( "HTTPAuth", ":Session: User is not authorised: %s ", $_SERVER['REMOTE_ADDR'] );
|
||||
exit;
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
|
||||
|
||||
@ -139,6 +139,11 @@ class HTTPAuthSession {
|
||||
*/
|
||||
if ( isset($_SERVER['PHP_AUTH_USER']) ) {
|
||||
if ( $p = $this->CheckPassword( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) {
|
||||
if ( isset($p->active) && !isset($p->user_active) ) {
|
||||
trace_bug('Some authentication failed to return a dav_principal record and needs fixing.');
|
||||
$p->user_active = $p->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe some external authentication didn't return false for an inactive
|
||||
* user, so we'll be pedantic here.
|
||||
@ -300,7 +305,11 @@ class HTTPAuthSession {
|
||||
* It can expect that:
|
||||
* - Configuration data will be in $c->authenticate_hook['config'], which might be an array, or whatever is needed.
|
||||
*/
|
||||
return call_user_func( $c->authenticate_hook['call'], $username, $password );
|
||||
$principal = call_user_func( $c->authenticate_hook['call'], $username, $password );
|
||||
if ( $principal !== false && !($principal instanceof Principal) ) {
|
||||
$principal = new Principal('username', $username);
|
||||
}
|
||||
return $principal;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -17,7 +17,7 @@ class WritableCollection extends DAVResource {
|
||||
return $p->GetParameterValue('TZID');
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Writes the data to a member in the collection and returns the segment_name of the
|
||||
* resource in our internal namespace.
|
||||
*
|
||||
@ -36,7 +36,7 @@ class WritableCollection extends DAVResource {
|
||||
return false;
|
||||
}
|
||||
|
||||
global $tz_regex, $session, $caldav_context;
|
||||
global $session, $caldav_context;
|
||||
|
||||
$resources = $vcal->GetComponents('VTIMEZONE',false); // Not matching VTIMEZONE
|
||||
$user_no = $this->user_no();
|
||||
@ -179,18 +179,11 @@ class WritableCollection extends DAVResource {
|
||||
$calitem_params[':dtstamp'] = $dtstamp;
|
||||
|
||||
$class = $first->GetPValue('CLASS');
|
||||
/* Check and see if we should over ride the class. */
|
||||
/** @todo is there some way we can move this out of this function? Or at least get rid of the need for the SQL query here. */
|
||||
if ( public_events_only($user_no, $path) ) {
|
||||
$class = 'PUBLIC';
|
||||
}
|
||||
|
||||
/*
|
||||
* It seems that some calendar clients don't set a class...
|
||||
* RFC2445, 4.8.1.3:
|
||||
* Default is PUBLIC
|
||||
* RFC2445, 4.8.1.3: Default is PUBLIC
|
||||
*/
|
||||
if ( !isset($class) || $class == '' ) {
|
||||
if ( $this->IsPublicOnly() || !isset($class) || $class == '' ) {
|
||||
$class = 'PUBLIC';
|
||||
}
|
||||
$calitem_params[':class'] = $class;
|
||||
@ -202,19 +195,11 @@ class WritableCollection extends DAVResource {
|
||||
$tz = $vcal->GetTimeZone($tzid);
|
||||
$olson = $vcal->GetOlsonName($tz);
|
||||
|
||||
dbg_error_log( 'PUT', ' Using TZID[%s] and location of [%s]', $tzid, (isset($olson) ? $olson : '') );
|
||||
if ( !empty($olson) && ($olson != $last_olson) && preg_match( $tz_regex, $olson ) ) {
|
||||
if ( !empty($olson) && ($olson != $last_olson) ) {
|
||||
dbg_error_log( 'PUT', ' Setting timezone to %s', $olson );
|
||||
$qry->QDo('SET TIMEZONE TO \''.$olson."'" );
|
||||
$last_olson = $olson;
|
||||
}
|
||||
$params = array( ':tzid' => $tzid);
|
||||
$qry = new AwlQuery('SELECT 1 FROM timezones WHERE tzid = :tzid', $params );
|
||||
if ( $qry->Exec('PUT',__LINE__,__FILE__) && $qry->rows() == 0 ) {
|
||||
$params[':olson_name'] = $olson;
|
||||
$params[':vtimezone'] = (isset($tz) ? $tz->Render() : null );
|
||||
$qry->QDo('INSERT INTO timezones (tzid, olson_name, active, vtimezone) VALUES(:tzid,:olson_name,false,:vtimezone)', $params );
|
||||
}
|
||||
}
|
||||
|
||||
$created = $first->GetPValue('CREATED');
|
||||
@ -258,8 +243,8 @@ EOSQL;
|
||||
}
|
||||
|
||||
if ( !$this->IsSchedulingCollection() ) {
|
||||
write_alarms($dav_id, $first);
|
||||
write_attendees($dav_id, $vcal);
|
||||
$this->WriteCalendarAlarms($dav_id, $vcal);
|
||||
$this->WriteCalendarAttendees($dav_id, $vcal);
|
||||
if ( $log_action && function_exists('log_caldav_action') ) {
|
||||
log_caldav_action( $put_action_type, $first->GetPValue('UID'), $user_no, $collection_id, $path );
|
||||
}
|
||||
@ -317,4 +302,144 @@ EOSQL;
|
||||
return $segment_name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a dav_id and an original vCalendar, pull out each of the VALARMs
|
||||
* and write the values into the calendar_alarm table.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function WriteCalendarAlarms( $dav_id, vCalendar $vcal ) {
|
||||
$qry = new AwlQuery('DELETE FROM calendar_alarm WHERE dav_id = '.$dav_id );
|
||||
$qry->Exec('PUT',__LINE__,__FILE__);
|
||||
|
||||
$components = $vcal->GetComponents();
|
||||
|
||||
$qry->SetSql('INSERT INTO calendar_alarm ( dav_id, action, trigger, summary, description, component, next_trigger )
|
||||
VALUES( '.$dav_id.', :action, :trigger, :summary, :description, :component,
|
||||
:related::timestamp with time zone + :related_trigger::interval )' );
|
||||
$qry->Prepare();
|
||||
foreach( $components AS $component ) {
|
||||
if ( $component->GetType() == 'VTIMEZONE' ) continue;
|
||||
$alarms = $component->GetComponents('VALARM');
|
||||
if ( count($alarms) < 1 ) return;
|
||||
|
||||
foreach( $alarms AS $v ) {
|
||||
$trigger = array_merge($v->GetProperties('TRIGGER'));
|
||||
if ( $trigger == null ) continue; // Bogus data.
|
||||
$trigger = $trigger[0];
|
||||
$related = null;
|
||||
$related_trigger = '0M';
|
||||
$trigger_type = $trigger->GetParameterValue('VALUE');
|
||||
if ( !isset($trigger_type) || $trigger_type == 'DURATION' ) {
|
||||
switch ( $trigger->GetParameterValue('RELATED') ) {
|
||||
case 'DTEND': $related = $component->GetPValue('DTEND'); break;
|
||||
case 'DUE': $related = $component->GetPValue('DUE'); break;
|
||||
default: $related = $component->GetPValue('DTSTART');
|
||||
}
|
||||
$duration = $trigger->Value();
|
||||
if ( !preg_match('{^-?P(:?\d+W)?(:?\d+D)?(:?T(:?\d+H)?(:?\d+M)?(:?\d+S)?)?$}', $duration ) ) continue;
|
||||
$minus = (substr($duration,0,1) == '-');
|
||||
$related_trigger = trim(preg_replace( '#[PT-]#', ' ', $duration ));
|
||||
if ( $minus ) {
|
||||
$related_trigger = preg_replace( '{(\d+[WDHMS])}', '-$1 ', $related_trigger );
|
||||
}
|
||||
else {
|
||||
$related_trigger = preg_replace( '{(\d+[WDHMS])}', '$1 ', $related_trigger );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( false === strtotime($trigger->Value()) ) continue; // Invalid date.
|
||||
}
|
||||
$qry->Bind(':action', $v->GetPValue('ACTION'));
|
||||
$qry->Bind(':trigger', $trigger->Render());
|
||||
$qry->Bind(':summary', $v->GetPValue('SUMMARY'));
|
||||
$qry->Bind(':description', $v->GetPValue('DESCRIPTION'));
|
||||
$qry->Bind(':component', $v->Render());
|
||||
$qry->Bind(':related', $related );
|
||||
$qry->Bind(':related_trigger', $related_trigger );
|
||||
$qry->Exec('PUT',__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse out the attendee property and write a row to the
|
||||
* calendar_attendee table for each one.
|
||||
* @param int $dav_id The dav_id of the caldav_data we're processing
|
||||
* @param vComponent The VEVENT or VTODO containing the ATTENDEEs
|
||||
* @return null
|
||||
*/
|
||||
function WriteCalendarAttendees( $dav_id, vCalendar $vcal ) {
|
||||
$qry = new AwlQuery('DELETE FROM calendar_attendee WHERE dav_id = '.$dav_id );
|
||||
$qry->Exec('PUT',__LINE__,__FILE__);
|
||||
|
||||
$attendees = $vcal->GetAttendees();
|
||||
if ( count($attendees) < 1 ) return;
|
||||
|
||||
$qry->SetSql('INSERT INTO calendar_attendee ( dav_id, status, partstat, cn, attendee, role, rsvp, property )
|
||||
VALUES( '.$dav_id.', :status, :partstat, :cn, :attendee, :role, :rsvp, :property )' );
|
||||
$qry->Prepare();
|
||||
$processed = array();
|
||||
foreach( $attendees AS $v ) {
|
||||
$attendee = $v->Value();
|
||||
if ( isset($processed[$attendee]) ) {
|
||||
dbg_error_log( 'LOG', 'Duplicate attendee "%s" in resource "%d"', $attendee, $dav_id );
|
||||
dbg_error_log( 'LOG', 'Original: "%s"', $processed[$attendee] );
|
||||
dbg_error_log( 'LOG', 'Duplicate: "%s"', $v->Render() );
|
||||
continue; /** @todo work out why we get duplicate ATTENDEE on one VEVENT */
|
||||
}
|
||||
$qry->Bind(':attendee', $attendee );
|
||||
$qry->Bind(':status', $v->GetParameterValue('STATUS') );
|
||||
$qry->Bind(':partstat', $v->GetParameterValue('PARTSTAT') );
|
||||
$qry->Bind(':cn', $v->GetParameterValue('CN') );
|
||||
$qry->Bind(':role', $v->GetParameterValue('ROLE') );
|
||||
$qry->Bind(':rsvp', $v->GetParameterValue('RSVP') );
|
||||
$qry->Bind(':property', $v->Render() );
|
||||
$qry->Exec('PUT',__LINE__,__FILE__);
|
||||
$processed[$attendee] = $v->Render();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data to a member in the collection and returns the segment_name of the
|
||||
* resource in our internal namespace.
|
||||
*
|
||||
* @param vCalendar $member_dav_name The path to the resource to be deleted.
|
||||
* @return boolean Success is true, or false on failure.
|
||||
*/
|
||||
function actualDeleteCalendarMember( $member_dav_name ) {
|
||||
global $session, $caldav_context;
|
||||
|
||||
// A quick sanity check...
|
||||
$segment_name = str_replace( $this->dav_name(), '', $member_dav_name );
|
||||
if ( strstr($segment_name, '/') !== false ) {
|
||||
@dbg_error_log( "DELETE", "DELETE: Refused to delete member '%s' from calendar '%s'!", $member_dav_name, $this->dav_name() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to serialise access to this process just for this collection
|
||||
$cache = getCacheInstance();
|
||||
$myLock = $cache->acquireLock('collection-'.$this->dav_name());
|
||||
|
||||
$qry = new AwlQuery();
|
||||
$params = array( ':dav_name' => $member_dav_name );
|
||||
|
||||
if ( $qry->QDo("SELECT write_sync_change(collection_id, 404, caldav_data.dav_name) FROM caldav_data WHERE dav_name = :dav_name", $params )
|
||||
&& $qry->QDo("DELETE FROM property WHERE dav_name = :dav_name", $params )
|
||||
&& $qry->QDo("DELETE FROM locks WHERE dav_name = :dav_name", $params )
|
||||
&& $qry->QDo("DELETE FROM caldav_data WHERE dav_name = :dav_name", $params ) ) {
|
||||
@dbg_error_log( "DELETE", "DELETE: Calendar member %s deleted from calendar '%s'", $member_dav_name, $this->dav_name() );
|
||||
|
||||
$cache->releaseLock($myLock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$cache->releaseLock($myLock);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ function early_exception_handler($e) {
|
||||
foreach( $trace AS $k => $v ) {
|
||||
printf( "%s[%d] %s%s%s()\n", $v['file'], $v['line'], (isset($v['class'])?$v['class']:''), (isset($v['type'])?$v['type']:''), (isset($v['function'])?$v['function']:'') );
|
||||
}
|
||||
@ob_flush();
|
||||
}
|
||||
set_exception_handler('early_exception_handler');
|
||||
|
||||
@ -89,7 +90,7 @@ if ( ! @include_once('AWLUtilities.php') ) {
|
||||
}
|
||||
if ( ! @include_once('AWLUtilities.php') ) {
|
||||
echo "Could not find the AWL libraries. Are they installed? Check your include_path in php.ini!\n";
|
||||
exit;
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +146,7 @@ else if ( @file_exists('config/config.php') ) {
|
||||
}
|
||||
else {
|
||||
include('davical_configuration_missing.php');
|
||||
exit;
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
$config_warnings = trim(ob_get_contents());
|
||||
ob_end_clean();
|
||||
|
||||
@ -299,7 +299,7 @@ function AuthExternalAWL( $username, $password ) {
|
||||
</body>
|
||||
</html>
|
||||
EOERRMSG;
|
||||
exit(1);
|
||||
@ob_flush(); exit(1);
|
||||
}
|
||||
|
||||
if ( $qry->Exec('Login',__LINE__,__FILE__) && $qry->rows() == 1 ) {
|
||||
|
||||
@ -14,7 +14,7 @@ $request = new CalDAVRequest();
|
||||
|
||||
if ( !isset($c->enable_autodiscover) || ! $c->enable_autodiscover ) {
|
||||
$request->DoResponse( 404 );
|
||||
exit(0);
|
||||
exit(0); // unneccessary
|
||||
}
|
||||
|
||||
$ns_outlook_req_2006 = "http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006";
|
||||
@ -40,7 +40,7 @@ function errorResponse( $code, $message, $debugdata = '' ) {
|
||||
ERROR;
|
||||
|
||||
$request->DoResponse( $code, $response, 'text/xml; charset="utf-8"' );
|
||||
exit(0);
|
||||
exit(0); // unneccessary
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ $container->NeedPrivilege('DAV::unbind');
|
||||
|
||||
$lock_opener = $request->FailIfLocked();
|
||||
|
||||
require_once('schedule-functions.php');
|
||||
|
||||
function delete_collection( $id ) {
|
||||
$params = array( ':collection_id' => $id );
|
||||
@ -72,12 +73,14 @@ else {
|
||||
$request->DoResponse( 412, translate("Resource has changed on server - not deleted") );
|
||||
}
|
||||
|
||||
$params = array( ':dav_id' => $dav_resource->resource_id() );
|
||||
|
||||
// Check to see if we need to do any scheduling transactions for this one.
|
||||
do_scheduling_for_delete($dav_resource);
|
||||
|
||||
// We need to serialise access to this process just for this collection
|
||||
$cache = getCacheInstance();
|
||||
$myLock = $cache->acquireLock('collection-'.$dav_resource->parent_path());
|
||||
|
||||
$params = array( ':dav_id' => $dav_resource->resource_id() );
|
||||
if ( $qry->QDo("SELECT write_sync_change(collection_id, 404, caldav_data.dav_name) FROM caldav_data WHERE dav_id = :dav_id", $params )
|
||||
&& $qry->QDo("DELETE FROM property WHERE dav_name = (SELECT dav_name FROM caldav_data WHERE dav_id = :dav_id)", $params )
|
||||
&& $qry->QDo("DELETE FROM locks WHERE dav_name = (SELECT dav_name FROM caldav_data WHERE dav_id = :dav_id)", $params )
|
||||
@ -92,7 +95,6 @@ else {
|
||||
$request->DoResponse( 204 );
|
||||
}
|
||||
$cache->releaseLock($myLock);
|
||||
|
||||
}
|
||||
|
||||
$request->DoResponse( 500 );
|
||||
|
||||
@ -353,6 +353,5 @@ if ( $qry->Commit() ) {
|
||||
* Or it was all crap.
|
||||
*/
|
||||
$request->DoResponse( 500 );
|
||||
|
||||
exit(0);
|
||||
exit(0); // unneccessary
|
||||
|
||||
|
||||
@ -334,25 +334,25 @@ $sql = 'SELECT caldav_data.*,calendar_item.* FROM collection INNER JOIN caldav_
|
||||
if ( isset($c->strict_result_ordering) && $c->strict_result_ordering ) $sql .= " ORDER BY caldav_data.dav_id";
|
||||
$qry = new AwlQuery( $sql, $params );
|
||||
if ( $qry->Exec("calquery",__LINE__,__FILE__) && $qry->rows() > 0 ) {
|
||||
while( $calendar_object = $qry->Fetch() ) {
|
||||
if ( !$need_post_filter || apply_filter( $qry_filters, $calendar_object ) ) {
|
||||
while( $dav_object = $qry->Fetch() ) {
|
||||
if ( !$need_post_filter || apply_filter( $qry_filters, $dav_object ) ) {
|
||||
if ( $bound_from != $target_collection->dav_name() ) {
|
||||
$calendar_object->dav_name = str_replace( $bound_from, $target_collection->dav_name(), $calendar_object->dav_name);
|
||||
$dav_object->dav_name = str_replace( $bound_from, $target_collection->dav_name(), $dav_object->dav_name);
|
||||
}
|
||||
if ( $need_expansion ) {
|
||||
$vResource = new vComponent($calendar_object->caldav_data);
|
||||
$vResource = new vComponent($dav_object->caldav_data);
|
||||
$expanded = expand_event_instances($vResource, $expand_range_start, $expand_range_end, $expand_as_floating );
|
||||
if ( $expanded->ComponentCount() == 0 ) continue;
|
||||
if ( $need_expansion ) $calendar_object->caldav_data = $expanded->Render();
|
||||
if ( $need_expansion ) $dav_object->caldav_data = $expanded->Render();
|
||||
}
|
||||
else if ( isset($range_filter) ) {
|
||||
$vResource = new vComponent($calendar_object->caldav_data);
|
||||
$vResource = new vComponent($dav_object->caldav_data);
|
||||
$expanded = getVCalendarRange($vResource);
|
||||
dbg_error_log('calquery', 'Expanded to %s:%s which might overlap %s:%s',
|
||||
$expanded->from, $expanded->until, $range_filter->from, $range_filter->until );
|
||||
if ( !$expanded->overlaps($range_filter) ) continue;
|
||||
}
|
||||
$responses[] = calendar_to_xml( $properties, $calendar_object );
|
||||
$responses[] = component_to_xml( $properties, $dav_object );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,8 @@ function get_address_properties( $address_data_xml ) {
|
||||
global $address_data_properties;
|
||||
$expansion = $address_data_xml->GetElements();
|
||||
foreach( $expansion AS $k => $v ) {
|
||||
$address_data_properties[strtoupper($v->GetAttribute('name'))] = true;
|
||||
if ( $v instanceof XMLElement )
|
||||
$address_data_properties[strtoupper($v->GetAttribute('name'))] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ if ( $xmltree->GetTag() != 'DAV::principal-property-search'
|
||||
$target->NeedPrivilege( array('DAV::read', 'urn:ietf:params:xml:ns:caldav:read-free-busy'), true ); // They may have either
|
||||
}
|
||||
|
||||
require_once("iCalendar.php");
|
||||
require_once("vCalendar.php");
|
||||
|
||||
$reportnum = -1;
|
||||
$report = array();
|
||||
@ -80,110 +80,6 @@ switch( $xmltree->GetTag() ) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return XML for a single calendar (or todo) entry from the DB
|
||||
*
|
||||
* @param array $properties The properties for this calendar
|
||||
* @param string $item The calendar data for this calendar
|
||||
*
|
||||
* @return string An XML document which is the response for the calendar
|
||||
*/
|
||||
function calendar_to_xml( $properties, $item ) {
|
||||
global $session, $c, $request, $reply;
|
||||
|
||||
dbg_error_log("REPORT","Building XML Response for item '%s'", $item->dav_name );
|
||||
|
||||
$denied = array();
|
||||
$caldav_data = $item->caldav_data;
|
||||
$displayname = $item->summary;
|
||||
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 ( $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':
|
||||
$reply->CalDAVElement($prop, $k, $caldav_data );
|
||||
break;
|
||||
case 'getcontenttype':
|
||||
$prop->NewElement($k, "text/calendar" );
|
||||
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[] = $v;
|
||||
break;
|
||||
default:
|
||||
dbg_error_log( 'REPORT', "Request for unsupported property '%s' of calendar item.", $v );
|
||||
$unsupported[] = $v;
|
||||
}
|
||||
}
|
||||
$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) );
|
||||
}
|
||||
|
||||
$response = new XMLElement( "response", $elements );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return XML for a single component from the DB
|
||||
@ -219,33 +115,27 @@ function component_to_xml( $properties, $item ) {
|
||||
$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');
|
||||
if ( $type == 'calendar' ) {
|
||||
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 calendar looking at his calendar and can not admin the other cal
|
||||
if ( $item->class == 'CONFIDENTIAL' || !$request->AllowedTo('read') ) {
|
||||
dbg_error_log("REPORT","Anonymising confidential event for: %s", $item->dav_name );
|
||||
$vcal = new vCalendar( $caldav_data );
|
||||
$caldav_data = $vcal->Confidential()->Render();
|
||||
$displayname = translate('Busy');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset($properties['calendar-data']) && isset($c->hide_alarm) && $c->hide_alarm && !$request->HavePrivilegeTo('write') ) {
|
||||
dbg_error_log("REPORT","Stripping event alarms for: %s", $item->dav_name );
|
||||
$vcal = new vCalendar($caldav_data);
|
||||
$vcal->ClearComponents('VALARM');
|
||||
$caldav_data = $vcal->Render();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$url = ConstructURL($item->dav_name);
|
||||
|
||||
$prop = new XMLElement("prop");
|
||||
|
||||
315
inc/schedule-functions.php
Normal file
315
inc/schedule-functions.php
Normal file
@ -0,0 +1,315 @@
|
||||
<?php
|
||||
/**
|
||||
* Functions for handling CalDAV Scheduling.
|
||||
*
|
||||
* @package davical
|
||||
* @subpackage caldav
|
||||
* @author Andrew McMillan <andrew@morphoss.com>
|
||||
* @copyright Morphoss Ltd - http://www.morphoss.com/
|
||||
* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later version
|
||||
*/
|
||||
|
||||
require_once('vCalendar.php');
|
||||
require_once('WritableCollection.php');
|
||||
require_once('RRule-v2.php');
|
||||
|
||||
/**
|
||||
* Entry point for scheduling on DELETE, for which there are thee outcomes:
|
||||
* - We don't do scheduling (disabled, no organizer, ...)
|
||||
* - We are an ATTENDEE declining the meeting.
|
||||
* - We are the ORGANIZER canceling the meeting.
|
||||
*
|
||||
* @param DAVResource $deleted_resource The resource which has already been deleted
|
||||
*/
|
||||
function do_scheduling_for_delete(DAVResource $deleted_resource ) {
|
||||
// By the time we arrive here the resource *has* actually been deleted from disk
|
||||
// we can only fail to (de-)schedule the activity...
|
||||
global $request, $c;
|
||||
|
||||
if ( !isset($request) || (isset($c->enable_auto_schedule) && !$c->enable_auto_schedule) ) return true;
|
||||
if ( $deleted_resource->IsInSchedulingCollection() ) return true;
|
||||
|
||||
$caldav_data = $deleted_resource->GetProperty('dav-data');
|
||||
if ( empty($caldav_data) ) return true;
|
||||
|
||||
$vcal = new vCalendar($caldav_data);
|
||||
$organizer = $vcal->GetOrganizer();
|
||||
if ( $organizer === false || empty($organizer) ) {
|
||||
dbg_error_log( 'schedule', 'Event has no organizer - no scheduling required.' );
|
||||
return true;
|
||||
}
|
||||
if ( $vcal->GetScheduleAgent() != 'SERVER' ) {
|
||||
dbg_error_log( 'schedule', 'SCHEDULE-AGENT=%s - no scheduling required.', $vcal->GetScheduleAgent() );
|
||||
return true;
|
||||
}
|
||||
$organizer_email = preg_replace( '/^mailto:/i', '', $organizer->Value() );
|
||||
|
||||
if ( $request->principal->email() == $organizer_email ) {
|
||||
return doItipOrganizerCancel( $vcal );
|
||||
}
|
||||
else {
|
||||
if ( isset($_SERVER['HTTP_SCHEDULE_REPLY']) && $_SERVER['HTTP_SCHEDULE_REPLY'] == 'F') {
|
||||
dbg_error_log( 'schedule', 'Schedule-Request header set to "F" - no scheduling required.' );
|
||||
return true;
|
||||
}
|
||||
return doItipAttendeeReply( $vcal, 'DECLINED', $request->principal->email());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do the scheduling adjustments for a REPLY when an ATTENDEE updates their status.
|
||||
* @param vCalendar $vcal The resource that the ATTENDEE is writing to their calendar
|
||||
* @param string $organizer The property which is the event ORGANIZER.
|
||||
*/
|
||||
//function do_scheduling_reply( vCalendar $vcal, vProperty $organizer ) {
|
||||
function doItipAttendeeReply( vCalendar $resource, $partstat ) {
|
||||
global $request;
|
||||
|
||||
$organizer = $resource->GetOrganizer();
|
||||
$organizer_email = preg_replace( '/^mailto:/i', '', $organizer->Value() );
|
||||
$organizer_principal = new Principal('email',$organizer_email );
|
||||
|
||||
if ( !$organizer_principal->Exists() ) {
|
||||
dbg_error_log( 'schedule', 'Unknown ORGANIZER "%s" - unable to notify.', $organizer->Value() );
|
||||
return true;
|
||||
}
|
||||
|
||||
$sql = 'SELECT caldav_data.dav_name, caldav_data.caldav_data FROM caldav_data JOIN calendar_item USING(dav_id) ';
|
||||
$sql .= 'WHERE caldav_data.collection_id IN (SELECT collection_id FROM collection WHERE is_calendar AND user_no =?) ';
|
||||
$sql .= 'AND uid=? LIMIT 1';
|
||||
$uids = $resource->GetPropertiesByPath('/VCALENDAR/*/UID');
|
||||
if ( count($uids) == 0 ) {
|
||||
dbg_error_log( 'schedule', 'No UID in VCALENDAR - giving up on REPLY.' );
|
||||
return true;
|
||||
}
|
||||
$uid = $uids[0]->Value();
|
||||
$qry = new AwlQuery($sql, $organizer_principal->user_no(), $uid);
|
||||
if ( !$qry->Exec('schedule',__LINE__,__FILE__) || $qry->rows() < 1 ) {
|
||||
dbg_error_log( 'schedule', 'Could not find original event from organizer - giving up on REPLY.' );
|
||||
return true;
|
||||
}
|
||||
$row = $qry->Fetch();
|
||||
$collection_path = preg_replace('{/[^/]+$}', '/', $row->dav_name );
|
||||
$segment_name = str_replace($collection_path, '', $row->dav_name );
|
||||
$vcal = new vCalendar($row->caldav_data);
|
||||
|
||||
$attendees = $vcal->GetAttendees();
|
||||
foreach( $attendees AS $v ) {
|
||||
$email = preg_replace( '/^mailto:/i', '', $v->Value() );
|
||||
if ( $email == $request->principal->email() ) {
|
||||
$attendee = $v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( empty($attendee) ) {
|
||||
dbg_error_log( 'schedule', 'Could not find ATTENDEE in VEVENT - giving up on REPLY.' );
|
||||
return true;
|
||||
}
|
||||
|
||||
$attendee->SetParameterValue('PARTSTAT', $partstat);
|
||||
$attendee->SetParameterValue('SCHEDULE-STATUS', '2.0');
|
||||
$vcal->UpdateAttendeeStatus($request->principal->email(), clone($attendee) );
|
||||
|
||||
$organizer_calendar = new WritableCollection(array('path' => $collection_path));
|
||||
$organizer_inbox = new WritableCollection(array('path' => $organizer_principal->internal_url('schedule-inbox')));
|
||||
|
||||
$schedule_reply = GetItip(new vCalendar($row->caldav_data),'REPLY',$attendee->Value());
|
||||
$schedule_request = GetItip(new vCalendar($row->caldav_data),'REQUEST',null);
|
||||
|
||||
dbg_error_log( 'schedule', 'Writing ATTENDEE scheduling REPLY from %s to %s', $request->principal->email(), $organizer_principal->email() );
|
||||
|
||||
$response = '3.7'; // Organizer was not found on server.
|
||||
if ( !$organizer_calendar->Exists() ) {
|
||||
dbg_error_log('ERROR','Default calendar at "%s" does not exist for user "%s"',
|
||||
$organizer_calendar->dav_name(), $schedule_target->username());
|
||||
$response = '5.2'; // No scheduling support for user
|
||||
}
|
||||
else {
|
||||
if ( ! $organizer_inbox->HavePrivilegeTo('schedule-deliver-reply') ) {
|
||||
$response = '3.8'; // No authority to deliver replies to organizer.
|
||||
}
|
||||
$response = '1.2'; // Scheduling reply delivered successfully
|
||||
if ( $organizer_calendar->WriteCalendarMember($vcal, false, false, $segment_name) === false ) {
|
||||
dbg_error_log('ERROR','Could not write updated calendar member to %s', $attendee_calendar->dav_name() );
|
||||
trace_bug('Failed to write scheduling resource.');
|
||||
}
|
||||
$organizer_inbox->WriteCalendarMember($schedule_reply, false, false, $request->principal->username().$segment_name);
|
||||
}
|
||||
|
||||
|
||||
dbg_error_log( 'schedule', 'Status for organizer <%s> set to "%s"', $organizer->Value(), $response );
|
||||
$organizer->SetParameterValue( 'SCHEDULE-STATUS', $response );
|
||||
$resource->UpdateOrganizerStatus($organizer); // Which was passed in by reference, and we're updating it here.
|
||||
|
||||
// Now we loop through the *other* ATTENDEEs, updating them on the status of the ATTENDEE DECLINE/ACCEPT
|
||||
foreach( $attendees AS $attendee ) {
|
||||
$email = preg_replace( '/^mailto:/i', '', $attendee->Value() );
|
||||
if ( $email == $request->principal->email() || $email == $organizer_principal->email() ) continue;
|
||||
|
||||
$agent = $attendee->GetParameterValue('SCHEDULE-AGENT');
|
||||
if ( !empty($agent) && $agent != 'SERVER' ) continue;
|
||||
|
||||
$schedule_target = new Principal('email',$email);
|
||||
if ( $schedule_target->Exists() ) {
|
||||
$attendee_calendar = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-default-calendar')));
|
||||
if ( !$attendee_calendar->Exists() ) {
|
||||
dbg_error_log('ERROR','Default calendar at "%s" does not exist for user "%s"',
|
||||
$attendee_calendar->dav_name(), $schedule_target->username());
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
$attendee_inbox = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-inbox')));
|
||||
if ( ! $attendee_inbox->HavePrivilegeTo('schedule-deliver-invite') ) continue;
|
||||
|
||||
if ( $attendee_calendar->WriteCalendarMember($vcal, false) === false ) {
|
||||
dbg_error_log('ERROR','Could not write updated calendar member to %s', $attendee_calendar->dav_name());
|
||||
trace_bug('Failed to write scheduling resource.');
|
||||
}
|
||||
$attendee_inbox->WriteCalendarMember($schedule_request, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function GetItip( VCalendar $vcal, $method, $attendee_value ) {
|
||||
|
||||
$iTIP = $vcal->GetItip($method, $attendee_value );
|
||||
$iTIP->AddProperty('REQUEST-STATUS','2.0');
|
||||
$components = $iTIP->GetComponents();
|
||||
foreach( $components AS $comp ) {
|
||||
$properties = array();
|
||||
foreach( $comp->GetProperties() AS $k=> $property ) {
|
||||
switch( $property->Name() ) {
|
||||
case 'DTSTART':
|
||||
case 'DTEND':
|
||||
case 'DUE':
|
||||
$when = new RepeatRuleDateTime($property);
|
||||
$properties[] = new vProperty( $property->Name() . ":" . $when->UTC() );
|
||||
break;
|
||||
default:
|
||||
$properties[] = $property;
|
||||
}
|
||||
}
|
||||
$comp->SetProperties($properties);
|
||||
}
|
||||
|
||||
return $iTIP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles sending the iTIP CANCEL messages to each ATTENDEE by the ORGANIZER.
|
||||
* @param vCalendar $vcal What's being cancelled.
|
||||
*/
|
||||
function doItipOrganizerCancel( vCalendar $vcal ) {
|
||||
global $request;
|
||||
|
||||
$attendees = $vcal->GetAttendees();
|
||||
if ( count($attendees) == 0 && count($old_attendees) == 0 ) {
|
||||
dbg_error_log( 'schedule', 'Event has no attendees - no scheduling required.', count($attendees) );
|
||||
return true;
|
||||
}
|
||||
|
||||
dbg_error_log( 'schedule', 'Writing scheduling resources for %d attendees', count($attendees) );
|
||||
$scheduling_actions = false;
|
||||
|
||||
$iTIP = GetItip($vcal, 'CANCEL', null);
|
||||
|
||||
foreach( $attendees AS $attendee ) {
|
||||
$email = preg_replace( '/^mailto:/i', '', $attendee->Value() );
|
||||
if ( $email == $request->principal->email() ) {
|
||||
dbg_error_log( 'schedule', "not delivering to owner '%s'", $request->principal->email() );
|
||||
continue;
|
||||
}
|
||||
|
||||
$agent = $attendee->GetParameterValue('SCHEDULE-AGENT');
|
||||
if ( $agent && $agent != 'SERVER' ) {
|
||||
dbg_error_log( 'schedule', "not delivering to %s, schedule agent set to value other than server", $email );
|
||||
continue;
|
||||
}
|
||||
$schedule_target = new Principal('email',$email);
|
||||
if ( !$schedule_target->Exists() ) {
|
||||
$response = '3.7';
|
||||
}
|
||||
else {
|
||||
$attendee_inbox = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-inbox')));
|
||||
if ( ! $attendee_inbox->HavePrivilegeTo('schedule-deliver-invite') ) {
|
||||
dbg_error_log( 'schedule', "No authority to deliver invite to %s", $schedule_target->internal_url('schedule-inbox') );
|
||||
$response = '3.8';
|
||||
}
|
||||
else {
|
||||
$attendee_calendar = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-default-calendar')));
|
||||
$response = processItipCancel( $vcal, $attendee, $attendee_calendar, $schedule_target );
|
||||
deliverItipCancel( $iTIP, $attendee, $attendee_inbox );
|
||||
}
|
||||
}
|
||||
dbg_error_log( 'schedule', 'Status for attendee <%s> set to "%s"', $attendee->Value(), $response );
|
||||
$attendee->SetParameterValue( 'SCHEDULE-STATUS', $response );
|
||||
$scheduling_actions = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual processing of the iTIP CANCEL message on behalf of an ATTENDEE,
|
||||
* which generally means writing it into the ATTENDEE's default calendar.
|
||||
*
|
||||
* @param vCalendar $vcal The message.
|
||||
* @param vProperty $attendee
|
||||
* @param WritableCollection $attendee_calendar
|
||||
*/
|
||||
function processItipCancel( vCalendar $vcal, vProperty $attendee, WritableCollection $attendee_calendar, Principal $attendee_principal ) {
|
||||
|
||||
dbg_error_log( 'schedule', 'Processing iTIP CANCEL to %s', $attendee->Value());
|
||||
if ( !$attendee_calendar->Exists() ) {
|
||||
dbg_error_log('ERROR', 'Default calendar at "%s" does not exist for attendee "%s"',
|
||||
$attendee_calendar->dav_name(), $attendee->Value());
|
||||
return '5.2'; // No scheduling support for user
|
||||
}
|
||||
|
||||
$sql = 'SELECT caldav_data.dav_name FROM caldav_data JOIN calendar_item USING(dav_id) ';
|
||||
$sql .= 'WHERE caldav_data.collection_id IN (SELECT collection_id FROM collection WHERE is_calendar AND user_no =?) ';
|
||||
$sql .= 'AND uid=? LIMIT 1';
|
||||
$uids = $vcal->GetPropertiesByPath('/VCALENDAR/*/UID');
|
||||
if ( count($uids) == 0 ) {
|
||||
dbg_error_log( 'schedule', 'No UID in VCALENDAR - giving up on CANCEL processing.' );
|
||||
return '3.8';
|
||||
}
|
||||
$uid = $uids[0]->Value();
|
||||
$qry = new AwlQuery($sql, $attendee_principal->user_no(), $uid);
|
||||
if ( !$qry->Exec('schedule',__LINE__,__FILE__) || $qry->rows() < 1 ) {
|
||||
dbg_error_log( 'schedule', 'Could not find ATTENDEE copy of original event - not trying to DELETE it!' );
|
||||
return '1.2';
|
||||
}
|
||||
$row = $qry->Fetch();
|
||||
|
||||
if ( $attendee_calendar->actualDeleteCalendarMember($row->dav_name) === false ) {
|
||||
dbg_error_log('ERROR', 'Could not delete calendar member %s for %s',
|
||||
$row->dav_name(), $attendee->Value());
|
||||
trace_bug('Failed to write scheduling resource.');
|
||||
return '5.2';
|
||||
}
|
||||
|
||||
return '1.2'; // Scheduling invitation delivered successfully
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delivers the iTIP CANCEL message to an ATTENDEE's Scheduling Inbox Collection.
|
||||
*
|
||||
* This is pretty simple at present, but could be extended in the future to do the sending
|
||||
* of e-mail to a remote attendee.
|
||||
*
|
||||
* @param vCalendar $iTIP
|
||||
* @param vProperty $attendee
|
||||
* @param WritableCollection $attendee_inbox
|
||||
*/
|
||||
function deliverItipCancel( vCalendar $iTIP, vProperty $attendee, WritableCollection $attendee_inbox ) {
|
||||
$attendee_inbox->WriteCalendarMember($iTIP, false);
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ switch ( $request->path ) {
|
||||
if ( $c->enable_scheduling != true )
|
||||
{
|
||||
$request->DoResponse( 404, translate('The application program does not understand that request.') );
|
||||
exit ();
|
||||
// Does not return
|
||||
}
|
||||
|
||||
header ( 'iSchedule-Version: 1.0' );
|
||||
@ -103,5 +103,6 @@ RESPONSE;
|
||||
</capability-set>
|
||||
</query-result>
|
||||
RESPONSE;
|
||||
exit ( 0 );
|
||||
|
||||
@ob_flush(); exit(0);
|
||||
}
|
||||
|
||||
40
po/nb_NO.po
40
po/nb_NO.po
@ -10,8 +10,8 @@ msgstr ""
|
||||
"Project-Id-Version: DAViCal\n"
|
||||
"Report-Msgid-Bugs-To: http://repo.or.cz/w/davical.git/tree/HEAD:/issues\n"
|
||||
"POT-Creation-Date: 2011-10-24 21:19+1300\n"
|
||||
"PO-Revision-Date: 2011-10-24 08:21+0000\n"
|
||||
"Last-Translator: karora <andrew@mcmillan.net.nz>\n"
|
||||
"PO-Revision-Date: 2011-10-26 18:54+0000\n"
|
||||
"Last-Translator: aleksand <daniel@aleksand.no>\n"
|
||||
"Language-Team: Norwegian Bokmål (Norway) (http://www.transifex.net/projects/p/davical/team/nb_NO/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -30,7 +30,7 @@ msgid "%T"
|
||||
msgstr "%T"
|
||||
|
||||
msgid "*** Default Locale ***"
|
||||
msgstr "*** Standard Locale ***"
|
||||
msgstr "*** Forvalgt Nasjonalitet ***"
|
||||
|
||||
msgid "*** Unknown ***"
|
||||
msgstr "*** Ukjent ***"
|
||||
@ -153,7 +153,7 @@ msgstr "Alle data til samlingen vil ugjenopprettelig bli slettet"
|
||||
|
||||
#, php-format
|
||||
msgid "All events of user \"%s\" were deleted and replaced by those from file %s"
|
||||
msgstr ""
|
||||
msgstr "Alle \"%s\" sine hendelser ble slettet og erstattet med de fra filen %s"
|
||||
|
||||
msgid ""
|
||||
"All of the principal's calendars and events will be unrecoverably deleted."
|
||||
@ -205,7 +205,7 @@ msgid "Bindings to this Principal's Collections"
|
||||
msgstr "Forbindelse til denne kontoens samlinger"
|
||||
|
||||
msgid "Body contains no XML data!"
|
||||
msgstr ""
|
||||
msgstr "Meldingskroppen inneholder ingen XML data!"
|
||||
|
||||
msgid "Bound As"
|
||||
msgstr "Forbundet som"
|
||||
@ -395,10 +395,10 @@ msgid "Date Style"
|
||||
msgstr "Datoformat"
|
||||
|
||||
msgid "Default Privileges"
|
||||
msgstr "Standard privilegier"
|
||||
msgstr "Forvalgte privilegier"
|
||||
|
||||
msgid "Default relationships added."
|
||||
msgstr ""
|
||||
msgstr "La til forvalgte relasjoner."
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Slett"
|
||||
@ -525,10 +525,10 @@ msgid "Expires"
|
||||
msgstr "Løper ut"
|
||||
|
||||
msgid "External Calendars"
|
||||
msgstr ""
|
||||
msgstr "Eksterne kalendere"
|
||||
|
||||
msgid "External Url"
|
||||
msgstr ""
|
||||
msgstr "Ekstern URL"
|
||||
|
||||
msgid "Fail"
|
||||
msgstr "Feil"
|
||||
@ -680,7 +680,7 @@ msgid "Last used"
|
||||
msgstr "Sist brukt"
|
||||
|
||||
msgid "List External Calendars"
|
||||
msgstr ""
|
||||
msgstr "List opp eksterne kalendere"
|
||||
|
||||
msgid "List Groups"
|
||||
msgstr "Liste grupper"
|
||||
@ -788,7 +788,7 @@ msgid "PHP PostgreSQL available"
|
||||
msgstr "PHP PostgreSQL tilgjengelig"
|
||||
|
||||
msgid "PHP calendar extension available"
|
||||
msgstr ""
|
||||
msgstr "PHP kalenderutvidelse er tilgjengelig."
|
||||
|
||||
msgid "PHP iconv support"
|
||||
msgstr "Støtte for PHP iconv"
|
||||
@ -804,6 +804,8 @@ msgid ""
|
||||
"PUT on a collection is only allowed for text/vcard content against an "
|
||||
"addressbook collection"
|
||||
msgstr ""
|
||||
"En PUT anmodning er kun tillatt for text/vcard innhold i en "
|
||||
"adresseboksamling."
|
||||
|
||||
msgid "Passed"
|
||||
msgstr "Godkjent"
|
||||
@ -901,7 +903,7 @@ msgid "Read/Write"
|
||||
msgstr "Les/Skriv"
|
||||
|
||||
msgid "References"
|
||||
msgstr ""
|
||||
msgstr "Referanser"
|
||||
|
||||
msgid "Remove"
|
||||
msgstr "Fjern"
|
||||
@ -910,7 +912,7 @@ msgid "Remove a lock"
|
||||
msgstr "Fjern en lås"
|
||||
|
||||
msgid "Remove dangling external calendars"
|
||||
msgstr ""
|
||||
msgstr "Fjern haltende eksterne kalendere"
|
||||
|
||||
msgid "Report Bug"
|
||||
msgstr "Rapporter feil"
|
||||
@ -1006,6 +1008,8 @@ msgid ""
|
||||
"Set the path to store your ics e.g. 'calendar' will be referenced as "
|
||||
"/caldav.php/username/calendar/"
|
||||
msgstr ""
|
||||
"Angi en sti for lagring av ics. For eksempel ‹kalender› vil bli referert som"
|
||||
" /caldav.php/brukernavn/kalender/"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "Oppsett"
|
||||
@ -1053,7 +1057,7 @@ msgid "Suhosin \"server.strip\" disabled"
|
||||
msgstr "Suhosin \"server.strip\" disabled"
|
||||
|
||||
msgid "Sync LDAP Groups with DAViCal"
|
||||
msgstr ""
|
||||
msgstr "Synkroniser LDAP grupper med DAViCal"
|
||||
|
||||
msgid "Sync LDAP with DAViCal"
|
||||
msgstr "Synk LDAP med DAViCal"
|
||||
@ -1091,7 +1095,7 @@ msgid ""
|
||||
msgstr "Adressebok-forespørselsrapport må kjøres mot en adressebok-samling"
|
||||
|
||||
msgid "The application failed to understand that request."
|
||||
msgstr ""
|
||||
msgstr "Programmet kunne ikke forstå den anmodningen."
|
||||
|
||||
msgid "The application program does not understand that request."
|
||||
msgstr "Programmet forstår ikke forespørselen"
|
||||
@ -1132,6 +1136,8 @@ msgstr "Epostadressen skulle absolutt ikke være tom"
|
||||
#, php-format
|
||||
msgid "The file \"%s\" is not UTF-8 encoded, please check error for more details"
|
||||
msgstr ""
|
||||
"Filen \"%s\" er ikke inkodet i UTF-8 encoded. Kontroller feilen for flere "
|
||||
"detaljer."
|
||||
|
||||
msgid ""
|
||||
"The file is not UTF-8 encoded, please check the error for more details."
|
||||
@ -1154,7 +1160,7 @@ msgstr "Foretrukket språk for denne personen"
|
||||
|
||||
#, php-format
|
||||
msgid "The principal \"%s\" does not exist"
|
||||
msgstr ""
|
||||
msgstr "Kontoen \"%s\" finnes ikke."
|
||||
|
||||
msgid "The style of dates used for this person."
|
||||
msgstr "Datoformat brukt for denne personen"
|
||||
@ -1219,6 +1225,8 @@ msgid ""
|
||||
"This process will import each file in a directory named \"username.ics\" and"
|
||||
" create a user and calendar for each file to import."
|
||||
msgstr ""
|
||||
"Prosesen vil hente inn hver fil i mappen med navnet \"brukernavn.ics\" og "
|
||||
"opprette en bruker og kalender for hver bruker og kalender som hentes inn."
|
||||
|
||||
msgid "This server only supports the text/calendar format for freebusy URLs"
|
||||
msgstr ""
|
||||
|
||||
42
po/pt_PT.po
42
po/pt_PT.po
@ -9,8 +9,8 @@ msgstr ""
|
||||
"Project-Id-Version: DAViCal\n"
|
||||
"Report-Msgid-Bugs-To: http://repo.or.cz/w/davical.git/tree/HEAD:/issues\n"
|
||||
"POT-Creation-Date: 2011-10-24 21:19+1300\n"
|
||||
"PO-Revision-Date: 2011-10-24 08:21+0000\n"
|
||||
"Last-Translator: karora <andrew@mcmillan.net.nz>\n"
|
||||
"PO-Revision-Date: 2011-10-26 19:34+0000\n"
|
||||
"Last-Translator: m42 <p.m42.ribeiro@gmail.com>\n"
|
||||
"Language-Team: Portuguese (Portugal) (http://www.transifex.net/projects/p/davical/team/pt_PT/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -157,6 +157,8 @@ msgstr "Todos os dados da colecção serão irremediavelmente apagados"
|
||||
#, php-format
|
||||
msgid "All events of user \"%s\" were deleted and replaced by those from file %s"
|
||||
msgstr ""
|
||||
"Todos os eventos do utilizador \"%s\" foram apagados e substituídos pelos do"
|
||||
" ficheiro %s"
|
||||
|
||||
msgid ""
|
||||
"All of the principal's calendars and events will be unrecoverably deleted."
|
||||
@ -210,7 +212,7 @@ msgid "Bindings to this Principal's Collections"
|
||||
msgstr "Ligações às colecções deste Principal"
|
||||
|
||||
msgid "Body contains no XML data!"
|
||||
msgstr ""
|
||||
msgstr "O corpo não contém dados XML!"
|
||||
|
||||
msgid "Bound As"
|
||||
msgstr "Ligado Como"
|
||||
@ -407,7 +409,7 @@ msgid "Default Privileges"
|
||||
msgstr "Privilégios predefinidos"
|
||||
|
||||
msgid "Default relationships added."
|
||||
msgstr ""
|
||||
msgstr "Acrescentados relacionamentos predefinidos"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Eliminar"
|
||||
@ -541,10 +543,10 @@ msgid "Expires"
|
||||
msgstr "Expira"
|
||||
|
||||
msgid "External Calendars"
|
||||
msgstr ""
|
||||
msgstr "Calendários Externos"
|
||||
|
||||
msgid "External Url"
|
||||
msgstr ""
|
||||
msgstr "Url Externo"
|
||||
|
||||
msgid "Fail"
|
||||
msgstr "Falha"
|
||||
@ -696,7 +698,7 @@ msgid "Last used"
|
||||
msgstr "Último usado"
|
||||
|
||||
msgid "List External Calendars"
|
||||
msgstr ""
|
||||
msgstr "Listar Calendários Externos"
|
||||
|
||||
msgid "List Groups"
|
||||
msgstr "Listar Grupos"
|
||||
@ -762,7 +764,7 @@ msgstr "Sem sumário"
|
||||
|
||||
#. Translators: short for 'Number'
|
||||
msgid "No."
|
||||
msgstr "Não."
|
||||
msgstr "Núm."
|
||||
|
||||
msgid "No. of Collections"
|
||||
msgstr "Núm. de colecções"
|
||||
@ -804,7 +806,7 @@ msgid "PHP PostgreSQL available"
|
||||
msgstr "PHP PostgreSQL disponível"
|
||||
|
||||
msgid "PHP calendar extension available"
|
||||
msgstr ""
|
||||
msgstr "Extensão PHP para calendários disponível"
|
||||
|
||||
msgid "PHP iconv support"
|
||||
msgstr "Suporte iconv do PHP"
|
||||
@ -813,13 +815,15 @@ msgid ""
|
||||
"PUT on a collection is only allowed for text/calendar content against a "
|
||||
"calendar collection"
|
||||
msgstr ""
|
||||
"PUT numa colecção é apenas permitido para conteúdo de texto/calendário em "
|
||||
"face de uma colecção de calendário"
|
||||
"PUT de conteúdo text/calendar apenas é permitido numa colecção do tipo "
|
||||
"calendário"
|
||||
|
||||
msgid ""
|
||||
"PUT on a collection is only allowed for text/vcard content against an "
|
||||
"addressbook collection"
|
||||
msgstr ""
|
||||
"PUT de conteúdo text/vcard apenas é permitido numa colecção do tipo livro de"
|
||||
" endereços"
|
||||
|
||||
msgid "Passed"
|
||||
msgstr "Passou"
|
||||
@ -918,7 +922,7 @@ msgid "Read/Write"
|
||||
msgstr "Ler/Escrever"
|
||||
|
||||
msgid "References"
|
||||
msgstr ""
|
||||
msgstr "Referências"
|
||||
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
@ -927,7 +931,7 @@ msgid "Remove a lock"
|
||||
msgstr "Remover um lock"
|
||||
|
||||
msgid "Remove dangling external calendars"
|
||||
msgstr ""
|
||||
msgstr "Remover calendários externos com problemas"
|
||||
|
||||
msgid "Report Bug"
|
||||
msgstr "Relatar um bug"
|
||||
@ -1027,6 +1031,8 @@ msgid ""
|
||||
"Set the path to store your ics e.g. 'calendar' will be referenced as "
|
||||
"/caldav.php/username/calendar/"
|
||||
msgstr ""
|
||||
"Definir o caminho para guardar o seu ficheiro ics - e.g. 'calendar' será "
|
||||
"referido como /caldav.php/nome_de_utilizador/calendar/"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "Configurar"
|
||||
@ -1075,7 +1081,7 @@ msgid "Suhosin \"server.strip\" disabled"
|
||||
msgstr "\"server.strip\" do suhosin desabilitado"
|
||||
|
||||
msgid "Sync LDAP Groups with DAViCal"
|
||||
msgstr ""
|
||||
msgstr "Sincronizar Grupos LDAP com o DAViCal"
|
||||
|
||||
msgid "Sync LDAP with DAViCal"
|
||||
msgstr "Sincronizar LDAP com o DAViCal"
|
||||
@ -1117,7 +1123,7 @@ msgstr ""
|
||||
"livros de endereços"
|
||||
|
||||
msgid "The application failed to understand that request."
|
||||
msgstr ""
|
||||
msgstr "A aplicação não conseguiu entender esse pedido."
|
||||
|
||||
msgid "The application program does not understand that request."
|
||||
msgstr "O programa não entende esse pedido."
|
||||
@ -1159,6 +1165,8 @@ msgstr "O endereço de email não devia, de facto, ficar em branco."
|
||||
#, php-format
|
||||
msgid "The file \"%s\" is not UTF-8 encoded, please check error for more details"
|
||||
msgstr ""
|
||||
"O ficheiro \"%s\" não está codificado como UTF-8, por favor verifique a "
|
||||
"mensagem de erro para mais promenores"
|
||||
|
||||
msgid ""
|
||||
"The file is not UTF-8 encoded, please check the error for more details."
|
||||
@ -1183,7 +1191,7 @@ msgstr "O idioma preferido para esta pessoa."
|
||||
|
||||
#, php-format
|
||||
msgid "The principal \"%s\" does not exist"
|
||||
msgstr ""
|
||||
msgstr "O principal \"%s\" não existe"
|
||||
|
||||
msgid "The style of dates used for this person."
|
||||
msgstr "O estilo de datas em uso para esta pessoa."
|
||||
@ -1251,6 +1259,8 @@ msgid ""
|
||||
"This process will import each file in a directory named \"username.ics\" and"
|
||||
" create a user and calendar for each file to import."
|
||||
msgstr ""
|
||||
"Este processo irá importar cada ficheiro chamado \"nome_de_utilizador.ics\" "
|
||||
"ecriar um utilizador e calendário para cada ficheiro."
|
||||
|
||||
msgid "This server only supports the text/calendar format for freebusy URLs"
|
||||
msgstr ""
|
||||
|
||||
54
scripts/refresh-alarms.php
Normal file → Executable file
54
scripts/refresh-alarms.php
Normal file → Executable file
@ -1,29 +1,18 @@
|
||||
#!/usr/bin/php
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Script to refresh the pending alarm times for the next alarm instance.
|
||||
*
|
||||
* @package davical
|
||||
* @subpackage alarms
|
||||
* @author Andrew McMillan <andrew@morphoss.com>
|
||||
* @copyright Morphoss Ltd
|
||||
* @license http://gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
$script_file = __FILE__;
|
||||
|
||||
set_include_path('.');
|
||||
|
||||
function add_path_for( $include, $paths ) {
|
||||
foreach( $paths AS $test_path ) {
|
||||
if ( @file_exists($test_path.'/'.$include) ) {
|
||||
set_include_path( $test_path. PATH_SEPARATOR. get_include_path());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_path_for('AWLUtilities.php', array( '../../awl/inc' , '../awl/inc'
|
||||
, '../../../awl/inc' , '/usr/share/awl/inc' , '/usr/local/share/awl/inc') );
|
||||
add_path_for('caldav-client-v2.php', array( '../../davical/inc' , '../davical/inc'
|
||||
, '../../../davical/inc' , '/usr/share/davical/inc' , '/usr/local/share/davical/inc') );
|
||||
add_path_for('always.php', array( 'scripts' ) );
|
||||
add_path_for('sync-config.php', array( 'config' ) );
|
||||
|
||||
|
||||
require('always.php');
|
||||
require_once('AwlQuery.php');
|
||||
require_once('RRule-v2.php');
|
||||
require_once('vComponent.php');
|
||||
chdir(str_replace('/scripts/refresh-alarms.php','/htdocs',$script_file));
|
||||
$_SERVER['SERVER_NAME'] = 'localhost';
|
||||
|
||||
/**
|
||||
* Call with something like e.g.:
|
||||
@ -41,15 +30,17 @@ $args->near_past = 'P1D';
|
||||
$args->far_past = 'P1200D';
|
||||
$debugging = null;
|
||||
|
||||
|
||||
function parse_arguments() {
|
||||
global $args;
|
||||
|
||||
$opts = getopt( 'f:p:n:d:lh' );
|
||||
$opts = getopt( 'f:p:s:n:d:lh' );
|
||||
foreach( $opts AS $k => $v ) {
|
||||
switch( $k ) {
|
||||
case 'f': $args->future = $v; break;
|
||||
case 'n': $args->near_past = $v; break;
|
||||
case 'p': $args->far_past = $v; break;
|
||||
case 's': $_SERVER['SERVER_NAME'] = $v; break;
|
||||
case 'd': $args->debug = true; $debugging = explode(',',$v); break;
|
||||
case 'l': $args->set_last = true; break;
|
||||
case 'h': usage(); break;
|
||||
@ -59,9 +50,10 @@ function parse_arguments() {
|
||||
}
|
||||
|
||||
function usage() {
|
||||
echo <<<EOUSAGE
|
||||
|
||||
echo <<<USAGE
|
||||
Usage:
|
||||
refresh-alarms.php [-d]
|
||||
refresh-alarms.php [-s server.domain.tld] [-d] [other options]
|
||||
|
||||
-n <duration> Near past period to skip for finding last instances: default 1 days ('P1D')
|
||||
-p <duration> Far past period to examine for finding last instances: default ~3 years ('P1200D')
|
||||
@ -71,8 +63,7 @@ Usage:
|
||||
|
||||
-d Enable debugging
|
||||
|
||||
EOUSAGE;
|
||||
|
||||
USAGE;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -86,6 +77,11 @@ if ( $args->debug && is_array($debugging )) {
|
||||
$args->near_past = '-' . $args->near_past;
|
||||
$args->far_past = '-' . $args->far_past;
|
||||
|
||||
require_once("./always.php");
|
||||
require_once('AwlQuery.php');
|
||||
require_once('RRule-v2.php');
|
||||
require_once('vComponent.php');
|
||||
|
||||
|
||||
/**
|
||||
* Essentially what we are doing is:
|
||||
|
||||
47
testing/tests/carddav/2034-REPORT-addressbook-query.result
Normal file
47
testing/tests/carddav/2034-REPORT-addressbook-query.result
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<multistatus xmlns="DAV:" xmlns:VC="urn:ietf:params:xml:ns:carddav">
|
||||
<response>
|
||||
<href>/caldav.php/user1/addressbook/andrew_mcmillan.vcf</href>
|
||||
<propstat>
|
||||
<prop>
|
||||
<VC:address-data>BEGIN:VCARD
|
||||
VERSION:3.0
|
||||
REV:2010-03-29T09:23:34Z
|
||||
UID:pas-id-4BB0719600000000
|
||||
X-SKYPE;X-EVOLUTION-UI-SLOT=1;TYPE=HOME:karora__
|
||||
X-JABBER;X-EVOLUTION-UI-SLOT=3;TYPE=HOME:karora@irc.oftc.net
|
||||
TEL;X-EVOLUTION-UI-SLOT=3;TYPE=CELL:+64 22 123 4567
|
||||
TEL;X-EVOLUTION-UI-SLOT=2;TYPE=HOME,VOICE:+64 4 123 4567
|
||||
TEL;X-EVOLUTION-UI-SLOT=1;TYPE=WORK,VOICE:+64 22 123 4567
|
||||
EMAIL;X-EVOLUTION-UI-SLOT=2;TYPE=HOME:andrew@mcmillan.net.nz
|
||||
EMAIL;X-EVOLUTION-UI-SLOT=1;TYPE=WORK:andrew@morphoss.com
|
||||
LABEL;TYPE=HOME:16 Kaka Place\nPorikana\n4173\nNew Zealand
|
||||
ADR;TYPE=HOME:;;16 Kaka Place;Porikana;;4173;New Zealand
|
||||
X-MOZILLA-HTML:FALSE
|
||||
X-EVOLUTION-VIDEO-URL:
|
||||
FBURL:https://davical.morphoss.com/freebusy.php/andrew@morphoss.com
|
||||
CALADRURI:mailto:andrew@morphoss.com
|
||||
CALURI:https://dotcal.com/karora
|
||||
X-EVOLUTION-BLOG-URL:http://andrew.mcmillan.net.nz/
|
||||
CATEGORIES:Developer,Personal,Debian,
|
||||
X-EVOLUTION-FILE-AS:McMillan\, Andrew
|
||||
N:McMillan;Andrew;Watson;;
|
||||
FN:Andrew Watson McMillan
|
||||
NOTE:Primary author of DAViCal CalDAV Server.
|
||||
X-EVOLUTION-SPOUSE:Heather Buchanan
|
||||
X-EVOLUTION-ANNIVERSARY:1989-04-22
|
||||
BDAY:1958-07-26
|
||||
NICKNAME:karora
|
||||
X-EVOLUTION-ASSISTANT:
|
||||
X-EVOLUTION-MANAGER:
|
||||
ROLE:Geek
|
||||
ORG:dotCal;;Porirua
|
||||
TITLE:Chief Technology Officer
|
||||
URL:http://andrew.mcmillan.net.nz/
|
||||
END:VCARD
|
||||
</VC:address-data>
|
||||
</prop>
|
||||
<status>HTTP/1.1 200 OK</status>
|
||||
</propstat>
|
||||
</response>
|
||||
</multistatus>
|
||||
28
testing/tests/carddav/2034-REPORT-addressbook-query.test
Normal file
28
testing/tests/carddav/2034-REPORT-addressbook-query.test
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Request a REPORT
|
||||
#
|
||||
TYPE=REPORT
|
||||
URL=http://mycaldav/caldav.php/user1/addressbook/
|
||||
|
||||
HEADER=Accept: text/xml,application/xml
|
||||
HEADER=Content-Type: text/xml
|
||||
HEADER=Depth: 1
|
||||
|
||||
# HEAD
|
||||
|
||||
BEGINDATA
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<C:addressbook-query xmlns:D="DAV:"
|
||||
xmlns:C="urn:ietf:params:xml:ns:carddav">
|
||||
<D:prop>
|
||||
<C:address-data/>
|
||||
</D:prop>
|
||||
<C:filter>
|
||||
<C:prop-filter name="NICKNAME">
|
||||
<C:text-match collation="i;unicode-casemap"
|
||||
match-type="equals"
|
||||
>karora</C:text-match>
|
||||
</C:prop-filter>
|
||||
</C:filter>
|
||||
</C:addressbook-query>
|
||||
ENDDATA
|
||||
@ -2,8 +2,8 @@ HTTP/1.1 207 Multi-Status
|
||||
Date: Dow, 01 Jan 2000 00:00:00 GMT
|
||||
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
|
||||
DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule
|
||||
ETag: "452f45250e12e66d9f6db823b4615a48"
|
||||
Content-Length: 3503
|
||||
ETag: "987fc68a44b7bc99bdf6fe3ab2d0b0ad"
|
||||
Content-Length: 3587
|
||||
Content-Type: text/xml; charset="utf-8"
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
@ -60,6 +60,16 @@ END:VCALENDAR
|
||||
<C:calendar-data>BEGIN:VCALENDAR
|
||||
PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
CREATED:20061223T032350Z
|
||||
LAST-MODIFIED:20061223T033144Z
|
||||
DTSTAMP:20061223T033144Z
|
||||
UID:9d050be7-8a02-4355-8ed3-02a9fc5f473f
|
||||
CLASS:CONFIDENTIAL
|
||||
DTSTART;TZID=/mozilla.org/20050126_1/Antarctica/McMurdo:20061223T160000
|
||||
DTEND;TZID=/mozilla.org/20050126_1/Antarctica/McMurdo:20061223T180000
|
||||
SUMMARY:Busy
|
||||
END:VEVENT
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:/mozilla.org/20050126_1/Antarctica/McMurdo
|
||||
X-LIC-LOCATION:Antarctica/McMurdo
|
||||
@ -78,13 +88,6 @@ DTSTART:19701004T020000
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=10
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:Busy
|
||||
CLASS:CONFIDENTIAL
|
||||
DTSTART;TZID=/mozilla.org/20050126_1/Antarctica/McMurdo:20061223T160000
|
||||
DTEND;TZID=/mozilla.org/20050126_1/Antarctica/McMurdo:20061223T180000
|
||||
UID:9d050be7-8a02-4355-8ed3-02a9fc5f473f
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
</C:calendar-data>
|
||||
</prop>
|
||||
|
||||
@ -2,8 +2,8 @@ HTTP/1.1 207 Multi-Status
|
||||
Date: Dow, 01 Jan 2000 00:00:00 GMT
|
||||
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
|
||||
DAV: extended-mkcol, calendar-proxy, bind, addressbook
|
||||
ETag: "452f45250e12e66d9f6db823b4615a48"
|
||||
Content-Length: 3503
|
||||
ETag: "987fc68a44b7bc99bdf6fe3ab2d0b0ad"
|
||||
Content-Length: 3587
|
||||
Content-Type: text/xml; charset="utf-8"
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
@ -60,6 +60,16 @@ END:VCALENDAR
|
||||
<C:calendar-data>BEGIN:VCALENDAR
|
||||
PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
CREATED:20061223T032350Z
|
||||
LAST-MODIFIED:20061223T033144Z
|
||||
DTSTAMP:20061223T033144Z
|
||||
UID:9d050be7-8a02-4355-8ed3-02a9fc5f473f
|
||||
CLASS:CONFIDENTIAL
|
||||
DTSTART;TZID=/mozilla.org/20050126_1/Antarctica/McMurdo:20061223T160000
|
||||
DTEND;TZID=/mozilla.org/20050126_1/Antarctica/McMurdo:20061223T180000
|
||||
SUMMARY:Busy
|
||||
END:VEVENT
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:/mozilla.org/20050126_1/Antarctica/McMurdo
|
||||
X-LIC-LOCATION:Antarctica/McMurdo
|
||||
@ -78,13 +88,6 @@ DTSTART:19701004T020000
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=10
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:Busy
|
||||
CLASS:CONFIDENTIAL
|
||||
DTSTART;TZID=/mozilla.org/20050126_1/Antarctica/McMurdo:20061223T160000
|
||||
DTEND;TZID=/mozilla.org/20050126_1/Antarctica/McMurdo:20061223T180000
|
||||
UID:9d050be7-8a02-4355-8ed3-02a9fc5f473f
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
</C:calendar-data>
|
||||
</prop>
|
||||
|
||||
@ -29,16 +29,16 @@ BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T110000
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T100000
|
||||
DTSTAMP:20111018T200107Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:5
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
@ -118,16 +118,16 @@ BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T110000
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T100000
|
||||
DTSTAMP:20111018T200107Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:5
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
@ -127,16 +127,16 @@ BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T110000
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T100000
|
||||
DTSTAMP:20111018T200107Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:5
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:user1@example.net
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
@ -5,7 +5,7 @@ TYPE=PUT
|
||||
URL=http://regression.host/caldav.php/manager1/home/E1A13F04-iCal-schedule.ics
|
||||
HEADER=Content-Type: text/calendar
|
||||
HEADER=DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549)
|
||||
HEADER=If-Match: "87421a4ff0b84a95a31db428ee6d11d9"
|
||||
HEADER=If-Match: "d60f8959edc5eee6e949a2e5b81dd746"
|
||||
HEAD
|
||||
|
||||
AUTH=manager1:manager1
|
||||
|
||||
14
testing/tests/scheduling/3028-DELETE-reply.result
Normal file
14
testing/tests/scheduling/3028-DELETE-reply.result
Normal file
@ -0,0 +1,14 @@
|
||||
HTTP/1.1 204 No Content
|
||||
Date: Dow, 01 Jan 2000 00:00:00 GMT
|
||||
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
|
||||
DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule
|
||||
Content-Length: 0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
|
||||
dav_name: >/manager1/home/E1A13F04-iCal-schedule.ics<
|
||||
|
||||
dav_name: >/user1/home/E1A13F04-iCal-schedule.ics<
|
||||
|
||||
dav_name: >/manager1/.in/user1E1A13F04-iCal-schedule.ics<
|
||||
|
||||
18
testing/tests/scheduling/3028-DELETE-reply.test
Normal file
18
testing/tests/scheduling/3028-DELETE-reply.test
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# iCal DELETE's the invitation in the .in
|
||||
#
|
||||
TYPE=DELETE
|
||||
URL=http://regression.host/user1/.in/E1A13F04-iCal-schedule.ics
|
||||
|
||||
HEADER=User-Agent: DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549)
|
||||
HEAD
|
||||
|
||||
#
|
||||
# Query to confirm we got rid of it. There should be two now.
|
||||
QUERY
|
||||
SELECT dav_name
|
||||
FROM calendar_item
|
||||
WHERE uid = 'E1A13F04-iCal-schedule'
|
||||
ORDER BY dav_id
|
||||
ENDQUERY
|
||||
|
||||
12
testing/tests/scheduling/3029-DELETE-reply.result
Normal file
12
testing/tests/scheduling/3029-DELETE-reply.result
Normal file
@ -0,0 +1,12 @@
|
||||
HTTP/1.1 204 No Content
|
||||
Date: Dow, 01 Jan 2000 00:00:00 GMT
|
||||
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
|
||||
DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule
|
||||
Content-Length: 0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
|
||||
dav_name: >/manager1/home/E1A13F04-iCal-schedule.ics<
|
||||
|
||||
dav_name: >/user1/home/E1A13F04-iCal-schedule.ics<
|
||||
|
||||
20
testing/tests/scheduling/3029-DELETE-reply.test
Normal file
20
testing/tests/scheduling/3029-DELETE-reply.test
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# iCal DELETE's the invitation in the .in
|
||||
#
|
||||
TYPE=DELETE
|
||||
URL=http://regression.host/manager1/.in/user1E1A13F04-iCal-schedule.ics
|
||||
|
||||
HEADER=User-Agent: DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549)
|
||||
HEAD
|
||||
|
||||
AUTH=manager1:manager1
|
||||
|
||||
#
|
||||
# Query to confirm we got rid of it. There should be two now.
|
||||
QUERY
|
||||
SELECT dav_name
|
||||
FROM calendar_item
|
||||
WHERE uid = 'E1A13F04-iCal-schedule'
|
||||
ORDER BY dav_id
|
||||
ENDQUERY
|
||||
|
||||
70
testing/tests/scheduling/3030-DELETE-attendee-event.result
Normal file
70
testing/tests/scheduling/3030-DELETE-attendee-event.result
Normal file
@ -0,0 +1,70 @@
|
||||
HTTP/1.1 204 No Content
|
||||
Date: Dow, 01 Jan 2000 00:00:00 GMT
|
||||
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
|
||||
DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule
|
||||
Content-Length: 0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
|
||||
dav_name: >/manager1/home/E1A13F04-iCal-schedule.ics<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:looks good
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:6
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=DECLINED;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=2.0:mai
|
||||
lto:user1@example.net
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
dav_name: >/manager1/.in/user1E1A13F04-iCal-schedule.ics<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:REPLY
|
||||
REQUEST-STATUS:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND:20111019T010000Z
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user1@example.net
|
||||
DTSTART:20111019T000000Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
DTSTAMP:looks good
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
23
testing/tests/scheduling/3030-DELETE-attendee-event.test
Normal file
23
testing/tests/scheduling/3030-DELETE-attendee-event.test
Normal file
@ -0,0 +1,23 @@
|
||||
#
|
||||
# We now DELETE the ATTENDEE's copy of the actual event.
|
||||
# - This should send a CANCEL reply and update the manager's
|
||||
# event copy with the PARTSTAT=DECLINED
|
||||
#
|
||||
TYPE=DELETE
|
||||
URL=http://regression.host/user1/home/E1A13F04-iCal-schedule.ics
|
||||
|
||||
HEADER=User-Agent: DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549)
|
||||
HEAD
|
||||
|
||||
#
|
||||
# Query to confirm we got rid of it. There should be two now:
|
||||
# - An event in the manager's calendar, with a PARTSTART=DECLINED for user 1
|
||||
# - An iTIP message in the managers's inbox.
|
||||
QUERY
|
||||
SELECT calendar_item.dav_name,
|
||||
regexp_replace(caldav_data,'DTSTAMP:[0-9T]{15}Z','DTSTAMP:looks good') AS vcalendar
|
||||
FROM calendar_item JOIN caldav_data USING(dav_id, dav_name)
|
||||
WHERE uid = 'E1A13F04-iCal-schedule'
|
||||
ORDER BY dav_id
|
||||
ENDQUERY
|
||||
|
||||
10
testing/tests/scheduling/3031-DELETE-reply.result
Normal file
10
testing/tests/scheduling/3031-DELETE-reply.result
Normal file
@ -0,0 +1,10 @@
|
||||
HTTP/1.1 204 No Content
|
||||
Date: Dow, 01 Jan 2000 00:00:00 GMT
|
||||
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
|
||||
DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule
|
||||
Content-Length: 0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
|
||||
dav_name: >/manager1/home/E1A13F04-iCal-schedule.ics<
|
||||
|
||||
21
testing/tests/scheduling/3031-DELETE-reply.test
Normal file
21
testing/tests/scheduling/3031-DELETE-reply.test
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Now DELETE's the cancelation reply in the Manager's .in
|
||||
#
|
||||
TYPE=DELETE
|
||||
URL=http://regression.host/manager1/.in/user1E1A13F04-iCal-schedule.ics
|
||||
|
||||
HEADER=User-Agent: DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549)
|
||||
HEAD
|
||||
|
||||
AUTH=manager1:manager1
|
||||
|
||||
#
|
||||
# Query to confirm we got rid of it. There should only be one
|
||||
# lonely meeting in the manager's calendar (which has been declined).
|
||||
QUERY
|
||||
SELECT dav_name
|
||||
FROM calendar_item
|
||||
WHERE uid = 'E1A13F04-iCal-schedule'
|
||||
ORDER BY dav_id
|
||||
ENDQUERY
|
||||
|
||||
370
testing/tests/scheduling/3032-PUT-iCal-with-attendees.result
Normal file
370
testing/tests/scheduling/3032-PUT-iCal-with-attendees.result
Normal file
@ -0,0 +1,370 @@
|
||||
HTTP/1.1 100 Continue
|
||||
|
||||
HTTP/1.1 204 No Content
|
||||
Date: Dow, 01 Jan 2000 00:00:00 GMT
|
||||
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
|
||||
DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule
|
||||
Content-Length: 0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
|
||||
caldav_type: >VEVENT<
|
||||
dav_name: >/manager1/home/E1A13F04-iCal-schedule.ics<
|
||||
logged_user: >20<
|
||||
summary: >Meeting with User1<
|
||||
user_no: >20<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user1@example.net
|
||||
ATTENDEE;CN=user2@example.net;CUTYPE=INDIVIDUAL;EMAIL=user2@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user2@example.net
|
||||
ATTENDEE;CN=user3@example.net;CUTYPE=INDIVIDUAL;EMAIL=user3@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user3@example.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:20111024T035702Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
caldav_type: >VEVENT<
|
||||
dav_name: >/user1/.in/E1A13F04-iCal-schedule.ics<
|
||||
logged_user: >20<
|
||||
summary: >Meeting with User1<
|
||||
user_no: >10<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:REQUEST
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag
|
||||
er1@example.net
|
||||
ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user2@example.net";CUTYPE=INDIVIDUAL;EMAIL="user2@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user2@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user3@example.net";CUTYPE=INDIVIDUAL;EMAIL="user3@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user3@ex
|
||||
ample.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:20111024T035702Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
caldav_type: >VEVENT<
|
||||
dav_name: >/user1/home/E1A13F04-iCal-schedule.ics<
|
||||
logged_user: >20<
|
||||
summary: >Meeting with User1<
|
||||
user_no: >10<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag
|
||||
er1@example.net
|
||||
ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user2@example.net";CUTYPE=INDIVIDUAL;EMAIL="user2@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user2@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user3@example.net";CUTYPE=INDIVIDUAL;EMAIL="user3@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user3@ex
|
||||
ample.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:20111024T035702Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
caldav_type: >VEVENT<
|
||||
dav_name: >/user2/.in/E1A13F04-iCal-schedule.ics<
|
||||
logged_user: >20<
|
||||
summary: >Meeting with User1<
|
||||
user_no: >11<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:REQUEST
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag
|
||||
er1@example.net
|
||||
ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user2@example.net";CUTYPE=INDIVIDUAL;EMAIL="user2@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user2@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user3@example.net";CUTYPE=INDIVIDUAL;EMAIL="user3@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user3@ex
|
||||
ample.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:20111024T035702Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
caldav_type: >VEVENT<
|
||||
dav_name: >/user2/home/E1A13F04-iCal-schedule.ics<
|
||||
logged_user: >20<
|
||||
summary: >Meeting with User1<
|
||||
user_no: >11<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag
|
||||
er1@example.net
|
||||
ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user2@example.net";CUTYPE=INDIVIDUAL;EMAIL="user2@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user2@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user3@example.net";CUTYPE=INDIVIDUAL;EMAIL="user3@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user3@ex
|
||||
ample.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:20111024T035702Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
caldav_type: >VEVENT<
|
||||
dav_name: >/user3/.in/E1A13F04-iCal-schedule.ics<
|
||||
logged_user: >20<
|
||||
summary: >Meeting with User1<
|
||||
user_no: >12<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:REQUEST
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag
|
||||
er1@example.net
|
||||
ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user2@example.net";CUTYPE=INDIVIDUAL;EMAIL="user2@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user2@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user3@example.net";CUTYPE=INDIVIDUAL;EMAIL="user3@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user3@ex
|
||||
ample.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:20111024T035702Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
caldav_type: >VEVENT<
|
||||
dav_name: >/user3/home/E1A13F04-iCal-schedule.ics<
|
||||
logged_user: >20<
|
||||
summary: >Meeting with User1<
|
||||
user_no: >12<
|
||||
vcalendar: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag
|
||||
er1@example.net
|
||||
ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user2@example.net";CUTYPE=INDIVIDUAL;EMAIL="user2@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user2@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user3@example.net";CUTYPE=INDIVIDUAL;EMAIL="user3@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user3@ex
|
||||
ample.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:20111024T035702Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
|
||||
72
testing/tests/scheduling/3032-PUT-iCal-with-attendees.test
Normal file
72
testing/tests/scheduling/3032-PUT-iCal-with-attendees.test
Normal file
@ -0,0 +1,72 @@
|
||||
#
|
||||
# PUT an event with several attendees - so we can delete the organizer
|
||||
# copy in the next request.
|
||||
#
|
||||
# After this we should see 7 events: 1 manager, 3 attendees, 3 attendee iTIP
|
||||
#
|
||||
TYPE=PUT
|
||||
URL=http://regression.host/caldav.php/manager1/home/E1A13F04-iCal-schedule.ics
|
||||
HEADER=Content-Type: text/calendar
|
||||
HEADER=DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549)
|
||||
HEAD
|
||||
|
||||
AUTH=manager1:manager1
|
||||
|
||||
BEGINDATA
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
|
||||
DTSTART:20070930T020000
|
||||
TZNAME:GMT+13:00
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
|
||||
DTSTART:20080406T030000
|
||||
TZNAME:GMT+12:00
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20111018T195845Z
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND;TZID=Pacific/Auckland:20111019T140000
|
||||
ATTENDEE;CN="Manager 1";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:manag
|
||||
er1@example.net
|
||||
ATTENDEE;CN="user1@example.net";CUTYPE=INDIVIDUAL;EMAIL="user1@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user1@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user2@example.net";CUTYPE=INDIVIDUAL;EMAIL="user2@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user2@ex
|
||||
ample.net
|
||||
ATTENDEE;CN="user3@example.net";CUTYPE=INDIVIDUAL;EMAIL="user3@example.n
|
||||
et";PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user3@ex
|
||||
ample.net
|
||||
TRANSP:OPAQUE
|
||||
SUMMARY:Meeting with User1
|
||||
DTSTART;TZID=Pacific/Auckland:20111019T130000
|
||||
DTSTAMP:20111024T035702Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
ENDDATA
|
||||
|
||||
|
||||
|
||||
QUERY
|
||||
SELECT caldav_data.user_no, caldav_data.dav_name,
|
||||
caldav_type, logged_user, caldav_data.caldav_data AS "vcalendar",
|
||||
summary
|
||||
FROM caldav_data JOIN calendar_item USING(dav_name) LEFT JOIN timezones ON (tz_id=tzid)
|
||||
WHERE calendar_item.uid = 'E1A13F04-iCal-schedule'
|
||||
ORDER BY caldav_data.dav_id
|
||||
ENDQUERY
|
||||
|
||||
95
testing/tests/scheduling/3033-DELETE-organizer-event.result
Normal file
95
testing/tests/scheduling/3033-DELETE-organizer-event.result
Normal file
@ -0,0 +1,95 @@
|
||||
SQL executed successfully.
|
||||
DELETE FROM caldav_data WHERE dav_name ~ E'/\\.in/.*E1A13F04-iCal-schedule\\.ics'
|
||||
|
||||
HTTP/1.1 204 No Content
|
||||
Date: Dow, 01 Jan 2000 00:00:00 GMT
|
||||
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
|
||||
DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule
|
||||
Content-Length: 0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
|
||||
caldav_data: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:CANCEL
|
||||
REQUEST-STATUS:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND:20111019T010000Z
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user1@example.net
|
||||
ATTENDEE;CN=user2@example.net;CUTYPE=INDIVIDUAL;EMAIL=user2@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user2@example.net
|
||||
ATTENDEE;CN=user3@example.net;CUTYPE=INDIVIDUAL;EMAIL=user3@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user3@example.net
|
||||
DTSTART:20111019T000000Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
dav_name: >/user1/.in/E1A13F04-iCal-schedule.ics<
|
||||
|
||||
caldav_data: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:CANCEL
|
||||
REQUEST-STATUS:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND:20111019T010000Z
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user1@example.net
|
||||
ATTENDEE;CN=user2@example.net;CUTYPE=INDIVIDUAL;EMAIL=user2@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user2@example.net
|
||||
ATTENDEE;CN=user3@example.net;CUTYPE=INDIVIDUAL;EMAIL=user3@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user3@example.net
|
||||
DTSTART:20111019T000000Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
dav_name: >/user2/.in/E1A13F04-iCal-schedule.ics<
|
||||
|
||||
caldav_data: >BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Apple Inc.//iCal 4.0.4//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:CANCEL
|
||||
REQUEST-STATUS:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:E1A13F04-iCal-schedule
|
||||
DTEND:20111019T010000Z
|
||||
ATTENDEE;CN=Manager 1;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:
|
||||
mailto:manager1@example.net
|
||||
ATTENDEE;CN=user1@example.net;CUTYPE=INDIVIDUAL;EMAIL=user1@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user1@example.net
|
||||
ATTENDEE;CN=user2@example.net;CUTYPE=INDIVIDUAL;EMAIL=user2@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user2@example.net
|
||||
ATTENDEE;CN=user3@example.net;CUTYPE=INDIVIDUAL;EMAIL=user3@example.net;
|
||||
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE;SCHEDULE-STATUS=1.2
|
||||
:mailto:user3@example.net
|
||||
DTSTART:20111019T000000Z
|
||||
ORGANIZER;CN="Manager 1":mailto:manager1@example.net
|
||||
SEQUENCE:7
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
<
|
||||
dav_name: >/user3/.in/E1A13F04-iCal-schedule.ics<
|
||||
|
||||
31
testing/tests/scheduling/3033-DELETE-organizer-event.test
Normal file
31
testing/tests/scheduling/3033-DELETE-organizer-event.test
Normal file
@ -0,0 +1,31 @@
|
||||
#
|
||||
# We now DELETE the ORGANIZER's copy of the actual event.
|
||||
# - This should send a CANCEL reply and remove each attendee's
|
||||
# copy of the event
|
||||
#
|
||||
TYPE=DELETE
|
||||
URL=http://regression.host/manager1/home/E1A13F04-iCal-schedule.ics
|
||||
|
||||
HEADER=User-Agent: DAVKit/4.0.3 (732.2); CalendarStore/4.0.4 (997.7); iCal/4.0.4 (1395.7); Mac OS X/10.6.8 (10K549)
|
||||
HEAD
|
||||
|
||||
AUTH=manager1:manager1
|
||||
|
||||
# Before we run, this time we'll assume everyone has read their inbox
|
||||
# and all existing iTIP messages are deleted.
|
||||
DOSQL
|
||||
DELETE FROM caldav_data WHERE dav_name ~ E'/\\.in/.*E1A13F04-iCal-schedule\\.ics'
|
||||
ENDDOSQL
|
||||
|
||||
#
|
||||
# Query to confirm we got rid of it. There should be two now:
|
||||
# - An event in the manager's calendar, with a PARTSTART=DECLINED for user 1
|
||||
# - An iTIP message in the managers's inbox.
|
||||
QUERY
|
||||
SELECT calendar_item.dav_name,
|
||||
caldav_data.caldav_data
|
||||
FROM calendar_item JOIN caldav_data USING(dav_id, dav_name)
|
||||
WHERE uid = 'E1A13F04-iCal-schedule'
|
||||
ORDER BY dav_id
|
||||
ENDQUERY
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
setval
|
||||
--------
|
||||
1657
|
||||
1667
|
||||
(1 row)
|
||||
|
||||
setval
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user