WebdavAction.class.php

gehe zur Dokumentation dieser Datei
00001 <?php
00002 
00003 
00016 class WebdavAction extends Action
00017 {
00018      var $defaultSubAction = 'show';
00019      var $database;
00020      var $depth;
00021      var $project;
00022      var $folder;
00023      var $obj;
00024      var $filename;
00025      var $pathnames = array();
00026      var $uri;
00027      var $headers;
00028      var $requestType;
00029      var $request;
00030      var $destination = null;
00031      var $fullSkriptName;
00032      var $create;
00033      var $readonly;
00034      var $maxFileSize;
00035      var $webdav_conf;
00036 
00037      function WebdavAction()
00038      {
00039           if (!defined('E_STRICT')) 
00040                define('E_STRICT', 2048);
00041 
00042           // Nicht notwendig, da wir den Error-Handler umbiegen:
00043           error_reporting(0); // PHP-Fehlermeldungen zerstoeren XML-Dokument, daher ausschalten.
00044           
00045           // PHP-Fehler ins Log schreiben, damit die Ausgabe nicht zerstoert wird.
00046           //set_error_handler('webdavErrorHandler');
00047           // PHP5-only?
00048           if (version_compare(PHP_VERSION, '5.0.0', '>'))
00049                set_error_handler('webdavErrorHandler',E_ERROR | E_WARNING | E_NOTICE);
00050           else
00051                set_error_handler('webdavErrorHandler');
00052 
00053           global $conf;
00054           $this->webdav_conf = $conf['webdav'];
00055 
00056           if   ( $this->webdav_conf['compliant_to_redmond'] )
00057                header('e'           ); // Extrawurst fuer MS-Clients.
00058                
00059           if   ( $this->webdav_conf['expose_openrat'] )
00060                header('X-Dav-powered-by: OpenRat CMS'); // Bandbreite verschwenden :)
00061 
00062 //        foreach(getallheaders() as $k=>$v)
00063 //             Logger::debug( 'WEBDAV: REQ_HEADER_'.$k.'='.$v);
00064 
00065           #    echo "error-rep:".error_reporting(0);
00066           Logger::debug( 'WEBDAV: URI='.$_SERVER['REQUEST_URI']);
00067 //        Logger::debug( 'WEBDAV: SCRIPT_NAME='.$_SERVER['SCRIPT_NAME']);
00068           
00069           if   ( !$conf['webdav']['enable'])
00070           {
00071                Logger::info( 'WEBDAV is disabled' );
00072                $this->httpStatus('403 Forbidden');
00073                exit;
00074           }
00075           
00076           $this->create      = $this->webdav_conf['create'];
00077           $this->readonly    = $this->webdav_conf['readonly'];
00078           $this->maxFileSize = $this->webdav_conf['max_file_size'];
00079           
00080           Logger::debug( 'method '.$_GET['subaction'] );
00081           
00082           $this->headers = getallheaders();
00083           /* DAV compliant servers MUST support the "0", "1" and
00084            * "infinity" behaviors. By default, the PROPFIND method without a Depth
00085            * header MUST act as if a "Depth: infinity" header was included. */
00086           if   ( !isset($this->headers['Depth']) )
00087                $this->depth = 1;
00088           elseif    ( strtolower($this->headers['Depth'])=='infinity')
00089                $this->depth = 1;
00090           else
00091                $this->depth = intval($this->headers['Depth']);
00092 
00093           if   ( isset($this->headers['Destination']) )
00094                $this->destination = $this->headers['Destination'];
00095 
00096           // Pr�fen, ob Benutzer angemeldet ist.
00097           $user = $this->getUserFromSession();
00098 
00099           // Authentisierung erzwingen.
00100         // for the motivation for not checking OPTIONS requests see 
00101         // http://pear.php.net/bugs/bug.php?id=5363
00102           if   ( !is_object($user) && $_GET[REQ_PARAM_SUBACTION] != 'options' )
00103           {
00104                Logger::debug( 'WEBDAV: Need Auth!' );
00105                if   ( !is_object(Session::getDatabase()) )
00106                     $this->setDefaultDb();
00107                     
00108                Logger::debug( 'WEBDAV: Need Auth! #2' );
00109                $ok = false;
00110                if   ( isset($_SERVER['PHP_AUTH_USER']) )
00111                {
00112                     Logger::debug( 'WEBDAV: Checking Auth!' );
00113                     $user = new User();
00114                     $user->name = $_SERVER['PHP_AUTH_USER'];
00115                     
00116                     $ok = $user->checkPassword( $_SERVER['PHP_AUTH_PW'] );
00117                     
00118                     if   ( $ok )
00119                     {
00120                          $user->setCurrent();
00121                          $this->redirectWithSessionId();
00122                     }
00123                }
00124                
00125                if   ( !$ok )
00126                {
00127                     Logger::debug( 'WEBDAV: Requesting Auth!' );
00128                     header('WWW-Authenticate: Basic realm="OpenRat"');
00129                     $this->httpStatus('401 Unauthorized');
00130                     exit;
00131                }
00132           }
00133           elseif    ( !is_object($user) && $_GET[REQ_PARAM_SUBACTION] == 'options' )
00134           {
00135                $this->setDefaultDb();
00136           }
00137           
00138           
00139           $this->fullSkriptName = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'/'; 
00140 
00141           if   ( $this->webdav_conf['session_in_uri'] )
00142                $sos = 1+strlen(session_id())+strlen($this->webdav_conf['session_in_uri_prefix']);
00143           else
00144                $sos = 0;
00145                
00146           // URL parsen.
00147           $uri = substr($_SERVER['REQUEST_URI'],strlen($_SERVER['SCRIPT_NAME']) + $sos);
00148 
00149           Logger::debug( 'URI='.$uri );
00150                
00151           $uri = $this->parseURI( $uri );
00152           $this->requestType = $uri['type'   ];
00153           $this->folder      = $uri['folder' ];
00154           $this->obj         = $uri['object' ];
00155           $this->project     = $uri['project'];
00156 
00157           $this->fullSkriptName .= implode('/',$uri['path']);
00158           
00159           if   ( is_object($this->obj) && $this->obj->isFolder ) 
00160                $this->fullSkriptName .= '/'; 
00161 
00162           /*
00163            * Verzeichnisse m�ssen mit einem '/' enden. Falls nicht, Redirect aussf�hren.
00164            * 
00165            * RFC 2518, 5.2 Collection Resources, Page 11:
00166            * "For example, if a client invokes a
00167            * method on http://foo.bar/blah (no trailing slash), the resource
00168            * http://foo.bar/blah/ (trailing slash) may respond as if the operation
00169            * were invoked on it, and should return a content-location header with
00170            * http://foo.bar/blah/ in it.  In general clients SHOULD use the "/"
00171            * form of collection names."
00172            */
00173           if   ( is_object($this->obj) && $this->obj->isFolder &&  $_GET['subaction']=='get' && substr($_SERVER['REQUEST_URI'],strlen($_SERVER['REQUEST_URI'])-1 ) != '/' )
00174           {
00175                Logger::debug( 'WEBDAV: Umleitung auf Verzeichnis mit ".../"' );
00176                
00177                header('HTTP/1.1 302 Moved Temporarily');
00178                header('Location: '.$_SERVER['REQUEST_URI'].'/');
00179                exit;     
00180           }    
00181 
00182           // Falls vorhanden, den "Destination"-Header parsen.
00183           if   ( isset($_SERVER['HTTP_DESTINATION']) )
00184           {
00185                $destUri = parse_url( $_SERVER['HTTP_DESTINATION'] );
00186                
00187                $uri = substr($destUri['path'],strlen($_SERVER['SCRIPT_NAME'])+$sos);
00188                     
00189                // URL parsen.
00190                $this->destination = $this->parseURI( $uri );
00191           }
00192 
00193 
00194           $this->request = implode('',file('php://input')); 
00195 //        Logger::debug( 'WEBDAV: REQ_BODY='.$this->request);
00196 
00197           #Logger::debug( 'Uff' );
00198 
00199      }
00200      
00201      
00202      
00203      function redirectWithSessionId()
00204      {
00205           if   ( $this->webdav_conf['session_in_uri'] )
00206           {
00207                header('Location: '.dirname($_SERVER['REQUEST_URI']).'/'. $this->webdav_conf['session_in_uri_prefix'].session_id().'/'.basename($_SERVER['REQUEST_URI']));
00208                //$this->httpStatus('303 See Other');
00209                $this->httpStatus('302 Moved');
00210           }
00211      }
00212      
00213      
00214      
00215      function setDefaultDb()
00216      {
00217           global $conf;
00218           
00219           if   ( !isset($conf['database']['default']) )
00220                die('default-database not set');
00221 
00222           $dbid = $conf['database']['default'];
00223                Logger::debug( 'db' );
00224 
00225           $db = new DB( $conf['database'][$dbid] );
00226           $db->id = $dbid;
00227           Session::setDatabase( $db );
00228      }
00229      
00230      
00231      
00237      function options()
00238      {
00239           Logger::debug('WEBDAV: client wants to see our OPTIONS');
00240           header('DAV: 1'); // Wir haben DAV-Level 1.
00241           
00242           if    ($this->readonly)
00243                header('Allow: OPTIONS, HEAD, GET, PROPFIND');  // Readonly-Modus
00244           else
00245                header('Allow: OPTIONS, HEAD, GET, PROPFIND, DELETE, PUT, COPY, MOVE, MKCOL, PROPPATCH');
00246 
00247           $this->httpStatus( '200 OK' );
00248           exit;
00249      }
00250      
00251      
00252 
00259      function httpStatus( $status = true )
00260      {
00261           if   ( $status === true )
00262                $status = '200 OK';
00263                
00264           Logger::debug('WEBDAV: HTTP-Status: '.$status);
00265           
00266           header('HTTP/1.1 '.$status);
00267           header('X-WebDAV-Status: '.$status,true);
00268           
00269           // Bei Status 200 und 207 folgt Inhalt. Sonst nicht und beenden. 
00270           if   ( !in_array(substr($status,0,3), array('200','207')) )
00271                exit;
00272      }
00273      
00274      
00275 
00279      function head()
00280      {
00281           if   ( $this->obj == null )
00282           {
00283                $this->httpStatus( '404 Not Found' );
00284           }
00285           elseif    ( $this->obj->isFolder )
00286           {
00287                $this->httpStatus( '200 OK' );
00288           }
00289           elseif( $this->obj->isPage )
00290           {
00291                $this->httpStatus( '200 OK' );
00292           }
00293           elseif( $this->obj->isLink )
00294           {
00295                $this->httpStatus( '200 OK' );
00296           }
00297           elseif( $this->obj->isFile )
00298           {
00299                $this->httpStatus( '200 OK' );
00300           }
00301           exit;
00302      }
00303      
00304      
00305      
00310      function get()
00311      {
00312           if   ( $this->obj->isFolder )
00313                $this->getDirectory();
00314           elseif( $this->obj->isPage )
00315           {
00316                $this->httpStatus( '403 Forbidden' );
00317                exit;
00318                $this->httpStatus( '200 OK' );
00319                
00320                header('Content-Type: text/html');
00321                echo '<html><head><title>OpenRat WEBDAV Access</title></head>';
00322                echo '<body>';
00323                echo '<h1>Page</h1>';
00324                echo '<pre>';
00325                echo 'No Content available';
00326                echo '</pre>';
00327                echo '</body>';
00328                echo '</html>';
00329           }
00330           elseif( $this->obj->isLink )
00331           {
00332                $this->httpStatus( '403 Forbidden' );
00333                exit;
00334                $this->httpStatus( '200 OK' );
00335                
00336                header('Content-Type: text/html');
00337                echo '<html><head><title>OpenRat WEBDAV Access</title></head>';
00338                echo '<body>';
00339                echo '<h1>Link</h1>';
00340                echo '<pre>';
00341                echo 'No Content available';
00342                echo '</pre>';
00343                echo '</body>';
00344                echo '</html>';
00345           }
00346           elseif( $this->obj->isFile )
00347           {
00348                $this->httpStatus( '200 OK' );
00349                
00350                $file = new File( $this->obj->objectid );
00351                $file->load();
00352                
00353                header('Content-Type: '.$file->mimeType() );
00354                header('X-File-Id: '.$file->fileid );
00355      
00356                // Angabe Content-Disposition
00357                // - Bild soll "inline" gezeigt werden
00358                // - Dateiname wird benutzt, wenn der Browser das Bild speichern moechte
00359                header('Content-Disposition: inline; filename='.$file->filenameWithExtension() );
00360                header('Content-Transfer-Encoding: binary' );
00361                header('Content-Description: '.$file->name );
00362      
00363                $file->loadValue(); // Bild aus Datenbank laden
00364      
00365                // Groesse der Datei in Bytes
00366                // Der Browser hat so die Moeglichkeit, einen Fortschrittsbalken zu zeigen
00367                header('Content-Length: '.strlen($file->value) );
00368      
00369                echo $file->value;
00370           }
00371           exit;
00372      }
00373      
00374      
00375      
00379      function getDirectory()
00380      {
00381           $this->httpStatus( '200 OK' );
00382           
00383           // Verzeichnis ausgeben
00384           header('Content-Type: text/html');
00385           $nl = "\n";
00386           $titel = 'Index of '.htmlspecialchars($this->fullSkriptName);
00387         $format = "%15s  %-19s  %-s\n";
00388           
00389           echo '<html><head><title>'.$titel.'</title></head>';
00390           echo '<body>';
00391         echo '<h1>'.$titel.'</h1>'.$nl;
00392           echo '<pre>';
00393 
00394         printf($format, "Size", "Last modified", "Filename");
00395 
00396 /*
00397 
00398  */
00399           if   ( $this->requestType == 'projectlist' )
00400           {
00401                foreach( Project::getAll() as $projectName )
00402                {
00403                     $objektinhalt = array();
00404                     $z = 30*365.25*24*60*60;
00405                     $objektinhalt['createdate'    ] = $z;
00406                     $objektinhalt['lastchangedate'] = $z;
00407                     $objektinhalt['size'          ] = 1;
00408                     echo '<a href="'.$this->fullSkriptName.'/'.$projectName.'">   </a>';
00409                }
00410           }
00411           elseif( $this->requestType == 'object' )  // Verzeichnisinhalt
00412           {
00413                $objects = $this->folder->getObjects();
00414 
00415                foreach( $objects as $object  )
00416                {
00417 //                  echo '<a href="'.$this->fullSkriptName.$object->filename.'/">'.$object->filename.'</a>';
00418 
00419 //                         number_format($object->size),
00420                     printf($format, 
00421                            number_format(1),
00422                            strftime("%Y-%m-%d %H:%M:%S",$object->lastchangeDate ),
00423                            '<a href="'.$object->filename.'">'.$object->filename.'</a>');
00424                     echo $nl;
00425                }
00426           }
00427           
00428           echo '</pre>';
00429           echo '</body>';
00430           echo '</html>';
00431           
00432           exit;
00433      }
00434      
00435      
00436 
00443      function lock()
00444      {
00445           $this->httpStatus('412 Precondition failed');
00446           $this->options();
00447           exit;
00448      }
00449 
00450 
00451           
00458      function unlock()
00459      {
00460           $this->httpStatus('412 Precondition failed');
00461           $this->options();
00462           exit;
00463      }
00464 
00465 
00466 
00472      function post()
00473      {
00474           // Die Methode POST ist bei Webdav nicht sinnvoll.
00475           $this->httpStatus('405 Method Not Allowed' );
00476           exit;
00477      }
00478      
00479      
00480      
00484      function mkcol()
00485      {
00486           
00487           if   ( !empty($this->request) )
00488           {
00489                $this->httpStatus('415 Unsupported Media Type' ); // Kein Body erlaubt
00490           }
00491           elseif    ( $this->readonly )
00492           {
00493                $this->httpStatus('403 Forbidden' ); // Kein Schreibzugriff erlaubt
00494           }
00495           elseif    ( $this->obj == null )
00496           {
00497                // Die URI ist noch nicht vorhanden
00498                $f = new Folder();
00499                $f->filename  = basename($this->fullSkriptName);
00500                $f->parentid  = $this->folder->objectid;
00501                $f->projectid = $this->project->projectid;
00502                $f->add();
00503                $this->httpStatus('201 Created');
00504           }
00505           else
00506           {
00507                // MKCOL ist nicht moeglich, wenn die URI schon existiert.
00508                $this->httpStatus('405 Method Not Allowed' );
00509           }
00510           exit;
00511      }
00512 
00513 
00514           
00518      function delete()
00519      {
00520           if   ( $this->readonly )
00521           {
00522                $this->httpStatus('403 Forbidden' ); // Kein Schreibzugriff erlaubt
00523                //$this->httpStatus('405 Not Allowed' );
00524           }
00525           else
00526           {
00527                if   ( $this->obj == null )
00528                {
00529                     // Nicht existente URIs kann man auch nicht loeschen.
00530                     $this->httpStatus('404 Not Found' );
00531                }
00532                elseif    ( $this->obj->isFolder )
00533                {
00534                     $f = new Folder( $this->obj->objectid );
00535                     $f->deleteAll();
00536                }
00537                elseif    ( $this->obj->isFile )
00538                {
00539                     $f = new File( $this->obj->objectid );
00540                     $f->delete();
00541                }
00542                elseif    ( $this->obj->isPage )
00543                {
00544                     $p = new Page( $this->obj->objectid );
00545                     $p->delete();
00546                }
00547                elseif    ( $this->obj->isLink )
00548                {
00549                     $l = new Link( $this->obj->objectid );
00550                     $l->delete();
00551                }
00552 
00553                $this->httpStatus( true ); // OK
00554           }
00555           
00556           exit;
00557      }
00558 
00559 
00560           
00566      function copy()
00567      {
00568           if   ( $this->readonly || !$this->create )
00569           {
00570                Logger::error('WEBDAV: COPY request, but readonly or no creating');
00571                $this->httpStatus('405 Not Allowed' );
00572                exit;
00573           }
00574           elseif( $this->obj == null )
00575           {
00576                // Was nicht da ist, laesst sich auch nicht verschieben.
00577                Logger::error('WEBDAV: COPY request, but Source not found');
00578                $this->httpStatus('405 Not Allowed' );
00579           }
00580           elseif ( $this->destination == null )
00581           {
00582                Logger::error('WEBDAV: COPY request, but no "Destination:"-Header');
00583                // $this->httpStatus('405 Not Allowed' );
00584                $this->httpStatus('412 Precondition failed');
00585           }
00586           else
00587           {
00588                // URL parsen.
00589                $dest = $this->destination;
00590                $destinationProject = $dest['project'];
00591                $destinationFolder  = $dest['folder' ];
00592                $destinationObject  = $dest['object' ];
00593                
00594                if   ( $dest['type'] != 'object' )
00595                {
00596                     Logger::debug('WEBDAV: COPY request, but "Destination:"-Header mismatch');
00597                     $this->httpStatus('405 Not Allowed');
00598                }
00599                elseif    ( $this->project->projectid != $destinationProject->projectid )
00600                {
00601                     // Kopieren in anderes Projekt nicht moeglich.
00602                     Logger::debug('WEBDAV: COPY request denied, project does not match');
00603                     $this->httpStatus('403 Forbidden');
00604                }
00605                elseif    ( $destinationObject != null )
00606                {
00607                     Logger::debug('WEBDAV: COPY request denied, Destination exists. Overwriting is not supported');
00608                     $this->httpStatus('403 Forbidden');
00609                }
00610                elseif ( is_object($destinationObject) && $destinationObject->isFolder)
00611                {
00612                     Logger::debug('WEBDAV: COPY request denied, Folder-Copy not implemented');
00613                     $this->httpStatus('405 Not Allowed');
00614                }
00615                elseif ( is_object($destinationObject) && $destinationObject->isLink)
00616                {
00617                     Logger::debug('WEBDAV: COPY request denied, Link copy not implemented');
00618                     $this->httpStatus('405 Not Allowed');
00619                }
00620                elseif ( is_object($destinationObject) && $destinationObject->isPage)
00621                {
00622                     Logger::debug('WEBDAV: COPY request denied, Page copy not implemented');
00623                     $this->httpStatus('405 Not Allowed');
00624                }
00625                else
00626                {
00627                     $f = new File();
00628                     $f->filename = basename($_SERVER['HTTP_DESTINATION']);
00629                     $f->name     = '';
00630                     $f->parentid = $destinationFolder->objectid;
00631                     $f->projectid = $this->project->projectid;
00632                     $f->add();
00633                     $f->copyValueFromFile( $this->obj->objectid );
00634                     
00635                     #Logger::debug('WEBDAV: COPY request accepted, Destination: '.tinationObject->filename );
00636                     Logger::debug('WEBDAV: COPY request accepted' );
00637                     // Objekt wird in anderen Ordner kopiert.
00638                     $this->httpStatus('201 Created' );
00639                }    
00640           }
00641 
00642      }
00643 
00644 
00645           
00653      function move()
00654      {
00655           if   ( $this->readonly )
00656           {
00657                $this->httpStatus('403 Forbidden - Readonly Mode' ); // Schreibgeschuetzt
00658           }
00659           elseif    ( !$this->create )
00660           {
00661                $this->httpStatus('403 Forbidden - No creation' ); // Schreibgeschuetzt
00662           }
00663           elseif( $this->obj == null )
00664           {
00665                // Was nicht da ist, laesst sich auch nicht verschieben.
00666                $this->httpStatus('404 Not Found' );
00667           }
00668           elseif ( $this->destination == null )
00669           {
00670                Logger::error('WEBDAV: MOVE request, but no "Destination:"-Header');
00671                // $this->httpStatus('405 Not Allowed' );
00672                $this->httpStatus('412 Precondition failed');
00673           }
00674           else
00675           {
00676                $dest = $this->destination;
00677                $destinationProject = $dest['project'];
00678                $destinationFolder  = $dest['folder' ];
00679                $destinationObject  = $dest['object' ];
00680 
00681                if   ( $dest['type'] != 'object' )
00682                {
00683                     Logger::debug('WEBDAV: MOVE request, but "Destination:"-Header mismatch');
00684                     $this->httpStatus('405 Not Allowed');
00685                     exit;
00686                }
00687                
00688                if   ( $destinationObject != null )
00689                {
00690                     Logger::debug('WEBDAV: MOVE request denied, destination exists');
00691                     $this->httpStatus('412 Precondition Failed');
00692                     exit;
00693                }
00694                
00695                if   ( $this->project->projectid != $destinationProject->projectid )
00696                {
00697                     // Verschieben in anderes Projekt nicht moeglich.
00698                     Logger::debug('WEBDAV: MOVE request denied, project does not match');
00699                     $this->httpStatus('405 Not Allowed');
00700                     exit;
00701                }
00702                
00703                Logger::debug( "Vergl.".$this->folder->objectid.' mit '.$destinationFolder->objectid );
00704                
00705                if   ( $this->folder->objectid == $destinationFolder->objectid )
00706                {
00707                     Logger::debug('WEBDAV: MOVE request accepted, object renamed');
00708                     // Resource bleibt in gleichem Ordner.
00709                     $this->obj->filename = basename($_SERVER['HTTP_DESTINATION']);
00710                     $this->obj->objectSave(false);
00711                     $this->httpStatus('201 Created' );
00712                     exit;
00713                }
00714                
00715                if   ( $destinationFolder->isFolder )
00716                {
00717                     Logger::debug('WEBDAV: MOVE request accepted, Destination: '.$destinationFolder->filename );
00718                     // Objekt wird in anderen Ordner verschoben.
00719                     $this->obj->setParentId( $destinationFolder->objectid );
00720                     $this->httpStatus('201 Created' );
00721                     exit;
00722                }
00723                
00724                $this->httpStatus('500 Internal Server Error - move' );
00725           }
00726 
00727           exit;
00728      }
00729 
00730 
00731           
00739      function put()
00740      {
00741           // TODO: 409 (Conflict) wenn �bergeordneter Ordner nicht da.
00742 
00743           if   ( $this->webdav_conf['readonly'] )
00744           {
00745                $this->httpStatus('405 Not Allowed' );
00746           }         
00747           elseif    ( strlen($this->request) > $this->maxFileSize*1000 )
00748           {
00749                // Maximale Dateigroesse ueberschritten.
00750                // Der Status 207 "Zuwenig Speicherplatz" passt nicht ganz, aber fast :)
00751                $this->httpStatus('507 Insufficient Storage' );
00752           }
00753           elseif    ( $this->obj == null )
00754           {
00755                // Neue Datei anlegen
00756                if   ( !$this->webdav_conf['create'] )
00757                {
00758                     $this->httpStatus('405 Not Allowed' );
00759                }
00760                $file = new File();
00761                $file->filename  = basename($this->fullSkriptName);
00762                $file->extension = '';        
00763                $file->size      = strlen($this->request);
00764                $file->parentid  = $this->folder->objectid;
00765                $file->projectid = $this->project->projectid;
00766                $file->value     = $this->request;
00767                $file->add();
00768                $this->httpStatus('201 Created');
00769                exit;
00770           }
00771           elseif    ( $this->obj->isFile )
00772           {
00773                // Bestehende Datei ueberschreiben.
00774                $file = new File( $this->obj->objectid );
00775                $file->saveValue( $this->request );
00776                $file->setTimestamp();
00777                $this->httpStatus('204 No Content');
00778                exit;
00779           }
00780           else
00781           {
00782                // F�r andere Objekttypen (Verzeichnisse, Links, Seiten) ist kein PUT moeglich.
00783                $this->httpStatus('405 Not Allowed' );
00784           }
00785           exit;
00786      }
00787      
00788      
00789 
00795      function propfind()
00796      {
00797           switch( $this->requestType )
00798           {
00799                case 'projectlist':  // Projektliste
00800                     
00801                     $inhalte = array();
00802                     
00803                     $objektinhalt = array();
00804                     $z = 30*365.25*24*60*60;
00805                     $objektinhalt['createdate'    ] = $z;
00806                     $objektinhalt['lastchangedate'] = $z;
00807                     $objektinhalt['size'          ] = 1;
00808                     $objektinhalt['name'          ] = $this->fullSkriptName;
00809                     $objektinhalt['displayname'   ] = '';
00810                     $objektinhalt['type']           = 'folder';
00811 
00812                     $inhalte[] = $objektinhalt;
00813                     
00814                     foreach( Project::getAll() as $projectName )
00815                     {
00816                          $objektinhalt = array();
00817                          $z = 30*365.25*24*60*60;
00818                          $objektinhalt['createdate'    ] = $z;
00819                          $objektinhalt['lastchangedate'] = $z;
00820                          $objektinhalt['size'          ] = 1;
00821                          $objektinhalt['name'          ] = $this->fullSkriptName.$projectName.'/';
00822                          $objektinhalt['displayname'   ] = $projectName;
00823                          $objektinhalt['type']           = 'folder';
00824                          $inhalte[] = $objektinhalt;
00825                     }
00826                          
00827                     $this->multiStatus( $inhalte );
00828                     break;
00829 
00830                case 'object':  // Verzeichnisinhalt
00831                
00832                     if   ( $this->obj == null )
00833                     {
00834                          // Objekt existiert nicht.
00835                          Logger::debug( 'WEBDAV: PROPFIND of non-existent object');
00836                          $this->httpStatus('404 Not Found');
00837                          exit;
00838                          #$this->multiStatus( array() );
00839                     }
00840                     elseif    ( $this->obj->isFolder )
00841                     {
00842                          Logger::debug( 'WEBDAV: PROPFIND of folder');
00843 
00844                          $inhalte = array();
00845 
00846                          $objektinhalt = array();
00847                          $objektinhalt['createdate'    ] = $this->obj->createDate;
00848                          $objektinhalt['lastchangedate'] = $this->obj->lastchangeDate;
00849 //                       $objektinhalt['name'] = substr($this->fullSkriptName,0,strlen($this->fullSkriptName)-1);
00850                          $objektinhalt['name'] = $this->fullSkriptName;
00851                          $objektinhalt['displayname'] = basename($this->fullSkriptName);
00852                          $objektinhalt['type'] = 'folder';
00853                          $objektinhalt['size'] = 1;
00854                          $inhalte[] = $objektinhalt;
00855                          
00856                          if   ( $this->depth > 0 )
00857                          {
00858                               $objects = $this->folder->getObjects();
00859                               foreach( $objects as $object  )
00860                               {
00861                                    //$object->loadRaw();
00862                                    $objektinhalt = array();
00863                                    $objektinhalt['createdate'    ] = $object->createDate;
00864                                    $objektinhalt['lastchangedate'] = $object->lastchangeDate;
00865                                    $objektinhalt['displayname'   ] = $object->filename;
00866 
00867                                    switch( $object->getType() )
00868                                    {
00869                                         
00870                                         case OR_TYPE_FOLDER:
00871                                              $objektinhalt['name'] = $this->fullSkriptName.$object->filename.'/';
00872                                              $objektinhalt['type'] = 'folder';
00873                                              $objektinhalt['size'] = 1;
00874                                              $inhalte[] = $objektinhalt;
00875                                              break;
00876                                         case OR_TYPE_FILE:
00877                                              $objektinhalt['name'] = $this->fullSkriptName.$object->filename;
00878                                              $objektinhalt['type'] = 'file';
00879                                              $objektinhalt['size'] = 1;
00880                                              $objektinhalt['mime'] = 'application/x-non-readable';
00881                                              $inhalte[] = $objektinhalt;
00882                                              break;
00883                                         case OR_TYPE_LINK:
00884                                              $objektinhalt['name'] = $this->fullSkriptName.$object->filename;
00885                                              $objektinhalt['type'] = 'file';
00886                                              $objektinhalt['size'] = 0;
00887                                              $objektinhalt['mime'] = 'application/x-non-readable';
00888                                              $inhalte[] = $objektinhalt;
00889                                              break;
00890                                         case OR_TYPE_PAGE:
00891                                              $objektinhalt['name'] = $this->fullSkriptName.$object->filename;
00892                                              $objektinhalt['type'] = 'file';
00893                                              $objektinhalt['size'] = 0;
00894                                              $inhalte[] = $objektinhalt;
00895                                              break;
00896                                         default:
00897                                    }
00898                               }
00899                          }
00900                          Logger::debug( 'WEBDAV: PROPFIND2');
00901                          
00902 //                       if   ( count($inhalte)==0 )
00903 //                            $inhalte[] = array('createdate'=>0,'lastchangedate'=>0,'name'=>'empty','size'=>0,'type'=>'file');
00904                               
00905                          Logger::debug('Anzahl Dateien:'.count($inhalte));
00906                          $this->multiStatus( $inhalte );
00907                     }
00908                     else
00909                     {
00910                          $object = $this->obj;
00911                          Logger::debug( 'WEBDAV: PROPFIND of file');
00912                          $objektinhalt = array();
00913                          //$object->loadRaw();
00914                          $objektinhalt = array();
00915                          $objektinhalt['name']           = $this->fullSkriptName.'/'.$object->filename.'/';
00916                          $objektinhalt['displayname']    = $object->filename;
00917                          $objektinhalt['createdate'    ] = $object->createDate;
00918                          $objektinhalt['lastchangedate'] = $object->lastchangeDate;
00919                          $objektinhalt['size'          ] = 0;
00920                          $objektinhalt['type'          ] = 'file';
00921                          
00922                          
00923                          $this->multiStatus( array($objektinhalt) );
00924                     }
00925                     break;
00926                     
00927                default:
00928                     die('???:'.$this->requestType);
00929           }
00930           
00931           exit;
00932      }
00933      
00934      
00938      function proppatch()
00939      {
00940           // TODO: Multistatus erzeugen.
00941           $this->httpStatus('405 Not Allowed');
00942 //        $this->httpStatus('409 Conflict');
00943           exit;
00944      }
00945      
00946      
00950      function multiStatus( $files )
00951      {
00952           $this->httpStatus('207 Multi-Status');
00953           header('Content-Type: text/xml; charset=utf-8');
00954           
00955           $response = '';
00956           $response .= '<?xml version="1.0" encoding="utf-8" ?>';
00957           $response .= '<d:multistatus xmlns:d="DAV:">';
00958 
00959           foreach( $files as $file )
00960                $response .= $this->getResponse( $file['name'],$file );
00961           
00962           $response .= '</d:multistatus>';
00963           Logger::debug('PROPFIND-Ausgabe: '.$response);
00964 
00965           $response = utf8_encode($response);
00966 
00967           header('Content-Length: '.strlen($response));
00968           echo $response;
00969      }
00970      
00971      
00975      function getResponse( $file,$options )
00976      {
00977           // TODO: Nur angeforderte Elemente erzeugen.
00978           $response = '';
00979           $response .= '<d:response>';
00980           $response .= '<d:href>'.$file.'</d:href>';
00981           $response .= '<d:propstat>';
00982           $response .= '<d:prop>';
00983 //        $response .= '<d:source></d:source>';
00984           $response .= '<d:creationdate>'.date('r',$options['createdate']).'</d:creationdate>';
00985           $response .= '<d:displayname>'.$options['displayname'].'</d:displayname>';
00986           $response .= '<d:getcontentlength>'.$options['size'].'</d:getcontentlength>';
00987           $response .= '<d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">'.date('r',$options['lastchangedate']).'</d:getlastmodified>';
00988           
00989           if   ( $options['type'] == 'folder')
00990                $response .= '<d:resourcetype><d:collection/></d:resourcetype>';
00991           else
00992                $response .= '<d:resourcetype />';
00993                
00994           $response .= '<d:categories />';
00995           $response .= '<d:fields></d:fields>';
00996           
00997           
00998           
00999 //        $response .= '<d:getcontenttype>text/html</d:getcontenttype>';
01000 //        $response .= '<d:getcontentlength />';
01001 //        $response .= '<d:getcontentlanguage />';
01002 //        $response .= '<d:executable />';
01003 //        $response .= '<d:resourcetype>';
01004 //        $response .= '<d:collection />';
01005 //        $response .= '</d:resourcetype>';
01006 //        $response .= '<d:getetag />';
01007 
01008           $response .= '</d:prop>';
01009           $response .= '<d:status>HTTP/1.1 200 OK</d:status>';
01010           $response .= '</d:propstat>';
01011           $response .= '</d:response>';
01012 
01013           return $response;        
01014      }
01015      
01016      
01017      
01021      function parseURI( $uri )
01022      {
01023           // Ergebnis initialisieren (damit alle Schl�ssel vorhanden sind)
01024           $ergebnis = array('type'    => null,
01025                             'project' => null,
01026                             'path'    => array(),
01027                             'folder'  => null,
01028                             'object'  => null  );
01029           
01030           Logger::debug( 'WEBDAV: Parsen der URI '.$uri);
01031           $uriParts = explode('/',$uri);
01032           
01033           $nr = 0;
01034           $f = null;
01035           $o = null;
01036           $ergebnis['type'] = 'projectlist';
01037 
01038           foreach( $uriParts as $uriPart )
01039           {
01040                if   ( empty( $uriPart))
01041                     continue;
01042 
01043                $ergebnis['path'][] = $uriPart;    
01044 
01045                if   ( $f == null )           
01046                {
01047                     // URI='/project/'
01048                     // Name des Projektes in der URL, es wird das Projekt geladen.
01049                     $ergebnis['type'] = 'object';
01050                     
01051                     $p = new Project();
01052                     $p->name = $uriPart;
01053                     Logger::debug("Projektname: ".$p->name);
01054                     $p->loadByName();
01055                     $ergebnis['project'] = $p;
01056                     // Das Projekt hat weder Sprache noch Variante gesetzt.
01057                     //Session::setProjectLanguage( new Language( $this->project->getDefaultLanguageId() ) );
01058                     //Session::setProjectModel   ( new Model   ( $this->project->getDefaultModelId()    ) );
01059 
01060                     $oid = $p->getRootObjectId();
01061 
01062                     $f = new Folder($oid);
01063 //                  $ergebnis['folder'] = $f;
01064                     $ergebnis['object'] = $f;
01065                     $ergebnis['folder'] = $f;
01066                
01067                }
01068                else
01069                {
01070                     // URI='/project/a'
01071                     // URI='/project/a/'
01072                     if   ( $ergebnis['object'] == null )
01073                     {
01074                          $this->httpStatus('409 Conflict');
01075                          exit;
01076                     }
01077                     
01078                     $oid = $f->getObjectIdByFileName($uriPart);
01079 
01080                     if   ( $oid == 0 )
01081                     {
01082                          Logger::debug( 'WEBDAV: URL-Teil existiert nicht: '.$uriPart);
01083                          $ergebnis['object'] = null;
01084                     }
01085                     else
01086                     {
01087                          Logger::debug( 'Teil '.$uriPart);
01088                          $o = new Object($oid);
01089                          $o->load();
01090                          $ergebnis['object'] = $o;
01091                          
01092                          if   ( $o->isFolder )
01093                          {
01094                               $f = new Folder($oid);
01095                               $ergebnis['folder'] = $f;
01096                          }
01097                     }
01098                }
01099           }
01100 
01101           #Logger::debug( 'WEBDAV: Fertig Parsen der URI');
01102           
01103           return $ergebnis;
01104       }
01105 }
01106 
01107 
01108 
01114 function webdavErrorHandler($errno, $errstr, $errfile, $errline) 
01115 {
01116      Logger::warn('WEBDAV ERROR: '.$errno.'/'.$errstr.'/file:'.$errfile.'/line:'.$errline);
01117 
01118      // Wir teilen dem Client mit, dass auf dem Server was schief gelaufen ist. 
01119      WebdavAction::httpStatus('500 Internal Server Error');
01120 }
01121 
01122 ?>

Erzeugt am Thu May 14 00:55:48 2009 für OpenRat von  doxygen 1.5.8