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);
 }
Exemple #2
0
    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;
    }