Blame view
sources/lib/private/files/storage/mappedlocal.php
9.3 KB
|
03e52840d
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php /** * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ namespace OC\Files\Storage; /** * for local filestore, we only have to map the paths */ |
|
6d9380f96
|
13 |
class MappedLocal extends \OC\Files\Storage\Common {
|
|
03e52840d
|
14 15 16 17 |
protected $datadir;
private $mapper;
public function __construct($arguments) {
|
|
6d9380f96
|
18 19 20 |
$this->datadir = $arguments['datadir'];
if (substr($this->datadir, -1) !== '/') {
$this->datadir .= '/';
|
|
03e52840d
|
21 |
} |
|
6d9380f96
|
22 |
$this->mapper = new \OC\Files\Mapper($this->datadir); |
|
03e52840d
|
23 |
} |
|
6d9380f96
|
24 |
|
|
03e52840d
|
25 26 27 28 29 |
public function __destruct() {
if (defined('PHPUNIT_RUN')) {
$this->mapper->removePath($this->datadir, true, true);
}
}
|
|
6d9380f96
|
30 31 32 |
public function getId() {
return 'local::' . $this->datadir;
|
|
03e52840d
|
33 |
} |
|
6d9380f96
|
34 |
|
|
03e52840d
|
35 |
public function mkdir($path) {
|
|
6d9380f96
|
36 |
return @mkdir($this->buildPath($path), 0777, true); |
|
03e52840d
|
37 |
} |
|
6d9380f96
|
38 |
|
|
03e52840d
|
39 |
public function rmdir($path) {
|
|
31b7f2792
|
40 41 42 43 44 |
try {
$it = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($this->buildPath($path)),
\RecursiveIteratorIterator::CHILD_FIRST
);
|
|
6d9380f96
|
45 46 47 48 49 50 51 |
/**
* RecursiveDirectoryIterator on an NFS path isn't iterable with foreach
* This bug is fixed in PHP 5.5.9 or before
* See #8376
*/
$it->rewind();
while ($it->valid()) {
|
|
31b7f2792
|
52 53 54 |
/** * @var \SplFileInfo $file */ |
|
6d9380f96
|
55 |
$file = $it->current(); |
|
31b7f2792
|
56 |
if (in_array($file->getBasename(), array('.', '..'))) {
|
|
6d9380f96
|
57 |
$it->next(); |
|
31b7f2792
|
58 59 60 61 62 63 |
continue;
} elseif ($file->isDir()) {
rmdir($file->getPathname());
} elseif ($file->isFile() || $file->isLink()) {
unlink($file->getPathname());
}
|
|
6d9380f96
|
64 |
$it->next(); |
|
31b7f2792
|
65 66 67 68 69 70 71 |
}
if ($result = @rmdir($this->buildPath($path))) {
$this->cleanMapper($path);
}
return $result;
} catch (\UnexpectedValueException $e) {
return false;
|
|
03e52840d
|
72 |
} |
|
03e52840d
|
73 |
} |
|
6d9380f96
|
74 |
|
|
03e52840d
|
75 76 |
public function opendir($path) {
$files = array('.', '..');
|
|
6d9380f96
|
77 |
$physicalPath = $this->buildPath($path); |
|
03e52840d
|
78 79 80 81 82 83 84 85 |
$logicalPath = $this->mapper->physicalToLogic($physicalPath);
$dh = opendir($physicalPath);
if(is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
if ($file === '.' or $file === '..') {
continue;
}
|
|
6d9380f96
|
86 |
$logicalFilePath = $this->mapper->physicalToLogic($physicalPath . '/' . $file); |
|
03e52840d
|
87 88 89 90 91 92 |
$file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); $file = $this->stripLeading($file); $files[]= $file; } } |
|
6d9380f96
|
93 94 |
\OC\Files\Stream\Dir::register('local-win32' . $path, $files);
return opendir('fakedir://local-win32' . $path);
|
|
03e52840d
|
95 |
} |
|
6d9380f96
|
96 |
|
|
03e52840d
|
97 |
public function is_dir($path) {
|
|
6d9380f96
|
98 99 |
if (substr($path, -1) == '/') {
$path = substr($path, 0, -1);
|
|
03e52840d
|
100 101 102 |
} return is_dir($this->buildPath($path)); } |
|
6d9380f96
|
103 |
|
|
03e52840d
|
104 105 106 |
public function is_file($path) {
return is_file($this->buildPath($path));
}
|
|
6d9380f96
|
107 |
|
|
03e52840d
|
108 109 110 |
public function stat($path) {
$fullPath = $this->buildPath($path);
$statResult = stat($fullPath);
|
|
6d9380f96
|
111 112 113 114 |
if (PHP_INT_SIZE === 4 && !$this->is_dir($path)) {
$filesize = $this->filesize($path);
$statResult['size'] = $filesize;
$statResult[7] = $filesize;
|
|
03e52840d
|
115 116 117 |
} return $statResult; } |
|
6d9380f96
|
118 |
|
|
03e52840d
|
119 |
public function filetype($path) {
|
|
6d9380f96
|
120 121 122 |
$filetype = filetype($this->buildPath($path));
if ($filetype == 'link') {
$filetype = filetype(realpath($this->buildPath($path)));
|
|
03e52840d
|
123 124 125 |
} return $filetype; } |
|
6d9380f96
|
126 |
|
|
03e52840d
|
127 |
public function filesize($path) {
|
|
6d9380f96
|
128 |
if ($this->is_dir($path)) {
|
|
03e52840d
|
129 |
return 0; |
|
03e52840d
|
130 |
} |
|
6d9380f96
|
131 132 133 134 135 136 |
$fullPath = $this->buildPath($path);
if (PHP_INT_SIZE === 4) {
$helper = new \OC\LargeFileHelper;
return $helper->getFilesize($fullPath);
}
return filesize($fullPath);
|
|
03e52840d
|
137 |
} |
|
6d9380f96
|
138 |
|
|
03e52840d
|
139 140 141 |
public function isReadable($path) {
return is_readable($this->buildPath($path));
}
|
|
6d9380f96
|
142 |
|
|
03e52840d
|
143 144 145 |
public function isUpdatable($path) {
return is_writable($this->buildPath($path));
}
|
|
6d9380f96
|
146 |
|
|
03e52840d
|
147 148 149 |
public function file_exists($path) {
return file_exists($this->buildPath($path));
}
|
|
6d9380f96
|
150 |
|
|
03e52840d
|
151 152 153 |
public function filemtime($path) {
return filemtime($this->buildPath($path));
}
|
|
6d9380f96
|
154 155 |
public function touch($path, $mtime = null) {
|
|
03e52840d
|
156 157 158 |
// sets the modification time of the file to the given value. // If mtime is nil the current time is set. // note that the access time of the file always changes to the current time. |
|
6d9380f96
|
159 160 161 162 |
if (!is_null($mtime)) {
$result = touch($this->buildPath($path), $mtime);
} else {
$result = touch($this->buildPath($path));
|
|
03e52840d
|
163 |
} |
|
6d9380f96
|
164 165 |
if ($result) {
clearstatcache(true, $this->buildPath($path));
|
|
03e52840d
|
166 167 168 169 |
} return $result; } |
|
6d9380f96
|
170 |
|
|
03e52840d
|
171 172 173 |
public function file_get_contents($path) {
return file_get_contents($this->buildPath($path));
}
|
|
6d9380f96
|
174 |
|
|
03e52840d
|
175 176 177 |
public function file_put_contents($path, $data) {
return file_put_contents($this->buildPath($path), $data);
}
|
|
6d9380f96
|
178 |
|
|
03e52840d
|
179 180 181 |
public function unlink($path) {
return $this->delTree($path);
}
|
|
6d9380f96
|
182 |
|
|
03e52840d
|
183 184 |
public function rename($path1, $path2) {
if (!$this->isUpdatable($path1)) {
|
|
6d9380f96
|
185 |
\OC_Log::write('core', 'unable to rename, file is not writable : ' . $path1, \OC_Log::ERROR);
|
|
03e52840d
|
186 187 |
return false; } |
|
6d9380f96
|
188 189 |
if (!$this->file_exists($path1)) {
\OC_Log::write('core', 'unable to rename, file does not exists : ' . $path1, \OC_Log::ERROR);
|
|
03e52840d
|
190 191 |
return false; } |
|
6d9380f96
|
192 193 194 195 196 |
if ($this->is_dir($path2)) {
$this->rmdir($path2);
} else if ($this->is_file($path2)) {
$this->unlink($path2);
}
|
|
03e52840d
|
197 198 |
$physicPath1 = $this->buildPath($path1); $physicPath2 = $this->buildPath($path2); |
|
6d9380f96
|
199 |
if ($return = rename($physicPath1, $physicPath2)) {
|
|
03e52840d
|
200 201 202 203 204 205 |
// mapper needs to create copies or all children $this->copyMapping($path1, $path2); $this->cleanMapper($physicPath1, false, true); } return $return; } |
|
6d9380f96
|
206 |
|
|
03e52840d
|
207 |
public function copy($path1, $path2) {
|
|
6d9380f96
|
208 209 210 211 212 |
if ($this->is_dir($path1)) {
if ($this->is_dir($path2)) {
$this->rmdir($path2);
} else if ($this->is_file($path2)) {
$this->unlink($path2);
|
|
03e52840d
|
213 |
} |
|
6d9380f96
|
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
$dir = $this->opendir($path1);
$this->mkdir($path2);
while ($file = readdir($dir)) {
if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) {
return false;
}
}
}
closedir($dir);
return true;
} else {
if ($return = copy($this->buildPath($path1), $this->buildPath($path2))) {
$this->copyMapping($path1, $path2);
}
return $return;
|
|
03e52840d
|
230 |
} |
|
03e52840d
|
231 |
} |
|
6d9380f96
|
232 |
|
|
03e52840d
|
233 |
public function fopen($path, $mode) {
|
|
6d9380f96
|
234 235 |
if ($return = fopen($this->buildPath($path), $mode)) {
switch ($mode) {
|
|
03e52840d
|
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
case 'r': break; case 'r+': case 'w+': case 'x+': case 'a+': break; case 'w': case 'x': case 'a': break; } } return $return; } |
|
6d9380f96
|
251 252 253 |
/** * @param string $dir */ |
|
03e52840d
|
254 |
private function delTree($dir, $isLogicPath=true) {
|
|
6d9380f96
|
255 |
$dirRelative = $dir; |
|
03e52840d
|
256 |
if ($isLogicPath) {
|
|
6d9380f96
|
257 |
$dir = $this->buildPath($dir); |
|
03e52840d
|
258 259 260 261 262 |
}
if (!file_exists($dir)) {
return true;
}
if (!is_dir($dir) || is_link($dir)) {
|
|
6d9380f96
|
263 |
if ($return = unlink($dir)) {
|
|
03e52840d
|
264 265 266 267 268 269 270 271 |
$this->cleanMapper($dir, false);
return $return;
}
}
foreach (scandir($dir) as $item) {
if ($item == '.' || $item == '..') {
continue;
}
|
|
6d9380f96
|
272 273 274 |
if (is_file($dir . '/' . $item)) {
if (unlink($dir . '/' . $item)) {
$this->cleanMapper($dir . '/' . $item, false);
|
|
03e52840d
|
275 |
} |
|
6d9380f96
|
276 277 |
} elseif (is_dir($dir . '/' . $item)) {
if (!$this->delTree($dir . "/" . $item, false)) {
|
|
03e52840d
|
278 279 280 281 |
return false; }; } } |
|
6d9380f96
|
282 |
if ($return = rmdir($dir)) {
|
|
03e52840d
|
283 284 285 286 |
$this->cleanMapper($dir, false); } return $return; } |
|
6d9380f96
|
287 |
public function hash($type, $path, $raw = false) {
|
|
03e52840d
|
288 289 290 291 292 293 294 295 296 297 |
return hash_file($type, $this->buildPath($path), $raw);
}
public function free_space($path) {
return @disk_free_space($this->buildPath($path));
}
public function search($query) {
return $this->searchInDir($query);
}
|
|
6d9380f96
|
298 |
|
|
03e52840d
|
299 300 301 |
public function getLocalFile($path) {
return $this->buildPath($path);
}
|
|
6d9380f96
|
302 |
|
|
03e52840d
|
303 304 305 |
public function getLocalFolder($path) {
return $this->buildPath($path);
}
|
|
6d9380f96
|
306 307 308 309 310 |
/**
* @param string $query
*/
protected function searchInDir($query, $dir = '') {
$files = array();
|
|
03e52840d
|
311 312 313 314 |
$physicalDir = $this->buildPath($dir);
foreach (scandir($physicalDir) as $item) {
if ($item == '.' || $item == '..')
continue;
|
|
6d9380f96
|
315 316 |
$physicalItem = $this->mapper->physicalToLogic($physicalDir . '/' . $item); $item = substr($physicalItem, strlen($physicalDir) + 1); |
|
03e52840d
|
317 |
|
|
6d9380f96
|
318 319 |
if (strstr(strtolower($item), strtolower($query)) !== false) {
$files[] = $dir . '/' . $item;
|
|
03e52840d
|
320 |
} |
|
6d9380f96
|
321 322 |
if (is_dir($physicalItem)) {
$files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
|
|
03e52840d
|
323 324 325 326 327 328 329 |
} } return $files; } /** * check if a file or folder has been updated since $time |
|
6d9380f96
|
330 |
* |
|
03e52840d
|
331 332 333 334 335 |
* @param string $path
* @param int $time
* @return bool
*/
public function hasUpdated($path, $time) {
|
|
6d9380f96
|
336 |
return $this->filemtime($path) > $time; |
|
03e52840d
|
337 |
} |
|
6d9380f96
|
338 339 340 341 |
/**
* @param string $path
*/
private function buildPath($path, $create = true) {
|
|
03e52840d
|
342 |
$path = $this->stripLeading($path); |
|
6d9380f96
|
343 |
$fullPath = $this->datadir . $path; |
|
03e52840d
|
344 345 |
return $this->mapper->logicToPhysical($fullPath, $create); } |
|
6d9380f96
|
346 347 348 349 |
/**
* @param string $path
*/
private function cleanMapper($path, $isLogicPath = true, $recursive=true) {
|
|
03e52840d
|
350 351 |
$fullPath = $path;
if ($isLogicPath) {
|
|
6d9380f96
|
352 |
$fullPath = $this->datadir . $path; |
|
03e52840d
|
353 354 355 |
} $this->mapper->removePath($fullPath, $isLogicPath, $recursive); } |
|
6d9380f96
|
356 357 358 359 |
/** * @param string $path1 * @param string $path2 */ |
|
03e52840d
|
360 361 362 |
private function copyMapping($path1, $path2) {
$path1 = $this->stripLeading($path1);
$path2 = $this->stripLeading($path2);
|
|
6d9380f96
|
363 364 |
$fullPath1 = $this->datadir . $path1; $fullPath2 = $this->datadir . $path2; |
|
03e52840d
|
365 366 367 |
$this->mapper->copy($fullPath1, $fullPath2); } |
|
6d9380f96
|
368 369 370 |
/** * @param string $path */ |
|
03e52840d
|
371 |
private function stripLeading($path) {
|
|
6d9380f96
|
372 |
if (strpos($path, '/') === 0) {
|
|
03e52840d
|
373 374 |
$path = substr($path, 1); } |
|
6d9380f96
|
375 |
if (strpos($path, '\\') === 0) {
|
|
03e52840d
|
376 377 378 379 380 381 382 383 384 |
$path = substr($path, 1);
}
if ($path === false) {
return '';
}
return $path;
}
}
|