From a5e6e9113ca305ec26c44672fe8482c52e5d595d Mon Sep 17 00:00:00 2001 From: Andrew McMillan Date: Wed, 19 May 2010 23:53:36 +1200 Subject: [PATCH] Handle VCARD on PUT. --- inc/caldav-PUT-vcard.php | 18 ++++-- inc/vcard.php | 129 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 135 insertions(+), 12 deletions(-) diff --git a/inc/caldav-PUT-vcard.php b/inc/caldav-PUT-vcard.php index 551fd4f2..ae69ff6c 100644 --- a/inc/caldav-PUT-vcard.php +++ b/inc/caldav-PUT-vcard.php @@ -66,20 +66,30 @@ $params = array( ); if ( $dest->Exists() ) { $sql = 'UPDATE caldav_data SET caldav_data=:dav_data, dav_etag=:etag, logged_user=:session_user, - modified=current_timestamp WHERE user_no=:user_no AND dav_name=:dav_name'; + modified=current_timestamp, user_no=:user_no WHERE dav_name=:dav_name'; $response_code = 200; + $qry->QDo( $sql, $params ); + + $qry->QDo("SELECT dav_id FROM caldav_data WHERE dav_name = :dav_name ", array(':dav_name' => $params[':dav_name']) ); } else { $sql = 'INSERT INTO caldav_data ( user_no, dav_name, dav_etag, caldav_data, logged_user, created, modified, collection_id ) VALUES( :user_no, :dav_name, :etag, :dav_data, :session_user, current_timestamp, current_timestamp, :collection_id )'; $params[':collection_id'] = $collection_id; $response_code = 201; + $qry->QDo( $sql, $params ); + + $qry->QDo("SELECT currval('dav_id_seq') AS dav_id" ); } -$qry->QDo( $sql, $params ); +$row = $qry->Fetch(); + +require_once('vcard.php'); + +$vcard = new vCard( $request->raw_post ); +$vcard->Write( $row->dav_id, $dest->Exists() ); $qry->QDo("SELECT write_sync_change( $collection_id, $response_code, :dav_name)", array(':dav_name' => $dest->bound_from() ) ); -$qry = new AwlQuery('COMMIT'); -if ( !$qry->Exec('move') ) rollback(500); +if ( !$qry->QDo('COMMIT') ) rollback(500); $request->DoResponse( $response_code ); diff --git a/inc/vcard.php b/inc/vcard.php index 0e922f0a..8910a002 100644 --- a/inc/vcard.php +++ b/inc/vcard.php @@ -3,13 +3,12 @@ * Extend the vComponent to specifically handle VCARD resources */ +require_once('AwlQuery.php'); require_once('vComponent.php'); class VCard extends vComponent { /** - * Into tables like this: - * CREATE TABLE addressbook_resource ( dav_id INT8 NOT NULL REFERENCES caldav_data(dav_id) ON UPDATE CASCADE ON DELETE CASCADE PRIMARY KEY, version TEXT, @@ -19,35 +18,149 @@ CREATE TABLE addressbook_resource ( n TEXT, -- Name Surname;First names note TEXT, org TEXT, - url TEXT + url TEXT, + fburl TEXT, + caluri TEXT ); + */ + function Write( $dav_id, $exists = true ) { + $qry = new AwlQuery(); + // Only run a local transaction if we're not in one already. + $in_transaction = ($qry->TransactionState() == 1); + if ( ! $in_transaction ) $qry->Begin(); + + if ( $exists ) { + $sql = 'UPDATE addressbook_resource SET version=:version, uid=:uid, nickname=:nickname, fn=:fn, n=:name, +note=:note, org=:org, url=:url, fburl=:fburl, caladruri=:caladruri, caluri=:caluri WHERE dav_id=:dav_id'; + } + else { + $sql = 'INSERT INTO addressbook_resource ( dav_id, version, uid, nickname, fn, n, note, org, url, fburl, caladruri, caluri ) +VALUES( :dav_id, :version, :uid, :nickname, :fn, :name, :note, :org, :url, :fburl, :caladruri, :caluri )'; + } + $params = array( ':dav_id' => $dav_id ); + + /** + * @TODO: Most of these allow duplicates, so we should save the preferred one in the user's language in such cases. + */ + $params[':version'] = $this->GetPValue('VERSION'); + $params[':uid'] = $this->GetPValue('UID'); + $params[':nickname'] = $this->GetPValue('NICKNAME'); + $params[':fn'] = $this->GetPValue('FN'); + $params[':name'] = $this->GetPValue('N'); + $params[':note'] = $this->GetPValue('NOTE'); + $params[':org'] = $this->GetPValue('ORG'); + $params[':url'] = $this->GetPValue('URL'); + $params[':fburl'] = $this->GetPValue('FBURL'); + $params[':caladruri'] = $this->GetPValue('CALADRURI'); + $params[':caluri'] = $this->GetPValue('CALURI'); + + $qry->QDo( $sql, $params ); + + $this->WriteAddresses($dav_id); + $this->WritePhones($dav_id); + $this->WriteEmails($dav_id); + + if ( ! $in_transaction ) $qry->Commit(); + } + + + /** CREATE TABLE addressbook_address_adr ( dav_id INT8 NOT NULL REFERENCES caldav_data(dav_id) ON UPDATE CASCADE ON DELETE CASCADE, type TEXT, - adr TEXT, + box_no TEXT, + unit_no TEXT, + street_address TEXT, + locality TEXT, + region TEXT, + postcode TEXT, + country TEXT, property TEXT -- The full text of the property ); + */ + function WriteAddresses( $dav_id ) { + $addresses = $this->GetProperties('ADR'); + $qry = new AwlQuery(); + // Only run a local transaction if we're not in one already. + $in_transaction = ($qry->TransactionState() == 1); + if ( ! $in_transaction ) $qry->Begin(); + + $params = array( ':dav_id' => $dav_id ); + $qry->QDo('DELETE FROM addressbook_address_adr WHERE dav_id = :dav_id', $params ); + foreach( $addresses AS $adr ) { + $params[':type'] = $adr->GetParameterValue('TYPE'); + $address = explode(';',$adr->Value()); + $params[':box_no'] = $address[0]; + $params[':unit_no'] = $address[1]; + $params[':street_address'] = $address[2]; + $params[':locality'] = $address[3]; + $params[':region'] = $address[4]; + $params[':postcode'] = $address[5]; + $params[':country'] = $address[6]; + $params[':property'] = $adr->Render(); + $qry->QDo( 'INSERT INTO addressbook_address_adr (dav_id, type, box_no, unit_no, street_address, locality, region, postcode, country, property) +VALUES( :dav_id, :type, :box_no, :unit_no, :street_address, :locality, :region, :postcode, :country, :property)', $params ); + } + if ( ! $in_transaction ) $qry->Commit(); + } + + + /** CREATE TABLE addressbook_address_tel ( dav_id INT8 NOT NULL REFERENCES caldav_data(dav_id) ON UPDATE CASCADE ON DELETE CASCADE, type TEXT, tel TEXT, property TEXT -- The full text of the property ); + */ + function WritePhones( $dav_id ) { + $telephones = $this->GetProperties('TEL'); + $qry = new AwlQuery(); + // Only run a local transaction if we're not in one already. + $in_transaction = ($qry->TransactionState() == 1); + if ( ! $in_transaction ) $qry->Begin(); + + $params = array( ':dav_id' => $dav_id ); + $qry->QDo('DELETE FROM addressbook_address_tel WHERE dav_id = :dav_id', $params ); + foreach( $telephones AS $tel ) { + $params[':type'] = $tel->GetParameterValue('TYPE'); + if ( ! isset($params[':type']) ) $params[':type'] = 'voice'; + $params[':tel'] = $tel->Value(); + $params[':property'] = $tel->Render(); + $qry->QDo( 'INSERT INTO addressbook_address_tel (dav_id, type, tel, property) VALUES( :dav_id, :type, :tel, :property)', $params ); + } + if ( ! $in_transaction ) $qry->Commit(); + } + + + /** CREATE TABLE addressbook_address_email ( dav_id INT8 NOT NULL REFERENCES caldav_data(dav_id) ON UPDATE CASCADE ON DELETE CASCADE, type TEXT, email TEXT, property TEXT -- The full text of the property ); - * */ - function Write( $dav_name ) { - $addresses = $this->GetProperties('ADR'); - $telephones = $this->GetProperties('TEL'); + function WriteEmails( $dav_id ) { $emails = $this->GetProperties('EMAIL'); + $qry = new AwlQuery(); + + // Only run a local transaction if we're not in one already. + $in_transaction = ($qry->TransactionState() == 1); + if ( ! $in_transaction ) $qry->Begin(); + + $params = array( ':dav_id' => $dav_id ); + $qry->QDo('DELETE FROM addressbook_address_email WHERE dav_id = :dav_id', $params ); + foreach( $emails AS $email ) { + $params[':type'] = $email->GetParameterValue('TYPE'); + $params[':email'] = $email->Value(); + $params[':property'] = $email->Render(); + $qry->QDo( 'INSERT INTO addressbook_address_email (dav_id, type, email, property) VALUES( :dav_id, :type, :email, :property)', $params ); + } + if ( ! $in_transaction ) $qry->Commit(); } } \ No newline at end of file