From 7c9f356abeaaa9348332908bfcced21be88011ac Mon Sep 17 00:00:00 2001 From: Jakob Sack Date: Fri, 22 Jul 2011 14:38:42 +0200 Subject: Support for locks, minor changes --- lib/Connector/Sabre/auth.php | 35 ++++++++++ lib/Connector/Sabre/directory.php | 131 ++++++++++++++++++++++++++++++++++++ lib/Connector/Sabre/file.php | 89 ++++++++++++++++++++++++ lib/Connector/Sabre/locks.php | 138 ++++++++++++++++++++++++++++++++++++++ lib/Connector/Sabre/node.php | 81 ++++++++++++++++++++++ 5 files changed, 474 insertions(+) create mode 100644 lib/Connector/Sabre/auth.php create mode 100644 lib/Connector/Sabre/directory.php create mode 100644 lib/Connector/Sabre/file.php create mode 100644 lib/Connector/Sabre/locks.php create mode 100644 lib/Connector/Sabre/node.php (limited to 'lib/Connector') diff --git a/lib/Connector/Sabre/auth.php b/lib/Connector/Sabre/auth.php new file mode 100644 index 00000000000..cfe7723e761 --- /dev/null +++ b/lib/Connector/Sabre/auth.php @@ -0,0 +1,35 @@ +path . '/' . $name; + OC_FILESYSTEM::file_put_contents($newPath,$data); + + } + + /** + * Creates a new subdirectory + * + * @param string $name + * @return void + */ + public function createDirectory($name) { + + $newPath = $this->path . '/' . $name; + OC_FILESYSTEM::mkdir($newPath); + + } + + /** + * Returns a specific child node, referenced by its name + * + * @param string $name + * @throws Sabre_DAV_Exception_FileNotFound + * @return Sabre_DAV_INode + */ + public function getChild($name) { + + $path = $this->path . '/' . $name; + + if (!OC_FILESYSTEM::file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File with name ' . $path . ' could not be located'); + + if (OC_FILESYSTEM::is_dir($path)) { + + return new OC_Connector_Sabre_Directory($path); + + } else { + + return new OC_Connector_Sabre_File($path); + + } + + } + + /** + * Returns an array with all the child nodes + * + * @return Sabre_DAV_INode[] + */ + public function getChildren() { + + $nodes = array(); + // foreach(scandir($this->path) as $node) if($node!='.' && $node!='..') $nodes[] = $this->getChild($node); + if( OC_FILESYSTEM::is_dir($this->path)){ + $dh = OC_FILESYSTEM::opendir($this->path); + while(( $node = readdir($dh)) !== false ){ + if($node!='.' && $node!='..'){ + $nodes[] = $this->getChild($node); + } + } + } + return $nodes; + + } + + /** + * Checks if a child exists. + * + * @param string $name + * @return bool + */ + public function childExists($name) { + + $path = $this->path . '/' . $name; + return OC_FILESYSTEM::file_exists($path); + + } + + /** + * Deletes all files in this directory, and then itself + * + * @return void + */ + public function delete() { + + foreach($this->getChildren() as $child) $child->delete(); + OC_FILESYSTEM::rmdir($this->path); + + } + + /** + * Returns available diskspace information + * + * @return array + */ + public function getQuotaInfo() { + + return array( + OC_FILESYSTEM::filesize('/'), + OC_FILESYSTEM::free_space() + ); + + } + +} + diff --git a/lib/Connector/Sabre/file.php b/lib/Connector/Sabre/file.php new file mode 100644 index 00000000000..bb5ab738430 --- /dev/null +++ b/lib/Connector/Sabre/file.php @@ -0,0 +1,89 @@ +path,$data); + + } + + /** + * Returns the data + * + * @return string + */ + public function get() { + + return OC_FILESYSTEM::file_get_contents($this->path); + + } + + /** + * Delete the current file + * + * @return void + */ + public function delete() { + + OC_FILESYSTEM::unlink($this->path); + + } + + /** + * Returns the size of the node, in bytes + * + * @return int + */ + public function getSize() { + + return OC_FILESYSTEM::filesize($this->path); + + } + + /** + * Returns the ETag for a file + * + * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change. + * The ETag is an arbritrary string, but MUST be surrounded by double-quotes. + * + * Return null if the ETag can not effectively be determined + * + * @return mixed + */ + public function getETag() { + + return null; + + } + + /** + * Returns the mime-type for a file + * + * If null is returned, we'll assume application/octet-stream + * + * @return mixed + */ + public function getContentType() { + + return OC_FILESYSTEM::getMimeType($this->path); + + } +} + diff --git a/lib/Connector/Sabre/locks.php b/lib/Connector/Sabre/locks.php new file mode 100644 index 00000000000..58a0359899e --- /dev/null +++ b/lib/Connector/Sabre/locks.php @@ -0,0 +1,138 @@ + CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)'; + $params = array(time(),$uri); + + // We need to check locks for every part in the uri. + $uriParts = explode('/',$uri); + + // We already covered the last part of the uri + array_pop($uriParts); + + $currentPath=''; + + foreach($uriParts as $part) { + + if ($currentPath) $currentPath.='/'; + $currentPath.=$part; + + $query.=' OR (depth!=0 AND uri = ?)'; + $params[] = $currentPath; + + } + + if ($returnChildLocks) { + + $query.=' OR (uri LIKE ?)'; + $params[] = $uri . '/%'; + + } + $query.=')'; + + $stmt = OC_DB::prepare($query); + $result = $stmt->execute($params); + + $lockList = array(); + while( $row = $result->fetchRow()){ + + $lockInfo = new Sabre_DAV_Locks_LockInfo(); + $lockInfo->owner = $row['owner']; + $lockInfo->token = $row['token']; + $lockInfo->timeout = $row['timeout']; + $lockInfo->created = $row['created']; + $lockInfo->scope = $row['scope']; + $lockInfo->depth = $row['depth']; + $lockInfo->uri = $row['uri']; + $lockList[] = $lockInfo; + + } + + return $lockList; + + } + + /** + * Locks a uri + * + * @param string $uri + * @param Sabre_DAV_Locks_LockInfo $lockInfo + * @return bool + */ + public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) { + + // We're making the lock timeout 5 minutes + $lockInfo->timeout = 300; + $lockInfo->created = time(); + $lockInfo->uri = $uri; + + $locks = $this->getLocks($uri,false); + $exists = false; + foreach($locks as $k=>$lock) { + if ($lock->token == $lockInfo->token) $exists = true; + } + + if ($exists) { + $query = OC_DB::prepare( 'UPDATE *PREFIX*locks SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?' ); + $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); + } else { + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*locks (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)' ); + $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); + } + + return true; + + } + + + + /** + * Removes a lock from a uri + * + * @param string $uri + * @param Sabre_DAV_Locks_LockInfo $lockInfo + * @return bool + */ + public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) { + + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE path=? AND token=?' ); + $result = $query->execute( array($uri,$lockInfo->token)); + + return $result->numRows() === 1; + + } + +} + diff --git a/lib/Connector/Sabre/node.php b/lib/Connector/Sabre/node.php new file mode 100644 index 00000000000..fb607a709e4 --- /dev/null +++ b/lib/Connector/Sabre/node.php @@ -0,0 +1,81 @@ +path = $path; + } + + + + /** + * Returns the name of the node + * + * @return string + */ + public function getName() { + + list(, $name) = Sabre_DAV_URLUtil::splitPath($this->path); + return $name; + + } + + /** + * Renames the node + * + * @param string $name The new name + * @return void + */ + public function setName($name) { + + list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); + list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); + + $newPath = $parentPath . '/' . $newName; + OC_FILESYSTEM::rename($this->path,$newPath); + + $this->path = $newPath; + + } + + + + /** + * Returns the last modification time, as a unix timestamp + * + * @return int + */ + public function getLastModified() { + + return OC_FILESYSTEM::filemtime($this->path); + + } + +} + -- cgit v1.2.3 From 5851da47f11d0b06c6415e22b080341d643aef14 Mon Sep 17 00:00:00 2001 From: Jakob Sack Date: Fri, 22 Jul 2011 16:21:29 +0200 Subject: properties nearly work --- lib/Connector/Sabre/locks.php | 17 ++++++++++ lib/Connector/Sabre/node.php | 77 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) (limited to 'lib/Connector') diff --git a/lib/Connector/Sabre/locks.php b/lib/Connector/Sabre/locks.php index 58a0359899e..ed5ea17beab 100644 --- a/lib/Connector/Sabre/locks.php +++ b/lib/Connector/Sabre/locks.php @@ -13,6 +13,23 @@ require_once("lib/base.php"); * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ +/* + * + * The following SQL statement is just a help for developers and will not be + * executed! + * + * CREATE TABLE locks ( + * `id` INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + * `owner` VARCHAR(100), + * `timeout` INTEGER UNSIGNED, + * `created` INTEGER, + * `token` VARCHAR(100), + * `scope` TINYINT, + * `depth` TINYINT, + * `uri` text + * ); + * + */ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { /** diff --git a/lib/Connector/Sabre/node.php b/lib/Connector/Sabre/node.php index fb607a709e4..0e8bae75fd9 100644 --- a/lib/Connector/Sabre/node.php +++ b/lib/Connector/Sabre/node.php @@ -13,7 +13,20 @@ require_once("lib/base.php"); * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode { +/* + * + * The following SQL statement is just a help for developers and will not be + * executed! + * + * CREATE TABLE IF NOT EXISTS `properties` ( + * `userid` varchar(200) COLLATE utf8_unicode_ci NOT NULL, + * `propertypath` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + * `propertyname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + * `propertyvalue` text COLLATE utf8_unicode_ci NOT NULL + * ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + * + */ +abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties { /** * The path to the current node @@ -77,5 +90,67 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode { } + /** + * Updates properties on this node, + * + * @param array $mutations + * @see Sabre_DAV_IProperties::updateProperties + * @return bool|array + */ + public function updateProperties($properties) { + $existing = $this->getProperties(array()); + foreach($properties as $propertyName => $propertyValue) { + // If it was null, we need to delete the property + if (is_null($propertyValue)) { + if(array_key_exists( $propertyName, $existing )){ + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); + $query->execute( array( 'OC_USER::getUser()', $this->path, $propertyName )); + } + } + else { + if(!array_key_exists( $propertyName, $existing )){ + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' ); + $query->execute( array( 'OC_USER::getUser()', $this->path, $propertyName,$propertyValue )); + } + elseif($existing[$propertyName] !== $propertyValue){ + $query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertyvalue = ? WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); + $query->execute( array( $propertyValue,'OC_USER::getUser()', $this->path, $propertyName )); + } + } + + } + return true; + } + + /** + * Returns a list of properties for this nodes.; + * + * The properties list is a list of propertynames the client requested, encoded as xmlnamespace#tagName, for example: http://www.example.org/namespace#author + * If the array is empty, all properties should be returned + * + * @param array $properties + * @return void + */ + function getProperties($properties) { + // At least some magic in here :-) + $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); + $result = $query->execute( array( 'OC_USER::getUser()', $this->path )); + + $existing = array(); + while( $row = $result->fetchRow()){ + $existing[$row['propertyname']] = $row['propertyvalue']; + } + + if(count($properties) == 0){ + return $existing; + } + + // if the array was empty, we need to return everything + $props = array(); + foreach($properties as $property) { + if (isset($existing[$property])) $props[$property] = $existing[$property]; + } + return $props; + } } -- cgit v1.2.3 From 3b92ec12c215754e84d7702e3f98e9428d5f9c3f Mon Sep 17 00:00:00 2001 From: Jakob Sack Date: Fri, 22 Jul 2011 22:30:45 +0200 Subject: Properties work fine now --- lib/Connector/Sabre/locks.php | 19 +++++++++---------- lib/Connector/Sabre/node.php | 15 ++++++++++----- 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'lib/Connector') diff --git a/lib/Connector/Sabre/locks.php b/lib/Connector/Sabre/locks.php index ed5ea17beab..6c370b188fb 100644 --- a/lib/Connector/Sabre/locks.php +++ b/lib/Connector/Sabre/locks.php @@ -20,6 +20,7 @@ require_once("lib/base.php"); * * CREATE TABLE locks ( * `id` INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + * `userid` VARCHAR(200), * `owner` VARCHAR(100), * `timeout` INTEGER UNSIGNED, * `created` INTEGER, @@ -50,8 +51,8 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { // NOTE: the following 10 lines or so could be easily replaced by // pure sql. MySQL's non-standard string concatination prevents us // from doing this though. - $query = 'SELECT owner, token, timeout, created, scope, depth, uri FROM *PREFIX*locks WHERE ((created + timeout) > CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)'; - $params = array(time(),$uri); + $query = 'SELECT * FROM *PREFIX*locks WHERE userid = ? AND ((created + timeout) > CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)'; + $params = array(OC_USER::getUser(),time(),$uri); // We need to check locks for every part in the uri. $uriParts = explode('/',$uri); @@ -122,19 +123,17 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { } if ($exists) { - $query = OC_DB::prepare( 'UPDATE *PREFIX*locks SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?' ); - $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); + $query = OC_DB::prepare( 'UPDATE *PREFIX*locks SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE userid = ? AND token = ?' ); + $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,OC_USER::getUser(),$lockInfo->token)); } else { - $query = OC_DB::prepare( 'INSERT INTO *PREFIX*locks (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)' ); - $result = $query->execute( array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*locks (userid,owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?,?)' ); + $result = $query->execute( array(OC_USER::getUser(),$lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token)); } return true; } - - /** * Removes a lock from a uri * @@ -144,8 +143,8 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { */ public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) { - $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE path=? AND token=?' ); - $result = $query->execute( array($uri,$lockInfo->token)); + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE userid = ? AND path=? AND token=?' ); + $result = $query->execute( array(OC_USER::getUser(),$uri,$lockInfo->token)); return $result->numRows() === 1; diff --git a/lib/Connector/Sabre/node.php b/lib/Connector/Sabre/node.php index 0e8bae75fd9..dc1013dc524 100644 --- a/lib/Connector/Sabre/node.php +++ b/lib/Connector/Sabre/node.php @@ -71,9 +71,14 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); $newPath = $parentPath . '/' . $newName; + $oldPath = $this->path; + OC_FILESYSTEM::rename($this->path,$newPath); $this->path = $newPath; + + $query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertypath = ? WHERE userid = ? AND propertypath = ?' ); + $query->execute( array( $newPath,OC_USER::getUser(), $oldPath )); } @@ -104,17 +109,17 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr if (is_null($propertyValue)) { if(array_key_exists( $propertyName, $existing )){ $query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); - $query->execute( array( 'OC_USER::getUser()', $this->path, $propertyName )); + $query->execute( array( OC_USER::getUser(), $this->path, $propertyName )); } } else { if(!array_key_exists( $propertyName, $existing )){ $query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' ); - $query->execute( array( 'OC_USER::getUser()', $this->path, $propertyName,$propertyValue )); + $query->execute( array( OC_USER::getUser(), $this->path, $propertyName,$propertyValue )); } - elseif($existing[$propertyName] !== $propertyValue){ + else{ $query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertyvalue = ? WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); - $query->execute( array( $propertyValue,'OC_USER::getUser()', $this->path, $propertyName )); + $query->execute( array( $propertyValue,OC_USER::getUser(), $this->path, $propertyName )); } } @@ -134,7 +139,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr function getProperties($properties) { // At least some magic in here :-) $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); - $result = $query->execute( array( 'OC_USER::getUser()', $this->path )); + $result = $query->execute( array( OC_USER::getUser(), $this->path )); $existing = array(); while( $row = $result->fetchRow()){ -- cgit v1.2.3 From 18a36be28cd94dd8d04c60f02b42bc79a5173b2f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 22 Jul 2011 23:06:53 +0200 Subject: fix problem with removing locks --- lib/Connector/Sabre/locks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Connector') diff --git a/lib/Connector/Sabre/locks.php b/lib/Connector/Sabre/locks.php index 6c370b188fb..8414891b778 100644 --- a/lib/Connector/Sabre/locks.php +++ b/lib/Connector/Sabre/locks.php @@ -143,7 +143,7 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { */ public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) { - $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE userid = ? AND path=? AND token=?' ); + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*locks WHERE userid = ? AND uri=? AND token=?' ); $result = $query->execute( array(OC_USER::getUser(),$uri,$lockInfo->token)); return $result->numRows() === 1; -- cgit v1.2.3