DAViCal
caldav-REPORT-principal.php
1 <?php
2 
3 if ( $request->depth > 0 ) {
4  $request->DoResponse( 400, 'The principal-property-search REPORT is only defined for Depth "0".' );
5 }
6 
10 $searches = $xmltree->GetPath('/DAV::principal-property-search/DAV::property-search');
11 dbg_log_array( "principal", "SEARCH", $searches, true );
12 
13 $clause_joiner = " AND ";
14 $CS_search_test = $xmltree->GetAttribute('test');
15 if ( isset($CS_search_test) && $CS_search_test == 'anyof' ) {
16  $clause_joiner = " OR ";
17 }
18 
19 $params = array();
20 $where = "";
21 foreach( $searches AS $k => $search ) {
22  $qry_props = $search->GetPath('/DAV::property-search/DAV::prop/*'); // There may be many
23  $match = $search->GetPath('/DAV::property-search/DAV::match'); // There may only be one
24  if ( empty($match) or !is_object($match[0]) ) {
25  dbg_error_log("ERROR", "Unable to extract a match clause from '%s'", $search->RenderContent() );
26  continue;
27  }
28  dbg_log_array( "principal", "MATCH", $match, true );
29  $match = $match[0]->GetContent();
30  $subwhere = "";
31  foreach( $qry_props AS $k1 => $v1 ) {
32  if ( $subwhere != "" ) $subwhere .= " OR ";
33  switch( $v1->GetNSTag() ) {
34  case 'DAV::displayname':
35  $subwhere .= ' displayname ILIKE :displayname_match ';
36  $params[':displayname_match'] = '%'.$match.'%';
37  break;
38 
39  case 'urn:ietf:params:xml:ns:caldav:calendar-user-address-set':
40  $match = preg_replace('{^.*/caldav.php/([^/]+)(/.*)?$}', '\\1', $match);
41  $match = preg_replace('{^mailto:}', '', $match);
42  $subwhere .= ' (email ILIKE :user_address_match OR username ILIKE :user_address_match) ';
43  $params[':user_address_match'] = '%'.$match.'%';
44  break;
45 
46  case 'urn:ietf:params:xml:ns:caldav:calendar-home-set':
47  $match = preg_replace('{^.*/caldav.php}', '', $match);
48  $subwhere .= ' dav_name LIKE :calendar_home_match ';
49  $params[':calendar_home_match'] = $match.'%';
50  break;
51 
52  default:
57  dbg_error_log("principal", "Unhandled tag '%s' to match '%s'\n", $v1->GetNSTag(), $match );
58  }
59  }
60  if ( $subwhere != "" ) {
61  $where .= sprintf( "%s(%s)", ($where == "" ? "" : $clause_joiner), $subwhere );
62  }
63 }
64 if ( $where != "" ) $where = "WHERE $where";
65 $sql = "SELECT * FROM dav_principal $where ORDER BY principal_id LIMIT 100";
66 $qry = new AwlQuery($sql, $params);
67 
68 
69 $get_props = $xmltree->GetPath('/DAV::principal-property-search/DAV::prop/*');
70 $properties = array();
71 foreach( $get_props AS $k1 => $v1 ) {
72  $properties[] = $v1->GetNSTag();
73 }
74 
75 $responses = array();
76 if ( $qry->Exec("REPORT",__LINE__,__FILE__) && $qry->rows() > 0 ) {
77  while( $row = $qry->Fetch() ) {
78  $principal = new DAVResource($row);
79  $responses[] = $principal->RenderAsXML( $properties, $reply );
80  }
81 }
82 
83 $multistatus = new XMLElement( "multistatus", $responses, $reply->GetXmlNsArray() );
84 
85 $request->XMLResponse( 207, $multistatus );