Changes to the way XML is created, and (to a lesser extent) parsed.

This commit is contained in:
Andrew McMillan 2012-05-03 19:11:28 +12:00
parent 33a84595a0
commit 155c70bba5
7 changed files with 98 additions and 102 deletions

View File

@ -452,43 +452,43 @@ class DAVPrincipal extends Principal
dbg_error_log('principal',': RenderAsXML: Principal Property "%s"', $tag );
switch( $tag ) {
case 'DAV::getcontenttype':
$prop->NewElement('getcontenttype', 'httpd/unix-directory' );
$reply->DAVElement( $prop, 'getcontenttype', 'httpd/unix-directory' );
break;
case 'DAV::resourcetype':
$prop->NewElement('resourcetype', array( new XMLElement('principal'), new XMLElement('collection')) );
$reply->DAVElement( $prop, 'resourcetype', array( new XMLElement('principal'), new XMLElement('collection')) );
break;
case 'DAV::displayname':
$prop->NewElement('displayname', $this->fullname );
$reply->DAVElement( $prop, 'displayname', $this->fullname );
break;
case 'DAV::principal-URL':
$prop->NewElement('principal-URL', $reply->href($this->url()) );
$reply->DAVElement( $prop, 'principal-URL', $reply->href($this->url()) );
break;
case 'DAV::getlastmodified':
$prop->NewElement('getlastmodified', ISODateToHTTPDate($this->modified) );
$reply->DAVElement( $prop, 'getlastmodified', ISODateToHTTPDate($this->modified) );
break;
case 'DAV::creationdate':
$prop->NewElement('creationdate', DateToISODate($this->created) );
$reply->DAVElement( $prop, 'creationdate', DateToISODate($this->created) );
break;
case 'DAV::getcontentlanguage':
/** Use the principal's locale by preference, otherwise system default */
$locale = (isset($c->current_locale) ? $c->current_locale : '');
if ( isset($this->locale) && $this->locale != '' ) $locale = $this->locale;
$prop->NewElement('getcontentlanguage', $locale );
$reply->DAVElement( $prop, 'getcontentlanguage', $locale );
break;
case 'DAV::group-member-set':
if ( ! $this->_is_group ) return false;
$prop->NewElement('group-member-set', $reply->href($this->group_member_set) );
$reply->DAVElement( $prop, 'group-member-set', $reply->href($this->group_member_set) );
break;
case 'DAV::group-membership':
$prop->NewElement('group-membership', $reply->href($this->GroupMembership()) );
$reply->DAVElement( $prop, 'group-membership', $reply->href($this->GroupMembership()) );
break;
case 'urn:ietf:params:xml:ns:caldav:schedule-inbox-URL':
@ -518,11 +518,11 @@ class DAVPrincipal extends Principal
break;
case 'urn:ietf:params:xml:ns:carddav:addressbook-home-set':
$reply->NSElement($prop, $tag, $reply->href( $this->addressbook_home_set() ) );
$reply->CardDAVElement($prop, $tag, $reply->href( $this->addressbook_home_set() ) );
break;
case 'urn:ietf:params:xml:ns:caldav:calendar-home-set':
$reply->NSElement($prop, $tag, $reply->href( $this->calendar_home_set() ) );
$reply->CalDAVElement($prop, $tag, $reply->href( $this->calendar_home_set() ) );
break;
case 'urn:ietf:params:xml:ns:caldav:calendar-free-busy-set':
@ -540,7 +540,7 @@ class DAVPrincipal extends Principal
// Empty tag responses.
case 'DAV::alternate-URI-set':
$prop->NewElement( $reply->Tag($tag));
$reply->DAVElement( $prop, $reply->Tag($tag));
break;
case 'SOME-DENIED-PROPERTY': /** @todo indicating the style for future expansion */

View File

@ -1488,7 +1488,7 @@ EOQRY;
global $c, $session, $request;
// dbg_error_log( 'DAVResource', 'Processing "%s" on "%s".', $tag, $this->dav_name );
if ( $reply === null ) $reply = $GLOBALS['reply'];
switch( $tag ) {
@ -1799,13 +1799,13 @@ EOQRY;
dbg_error_log('DAVResource',':GetPropStat: propstat for href "%s"', $this->dav_name );
$prop = new XMLElement('prop');
$prop = new XMLElement('prop', null, null, 'DAV:');
$denied = array();
$not_found = array();
foreach( $properties AS $k => $tag ) {
if ( is_object($tag) ) {
dbg_error_log( 'DAVResource', ':GetPropStat: "$properties" should be an array of text. Assuming this object is an XMLElement!.' );
$tag = $tag->GetTag();
$tag = $tag->GetNSTag();
}
$found = $this->ResourceProperty($tag, $prop, $reply, $denied );
if ( !$found ) {
@ -1814,31 +1814,31 @@ EOQRY;
}
if ( ! $found ) {
// dbg_error_log( 'DAVResource', 'Request for unsupported property "%s" of resource "%s".', $tag, $this->dav_name );
$not_found[] = $reply->Tag($tag);
$not_found[] = $tag;
}
}
if ( $props_only ) return $prop;
$status = new XMLElement('status', 'HTTP/1.1 200 OK' );
$status = new XMLElement('status', 'HTTP/1.1 200 OK', null, 'DAV:' );
$elements = array( new XMLElement( 'propstat', array($prop,$status) ) );
$elements = array( new XMLElement( 'propstat', array($prop,$status), null, 'DAV:' ) );
if ( count($denied) > 0 ) {
$status = new XMLElement('status', 'HTTP/1.1 403 Forbidden' );
$noprop = new XMLElement('prop');
$status = new XMLElement('status', 'HTTP/1.1 403 Forbidden', null, 'DAV:' );
$noprop = new XMLElement('prop', null, null, 'DAV:');
foreach( $denied AS $k => $v ) {
$reply->NSElement($noprop, $v);
}
$elements[] = new XMLElement( 'propstat', array( $noprop, $status) );
$elements[] = new XMLElement( 'propstat', array( $noprop, $status), null, 'DAV:' );
}
if ( !(isset($request->brief_response) && $request->brief_response) && count($not_found) > 0 ) {
$status = new XMLElement('status', 'HTTP/1.1 404 Not Found' );
$noprop = new XMLElement('prop');
if ( !$request->PreferMinimal() && count($not_found) > 0 ) {
$status = new XMLElement('status', 'HTTP/1.1 404 Not Found', null, 'DAV:' );
$noprop = new XMLElement('prop', null, null, 'DAV:');
foreach( $not_found AS $k => $v ) {
$noprop->NewElement($v);
$reply->NSElement($noprop,$v);
}
$elements[] = new XMLElement( 'propstat', array( $noprop, $status) );
$elements[] = new XMLElement( 'propstat', array( $noprop, $status), null, 'DAV:' );
}
return $elements;
}
@ -1869,7 +1869,7 @@ EOQRY;
array_unshift( $elements, $reply->href(ConstructURL($dav_name)));
$response = new XMLElement( 'response', $elements );
$response = new XMLElement( 'response', $elements, null, 'DAV:' );
return $response;
}

View File

@ -26,7 +26,7 @@ $xmltree = BuildXMLTree( $request->xml_tags, $position);
// echo $xmltree->Render();
if ( $xmltree->GetTag() != "DAV::propertyupdate" ) {
if ( $xmltree->GetNSTag() != "DAV::propertyupdate" ) {
$request->PreconditionFailed( 403, 'DAV::propertyupdate', 'XML request did not contain a <propertyupdate> tag' );
}
@ -45,6 +45,7 @@ $rmprops = $xmltree->GetPath("/DAV::propertyupdate/DAV::remove/DAV::prop/*");
$failure = array();
$success = array();
$reply = new XMLDocument( array( 'DAV:' => '') );
/**
* Small utility function to add propstat for one failure
@ -54,11 +55,10 @@ $success = array();
* @param unknown_type $error_tag
*/
function add_failure( $type, $tag, $status, $description=null, $error_tag = null) {
global $failure;
$propstat = array(
new XMLElement( 'prop', new XMLElement($tag)),
new XMLElement( 'status', $status )
);
global $failure, $reply;
$prop = new XMLElement('prop');
$reply->NSElement($prop, $tag);
$propstat = array($prop,new XMLElement( 'status', $status ));
if ( isset($description))
$propstat[] = new XMLElement( 'responsedescription', $description );
@ -78,7 +78,7 @@ $qry = new AwlQuery();
$qry->Begin();
$setcalendar = count($xmltree->GetPath('/DAV::propertyupdate/DAV::set/DAV::prop/DAV::resourcetype/urn:ietf:params:xml:ns:caldav:calendar'));
foreach( $setprops AS $k => $setting ) {
$tag = $setting->GetTag();
$tag = $setting->GetNSTag();
$content = $setting->RenderContent();
switch( $tag ) {
@ -134,7 +134,7 @@ foreach( $setprops AS $k => $setting ) {
case 'urn:ietf:params:xml:ns:caldav:schedule-calendar-transp':
if ( $dav_resource->IsCollection() && ( $dav_resource->IsCalendar() || $setcalendar ) && !$dav_resource->IsBinding() ) {
$transparency = $setting->GetPath('urn:ietf:params:xml:ns:caldav:schedule-calendar-transp/*');
$transparency = preg_replace( '{^.*:}', '', $transparency[0]->GetTag());
$transparency = preg_replace( '{^.*:}', '', $transparency[0]->GetNSTag());
$qry->QDo('UPDATE collection SET schedule_transp = :transparency WHERE dav_name = :dav_name',
array( ':dav_name' => $dav_resource->dav_name(), ':transparency' => $transparency ) );
$success[$tag] = 1;
@ -206,7 +206,7 @@ foreach( $setprops AS $k => $setting ) {
}
foreach( $rmprops AS $k => $setting ) {
$tag = $setting->GetTag();
$tag = $setting->GetNSTag();
$content = $setting->RenderContent();
switch( $tag ) {
@ -266,20 +266,20 @@ if ( count($failure) > 0 ) {
$qry->Rollback();
foreach( $success AS $tag => $v ) {
// Unfortunately although these succeeded, we failed overall, so they didn't happen...
$failure[] = new XMLElement( 'propstat', array(
new XMLElement( 'prop', new XMLElement($tag)),
new XMLElement( 'status', 'HTTP/1.1 424 Failed Dependency' ),
));
}
$url = ConstructURL($request->path);
array_unshift( $failure, new XMLElement('href', $url ) );
$failure[] = new XMLElement('responsedescription', translate("Some properties were not able to be changed.") );
$multistatus = new XMLElement( "multistatus", new XMLElement( 'response', $failure ), array('xmlns'=>'DAV:') );
$request->DoResponse( 207, $multistatus->Render(0,'<?xml version="1.0" encoding="utf-8" ?>'), 'text/xml; charset="utf-8"' );
$multistatus = new XMLElement('multistatus');
array_unshift($failure,new XMLElement('responsedescription', translate("Some properties were not able to be changed.") ));
array_unshift($failure,new XMLElement('href', $url));
$response = $reply->DAVElement($multistatus,'response', $failure);
if ( !empty($success) ) {
$prop = new XMLElement('prop');
foreach( $success AS $tag => $v ) {
$reply->NSElement($prop, $tag);
}
$reply->DAVElement($response, 'propstat', array( $prop, new XMLElement( 'status', 'HTTP/1.1 424 Failed Dependency' )) );
}
$request->DoResponse( 207, $reply->Render($multistatus), 'text/xml; charset="utf-8"' );
}
@ -300,27 +300,25 @@ if ( $qry->Commit() ) {
if ( isset($cache_ns) ) $cache->delete( $cache_ns, null );
if ( $request->brief_response ) {
$request->DoResponse(200); // Does not return. See: http://msdn.microsoft.com/en-us/library/aa142976%28v=exchg.65%29.aspx
if ( $request->PreferMinimal() ) {
$request->DoResponse(200); // Does not return.
}
$url = ConstructURL($request->path);
$href = new XMLElement('href', $url );
$desc = new XMLElement('responsedescription', translate("All requested changes were made.") );
$propstat = array();
$url = ConstructURL($request->path);
$multistatus = new XMLElement('multistatus');
$reply->DAVElement($multistatus,'href', $url);
$reply->DAVElement($multistatus,'responsedescription', translate("All requested changes were made.") );
$prop = new XMLElement('prop');
foreach( $success AS $tag => $v ) {
$propstat[] = new XMLElement( 'propstat', array(
new XMLElement( 'prop', new XMLElement($tag)),
new XMLElement( 'status', 'HTTP/1.1 200 OK' ),
));
$reply->NSElement($prop, $tag);
}
$reply->DAVElement($multistatus, 'propstat', array( $prop, new XMLElement( 'status', 'HTTP/1.1 200 OK' )) );
$url = ConstructURL($request->path);
array_unshift( $failure, new XMLElement('href', $url ) );
$multistatus = new XMLElement( "multistatus", new XMLElement( 'response', array( $href, $propstat, $desc ) ), array('xmlns'=>'DAV:') );
$request->DoResponse( 207, $multistatus->Render(0,'<?xml version="1.0" encoding="utf-8" ?>'), 'text/xml; charset="utf-8"' );
$request->DoResponse( 207, $reply->Render($multistatus), 'text/xml; charset="utf-8"' );
}
/**

View File

@ -23,8 +23,7 @@ switch( $proptype ) {
case 'DAV::prop':
$qry_props = $xmltree->GetPath('/urn:ietf:params:xml:ns:carddav:addressbook-query/'.$proptype.'/*');
foreach( $qry_content[0]->GetElements() AS $k => $v ) {
$propertyname = preg_replace( '/^.*:/', '', $v->GetNSTag() );
$properties[$propertyname] = 1;
$properties[$v->GetNSTag()] = 1;
if ( $v->GetNSTag() == 'urn:ietf:params:xml:ns:carddav:address-data' ) get_address_properties($v);
}
break;
@ -40,8 +39,7 @@ switch( $proptype ) {
break;
default:
$propertyname = preg_replace( '/^.*:/', '', $proptype );
$properties[$propertyname] = 1;
$properties[$proptype] = 1;
}
/**

View File

@ -53,9 +53,10 @@ function expand_properties( $urls, $ptree, &$reply, $recurse_again = true ) {
foreach( $ptree AS $n => $property ) {
if ( ! is_object($property) ) continue;
$pname = $property->GetAttribute('name');
$pns = $property->GetNamespace('namespace');
if ( !isset($pns) || $pns == '' ) $pns = $property->GetNameSpace();
$pname = $pns .':'. $pname;
$pns = $property->GetAttribute('namespace');
if ( empty($pns) ) $pns = $property->GetAttribute('xmlns');
if ( empty($pns) ) $pns = $reply->DefaultNamespace();
$pname = (empty($pns)?'':$pns .':'). $pname;
$props[] = $pname;
$subtrees[$pname] = $property->GetElements();
}
@ -72,7 +73,7 @@ function expand_properties( $urls, $ptree, &$reply, $recurse_again = true ) {
$content = $v->GetContent();
$paths[] = $content;
}
// dbg_error_log('REPORT',' Found property "%s" contains hrefs "%s"', $pname, implode(', ',$paths) );
// dbg_error_log('REPORT',' Found property "%s" contains hrefs "%s"', $pname, implode(', ',$paths) );
$property->SetContent( expand_properties($paths, $subtrees[$pname], $reply, false) );
}
}

View File

@ -32,8 +32,7 @@ switch( $proptype ) {
case 'DAV::prop':
$qry_props = $xmltree->GetPath('/*/'.$proptype.'/*');
foreach( $qry_content[0]->GetElements() AS $k => $v ) {
$propertyname = preg_replace( '/^.*:/', '', $v->GetNSTag() );
$properties[$propertyname] = 1;
$properties[$v->GetNSTag()] = 1;
if ( $v->GetNSTag() == 'urn:ietf:params:xml:ns:caldav:calendar-data' ) check_for_expansion($v);
}
break;
@ -49,8 +48,7 @@ switch( $proptype ) {
break;
default:
$propertyname = preg_replace( '/^.*:/', '', $proptype );
$properties[$propertyname] = 1;
$properties[$proptype] = 1;
}
$collection = new DAVResource($request->path);

View File

@ -142,47 +142,48 @@ function component_to_xml( $properties, $item ) {
$url = ConstructURL($item->dav_name);
$prop = new XMLElement("prop");
foreach( $properties AS $k => $v ) {
switch( $k ) {
case 'getcontentlength':
foreach( $properties AS $full_tag => $v ) {
$base_tag = preg_replace('{^.*:}', '', $full_tag );
switch( $full_tag ) {
case 'DAV::getcontentlength':
$contentlength = strlen($caldav_data);
$prop->NewElement($k, $contentlength );
$prop->NewElement($base_tag, $contentlength );
break;
case 'getlastmodified':
$prop->NewElement($k, ISODateToHTTPDate($item->modified) );
case 'DAV::getlastmodified':
$prop->NewElement($base_tag, ISODateToHTTPDate($item->modified) );
break;
case 'calendar-data':
if ( $type == 'calendar' ) $reply->CalDAVElement($prop, $k, $caldav_data );
else $unsupported[] = $k;
case 'urn:ietf:params:xml:ns:caldav:calendar-data':
if ( $type == 'calendar' ) $reply->CalDAVElement($prop, $base_tag, $caldav_data );
else $unsupported[] = $base_tag;
break;
case 'address-data':
if ( $type == 'vcard' ) $reply->CardDAVElement($prop, $k, $caldav_data );
else $unsupported[] = $k;
case 'urn:ietf:params:xml:ns:carddav:address-data':
if ( $type == 'vcard' ) $reply->CardDAVElement($prop, $base_tag, $caldav_data );
else $unsupported[] = $base_tag;
break;
case 'getcontenttype':
$prop->NewElement($k, $contenttype );
case 'DAV::getcontenttype':
$prop->NewElement($base_tag, $contenttype );
break;
case 'current-user-principal':
case 'DAV::current-user-principal':
$prop->NewElement("current-user-principal", $request->current_user_principal_xml);
break;
case 'displayname':
$prop->NewElement($k, $displayname );
case 'DAV::displayname':
$prop->NewElement($base_tag, $displayname );
break;
case 'resourcetype':
$prop->NewElement($k); // Just an empty resourcetype for a non-collection.
case 'DAV::resourcetype':
$prop->NewElement($base_tag); // Just an empty resourcetype for a non-collection.
break;
case 'getetag':
$prop->NewElement($k, '"'.$item->dav_etag.'"' );
case 'DAV::getetag':
$prop->NewElement($base_tag, '"'.$item->dav_etag.'"' );
break;
case '"current-user-privilege-set"':
$prop->NewElement($k, privileges($request->permissions) );
$prop->NewElement($base_tag, privileges($request->permissions) );
break;
case 'SOME-DENIED-PROPERTY': /** indicating the style for future expansion */
$denied[] = $k;
$denied[] = $full_tag;
break;
default:
dbg_error_log( 'REPORT', "Request for unsupported property '%s' of calendar item.", $v );
$unsupported[] = $k;
dbg_error_log( 'REPORT', "Request for unsupported property '%s' of calendar item.", $full_tag );
$unsupported[] = $full_tag;
}
}
$status = new XMLElement("status", "HTTP/1.1 200 OK" );
@ -195,16 +196,16 @@ function component_to_xml( $properties, $item ) {
$status = new XMLElement("status", "HTTP/1.1 403 Forbidden" );
$noprop = new XMLElement("prop");
foreach( $denied AS $k => $v ) {
$noprop->NewElement( strtolower($v) );
$reply->NSElement($noprop, $v);
}
$elements[] = new XMLElement( "propstat", array( $noprop, $status) );
}
if ( !(isset($request->brief_response) && $request->brief_response) && count($unsupported) > 0 ) {
if ( ! $request->PreferMinimal() && count($unsupported) > 0 ) {
$status = new XMLElement("status", "HTTP/1.1 404 Not Found" );
$noprop = new XMLElement("prop");
foreach( $unsupported AS $k => $v ) {
$noprop->NewElement( strtolower($v) );
$reply->NSElement($noprop, $v);
}
$elements[] = new XMLElement( "propstat", array( $noprop, $status) );
}