Blame view

sources/lib/private/connector/sabre/node.php 7.33 KB
03e52840d   Kload   Init
1
  <?php
6d9380f96   Cédric Dupont   Update sources OC...
2
  use Sabre\DAV\URLUtil;
03e52840d   Kload   Init
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  
  /**
   * 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/>.
   *
   */
6d9380f96   Cédric Dupont   Update sources OC...
24
  abstract class OC_Connector_Sabre_Node implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
03e52840d   Kload   Init
25
26
27
28
29
30
31
  	const GETETAG_PROPERTYNAME = '{DAV:}getetag';
  	const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
  
  	/**
  	 * Allow configuring the method used to generate Etags
  	 *
  	 * @var array(class_name, function_name)
6d9380f96   Cédric Dupont   Update sources OC...
32
  	 */
03e52840d   Kload   Init
33
34
35
  	public static $ETagFunction = null;
  
  	/**
31b7f2792   Kload   Upgrade to ownclo...
36
37
  	 * @var \OC\Files\View
  	 */
6d9380f96   Cédric Dupont   Update sources OC...
38
  	protected $fileView;
31b7f2792   Kload   Upgrade to ownclo...
39
40
  
  	/**
03e52840d   Kload   Init
41
42
43
44
45
  	 * The path to the current node
  	 *
  	 * @var string
  	 */
  	protected $path;
31b7f2792   Kload   Upgrade to ownclo...
46

03e52840d   Kload   Init
47
  	/**
03e52840d   Kload   Init
48
  	 * node properties cache
6d9380f96   Cédric Dupont   Update sources OC...
49
  	 *
03e52840d   Kload   Init
50
51
52
53
54
  	 * @var array
  	 */
  	protected $property_cache = null;
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
55
  	 * @var \OCP\Files\FileInfo
03e52840d   Kload   Init
56
  	 */
6d9380f96   Cédric Dupont   Update sources OC...
57
  	protected $info;
03e52840d   Kload   Init
58

6d9380f96   Cédric Dupont   Update sources OC...
59
60
61
62
63
64
65
66
67
68
  	/**
  	 * Sets up the node, expects a full path name
  	 * @param \OC\Files\View $view
  	 * @param \OCP\Files\FileInfo $info
  	 */
  	public function __construct($view, $info) {
  		$this->fileView = $view;
  		$this->path = $this->fileView->getRelativePath($info->getPath());
  		$this->info = $info;
  	}
03e52840d   Kload   Init
69

6d9380f96   Cédric Dupont   Update sources OC...
70
71
72
  	protected function refreshInfo() {
  		$this->info = $this->fileView->getFileInfo($this->path);
  	}
03e52840d   Kload   Init
73
74
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
75
  	 *  Returns the name of the node
03e52840d   Kload   Init
76
77
78
  	 * @return string
  	 */
  	public function getName() {
6d9380f96   Cédric Dupont   Update sources OC...
79
  		return $this->info->getName();
03e52840d   Kload   Init
80
81
82
  	}
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
83
  	 * Renames the node
03e52840d   Kload   Init
84
  	 * @param string $name The new name
6d9380f96   Cédric Dupont   Update sources OC...
85
86
  	 * @throws \Sabre\DAV\Exception\BadRequest
  	 * @throws \Sabre\DAV\Exception\Forbidden
