mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-06-05 04:20:17 +00:00
Initial commit
This commit is contained in:
commit
792b1a5083
12
caldav.session
Normal file
12
caldav.session
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE webprojectsession>
|
||||
<webprojectsession>
|
||||
<session usePreviewPrefix="0" previewPrefix="" >
|
||||
<itemcursorpositions/>
|
||||
<treestatus>
|
||||
<openfolder url="config" />
|
||||
<openfolder url="dba" />
|
||||
<openfolder url="htdocs" />
|
||||
<openfolder url="inc" />
|
||||
</treestatus>
|
||||
</session>
|
||||
</webprojectsession>
|
||||
27
caldav.webprj
Normal file
27
caldav.webprj
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE webproject>
|
||||
<webproject>
|
||||
<project type="Local" name="caldav" encoding="utf8" >
|
||||
<upload/>
|
||||
<author>Andrew McMillan</author>
|
||||
<email>andrew@catalyst.net.nz</email>
|
||||
<defaultDTD>-//W3C//DTD XHTML 1.0 Transitional//EN</defaultDTD>
|
||||
<item url="" uploadstatus="1" />
|
||||
<templates>templates/</templates>
|
||||
<toolbars>toolbars/</toolbars>
|
||||
<item url="htdocs/index.php" uploadstatus="1" />
|
||||
<item url="htdocs/" uploadstatus="1" />
|
||||
<annotations/>
|
||||
<item url="inc/caldav-OPTIONS.php" uploadstatus="1" />
|
||||
<item url="inc/" uploadstatus="1" />
|
||||
<item url="inc/caldav-REPORT.php" uploadstatus="1" />
|
||||
<item url="inc/iCalendar.php" uploadstatus="1" />
|
||||
<item url="inc/always.php" uploadstatus="1" />
|
||||
<item url="config/config.php" uploadstatus="1" />
|
||||
<item url="config/" uploadstatus="1" />
|
||||
<item url="inc/caldav-PUT.php" uploadstatus="1" />
|
||||
<item url="dba/caldav.sql" />
|
||||
<item url="dba/" />
|
||||
<item url="dba/create-database.sh" />
|
||||
<item url="dba/sample-data.sql" />
|
||||
</project>
|
||||
</webproject>
|
||||
15
config/config.php
Normal file
15
config/config.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
$c->domainname = "mycaldav.andrew";
|
||||
|
||||
if ( ! $dbconn = pg_Connect("port=5433 dbname=caldav user=general") ) {
|
||||
if ( ! $dbconn = pg_Connect("port=5432 dbname=caldav user=general") ) {
|
||||
echo "<html><head><title>Database Error</title></head><body>
|
||||
<h1>Database Error</h1>
|
||||
<h3>Could not connect to PGPool or to Postgres</h3>
|
||||
</body>
|
||||
</html>";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
14
dba/caldav.sql
Normal file
14
dba/caldav.sql
Normal file
@ -0,0 +1,14 @@
|
||||
-- My CalDAV server - Database Schema
|
||||
--
|
||||
|
||||
-- Use the usr, group and schema management stufffrom libawl-php
|
||||
\i /usr/share/awl/dba/awl-tables.sql
|
||||
\i /usr/share/awl/dba/schema-management.sql
|
||||
|
||||
CREATE TABLE ics_event_data (
|
||||
user_no INT references usr(user_no),
|
||||
ics_event_name TEXT,
|
||||
ics_event_etag TEXT,
|
||||
ics_raw_data TEXT
|
||||
);
|
||||
|
||||
12
dba/create-database.sh
Executable file
12
dba/create-database.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Build the CalDAV database
|
||||
#
|
||||
|
||||
DBNAME="${1:-caldav}"
|
||||
|
||||
createdb -E UTF8 "${DBNAME}"
|
||||
|
||||
psql -f caldav.sql "${DBNAME}"
|
||||
|
||||
psql -f sample-data.sql "${DBNAME}"
|
||||
6
dba/sample-data.sql
Normal file
6
dba/sample-data.sql
Normal file
@ -0,0 +1,6 @@
|
||||
-- Some sample data to prime the database...
|
||||
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 1, TRUE, current_date, current_date, 'andrew', '**x', 'Andrew McMillan', 'andrew@catalyst.net.nz' );
|
||||
|
||||
SELECT setval('usr_user_no_seq', 1);
|
||||
7342
docs/IETF-CAP-RFC4324.txt
Normal file
7342
docs/IETF-CAP-RFC4324.txt
Normal file
File diff suppressed because it is too large
Load Diff
1368
docs/draft-dawson-ical-xml-dtd-01.txt
Normal file
1368
docs/draft-dawson-ical-xml-dtd-01.txt
Normal file
File diff suppressed because it is too large
Load Diff
2971
docs/draft-ietf-calsch-many-xcal-02.txt
Normal file
2971
docs/draft-ietf-calsch-many-xcal-02.txt
Normal file
File diff suppressed because it is too large
Load Diff
6155
docs/dusseault-caldav-12.txt.html
Normal file
6155
docs/dusseault-caldav-12.txt.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
docs/dusseault2005CalDAV.pdf
Normal file
BIN
docs/dusseault2005CalDAV.pdf
Normal file
Binary file not shown.
8342
docs/rfc2445.html
Normal file
8342
docs/rfc2445.html
Normal file
File diff suppressed because it is too large
Load Diff
8291
docs/rfc2445.txt
Normal file
8291
docs/rfc2445.txt
Normal file
File diff suppressed because it is too large
Load Diff
5109
docs/rfc2518.html
Normal file
5109
docs/rfc2518.html
Normal file
File diff suppressed because it is too large
Load Diff
9901
docs/rfc2616.html
Normal file
9901
docs/rfc2616.html
Normal file
File diff suppressed because it is too large
Load Diff
47
htdocs/index.php
Normal file
47
htdocs/index.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
require_once("always.php");
|
||||
|
||||
if ( !function_exists('apache_request_headers') ) {
|
||||
function apache_request_headers() {
|
||||
return getallheaders();
|
||||
}
|
||||
}
|
||||
|
||||
function dbg_log_array( $name, $arr, $recursive = false ) {
|
||||
foreach ($arr as $key => $value) {
|
||||
error_log( "caldav: DBG: $name: >>$key<< = >>$value<<");
|
||||
if ( $recursive && (gettype($value) == 'array' || gettype($value) == 'object') ) {
|
||||
dbg_log_array( "$name"."[$key]", $value, $recursive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$raw_headers = apache_request_headers();
|
||||
$raw_post = file_get_contents ( 'php://input');
|
||||
|
||||
if ( $debugging && isset($_GET['method']) ) {
|
||||
$_SERVER['REQUEST_METHOD'] = $_GET['method'];
|
||||
}
|
||||
|
||||
switch ( $_SERVER['REQUEST_METHOD'] ) {
|
||||
case 'OPTIONS':
|
||||
include_once("caldav-OPTIONS.php");
|
||||
break;
|
||||
|
||||
case 'REPORT':
|
||||
include_once("caldav-REPORT.php");
|
||||
break;
|
||||
|
||||
case 'PUT':
|
||||
include_once("caldav-PUT.php");
|
||||
break;
|
||||
|
||||
default:
|
||||
error_log("Unhandled request method >>".$_SERVER['REQUEST_METHOD']."<<");
|
||||
dbg_log_array( 'HEADERS', $raw_headers );
|
||||
dbg_log_array( '_SERVER', $_SERVER, true );
|
||||
error_log( "caldav: DBG: RAW: ".str_replace("\n", "", str_replace("\r", "", $raw_post)));
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
21
inc/always.php
Normal file
21
inc/always.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
$c->sysabbr = 'caldav';
|
||||
$c->admin_email = 'andrew@catalyst.net.nz';
|
||||
$c->system_name = "Andrew's CalDAV Server";
|
||||
|
||||
error_log( $c->sysabbr.": DBG: ======================================= Start $PHP_SELF for $HTTP_HOST on $_SERVER[SERVER_NAME]" );
|
||||
if ( file_exists("/etc/caldav/".$_SERVER['SERVER_NAME']."-conf.php") ) {
|
||||
include_once("/etc/caldav/".$_SERVER['SERVER_NAME']."-conf.php");
|
||||
}
|
||||
else if ( file_exists("../config/config.php") ) {
|
||||
include_once("../config/config.php");
|
||||
}
|
||||
else {
|
||||
include_once("caldav_configuration_missing.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
include_once("iCalendar.php");
|
||||
|
||||
?>
|
||||
6
inc/caldav-OPTIONS.php
Normal file
6
inc/caldav-OPTIONS.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
error_log("caldav: DBG: OPTIONS method handler");
|
||||
header( "Content-type: text/plain");
|
||||
header( "Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE, PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL");
|
||||
header( "DAV: 1, 2, 3, access-control, calendar-access");
|
||||
?>
|
||||
105
inc/caldav-PUT.php
Normal file
105
inc/caldav-PUT.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
error_log("caldav: DBG: PUT method handler");
|
||||
|
||||
$parser = xml_parser_create_ns('UTF-8');
|
||||
xml_parser_set_option ( $parser, XML_OPTION_SKIP_WHITE, 1 );
|
||||
|
||||
function xml_start_callback( $parser, $el_name, $el_attrs ) {
|
||||
error_log( "DBG: Parsing $el_name" );
|
||||
dbg_log_array( "$el_name::attrs", $el_attrs, true );
|
||||
}
|
||||
|
||||
function xml_end_callback( $parser, $el_name ) {
|
||||
error_log( "DBG: Finished Parsing $el_name" );
|
||||
}
|
||||
|
||||
xml_set_element_handler ( $parser, 'xml_start_callback', 'xml_end_callback' );
|
||||
|
||||
$put_request = array();
|
||||
xml_parse_into_struct( $parser, $raw_post, $put_request );
|
||||
xml_parser_free($parser);
|
||||
|
||||
|
||||
$putnum = -1;
|
||||
$put = array();
|
||||
foreach( $put_request AS $k => $v ) {
|
||||
|
||||
switch ( $v['tag'] ) {
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-QUERY':
|
||||
if ( $v['type'] == "open" ) {
|
||||
$putnum++;
|
||||
$put_type = substr($v['tag'],30);
|
||||
$put[$putnum]['type'] = $put_type;
|
||||
}
|
||||
else {
|
||||
unset($put_type);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'DAV::PROP':
|
||||
if ( isset($put_type) ) {
|
||||
if ( $v['type'] == "open" ) {
|
||||
$put_properties = array();
|
||||
}
|
||||
else if ( $v['type'] == "close" ) {
|
||||
$put[$putnum]['properties'] = $put_properties;
|
||||
unset($put_properties);
|
||||
}
|
||||
else {
|
||||
error_log( "DBG: Unexpected DAV::PROP type of ".$v['type'] );
|
||||
}
|
||||
}
|
||||
else {
|
||||
error_log( "DBG: Unexpected DAV::PROP type of ".$v['type']." when no active put type.");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'DAV::GETETAG':
|
||||
if ( isset($put_properties) ) {
|
||||
if ( $v['type'] == "complete" ) {
|
||||
$put_properties['GETETAG'] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error_log("caldav: DBG: Unhandled tag >>".$v['tag']."<<");
|
||||
}
|
||||
}
|
||||
|
||||
dbg_log_array( 'RPT', $put_request, true );
|
||||
|
||||
dbg_log_array( 'REPORT', $put, true );
|
||||
|
||||
header("Content-type: text/xml");
|
||||
|
||||
echo <<<EOXML
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<D:multistatus xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||
<D:response>
|
||||
<D:href>http://mycaldav/?andrewmcmillan.ics</D:href>
|
||||
<D:propstat>
|
||||
<D:prop>
|
||||
<D:getetag>"fffff-abcd1"</D:getetag>
|
||||
<C:calendar-data>BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Andrew's CalDAV Server//PHP//0.0.1
|
||||
EOXML;
|
||||
|
||||
echo iCalendar::vTimeZone("Pacific/Auckland");
|
||||
$event = new vEvent( '20060517T150000Z', 'PT2H', 'andrew@catalyst.net.nz', '', 'A Test Event for Andrew' );
|
||||
echo $event->ToString();
|
||||
|
||||
echo <<<EOXML
|
||||
END:VCALENDAR
|
||||
</C:calendar-data>
|
||||
</D:prop>
|
||||
<D:status>HTTP/1.1 200 OK</D:status>
|
||||
</D:propstat>
|
||||
</D:response>
|
||||
</D:multistatus>
|
||||
EOXML;
|
||||
|
||||
?>
|
||||
108
inc/caldav-REPORT.php
Normal file
108
inc/caldav-REPORT.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
error_log("caldav: DBG: REPORT method handler");
|
||||
|
||||
include_once("iCalendar.php");
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$parser = xml_parser_create_ns('UTF-8');
|
||||
xml_parser_set_option ( $parser, XML_OPTION_SKIP_WHITE, 1 );
|
||||
|
||||
function xml_start_callback( $parser, $el_name, $el_attrs ) {
|
||||
error_log( "DBG: Parsing $el_name" );
|
||||
dbg_log_array( "$el_name::attrs", $el_attrs, true );
|
||||
}
|
||||
|
||||
function xml_end_callback( $parser, $el_name ) {
|
||||
error_log( "DBG: Finished Parsing $el_name" );
|
||||
}
|
||||
|
||||
xml_set_element_handler ( $parser, 'xml_start_callback', 'xml_end_callback' );
|
||||
|
||||
$rpt_request = array();
|
||||
xml_parse_into_struct( $parser, $raw_post, $rpt_request );
|
||||
xml_parser_free($parser);
|
||||
|
||||
|
||||
$reportnum = -1;
|
||||
$report = array();
|
||||
foreach( $rpt_request AS $k => $v ) {
|
||||
|
||||
switch ( $v['tag'] ) {
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-QUERY':
|
||||
if ( $v['type'] == "open" ) {
|
||||
$reportnum++;
|
||||
$report_type = substr($v['tag'],30);
|
||||
$report[$reportnum]['type'] = $report_type;
|
||||
}
|
||||
else {
|
||||
unset($report_type);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'DAV::PROP':
|
||||
if ( isset($report_type) ) {
|
||||
if ( $v['type'] == "open" ) {
|
||||
$report_properties = array();
|
||||
}
|
||||
else if ( $v['type'] == "close" ) {
|
||||
$report[$reportnum]['properties'] = $report_properties;
|
||||
unset($report_properties);
|
||||
}
|
||||
else {
|
||||
error_log( "DBG: Unexpected DAV::PROP type of ".$v['type'] );
|
||||
}
|
||||
}
|
||||
else {
|
||||
error_log( "DBG: Unexpected DAV::PROP type of ".$v['type']." when no active report type.");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'DAV::GETETAG':
|
||||
if ( isset($report_properties) ) {
|
||||
if ( $v['type'] == "complete" ) {
|
||||
$report_properties['GETETAG'] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error_log("caldav: DBG: Unhandled tag >>".$v['tag']."<<");
|
||||
}
|
||||
}
|
||||
|
||||
dbg_log_array( 'RPT', $rpt_request, true );
|
||||
|
||||
dbg_log_array( 'REPORT', $report, true );
|
||||
|
||||
header("Content-type: text/xml");
|
||||
|
||||
echo <<<EOXML
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<D:multistatus xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||
<D:response>
|
||||
<D:href>http://mycaldav/?andrewmcmillan.ics</D:href>
|
||||
<D:propstat>
|
||||
<D:prop>
|
||||
<D:getetag>"fffff-abcd1"</D:getetag>
|
||||
<C:calendar-data>BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Andrew's CalDAV Server//PHP//0.0.1
|
||||
EOXML;
|
||||
|
||||
echo iCalendar::vTimeZone("Pacific/Auckland");
|
||||
$event = new vEvent( '20060517T150000Z', 'PT2H', 'andrew@catalyst.net.nz', '', 'A Test Event for Andrew' );
|
||||
echo $event->ToString();
|
||||
|
||||
echo <<<EOXML
|
||||
END:VCALENDAR
|
||||
</C:calendar-data>
|
||||
</D:prop>
|
||||
<D:status>HTTP/1.1 200 OK</D:status>
|
||||
</D:propstat>
|
||||
</D:response>
|
||||
</D:multistatus>
|
||||
EOXML;
|
||||
|
||||
?>
|
||||
231
inc/iCalendar.php
Normal file
231
inc/iCalendar.php
Normal file
@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/**
|
||||
* A Class for handling iCalendar data
|
||||
*
|
||||
* @package caldav
|
||||
* @subpackage iCalendar
|
||||
* @author Andrew McMillan <andrew@catalyst.net.nz>
|
||||
* @copyright Catalyst IT Ltd
|
||||
* @license http://gnu.org/copyleft/gpl.html GNU GPL v2
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Class for handling participants to events
|
||||
*
|
||||
* @package caldav
|
||||
*/
|
||||
class Participant {
|
||||
/**#@+
|
||||
* @access private
|
||||
*/
|
||||
|
||||
/**
|
||||
* Participant e-mail
|
||||
* @var email string
|
||||
*/
|
||||
var $email;
|
||||
|
||||
/**
|
||||
* Status of participant in relation to the event
|
||||
* @var status string
|
||||
*/
|
||||
var $status;
|
||||
|
||||
/**
|
||||
* Role of participant in relation to event
|
||||
* @var email string
|
||||
*/
|
||||
var $role;
|
||||
/**#@-*/
|
||||
|
||||
function Participant( $email, $status="NEEDS-ACTION", $role="ATTENDEE" ) {
|
||||
$this->email = $email;
|
||||
$this->status = $status;
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
function ToString() {
|
||||
$rv = sprintf( "ATTENDEE;PARTSTAT=%s%s:%s\n", $this->status, ($this-role == "ATTENDEE" ? "" : "ROLE=$this->role"), $this->email );
|
||||
return $rv;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class for handling Evends on a calendar
|
||||
*
|
||||
* @package caldav
|
||||
*/
|
||||
class vEvent {
|
||||
/**#@+
|
||||
* @access private
|
||||
*/
|
||||
|
||||
/**
|
||||
* List of participants in this event
|
||||
* @var participants array
|
||||
*/
|
||||
var $participants = array();
|
||||
|
||||
/**
|
||||
* The start time for the event
|
||||
* @var start datetime
|
||||
*/
|
||||
var $start;
|
||||
|
||||
/**
|
||||
* The duration of the event
|
||||
* @var duration interval
|
||||
*/
|
||||
var $duration;
|
||||
|
||||
/**
|
||||
* The organizer of othe event
|
||||
* @var organizer string
|
||||
*/
|
||||
var $organizer;
|
||||
|
||||
/**
|
||||
* The status of the event
|
||||
* @var status string
|
||||
*/
|
||||
var $status;
|
||||
|
||||
/**
|
||||
* A summary description of the event
|
||||
* @var summary string
|
||||
*/
|
||||
var $summary;
|
||||
|
||||
/**
|
||||
* A last modified timestamp
|
||||
* @var modified int
|
||||
*/
|
||||
var $modified;
|
||||
|
||||
/**
|
||||
* A sequence for different revisions of the event
|
||||
* @var sequence integer
|
||||
*/
|
||||
var $sequence;
|
||||
|
||||
/**
|
||||
* A unique ID for the event
|
||||
* @var uid string
|
||||
*/
|
||||
var $uid;
|
||||
|
||||
/**
|
||||
* A GUID for the event
|
||||
* @var guid string
|
||||
*/
|
||||
var $guid;
|
||||
/**#@-*/
|
||||
|
||||
function vEvent( $start, $duration="PT1H", $organizer="", $status="TENTATIVE", $summary="" ) {
|
||||
global $c;
|
||||
|
||||
$this->participants = array();
|
||||
$this->start = $start;
|
||||
$this->duration = $duration;
|
||||
$this->organizer = $organizer;
|
||||
$this->status = $status;
|
||||
$this->summary = $summary;
|
||||
$this->modified = iCalendar::EpochTS(time());
|
||||
$this->sequence = 1;
|
||||
$this->uid = sprintf( "%s@%s", time() * 1000 + rand(0,1000), $c->domainname);
|
||||
$this->guid = sprintf( "%s@%s", time() * 1000 + rand(0,1000), $c->domainname);
|
||||
}
|
||||
|
||||
function AddParticipant( $email, $status, $role ) {
|
||||
$this->participants[] = new Participant($email,$status,$role);
|
||||
}
|
||||
|
||||
/*
|
||||
BEGIN:VEVENT
|
||||
ATTENDEE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:cyrus@example.com
|
||||
ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
|
||||
DTSTAMP:20060206T001220Z
|
||||
DTSTART;TZID=US/Eastern:20060104T100000
|
||||
DURATION:PT1H
|
||||
LAST-MODIFIED:20060206T001330Z
|
||||
ORGANIZER:mailto:cyrus@example.com
|
||||
SEQUENCE:1
|
||||
STATUS:TENTATIVE
|
||||
SUMMARY:Event #3
|
||||
UID:DC6C50A017428C5216A2F1CD@example.com
|
||||
X-ABC-GUID:E1CX5Dr-0007ym-Hz@example.com
|
||||
END:VEVENT
|
||||
*/
|
||||
function ToString() {
|
||||
$participants = "";
|
||||
foreach( $this->participants AS $k => $p ) {
|
||||
$participants .= $p->ToString();
|
||||
}
|
||||
$fmt = <<<EOFMT
|
||||
BEGIN:VEVENT
|
||||
%sDTSTAMP:%s
|
||||
DTSTART;TXID=%s:%s".
|
||||
DURATION:%s
|
||||
LAST-MODIFIED:%s
|
||||
ORGANIZER:%s
|
||||
SEQUENCE:%d
|
||||
STATUS:%s
|
||||
SUMMARY:%s
|
||||
UID:%s
|
||||
X-ABC-GUID:%s
|
||||
END:VEVENT
|
||||
|
||||
EOFMT;
|
||||
$string = sprintf( $fmt, $participants, iCalendar::EpochTS(time()), "Pacific/Auckland", $this->start, $this->duration, $this->modified,
|
||||
$this->organizer, $this->sequence, $this->status, $this->summary, $this->uid, $this->guid );
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A Class for handling iCalendar data
|
||||
*
|
||||
* @package caldav
|
||||
*/
|
||||
class iCalendar {
|
||||
|
||||
function iCalendar() {
|
||||
}
|
||||
|
||||
function EpochTS($epoch) {
|
||||
$ts = date('Ymd\THis\Z', $epoch );
|
||||
return $ts;
|
||||
}
|
||||
|
||||
function vTimeZone( $tzname ) {
|
||||
switch ( $tzname ) {
|
||||
case 'Pacific/Auckland':
|
||||
default:
|
||||
$tzstring = <<<EOTZ
|
||||
BEGIN:VTIMEZONE
|
||||
LAST-MODIFIED:20040110T032845Z
|
||||
TZID:Pacific/Auckland
|
||||
BEGIN:STANDARD
|
||||
DTSTART:20000404T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
|
||||
TZNAME:NZST
|
||||
TZOFFSETFROM:+1300
|
||||
TZOFFSETTO:+1200
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:20001026T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
TZNAME:EST
|
||||
TZOFFSETFROM:+1200
|
||||
TZOFFSETTO:+1300
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
|
||||
EOTZ;
|
||||
}
|
||||
return $tzstring;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
4
testing/delete-meeting.txt
Normal file
4
testing/delete-meeting.txt
Normal file
@ -0,0 +1,4 @@
|
||||
DELETE /?andrewmcmillan.ics/20060509T195919Z.ics HTTP/1.1
|
||||
Host: mycaldav
|
||||
User-Agent: Evolution/1.6.1
|
||||
|
||||
7
testing/full-options-response.txt
Normal file
7
testing/full-options-response.txt
Normal file
@ -0,0 +1,7 @@
|
||||
HTTP/1.1 200 OK
|
||||
Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE
|
||||
Allow: PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL
|
||||
DAV: 1, 2, 3, access-control, calendar-access
|
||||
Date: Fri, 11 May 2006 09:32:12 GMT
|
||||
Content-Length: 0
|
||||
|
||||
87
testing/sample-tcp-stream.txt
Normal file
87
testing/sample-tcp-stream.txt
Normal file
@ -0,0 +1,87 @@
|
||||
OPTIONS /?andrewmcmillan.ics HTTP/1.1
|
||||
|
||||
Host: mycaldav
|
||||
|
||||
User-Agent: Evolution/1.6.1
|
||||
|
||||
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
Date: Tue, 09 May 2006 00:40:08 GMT
|
||||
|
||||
Server: Apache/2.0.55 (Debian) DAV/2 PHP/4.4.2-1+b1
|
||||
|
||||
X-Powered-By: PHP/4.4.2-1+b1
|
||||
|
||||
Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE, PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL
|
||||
|
||||
DAV: 1, 2, 3, access-control, calendar-access
|
||||
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
|
||||
|
||||
0
|
||||
|
||||
|
||||
|
||||
OPTIONS /?andrewmcmillan.ics HTTP/1.1
|
||||
|
||||
Host: mycaldav
|
||||
|
||||
User-Agent: Evolution/1.6.1
|
||||
|
||||
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
Date: Tue, 09 May 2006 00:40:08 GMT
|
||||
|
||||
Server: Apache/2.0.55 (Debian) DAV/2 PHP/4.4.2-1+b1
|
||||
|
||||
X-Powered-By: PHP/4.4.2-1+b1
|
||||
|
||||
Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE, PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL
|
||||
|
||||
DAV: 1, 2, 3, access-control, calendar-access
|
||||
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
|
||||
|
||||
0
|
||||
|
||||
|
||||
|
||||
REPORT /?andrewmcmillan.ics HTTP/1.1
|
||||
|
||||
Host: mycaldav
|
||||
|
||||
Content-Length: 301
|
||||
|
||||
Depth: 1
|
||||
|
||||
User-Agent: Evolution/1.6.1
|
||||
|
||||
Content-Type: text/xml
|
||||
|
||||
|
||||
|
||||
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:D="DAV:">
|
||||
<D:prop>
|
||||
<D:getetag/>
|
||||
</D:prop>
|
||||
<C:filter>
|
||||
<C:comp-filter name="VCALENDAR">
|
||||
<C:comp-filter name="VEVENT">
|
||||
<C:is-defined/>
|
||||
</C:comp-filter>
|
||||
</C:comp-filter>
|
||||
</C:filter>
|
||||
</C:calendar-query>
|
||||
|
||||
77
testing/schedule-meeting.txt
Normal file
77
testing/schedule-meeting.txt
Normal file
@ -0,0 +1,77 @@
|
||||
PUT /?andrewmcmillan.ics/20060509T200223Z.ics HTTP/1.1
|
||||
Host: mycaldav
|
||||
Content-Length: 1049
|
||||
If-None-Match: *
|
||||
User-Agent: Evolution/1.6.1
|
||||
Content-Type: text/calendar
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
CALSCALE:GREGORIAN
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:20060509T200218Z-7351-1000-1-9@ubu
|
||||
DTSTAMP:20060509T200218Z
|
||||
DTSTART;TZID=/softwarestudio.org/Olson_20011030_5/Pacific/Auckland:
|
||||
20060510T100000
|
||||
DTEND;TZID=/softwarestudio.org/Olson_20011030_5/Pacific/Auckland:
|
||||
20060510T110000
|
||||
SUMMARY:Alistair
|
||||
X-EVOLUTION-CALDAV-HREF:http:
|
||||
//mycaldav/?andrewmcmillan.ics/20060509T200223Z.ics
|
||||
BEGIN:VALARM
|
||||
X-EVOLUTION-ALARM-UID:20060509T200218Z-10149-1000-1-48@ubu
|
||||
ACTION:DISPLAY
|
||||
TRIGGER;VALUE=DURATION;RELATED=START:-PT15M
|
||||
DESCRIPTION:Alistair
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:/softwarestudio.org/Olson_20011030_5/Pacific/Auckland
|
||||
X-LIC-LOCATION:Pacific/Auckland
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+1300
|
||||
TZOFFSETTO:+1200
|
||||
TZNAME:NZST
|
||||
DTSTART:19700315T030000
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=3SU;BYMONTH=3
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+1200
|
||||
TZOFFSETTO:+1300
|
||||
TZNAME:NZDT
|
||||
DTSTART:19701004T020000
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=10
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
END:VCALENDAR
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
Date: Tue, 09 May 2006 20:02:23 GMT
|
||||
Server: Apache/2.0.55 (Debian) DAV/2 PHP/4.4.2-1+b1
|
||||
X-Powered-By: PHP/4.4.2-1+b1
|
||||
Transfer-Encoding: chunked
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
0
|
||||
|
||||
REPORT /?andrewmcmillan.ics HTTP/1.1
|
||||
Host: mycaldav
|
||||
Content-Length: 301
|
||||
Depth: 1
|
||||
User-Agent: Evolution/1.6.1
|
||||
Content-Type: text/xml
|
||||
|
||||
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:D="DAV:">
|
||||
<D:prop>
|
||||
<D:getetag/>
|
||||
</D:prop>
|
||||
<C:filter>
|
||||
<C:comp-filter name="VCALENDAR">
|
||||
<C:comp-filter name="VEVENT">
|
||||
<C:is-defined/>
|
||||
</C:comp-filter>
|
||||
</C:comp-filter>
|
||||
</C:filter>
|
||||
</C:calendar-query>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user