We don't need to test for the PostgreSQL non-PDO drivers now.
[davical.git] / inc / caldav-BIND.php
blob429de2aee9cb5e18d01ccb1f31133bde655dee93
1 <?php
2 /**
3 * CalDAV Server - handle BIND method
5 * @package davical
6 * @subpackage caldav
7 * @author Andrew McMillan <andrew@mcmillan.net.nz>
8 * @copyright Morphoss Ltd - http://www.morphoss.com/
9 * @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later
11 dbg_error_log('BIND', 'method handler');
12 require_once('AwlQuery.php');
14 $request->NeedPrivilege('DAV::bind');
16 if ( ! $request->IsCollection() ) {
17 $request->PreconditionFailed(403,'DAV::bind-into-collection',translate('The BIND Request-URI MUST identify a collection.'));
19 $parent_container = $request->path;
20 if ( preg_match( '{[^/]$}', $parent_container ) ) $parent_container .= '/';
22 require_once('DAVResource.php');
23 $parent = new DAVResource( $parent_container );
24 if ( ! $parent->Exists() || $parent->IsSchedulingCollection() ) {
25 $request->PreconditionFailed(403, 'DAV::method-not-allowed',translate('The BIND method is not allowed at that location.') );
28 require_once('XMLDocument.php');
29 $reply = new XMLDocument(array( 'DAV:' => '' ));
31 $position = 0;
32 $xmltree = BuildXMLTree( $request->xml_tags, $position);
34 $segment = $xmltree->GetElements('DAV::segment');
35 $segment = $segment[0]->GetContent();
37 if ( preg_match( '{[/\\\\]}', $segment ) ) {
38 $request->PreconditionFailed(403, 'DAV::name-allowed',translate('That destination name contains invalid characters.') );
41 $href = $xmltree->GetElements('DAV::href');
42 $href = $href[0]->GetContent();
44 $destination_path = $parent_container . $segment .'/';
45 $destination = new DAVResource( $destination_path );
46 if ( $destination->Exists() ) {
47 $request->PreconditionFailed(403,'DAV::can-overwrite',translate('A resource already exists at the destination.'));
50 if ( preg_match ( '{^https?://[A-Za-z][^/]*/.+$}', $href ) ) {
51 require_once('external-fetch.php');
52 $qry = new AwlQuery( );
53 $qry->QDo('SELECT collection_id FROM collection WHERE dav_name = :dav_name ', array( ':dav_name' => '/.external/'. md5($href) ));
54 if ( $qry->rows() == 1 && ($row = $qry->Fetch()) ) {
55 $dav_id = $row->dav_id;
57 else {
58 create_external ( '/.external/'. md5($href) ,true,false );
59 $qry->QDo('SELECT collection_id FROM collection WHERE dav_name = :dav_name ', array( ':dav_name' => '/.external/'. md5($href) ));
60 if ( $qry->rows() != 1 || !($row = $qry->Fetch()) )
61 $request->DoResponse(500,translate('Database Error'));
62 $dav_id = $row->collection_id;
65 $sql = 'INSERT INTO dav_binding ( bound_source_id, access_ticket_id, dav_owner_id, parent_container, dav_name, dav_displayname, external_url, type )
66 VALUES( :target_id, :ticket_id, :session_principal, :parent_container, :dav_name, :displayname, :external_url, :external_type )';
67 $params = array(
68 ':target_id' => $dav_id,
69 ':ticket_id' => null,
70 ':parent_container' => $parent->dav_name(),
71 ':session_principal' => $session->principal_id,
72 ':dav_name' => $destination_path,
73 ':displayname' => $segment,
74 ':external_url' => $href,
75 ':external_type' => 'calendar'
77 $qry = new AwlQuery( $sql, $params );
78 if ( $qry->Exec('BIND',__LINE__,__FILE__) ) {
79 $qry = new AwlQuery( 'SELECT bind_id from dav_binding where dav_name = :dav_name', array( ':dav_name' => $destination_path ) );
80 if ( ! $qry->Exec('BIND',__LINE__,__FILE__) || $qry->rows() != 1 || !($row = $qry->Fetch()) )
81 $request->DoResponse(500,translate('Database Error'));
82 fetch_external ( $row->bind_id, '' );
83 $request->DoResponse(201);
85 else {
86 $request->DoResponse(500,translate('Database Error'));
89 else {
90 $source = new DAVResource( $href );
91 if ( !$source->Exists() ) {
92 $request->PreconditionFailed(403,'DAV::bind-source-exists',translate('The BIND Request MUST identify an existing resource.'));
95 if ( $source->IsPrincipal() || !$source->IsCollection() ) {
96 $request->PreconditionFailed(403,'DAV::binding-allowed',translate('DAViCal only allows BIND requests for collections at present.'));
100 bind_id INT8 DEFAULT nextval('dav_id_seq') PRIMARY KEY,
101 bound_source_id INT8 REFERENCES collection(collection_id) ON UPDATE CASCADE ON DELETE CASCADE,
102 access_ticket_id TEXT REFERENCES access_ticket(ticket_id) ON UPDATE CASCADE ON DELETE SET NULL,
103 parent_container TEXT NOT NULL,
104 dav_name TEXT UNIQUE NOT NULL,
105 dav_displayname TEXT,
106 external_url TEXT,
107 type TEXT
110 $sql = 'INSERT INTO dav_binding ( bound_source_id, access_ticket_id, dav_owner_id, parent_container, dav_name, dav_displayname )
111 VALUES( :target_id, :ticket_id, :session_principal, :parent_container, :dav_name, :displayname )';
112 $params = array(
113 ':target_id' => $source->GetProperty('collection_id'),
114 ':ticket_id' => (isset($request->ticket) ? $request->ticket->id() : null),
115 ':parent_container' => $parent->dav_name(),
116 ':session_principal' => $session->principal_id,
117 ':dav_name' => $destination_path,
118 ':displayname' => $source->GetProperty('displayname')
120 $qry = new AwlQuery( $sql, $params );
121 if ( $qry->Exec('BIND',__LINE__,__FILE__) ) {
122 header('Location: '. ConstructURL($destination_path) );
124 // Uncache anything to do with the target
125 $cache = getCacheInstance();
126 $cache_ns = 'collection-'.$destination_path;
127 $cache->delete( $cache_ns, null );
129 $request->DoResponse(201);
131 else {
132 $request->DoResponse(500,translate('Database Error'));