03e52840d   Kload   Init
87
88
89
90
  	 */
  	public function setName($name) {
  
  		// rename is only allowed if the update privilege is granted
6d9380f96   Cédric Dupont   Update sources OC...
91
92
  		if (!$this->info->isUpdateable()) {
  			throw new \Sabre\DAV\Exception\Forbidden();
03e52840d   Kload   Init
93
  		}
6d9380f96   Cédric Dupont   Update sources OC...
94
95
96
97
98
99
  		list($parentPath,) = URLUtil::splitPath($this->path);
  		list(, $newName) = URLUtil::splitPath($name);
  
  		if (!\OCP\Util::isValidFileName($newName)) {
  			throw new \Sabre\DAV\Exception\BadRequest();
  		}
03e52840d   Kload   Init
100
101
102
  
  		$newPath = $parentPath . '/' . $newName;
  		$oldPath = $this->path;
6d9380f96   Cédric Dupont   Update sources OC...
103
  		$this->fileView->rename($this->path, $newPath);
03e52840d   Kload   Init
104
105
  
  		$this->path = $newPath;
6d9380f96   Cédric Dupont   Update sources OC...
106
107
108
109
  		$query = OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?'
  			. ' WHERE `userid` = ? AND `propertypath` = ?');
  		$query->execute(array($newPath, OC_User::getUser(), $oldPath));
  		$this->refreshInfo();
03e52840d   Kload   Init
110
  	}
6d9380f96   Cédric Dupont   Update sources OC...
111
  	public function setPropertyCache($property_cache) {
03e52840d   Kload   Init
112
113
114
115
  		$this->property_cache = $property_cache;
  	}
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
116
  	 * Returns the last modification time, as a unix timestamp
837968727   Kload   [enh] Upgrade to ...
117
  	 * @return int timestamp as integer
03e52840d   Kload   Init
118
119
  	 */
  	public function getLastModified() {
6d9380f96   Cédric Dupont   Update sources OC...
120
  		$timestamp = $this->info->getMtime();
837968727   Kload   [enh] Upgrade to ...
121
122
123
124
  		if (!empty($timestamp)) {
  			return (int)$timestamp;
  		}
  		return $timestamp;
03e52840d   Kload   Init
125
126
127
128
129
130
131
132
  	}
  
  	/**
  	 *  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) {
6d9380f96   Cédric Dupont   Update sources OC...
133
134
  		$this->fileView->touch($this->path, $mtime);
  		$this->refreshInfo();
03e52840d   Kload   Init
135
136
137
  	}
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
138
139
140
141
  	 * Updates properties on this node,
  	 * @see \Sabre\DAV\IProperties::updateProperties
  	 * @param array $properties
  	 * @return boolean
03e52840d   Kload   Init
142
143
144
  	 */
  	public function updateProperties($properties) {
  		$existing = $this->getProperties(array());
6d9380f96   Cédric Dupont   Update sources OC...
145
  		foreach ($properties as $propertyName => $propertyValue) {
03e52840d   Kload   Init
146
147
  			// If it was null, we need to delete the property
  			if (is_null($propertyValue)) {
6d9380f96   Cédric Dupont   Update sources OC...
148
149
150
151
  				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));
03e52840d   Kload   Init
152
  				}
6d9380f96   Cédric Dupont   Update sources OC...
153
154
155
156
  			} else {
  				if (strcmp($propertyName, self::GETETAG_PROPERTYNAME) === 0) {
  					\OC\Files\Filesystem::putFileInfo($this->path, array('etag' => $propertyValue));
  				} elseif (strcmp($propertyName, self::LASTMODIFIED_PROPERTYNAME) === 0) {
03e52840d   Kload   Init
157
158
  					$this->touch($propertyValue);
  				} else {
6d9380f96   Cédric Dupont   Update sources OC...
159
160
161
162
  					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));
03e52840d   Kload   Init
163
  					} else {
6d9380f96   Cédric Dupont   Update sources OC...
164
165
166
  						$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));
03e52840d   Kload   Init
167
168
169
170
171
172
173
174
175
176
  					}
  				}
  			}
  
  		}
  		$this->setPropertyCache(null);
  		return true;
  	}
  
  	/**
31b7f2792   Kload   Upgrade to ownclo...
177
178
179
  	 * removes all properties for this node and user
  	 */
  	public function removeProperties() {
6d9380f96   Cédric Dupont   Update sources OC...
180
181
182
  		$query = OC_DB::prepare('DELETE FROM `*PREFIX*properties`'
  			. ' WHERE `userid` = ? AND `propertypath` = ?');
  		$query->execute(array(OC_User::getUser(), $this->path));
31b7f2792   Kload   Upgrade to ownclo...
183
184
185
186
187
  
  		$this->setPropertyCache(null);
  	}
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
188
  	 * Returns a list of properties for this nodes.;
