More fixes to CalDAV Scheduling
[davical.git] / inc / caldav-REPORT-expand-property.php
blobb72f23b5911929ac74396f7c249ec9810abc576e
1 <?php
3 /**
4 * Given a <response><href>...</href><propstat><prop><someprop/></prop><status>HTTP/1.1 200 OK</status></propstat>...</response>
5 * pull out the content of <someprop>content</someprop> and check to see if it has any href elements. If it *does* then
6 * recurse into them, looking for the next deeper nesting of properties.
7 */
8 function get_href_containers( &$multistatus_response ) {
9 $propstat_set = $multistatus_response->GetElements('propstat');
10 $propstat_200 = null;
11 foreach( $propstat_set AS $k => $v ) {
12 $status = $v->GetElements('status');
13 if ( preg_match( '{^HTTP/\S+\s+200}', $status[0]->GetContent() ) ) {
14 $propstat_200 = $v;
15 break;
18 if ( isset($propstat_200) ) {
19 $props = $propstat_200->GetElements('prop');
20 $properties = array();
21 foreach( $props AS $k => $p ) {
22 $properties = array_merge($properties,$p->GetElements());
24 $href_containers = array();
25 foreach( $properties AS $k => $property ) {
26 if ( !is_object($property) ) continue;
27 // dbg_error_log('REPORT',' get_href_containers: Checking property "%s" for hrefs.', $property->GetNSTag() );
28 $hrefs = $property->GetElements('href');
29 if ( count($hrefs) > 0 ) {
30 $href_containers[] = $property;
33 if ( count($href_containers) > 0 ) {
34 return $href_containers;
37 return null;
41 /**
42 * Expand the properties, recursing only once
44 function expand_properties( $urls, $ptree, &$reply, $recurse_again = true ) {
45 if ( !is_array($urls) ) $urls = array($urls);
46 if ( !is_array($ptree) ) $ptree = array($ptree);
48 $responses = array();
49 foreach( $urls AS $m => $url ) {
50 $resource = new DAVResource($url);
51 $props = array();
52 $subtrees = array();
53 foreach( $ptree AS $n => $property ) {
54 if ( ! is_object($property) ) continue;
55 $pname = $property->GetAttribute('name');
56 $pns = $property->GetAttribute('namespace');
57 if ( !isset($pns) || $pns == '' ) $pns = 'DAV:'; // Not sure if this is the correct way to default this.
58 $pname = $pns .':'. $pname;
59 $props[] = $pname;
60 $subtrees[$pname] = $property->GetElements();
62 $part_response = $resource->RenderAsXML( $props, $reply );
63 if ( isset($part_response) ) {
64 if ( $recurse_again ) {
65 $href_containers = get_href_containers($part_response);
66 if ( isset($href_containers) ) {
67 foreach( $href_containers AS $h => $property ) {
68 $hrefs = $property->GetElements();
69 $pname = $property->GetTag();
70 $pns = $property->GetAttribute('xmlns');
71 if ( !isset($pns) || $pns == '' ) $pns = 'DAV:'; // Not sure if this is the correct way to default this.
72 $pname = $pns .':'. $pname;
73 $paths = array();
74 foreach( $hrefs AS $k => $v ) {
75 $content = $v->GetContent();
76 $paths[] = $content;
78 // dbg_error_log('REPORT',' Found property "%s" contains hrefs "%s"', $pname, implode(', ',$paths) );
79 $property->SetContent( expand_properties($paths, $subtrees[$pname], $reply, false) );
82 // else {
83 // dbg_error_log('REPORT',' No href containers in response to "%s"', implode(', ', $props ) );
84 // }
86 $responses[] = $part_response;
90 return $responses;
94 /**
95 * Build the array of properties to include in the report output
97 $property_tree = $xmltree->GetPath('/DAV::expand-property/DAV::property');
99 $multistatus = new XMLElement( "multistatus", expand_properties( $request->path, $property_tree, $reply), $reply->GetXmlNsArray() );
101 $request->XMLResponse( 207, $multistatus );