function setupXMLOutputCharset() { $charset = eZWebDAVServer::dataCharset(); $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : false; $pattern = eZWebDAVServer::userAgentPattern(); $userAgentSettings = eZWebDAVServer::userAgentSettings(); if (preg_match($pattern, $userAgent, $matches) && isset($userAgentSettings[$matches[0]])) { $agentSettings = $userAgentSettings[$matches[0]]; if (isset($agentSettings['xmlCharset']) && $agentSettings['xmlCharset'] != '') { $charset = $agentSettings['xmlCharset']; } } $this->setXMLOutputCharset($charset); }
function outputCollectionContent( $collection, $requestedProperties ) { // Sanity check & action: if client forgot to ask, we'll still // play along revealing some basic/default properties. This is // necessary to make it work with Windows XP + SP2. if( !is_array( $requestedProperties ) || count( $requestedProperties ) == 0 ) { $requestedProperties = array( 'displayname', 'creationdate', 'getlastmodified', 'getcontenttype', 'getcontentlength', 'resourcetype' ); } // Fix for CaDAVer (text based linux client) -> error if not revealed. // Apparently it does not mess up for other clients so I'll just leave // it without wrapping it inside a client-specific check. if( !in_array( 'getcontenttype', $requestedProperties ) ) { $requestedProperties[] = 'getcontenttype'; } $this->appendLogEntry( 'Client requested ' . count( $requestedProperties ) . ' properties.', 'outputCollectionContent' ); $dataCharset = eZWebDAVServer::dataCharset(); $xmlCharset = $this->XMLOutputCharset(); $xmlText = "<?xml version=\"1.0\" encoding=\"$xmlCharset\"?>\n" . "<D:multistatus xmlns:D=\"DAV:\">\n"; // Maps from WebDAV property names to internal names $nameMap = array( 'displayname' => 'name', 'creationdate' => 'ctime', 'getlastmodified' => 'mtime', 'getcontenttype' => 'mimetype', 'getcontentlength' => 'size' ); foreach ( $requestedProperties as $requestedProperty ) { if ( !isset( $nameMap[$requestedProperty] ) ) $nameMap[$requestedProperty] = $requestedProperty; } // Misc helpful debug info (use when things go wrong..) //$this->appendLogEntry( var_dump( $requestedProperties ), 'outputCollectionContent' ); //$this->appendLogEntry( var_dump( $nameMap ), 'outputCollectionContent' ); //$this->appendLogEntry( var_dump( $collection ), 'outputCollectionContent' ); // For all the entries in this dir/collection-array: foreach ( $collection as $entry ) { // Translate the various UNIX timestamps to WebDAV format: $creationTime = date( eZWebDAVServer::CTIME_FORMAT, $entry['ctime'] ); $modificationTime = date( eZWebDAVServer::MTIME_FORMAT, $entry['mtime'] ); // The following lines take care of URL encoding special characters // for each element (stuff between slashes) in the path. $href = $entry['href']; $pathArray = explode( '/', eZWebDAVServer::recode( "$href", $dataCharset, $xmlCharset ) ); $encodedPath = '/'; foreach( $pathArray as $pathElement ) { if( $pathElement != '' ) { $encodedPath .= rawurlencode( $pathElement ); $encodedPath .= '/'; } } $isCollection = $entry['mimetype'] == 'httpd/unix-directory'; // If this is not a collection, don't leave a trailing '/' // on the href. If you do, Goliath gets confused. if ( !$isCollection ) $encodedPath = rtrim($encodedPath, '/'); $xmlText .= " <D:response>\n" . " <D:href>" . $encodedPath ."</D:href>\n" . " <D:propstat>\n" . " <D:prop>\n"; $unknownProperties = array(); foreach ( $requestedProperties as $requestedProperty ) { $name = $nameMap[$requestedProperty]; if ( isset( $entry[$name] ) ) { if ( $requestedProperty == 'creationdate' ) { $creationTime = date( eZWebDAVServer::CTIME_FORMAT, $entry['ctime'] ); $xmlText .= " <D:" . $requestedProperty . ">" . $creationTime . "</D:" . $requestedProperty . ">\n"; } else if ( $requestedProperty == 'getlastmodified' ) { $modificationTime = date( eZWebDAVServer::MTIME_FORMAT, $entry['mtime'] ); $xmlText .= " <D:" . $requestedProperty . ">" . $modificationTime . "</D:" . $requestedProperty . ">\n"; } else if ( $isCollection and $requestedProperty == 'getcontenttype' ) { $xmlText .= ( " <D:resourcetype>\n" . " <D:collection/>\n" . " </D:resourcetype>\n" ); $unknownProperties[] = $requestedProperty; } else { $xmlText .= " <D:" . $requestedProperty . ">" . htmlspecialchars( eZWebDAVServer::recode( "$entry[$name]", $dataCharset, $xmlCharset ) ) . "</D:" . $requestedProperty . ">\n"; } } else if ( $requestedProperty != 'resourcetype' or !$isCollection ) { $unknownProperties[] = $requestedProperty; } } $xmlText .= ( " <D:lockdiscovery/>\n" ); $xmlText .= ( " </D:prop>\n" . " <D:status>HTTP/1.1 200 OK</D:status>\n" . " </D:propstat>\n" ); // List the non supported properties and mark with 404 // This behavior (although recommended/standard) might // confuse some clients. Try commenting out if necessary... $xmlText .= " <D:propstat>\n"; $xmlText .= " <D:prop>\n"; foreach ( $unknownProperties as $unknownProperty ) { $xmlText .= " <D:" . $unknownProperty . "/>\n"; } $xmlText .= " </D:prop>\n"; $xmlText .= " <D:status>HTTP/1.1 404 Not Found</D:status>\n"; $xmlText .= " </D:propstat>\n"; $xmlText .= " </D:response>\n"; } $xmlText .= "</D:multistatus>\n"; // Send the necessary headers... header( 'HTTP/1.1 207 Multi-Status' ); header( 'Content-Type: text/xml' ); // Comment out the next line if you don't // want to use chunked transfer encoding. //header( 'Content-Length: '.strlen( $xmlText ) ); $text = @ob_get_contents(); if ( strlen( $text ) != 0 ) $this->appendLogEntry( $text, "DAV: PHP Output" ); for ( $i = 0, $obLevel = ob_get_level(); $i < $obLevel; ++$i ) { ob_end_clean(); } // Dump XML response (from server to client to logfile. //$this->appendLogEntry( $xmlText, 'xmlText' ); // Dump the actual XML data containing collection list. // @as use $GLOBALS $GLOBALS['ezc_response_body'] = $xmlText; // @as $dom = new DOMDocument( '1.0', 'utf-8' ); // $success = $dom->loadXML( $xmlText ); // if ( $success ) // $this->appendLogEntry( "XML was parsed", 'outputCollectionContent' ); // else // $this->appendLogEntry( "XML was NOT parsed $xmlText", 'outputCollectionContent' ); // If we got this far: everything is OK. return eZWebDAVServer::OK_SILENT; }