03e52840d   Kload   Init
189
190
191
192
193
194
195
196
  	 * @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   Kload   Upgrade to ownclo...
197

03e52840d   Kload   Init
198
  		if (is_null($this->property_cache)) {
31b7f2792   Kload   Upgrade to ownclo...
199
  			$sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?';
6d9380f96   Cédric Dupont   Update sources OC...
200
  			$result = OC_DB::executeAudited($sql, array(OC_User::getUser(), $this->path));
03e52840d   Kload   Init
201
202
  
  			$this->property_cache = array();
6d9380f96   Cédric Dupont   Update sources OC...
203
  			while ($row = $result->fetchRow()) {
03e52840d   Kload   Init
204
205
  				$this->property_cache[$row['propertyname']] = $row['propertyvalue'];
  			}
31b7f2792   Kload   Upgrade to ownclo...
206

6d9380f96   Cédric Dupont   Update sources OC...
207
  			$this->property_cache[self::GETETAG_PROPERTYNAME] = '"' . $this->info->getEtag() . '"';
03e52840d   Kload   Init
208
209
210
  		}
  
  		// if the array was empty, we need to return everything
6d9380f96   Cédric Dupont   Update sources OC...
211
  		if (count($properties) == 0) {
03e52840d   Kload   Init
212
213
214
215
  			return $this->property_cache;
  		}
  
  		$props = array();
6d9380f96   Cédric Dupont   Update sources OC...
216
  		foreach ($properties as $property) {
31b7f2792   Kload   Upgrade to ownclo...
217
218
219
  			if (isset($this->property_cache[$property])) {
  				$props[$property] = $this->property_cache[$property];
  			}
03e52840d   Kload   Init
220
  		}
31b7f2792   Kload   Upgrade to ownclo...
221

03e52840d   Kload   Init
222
223
224
225
  		return $props;
  	}
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
226
  	 * @return string|null
03e52840d   Kload   Init
227
  	 */
6d9380f96   Cédric Dupont   Update sources OC...
228
229
230
231
232
  	public function getFileId() {
  		if ($this->info->getId()) {
  			$instanceId = OC_Util::getInstanceId();
  			$id = sprintf('%08d', $this->info->getId());
  			return $id . $instanceId;
03e52840d   Kload   Init
233
  		}
03e52840d   Kload   Init
234

6d9380f96   Cédric Dupont   Update sources OC...
235
  		return null;
31b7f2792   Kload   Upgrade to ownclo...
236
237
238
  	}
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
239
  	 * @return string|null
31b7f2792   Kload   Upgrade to ownclo...
240
  	 */
6d9380f96   Cédric Dupont   Update sources OC...
241
242
243
244
  	public function getDavPermissions() {
  		$p ='';
  		if ($this->info->isShared()) {
  			$p .= 'S';
31b7f2792   Kload   Upgrade to ownclo...
245
  		}
6d9380f96   Cédric Dupont   Update sources OC...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  		if ($this->info->isShareable()) {
  			$p .= 'R';
  		}
  		if ($this->info->isMounted()) {
  			$p .= 'M';
  		}
  		if ($this->info->isDeletable()) {
  			$p .= 'D';
  		}
  		if ($this->info->isDeletable()) {
  			$p .= 'NV'; // Renameable, Moveable
  		}
  		if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) {
  			if ($this->info->isUpdateable()) {
  				$p .= 'W';
  			}
  		} else {
  			if ($this->info->isUpdateable()) {
  				$p .= 'CK';
  			}
  		}
  		return $p;
31b7f2792   Kload   Upgrade to ownclo...
268
  	}
03e52840d   Kload   Init
269
  }