Blame view
sources/lib/private/connector/sabre/node.php
7.85 KB
|
03e52840d
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php
/**
* ownCloud
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack kde@jakobsack.de
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties {
const GETETAG_PROPERTYNAME = '{DAV:}getetag';
const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
/**
* Allow configuring the method used to generate Etags
*
* @var array(class_name, function_name)
*/
public static $ETagFunction = null;
/**
|
|
31b7f2792
|
36 37 38 39 40 41 42 |
* is kept public to allow overwrite for unit testing * * @var \OC\Files\View */ public $fileView; /** |
|
03e52840d
|
43 44 45 46 47 |
* The path to the current node * * @var string */ protected $path; |
|
31b7f2792
|
48 |
|
|
03e52840d
|
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
/**
* node fileinfo cache
* @var array
*/
protected $fileinfo_cache;
/**
* node properties cache
* @var array
*/
protected $property_cache = null;
/**
* @brief Sets up the node, expects a full path name
* @param string $path
* @return void
*/
public function __construct($path) {
$this->path = $path;
}
/**
* @brief Returns the name of the node
* @return string
*/
public function getName() {
list(, $name) = Sabre_DAV_URLUtil::splitPath($this->path);
return $name;
}
/**
* @brief Renames the node
* @param string $name The new name
* @return void
*/
public function setName($name) {
// rename is only allowed if the update privilege is granted
if (!\OC\Files\Filesystem::isUpdatable($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path);
list(, $newName) = Sabre_DAV_URLUtil::splitPath($name);
$newPath = $parentPath . '/' . $newName;
$oldPath = $this->path;
\OC\Files\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 ));
}
public function setFileinfoCache($fileinfo_cache)
{
$this->fileinfo_cache = $fileinfo_cache;
}
/**
* @brief Ensure that the fileinfo cache is filled
* @note Uses OC_FileCache or a direct stat
*/
protected function getFileinfoCache() {
if (!isset($this->fileinfo_cache)) {
if ($fileinfo_cache = \OC\Files\Filesystem::getFileInfo($this->path)) {
} else {
$fileinfo_cache = \OC\Files\Filesystem::stat($this->path);
}
$this->fileinfo_cache = $fileinfo_cache;
}
}
public function setPropertyCache($property_cache)
{
$this->property_cache = $property_cache;
}
/**
* @brief Returns the last modification time, as a unix timestamp
|
|
837968727
|
137 |
* @return int timestamp as integer |
|
03e52840d
|
138 139 140 |
*/
public function getLastModified() {
$this->getFileinfoCache();
|
|
837968727
|
141 142 143 144 145 |
$timestamp = $this->fileinfo_cache['mtime'];
if (!empty($timestamp)) {
return (int)$timestamp;
}
return $timestamp;
|
|
03e52840d
|
146 147 148 149 150 151 152 153 |
}
/**
* sets the last modification time of the file (mtime) to the value given
* in the second parameter or to now if the second param is empty.
* Even if the modification time is set to a custom value the access time is set to now.
*/
public function touch($mtime) {
|
|
03e52840d
|
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
\OC\Files\Filesystem::touch($this->path, $mtime);
}
/**
* @brief 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( strcmp( $propertyName, self::GETETAG_PROPERTYNAME) === 0 ) {
\OC\Files\Filesystem::putFileInfo($this->path, array('etag'=> $propertyValue));
} elseif( strcmp( $propertyName, self::LASTMODIFIED_PROPERTYNAME) === 0 ) {
$this->touch($propertyValue);
} 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 ));
} 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 ));
}
}
}
}
$this->setPropertyCache(null);
return true;
}
/**
|
|
31b7f2792
|
198 199 200 201 202 203 204 205 206 207 208 |
* removes all properties for this node and user
*/
public function removeProperties() {
$query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`'
.' WHERE `userid` = ? AND `propertypath` = ?' );
$query->execute( array( OC_User::getUser(), $this->path));
$this->setPropertyCache(null);
}
/**
|
|
03e52840d
|
209 210 211 212 213 214 215 216 217 |
* @brief Returns a list of properties for this nodes.;
* @param array $properties
* @return array
* @note 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
*/
public function getProperties($properties) {
|
|
31b7f2792
|
218 |
|
|
03e52840d
|
219 |
if (is_null($this->property_cache)) {
|
|
31b7f2792
|
220 221 |
$sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?'; $result = OC_DB::executeAudited( $sql, array( OC_User::getUser(), $this->path ) ); |
|
03e52840d
|
222 223 224 225 226 |
$this->property_cache = array();
while( $row = $result->fetchRow()) {
$this->property_cache[$row['propertyname']] = $row['propertyvalue'];
}
|
|
31b7f2792
|
227 228 229 230 231 232 233 234 |
// Don't call the static getETagPropertyForPath, its result is not cached
$this->getFileinfoCache();
if ($this->fileinfo_cache['etag']) {
$this->property_cache[self::GETETAG_PROPERTYNAME] = '"'.$this->fileinfo_cache['etag'].'"';
} else {
$this->property_cache[self::GETETAG_PROPERTYNAME] = null;
}
|
|
03e52840d
|
235 236 237 238 239 240 241 242 243 |
}
// if the array was empty, we need to return everything
if(count($properties) == 0) {
return $this->property_cache;
}
$props = array();
foreach($properties as $property) {
|
|
31b7f2792
|
244 245 246 |
if (isset($this->property_cache[$property])) {
$props[$property] = $this->property_cache[$property];
}
|
|
03e52840d
|
247 |
} |
|
31b7f2792
|
248 |
|
|
03e52840d
|
249 250 251 252 253 254 255 256 |
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 */ |
|
31b7f2792
|
257 258 |
protected function getETagPropertyForPath($path) {
$data = $this->getFS()->getFileInfo($path);
|
|
03e52840d
|
259 260 261 262 263 |
if (isset($data['etag'])) {
return '"'.$data['etag'].'"';
}
return null;
}
|
|
31b7f2792
|
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
protected function getFS() {
if (is_null($this->fileView)) {
$this->fileView = \OC\Files\Filesystem::getView();
}
return $this->fileView;
}
/**
* @return mixed
*/
public function getFileId()
{
$this->getFileinfoCache();
if (isset($this->fileinfo_cache['fileid'])) {
$instanceId = OC_Util::getInstanceId();
$id = sprintf('%08d', $this->fileinfo_cache['fileid']);
return $id . $instanceId;
}
return null;
}
|
|
03e52840d
|
286 |
} |