This is based on the md5 of the file, can be changed latertags/v4.5.0beta1
@@ -26,17 +26,33 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa | |||
/** | |||
* Creates a new file in the directory | |||
* | |||
* data is a readable stream resource | |||
* Data will either be supplied as a stream resource, or in certain cases | |||
* as a string. Keep in mind that you may have to support either. | |||
* | |||
* After succesful creation of the file, you may choose to return the ETag | |||
* of the new file here. | |||
* | |||
* The returned ETag must be surrounded by double-quotes (The quotes should | |||
* be part of the actual string). | |||
* | |||
* If you cannot accurately determine the ETag, you should not return it. | |||
* If you don't store the file exactly as-is (you're transforming it | |||
* somehow) you should also not return an ETag. | |||
* | |||
* This means that if a subsequent GET to this new file does not exactly | |||
* return the same contents of what was submitted here, you are strongly | |||
* recommended to omit the ETag. | |||
* | |||
* @param string $name Name of the file | |||
* @param resource $data Initial payload | |||
* @return void | |||
* @param resource|string $data Initial payload | |||
* @return null|string | |||
*/ | |||
public function createFile($name, $data = null) { | |||
$newPath = $this->path . '/' . $name; | |||
OC_Filesystem::file_put_contents($newPath,$data); | |||
return OC_Connector_Sabre_Node::getETagPropertyForFile($newPath); | |||
} | |||
/** |
@@ -26,13 +26,28 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D | |||
/** | |||
* Updates the data | |||
* | |||
* The data argument is a readable stream resource. | |||
* | |||
* After a succesful put operation, you may choose to return an ETag. The | |||
* etag must always be surrounded by double-quotes. These quotes must | |||
* appear in the actual string you're returning. | |||
* | |||
* Clients may use the ETag from a PUT request to later on make sure that | |||
* when they update the file, the contents haven't changed in the mean | |||
* time. | |||
* | |||
* If you don't plan to store the file byte-by-byte, and you return a | |||
* different object on a subsequent GET you are strongly recommended to not | |||
* return an ETag, and just return null. | |||
* | |||
* @param resource $data | |||
* @return void | |||
* @return string|null | |||
*/ | |||
public function put($data) { | |||
OC_Filesystem::file_put_contents($this->path,$data); | |||
return OC_Connector_Sabre_Node::getETagPropertyForFile($this->path); | |||
} | |||
/** | |||
@@ -79,9 +94,11 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D | |||
* @return mixed | |||
*/ | |||
public function getETag() { | |||
return null; | |||
$properties = $this->getProperties(array(self::GETETAG_PROPERTYNAME)); | |||
if (isset($properties[self::GETETAG_PROPERTYNAME])) { | |||
return $properties[self::GETETAG_PROPERTYNAME]; | |||
} | |||
return $this->getETagPropertyForFile($this->path); | |||
} | |||
/** |
@@ -22,6 +22,7 @@ | |||
*/ | |||
abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties { | |||
const GETETAG_PROPERTYNAME = '{DAV:}getetag'; | |||
/** | |||
* The path to the current node | |||
@@ -200,4 +201,29 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr | |||
} | |||
return $props; | |||
} | |||
/** | |||
* Returns the ETag surrounded by double-quotes for this path. | |||
* @param string $path Path of the file | |||
* @return string|null Returns null if the ETag can not effectively be determined | |||
*/ | |||
static public function getETagPropertyForFile($path) { | |||
$tag = OC_Filesystem::hash('md5', $path); | |||
if (empty($tag)) { | |||
return null; | |||
} | |||
$etag = '"'.$tag.'"'; | |||
$query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' ); | |||
$query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag )); | |||
return $etag; | |||
} | |||
/** | |||
* Remove the ETag from the cache. | |||
* @param string $path Path of the file | |||
*/ | |||
static public function removeETagPropertyForFile($path) { | |||
$query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); | |||
$query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME )); | |||
} | |||
} |
@@ -483,7 +483,15 @@ class OC_Filesystem{ | |||
static public function hasUpdated($path,$time){ | |||
return self::$defaultInstance->hasUpdated($path,$time); | |||
} | |||
static public function removeETagHook() { | |||
$path=$params['path']; | |||
OC_Connector_Sabre_Node::removeETagPropertyForFile($path); | |||
} | |||
} | |||
OC_Hook::connect('OC_Filesystem','post_write', 'OC_Filesystem','removeETagHook'); | |||
OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook'); | |||
OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook'); | |||
OC_Util::setupFS(); | |||
require_once('filecache.php'); |