CalDAVは、WebDAV上に実装さえているので、WebDAVの機能を含んでいる必要があるらしい。また、WebDAVは、HTTP上に実装されるべきものなので、当然それも含む。
というころなので、CalDAVは、HTTPの機能がわかっていれば、大体実装できそうである。RFCによると、CalDAVで使用するコマンドは、大体次のようになる。
OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE
PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL
この中で、今回実装しようと思っている、スケジュールの参照、登録、修正、削除に関するものは、REPORT(参照)、PUT(登録、編集)、DELETE(削除)ということがわかった。
他の命令は、サーバーが決まっていないと色々やることがあるが、今回のCalDAVサーバーは、Chandlerということにするとこれで十分だろう。あとは、個人認証とHTTPの基本的な動作とXMLのパージング、iCalendar形式の対応部分をを実装すればよいことになる。
さて次に、CalDAVクライアントを実装する言語なのだが、GUIの実装は面倒なので、ブラウザを利用することにする。ちょうど以前グループウェアを実装したものがあるので、ほとんどは、これを流用する。
てなわけで、PHPで実装することに決定。
PHPは、サーバーでCGI風に使うことがほとんどだが、今回は、CalDAVクライアントつまりHTTPクライアントとして実装する。PHPには、cURLやHTTPの拡張モジュールがあるので、これらを利用することにした。
また、XMLのパージングなのだが、PHPのDOMを使うほうがよい気がするが、とりあえずフリーで公開されているxml2array.phpというライブラリを使わせていただく。
とりあえずツールの準備はできたので、実装開始。
まずは、個人認証。
個人認証は、大したことはない。http_request関数の option変数で
option["httpauth"] = $username.":".$password
option["httpauthtype"] = HTTP_AUTH_BASIC または HTTP_AUTH_DIGEST
ChandlerServer のときはBASIC認証なので、HTTP_AUTH_BASIC で大丈夫。
次に、CalDAVにおける基本的なリクエストは、option変数のheaderで、
"Content-Type" => "text/xml"
"User-Agent" => "エージェント名"
"Accept" => "text/xml"
"Connection" => "keep-alive"
"Depth" => "1"
"Keep-Alive" => "300"
を設定する。さらに、新規のイベント作成時は、
"Content-Type" => "text/calendar
"If-None-Match" => "*"
イベントの編集、削除時は、
"Content-Type" => "text/calendar
"If-Match" => 編集、削除するイベントのEtag
とすればよい。
あとは、それぞれのアクションに応じて、XML 形式のデータを一緒に送ってあげれば、サーバーから、それに応じて XML形式のレスポンスがあるので、解析して、出力にまわせば完成です。
参考までに、期間を指定して、イベントを取得する場合には、下記のようにすればよい。
function RequestEvent($start=null, $end=null){
$this->body =<<<_XML
<?xml version="1.0" encoding="UTF-8">
<calendar-query xmlns="urn:ietf:params:xml:ns:caldav" d="DAV:">
<D:prop>
<D:getetag/>
</d:prop>
<filter>
<comp-filter name="VCALENDAR">
<comp-filter name="VEVENT">
_XML;
if($start){
if($end){
$this->body .= "<time-range end=\"".$end."\" start=\"".$start."\">";
}else{
$this->body .= "<time-range end=\"".$end."\" start=\"".$start."\">";
}
}
$this->body .=<<<_XML
</COMP-FILTER>
</filter>
</CALENDAR-QUERY>
_XML;
}
これからもわかるように、