dataDir = $dataDir; } /** * Initialize the addon * * This is called automatically be the Server class after this addon is * added with Sabre_DAV_Server::addPlugin() * * @param Sabre_DAV_Server $server * @return void */ public function initialize(Sabre_DAV_Server $server) { $this->server = $server; $server->subscribeEvent('beforeMethod',array($this,'beforeMethod')); $server->subscribeEvent('beforeCreateFile',array($this,'beforeCreateFile')); } /** * This method is called before any HTTP method handler * * This method intercepts any GET, DELETE, PUT and PROPFIND calls to * filenames that are known to match the 'temporary file' regex. * * @param string $method * @param string $uri * @return bool */ public function beforeMethod($method, $uri) { if (!$tempLocation = $this->isTempFile($uri)) return true; switch($method) { case 'GET' : return $this->httpGet($tempLocation); case 'PUT' : return $this->httpPut($tempLocation); case 'PROPFIND' : return $this->httpPropfind($tempLocation, $uri); case 'DELETE' : return $this->httpDelete($tempLocation); } return true; } /** * This method is invoked if some subsystem creates a new file. * * This is used to deal with HTTP LOCK requests which create a new * file. * * @param string $uri * @param resource $data * @return bool */ public function beforeCreateFile($uri,$data) { if ($tempPath = $this->isTempFile($uri)) { $hR = $this->server->httpResponse; $hR->setHeader('X-Sabre-Temp','true'); file_put_contents($tempPath,$data); return false; } return true; } /** * This method will check if the url matches the temporary file pattern * if it does, it will return an path based on $this->dataDir for the * temporary file storage. * * @param string $path * @return boolean|string */ protected function isTempFile($path) { // We're only interested in the basename. list(, $tempPath) = Sabre_DAV_URLUtil::splitPath($path); foreach($this->temporaryFilePatterns as $tempFile) { if (preg_match($tempFile,$tempPath)) { return $this->getDataDir() . '/sabredav_' . md5($path) . '.tempfile'; } } return false; } /** * This method handles the GET method for temporary files. * If the file doesn't exist, it will return false which will kick in * the regular system for the GET method. * * @param string $tempLocation * @return bool */ public function httpGet($tempLocation) { if (!file_exists($tempLocation)) return true; $hR = $this->server->httpResponse; $hR->setHeader('Content-Type','application/octet-stream'); $hR->setHeader('Content-Length',filesize($tempLocation)); $hR->setHeader('X-Sabre-Temp','true'); $hR->sendStatus(200); $hR->sendBody(fopen($tempLocation,'r')); return false; } /** * This method handles the PUT method. * * @param string $tempLocation * @return bool */ public function httpPut($tempLocation) { $hR = $this->server->httpResponse; $hR->setHeader('X-Sabre-Temp','true'); $newFile = !file_exists($tempLocation); if (!$newFile && ($this->server->httpRequest->getHeader('If-None-Match'))) { throw new Sabre_DAV_Exception_PreconditionFailed('The resource already exists, and an If-None-Match header was supplied'); } file_put_contents($tempLocation,$this->server->httpRequest->getBody()); $hR->sendStatus($newFile?201:200); return false; } /** * This method handles the DELETE method. * * If the file didn't exist, it will return false, which will make the * standard HTTP DELETE handler kick in. * * @param string $tempLocation * @return bool */ public function httpDelete($tempLocation) { if (!file_exists($tempLocation)) return true; unlink($tempLocation); $hR = $this->server->httpResponse; $hR->setHeader('X-Sabre-Temp','true'); $hR->sendStatus(204); return false; } /** * This method handles the PROPFIND method. * * It's a very lazy method, it won't bother checking the request body * for which properties were requested, and just sends back a default * set of properties. * * @param string $tempLocation * @param string $uri * @return bool */ public function httpPropfind($tempLocation, $uri) { if (!file_exists($tempLocation)) return true; $hR = $this->server->httpResponse; $hR->setHeader('X-Sabre-Temp','true'); $hR->sendStatus(207); $hR->setHeader('Content-Type','application/xml; charset=utf-8'); $this->server->parsePropFindRequest($this->server->httpRequest->getBody(true)); $properties = array( 'href' => $uri, 200 => array( '{DAV:}getlastmodified' => new Sabre_DAV_Property_GetLastModified(filemtime($tempLocation)), '{DAV:}getcontentlength' => filesize($tempLocation), '{DAV:}resourcetype' => new Sabre_DAV_Property_ResourceType(null), '{'.Sabre_DAV_Server::NS_SABREDAV.'}tempFile' => true, ), ); $data = $this->server->generateMultiStatus(array($properties)); $hR->sendBody($data); return false; } /** * This method returns the directory where the temporary files should be stored. * * @return string */ protected function getDataDir() { return $this->dataDir; } }