openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit cebf55b2136d4f4f01c9336acdad3fab7ff0074c
parent 388ecd4e425ed731314697a16a331042439b11a5
Author: dankert <devnull@localhost>
Date:   Thu, 15 Mar 2007 02:00:12 +0100

PUT und MKCOL implementiert.

Diffstat:
actionClasses/WebdavAction.class.php | 443+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 322 insertions(+), 121 deletions(-)

diff --git a/actionClasses/WebdavAction.class.php b/actionClasses/WebdavAction.class.php @@ -19,12 +19,11 @@ class WebdavAction extends Action var $database; var $depth; var $project; - var $folder; +// var $folder; + var $obj; var $filename; var $pathnames = array(); var $uri; - var $isFolder; - var $isFile; var $headers; var $requestType; var $fullSkriptName; @@ -40,10 +39,11 @@ class WebdavAction extends Action header('MS-Author-Via: DAV' ); // Extrawurst fuer MS-Clients. header('X-Dav-powered-by: OpenRat CMS'); // Bandbreite verschwenden :) - Logger::debug( 'WEBDAV: Method '.$this->subActionName); + Logger::debug( 'WEBDAV: Method '.$_GET['subaction'] ); $this->headers = getallheaders(); + // Prüfen, ob Benutzer angemeldet ist. $user = $this->getUserFromSession(); if ( !is_object($user)) { @@ -71,7 +71,7 @@ class WebdavAction extends Action } - $this->fullSkriptName = 'http://'.$_SERVER['HTTP_HOST'].'/'.$_SERVER['SCRIPT_NAME'].'/'; + $this->fullSkriptName = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'/'; $uri = '/1/2'.substr($_SERVER['REQUEST_URI'],strlen($_SERVER['SCRIPT_NAME'])); @@ -100,12 +100,16 @@ class WebdavAction extends Action $this->project = new Project(); $this->project->name = $uriPart; - Logger::warn($this->project->name); +// Logger::warn($this->project->name); $this->project->loadByName(); + //Session::setProjectLanguage( new Language( $this->project->getDefaultLanguageId() ) ); + //Session::setProjectModel ( new Model ( $this->project->getDefaultModelId() ) ); $oid = $this->project->getRootObjectId(); $this->folder = new Folder($oid); + $this->obj = $this->folder; +// Logger::debug('ja'); $this->fullSkriptName .= $uriPart.'/'; break; @@ -115,17 +119,38 @@ class WebdavAction extends Action // URI='/project/a/' $oid = $this->folder->getObjectIdByFileName($uriPart); - $this->folder = new Folder($oid); +// $this->obj = ObjectFactory::create($oid); - $this->fullSkriptName .= $uriPart.'/'; + if ( $oid == 0 ) + { + + Logger::debug( 'Existiert nicht: Teil '.$uriPart); + $this->obj = null; + } + else + { + Logger::debug( 'Teil '.$uriPart); + $this->obj = new Object($oid); + $this->obj->load(); + + // if ( $this->obj->isFolder() ) + $this->folder = new Folder($oid); + } + + $this->fullSkriptName .= $uriPart; + + if ( $this->obj != null && $this->obj->isFolder ) + $this->fullSkriptName .= '/'; break; } } - $this->fullSkriptName .= $this->filename; +// $this->fullSkriptName .= $this->filename; -// Html::debug($this); + Logger::debug( 'Skriptname: '.$this->fullSkriptName); +// Logger::debug( 'Objekt: '.$this->obj->getType() ); +// Logger::debug( 'Objekt: '.print_r($this->obj,true) ); foreach(getallheaders() as $k=>$v) Logger::debug( 'WEBDAV: REQ_HEADER_'.$k.'='.$v); @@ -133,7 +158,7 @@ class WebdavAction extends Action $this->request = implode('',file('php://input')); Logger::debug( 'WEBDAV: REQ_BODY='.$this->request); - Logger::debug('E super'); +// Logger::debug('E super'); } @@ -156,17 +181,25 @@ class WebdavAction extends Action function options() { + Logger::debug('WEBDAV: client wants to see our OPTIONS'); header('DAV: 1'); - header('Allow: GET,PUT,PROPFIND'); + header('Allow: GET,PUT,MKCOL,PROPFIND'); $this->httpStatus( '200 OK' ); exit(); } - + + /** + * Setzt einen HTTP-Status.<br> + * <br> + * Es wird ein HTTP-Status gesetzt, zusätzlich wird der Status in den Header "X-WebDAV-Status" geschrieben. + */ function httpStatus( $status = true ) { + Logger::debug('WEBDAV: HTTP-Status: '.$status); + if ( $status === true ) $status = '200 OK'; @@ -175,32 +208,82 @@ class WebdavAction extends Action } - + + /** + * WebDav-GET-Methode. + * Die gewünschte Datei wird geladen und im HTTP-Body mitgeliefert. + */ function get() { - if ( $this->isFolder ) + if ( $this->obj->isFolder ) $this->getDirectory(); + elseif( $this->obj->isPage ) + { + $this->httpStatus( '200 OK' ); - $this->httpStatus( '200 OK' ); - - // Verzeichnis ausgeben - header('Content-Type: text/html'); - echo '<html><head><title>OpenRat WEBDAV Access</title></head>'; - echo '<body>'; - echo '<h1>OpenRat WEBDAV Access</h1>'; - echo '<pre>'; -// echo 'Testseite: '.$this->uri; -// echo 'Pathname: '.$this->pathname; -// echo 'Filename: '.$this->filename; - echo '</pre>'; - echo '</body>'; - echo '</html>'; - + header('Content-Type: text/html'); + echo '<html><head><title>OpenRat WEBDAV Access</title></head>'; + echo '<body>'; + echo '<h1>Page</h1>'; + echo '<pre>'; + echo 'No Content available'; + // echo 'Testseite: '.$this->uri; + // echo 'Pathname: '.$this->pathname; + // echo 'Filename: '.$this->filename; + echo '</pre>'; + echo '</body>'; + echo '</html>'; + } + elseif( $this->obj->isLink ) + { + $this->httpStatus( '200 OK' ); + + header('Content-Type: text/html'); + echo '<html><head><title>OpenRat WEBDAV Access</title></head>'; + echo '<body>'; + echo '<h1>Link</h1>'; + echo '<pre>'; + echo 'No Content available'; + // echo 'Testseite: '.$this->uri; + // echo 'Pathname: '.$this->pathname; + // echo 'Filename: '.$this->filename; + echo '</pre>'; + echo '</body>'; + echo '</html>'; + } + elseif( $this->obj->isFile ) + { + $this->httpStatus( '200 OK' ); + + $file = new File( $this->obj->objectid ); + $file->load(); + + header('Content-Type: '.$file->mimeType() ); + header('X-File-Id: '.$file->fileid ); + + // Angabe Content-Disposition + // - Bild soll "inline" gezeigt werden + // - Dateiname wird benutzt, wenn der Browser das Bild speichern moechte + header('Content-Disposition: inline; filename='.$file->filenameWithExtension() ); + header('Content-Transfer-Encoding: binary' ); + header('Content-Description: '.$file->name ); + + $file->loadValue(); // Bild aus Datenbank laden + + // Groesse des Bildes in Bytes + // Der Browser hat so die Moeglichkeit, einen Fortschrittsbalken zu zeigen + header('Content-Length: '.strlen($file->value) ); + + echo $file->value; + } exit; } + /** + * Erzeugt ein Unix-ähnliche Ausgabe des Verzeichnisses als HTML. + */ function getDirectory() { $this->httpStatus( '200 OK' ); @@ -216,27 +299,6 @@ class WebdavAction extends Action echo '</html>'; exit; - - - - /* - die('GET not implemented'); - global $conf; - global $PHP_AUTH_USER; - global $PHP_AUTH_PW; - - $user = Session::getUser(); - - // Seite ändert sich nur 1x pro Session - $this->lastModified( $user->loginDate ); - - $this->setTemplateVar( 'stylesheet',$user->style ); - $this->setTemplateVar( 'css_body_class','background' ); - - $this->maxAge( 4*60*60 ); // 1 Stunde Browsercache - - $this->forward( 'border' ); - */ } @@ -260,23 +322,73 @@ class WebdavAction extends Action } - + + /** + * Verzeichnis anlegen. + * + * Diese Methode ist nicht implementiert. Der Client erhält eine Nachricht, dass die Methode nicht verfügbar ist. + */ function mkcol() { - $this->httpStatus('405 Not Allowed, Not implemented'); + if ( $this->obj == null ) + { + // NEUE Datei + $f = new Folder(); + $f->filename = basename($this->fullSkriptName); + $f->parentid = $this->folder->objectid; + $f->projectid = $this->project->projectid; + $f->add(); + $this->httpStatus('201 Created'); + } + elseif ( $this->obj->isFolder ) + { + $file = new File( $this->obj->objectid ); + $file->saveValue( $this->request ); + $file->setTimestamp(); + $this->httpStatus('204 No Content'); + } + else + { + $this->httpStatus('405 Not Allowed, MKCOL on existing object' ); + echo 'Error: MKCOL on existing object'; + } exit; } + /** + * Objekt löschen. + */ function delete() { - $this->httpStatus('405 Not Allowed, Not implemented'); - exit; + // Aus Sicherheitsgründen erstmal deaktiviert! + if ( true ) + { + $this->httpStatus('405 Not Allowed' ); + exit; + } + else + { + if ( $this->obj->isFolder ) + { + $this->obj->deleteAll(); + } + else + { + $this->obj->delete(); + } + + $this->httpStatus( true ); + exit; + } } + /** + * Diese Methode ist nicht implementiert. Der Client erhält eine Nachricht, dass die Methode nicht verfügbar ist. + */ function copy() { $this->httpStatus('405 Not Allowed, Not implemented'); @@ -285,6 +397,9 @@ class WebdavAction extends Action + /** + * Diese Methode ist nicht implementiert. Der Client erhält eine Nachricht, dass die Methode nicht verfügbar ist. + */ function move() { $this->httpStatus('405 Not Allowed, Not implemented'); @@ -293,69 +408,167 @@ class WebdavAction extends Action + /** + * Das PUT ist nur für Dateien möglich. + */ function put() { - $this->httpStatus('405 Not Allowed, PUT not implemented'); + if ( $this->obj == null ) + { + // NEUE Datei + $file = new File(); + $file->filename = basename($this->fullSkriptName); + $file->extension = ''; + $file->size = strlen($this->request); + $file->parentid = $this->folder->objectid; + $file->projectid = $this->project->projectid; + $file->value = $this->request; + Logger::debug('NEUE DATEI '.print_r($file,true)); + $file->add(); + $this->httpStatus('201 Created'); + } + elseif ( $this->obj->isFile ) + { + $file = new File( $this->obj->objectid ); + $file->saveValue( $this->request ); + $file->setTimestamp(); + $this->httpStatus('204 No Content'); + } + else + { + $this->httpStatus('405 Not Allowed, PUT not implemented for object type '.$this->obj->getType() ); + } exit; - - global $conf; - global $PHP_AUTH_USER; - global $PHP_AUTH_PW; - - $user = Session::getUser(); - - // Seite ändert sich nur 1x pro Session - $this->lastModified( $user->loginDate ); - - $this->setTemplateVar( 'stylesheet',$user->style ); - $this->setTemplateVar( 'css_body_class','background' ); - - $this->maxAge( 4*60*60 ); // 1 Stunde Browsercache - - $this->forward( 'border' ); } - + + /** + * WebDav-Methode PROPFIND. + * + * Diese Methode wird beim Ermitteln von Verzeichnisinhalten verwendet. + */ function propfind() { Logger::debug( 'WEBDAV: PROPFIND'); switch( $this->requestType ) { - case 'projectlist': - $projects = array(); + case 'projectlist': // Projektliste + + $inhalte = array(); foreach( Project::getAll() as $projectName ) - $projects[] = $this->fullSkriptName.'/'.$projectName; + { + $objektinhalt = array(); + $z = 30*365.25*24*60*60; + $objektinhalt['createdate' ] = $z; + $objektinhalt['lastchangedate'] = $z; + $objektinhalt['size' ] = 1; + $objektinhalt['name' ] = $this->fullSkriptName.'/'.$projectName; + $objektinhalt['type'] = 'folder'; + $inhalte[] = $objektinhalt; + } - $this->multiStatus( $projects ); + $this->multiStatus( $inhalte ); break; - case 'object': + case 'object': // Verzeichnisinhalt -// $o = ObjectFactory::create($this->folder->objectid); -// -// if ( $o->isFolder ) -// { - $objects = $this->folder->getObjects(); + if ( $this->obj == null ) + { + Logger::debug( 'WEBDAV: PROPFIND of non-existent object'); + // Objekt existiert nicht. + } + elseif ( $this->obj->isFolder ) + { + Logger::debug( 'WEBDAV: PROPFIND of folder'); + $inhalte = array(); + + $objektinhalt = array(); + $objektinhalt['createdate' ] = $this->obj->createDate; + $objektinhalt['lastchangedate'] = $this->obj->lastchangeDate; + $objektinhalt['name'] = $this->fullSkriptName; + $objektinhalt['type'] = 'folder'; + $objektinhalt['size'] = 1; + $inhalte[] = $objektinhalt; + + $objects = $this->folder->getObjects(); foreach( $objects as $object ) - $inhalte[] = $this->fullScriptName.'/'.$object->filename.'/'; + { + //$object->loadRaw(); + $objektinhalt = array(); + $objektinhalt['createdate' ] = $object->createDate; + $objektinhalt['lastchangedate'] = $object->lastchangeDate; + + switch( $object->getType() ) + { + case OR_TYPE_FOLDER: + $objektinhalt['name'] = $this->fullSkriptName.$object->filename.'/'; + $objektinhalt['type'] = 'folder'; + $objektinhalt['size'] = 1; + $inhalte[] = $objektinhalt; + break; + case OR_TYPE_FILE: + $objektinhalt['name'] = $this->fullSkriptName.$object->filename; + $objektinhalt['type'] = 'file'; + $objektinhalt['size'] = 1; + $objektinhalt['mime'] = 'application/x-non-readable'; + $inhalte[] = $objektinhalt; + break; + case OR_TYPE_LINK: + $objektinhalt['name'] = $this->fullSkriptName.$object->filename; + $objektinhalt['type'] = 'file'; + $objektinhalt['size'] = 0; + $objektinhalt['mime'] = 'application/x-non-readable'; + $inhalte[] = $objektinhalt; + break; + case OR_TYPE_PAGE: + $objektinhalt['name'] = $this->fullSkriptName.$object->filename; + $objektinhalt['type'] = 'file'; + $objektinhalt['size'] = 0; + $inhalte[] = $objektinhalt; + break; + default: + } + } + Logger::debug( 'WEBDAV: PROPFIND2'); + + if ( count($inhalte)==0 ) + $inhalte[] = array('createdate'=>0,'lastchangedate'=>0,'name'=>'empty','size'=>0,'type'=>'file'); + Logger::debug('Anzahl Dateien:'.count($inhalte)); $this->multiStatus( $inhalte ); -// } -// else -// { -// $this->multiStatus( array($o->filename) ); -// } + } + else + { + $object = $this->obj; + Logger::debug( 'WEBDAV: PROPFIND of file'); + $objektinhalt = array(); + //$object->loadRaw(); + $objektinhalt = array(); + $objektinhalt['name'] = $this->fullSkriptName.'/'.$object->filename.'/'; + $objektinhalt['createdate' ] = $object->createDate; + $objektinhalt['lastchangedate'] = $object->lastchangeDate; + $objektinhalt['size' ] = 0; + $objektinhalt['type' ] = 'file'; + + + $this->multiStatus( array($objektinhalt) ); + } break; default: die('???:'.$this->requestType); } + + exit; } + /** + * Webdav-Methode PROPPATCH ist nicht implementiert. + */ function proppatch() { @@ -366,6 +579,9 @@ class WebdavAction extends Action } + /** + * Erzeugt einen Multi-Status. + */ function multiStatus( $files ) { $this->httpStatus('207 Multi-Status'); @@ -376,7 +592,7 @@ class WebdavAction extends Action $response .= '<d:multistatus xmlns:d="DAV:">'; foreach( $files as $file ) - $response .= $this->getResponse( $file,array() ); + $response .= $this->getResponse( $file['name'],$file ); $response .= '</d:multistatus>'; Logger::debug('PROPFIND-Ausgabe: '.$response); @@ -390,21 +606,27 @@ class WebdavAction extends Action function getResponse( $file,$options ) { +// extract($options,EXTR_OVERWRITE,'opt'); + $response = ''; $response .= '<d:response>'; $response .= '<d:href>'.$file.'</d:href>'; $response .= '<d:propstat>'; $response .= '<d:prop>'; // $response .= '<d:source></d:source>'; - $response .= '<d:creationdate>1997-12-01T17:42:21-08:00</d:creationdate>'; - $response .= '<d:getlastmodified>1997-12-01T17:42:21-08:00</d:getlastmodified>'; - $response .= '<d:displayname>Dumpfbacke/</d:displayname>'; - - $response .= ' - <d:creationdate>2003-03-16T19:28:51Z</d:creationdate> - <d:displayname>Default</d:displayname><d:getcontentlength>9841152</d:getcontentlength> - <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sun, 16 Mar 2003 19:28:51 GMT</d:getlastmodified> - <d:resourcetype><d:collection/></d:resourcetype><d:categories></d:categories><d:fields></d:fields>'; + $response .= '<d:creationdate>'.date('r',$options['createdate']).'</d:creationdate>'; +// $response .= '<d:getlastmodified>'.date('r',$options['lastchangedate']).'</d:getlastmodified>'; + $response .= '<d:displayname>'.$options['name'].'</d:displayname>'; + $response .= '<d:getcontentlength>'.$options['size'].'</d:getcontentlength>'; + $response .= '<d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">'.date('r',$options['lastchangedate']).'</d:getlastmodified>'; + + if ( $options['type'] == 'folder') + $response .= '<d:resourcetype><d:collection/></d:resourcetype>'; + else + $response .= '<d:resourcetype></d:resourcetype>'; + + $response .= '<d:categories></d:categories>'; + $response .= '<d:fields></d:fields>'; @@ -417,27 +639,6 @@ class WebdavAction extends Action // $response .= '</d:resourcetype>'; // $response .= '<d:getetag />'; -/* - $response .= '<d:supportedlock> - -<d:lockentry> - -<d:lockscope><d:exclusive/></d:lockscope> - -<d:locktype><d:write/></d:locktype> - -</d:lockentry> - -<d:lockentry> - -<d:lockscope><d:shared/></d:lockscope> - -<d:locktype><d:write/></d:locktype> - -</d:lockentry> - -</d:supportedlock>'; -*/ $response .= '</d:prop>'; $response .= '<d:status>HTTP/1.1 200 OK</d:status>'; $response .= '</d:propstat>'; @@ -451,7 +652,7 @@ class WebdavAction extends Action function webdavErrorHandler($errno, $errstr, $errfile, $errline) { - Logger::warn($errno.'/'.$errstr.'/file:'.$errfile.'/line:'.$errline); + Logger::warn('WEBDAV ERROR: '.$errno.'/'.$errstr.'/file:'.$errfile.'/line:'.$errline); } ?> \ No newline at end of file