most apps would want to use this api instead of using the cache directlytags/v5.0.0alpha1
@@ -41,69 +41,67 @@ class OC_Files { | |||
* - versioned | |||
*/ | |||
public static function getFileInfo($path) { | |||
if (($path == '/Shared' || substr($path, 0, 8) == '/Shared/') && OC_App::isEnabled('files_sharing')) { | |||
if ($path == '/Shared') { | |||
list($info) = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT); | |||
}else{ | |||
$info['size'] = \OC\Files\Filesystem::filesize($path); | |||
$info['mtime'] = \OC\Files\Filesystem::filemtime($path); | |||
$info['ctime'] = \OC\Files\Filesystem::filectime($path); | |||
$info['mimetype'] = \OC\Files\Filesystem::getMimeType($path); | |||
$info['encrypted'] = false; | |||
$info['versioned'] = false; | |||
$path=\OC\Files\Filesystem::normalizePath($path); | |||
/** | |||
* @var \OC\Files\Storage\Storage $storage | |||
* @var string $path | |||
*/ | |||
list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); | |||
$cache=$storage->getCache(); | |||
$data = $cache->get($internalPath); | |||
if($data['mimetype'] === 'httpd/unix-directory'){ | |||
//add the sizes of other mountpoints to the folder | |||
$mountPoints = \OC\Files\Filesystem::getMountPoints($path); | |||
foreach($mountPoints as $mountPoint){ | |||
$subStorage = \OC\Files\Filesystem::getStorage($mountPoint); | |||
$subCache = $subStorage->getCache(); | |||
$rootEntry = $subCache->get(''); | |||
$data['size'] += $rootEntry['size']; | |||
} | |||
} else { | |||
$info = OC_FileCache::get($path); | |||
} | |||
return $info; | |||
return $data; | |||
} | |||
/** | |||
* get the content of a directory | |||
* @param dir $directory path under datadirectory | |||
* @param string $directory path under datadirectory | |||
* @return array | |||
*/ | |||
public static function getDirectoryContent($directory, $mimetype_filter = '') { | |||
$directory=\OC\Files\Filesystem::normalizePath($directory); | |||
if($directory=='/') { | |||
$directory=''; | |||
} | |||
$files = array(); | |||
if (($directory == '/Shared' || substr($directory, 0, 8) == '/Shared/') && OC_App::isEnabled('files_sharing')) { | |||
if ($directory == '/Shared') { | |||
$files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP, array('folder' => $directory, 'mimetype_filter' => $mimetype_filter)); | |||
} else { | |||
$pos = strpos($directory, '/', 8); | |||
// Get shared folder name | |||
if ($pos !== false) { | |||
$itemTarget = substr($directory, 7, $pos - 7); | |||
} else { | |||
$itemTarget = substr($directory, 7); | |||
} | |||
$files = OCP\Share::getItemSharedWith('folder', $itemTarget, OC_Share_Backend_File::FORMAT_FILE_APP, array('folder' => $directory, 'mimetype_filter' => $mimetype_filter)); | |||
} | |||
} else { | |||
$files = OC_FileCache::getFolderContent($directory, false, $mimetype_filter); | |||
foreach ($files as &$file) { | |||
$file['directory'] = $directory; | |||
$file['type'] = ($file['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file'; | |||
$permissions = OCP\Share::PERMISSION_READ; | |||
// NOTE: Remove check when new encryption is merged | |||
if (!$file['encrypted']) { | |||
$permissions |= OCP\Share::PERMISSION_SHARE; | |||
} | |||
if ($file['type'] == 'dir' && $file['writable']) { | |||
$permissions |= OCP\Share::PERMISSION_CREATE; | |||
} | |||
if ($file['writable']) { | |||
$permissions |= OCP\Share::PERMISSION_UPDATE | OCP\Share::PERMISSION_DELETE; | |||
$path=\OC\Files\Filesystem::normalizePath($directory); | |||
/** | |||
* @var \OC\Files\Storage\Storage $storage | |||
* @var string $path | |||
*/ | |||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); | |||
$cache=$storage->getCache(); | |||
$files=$cache->getFolderContents($internalPath); //TODO: mimetype_filter | |||
//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders | |||
$mountPoints = \OC\Files\Filesystem::getMountPoints($directory); | |||
$dirLength = strlen($path); | |||
foreach($mountPoints as $mountPoint){ | |||
$subStorage = \OC\Files\Filesystem::getStorage($mountPoint); | |||
$subCache = $subStorage->getCache(); | |||
$rootEntry = $subCache->get(''); | |||
$relativePath = trim(substr($mountPoint, $dirLength), '/'); | |||
if($pos = strpos($relativePath, '/')){ //mountpoint inside subfolder add size to the correct folder | |||
$entryName = substr($relativePath, 0, $pos); | |||
foreach($files as &$entry){ | |||
if($entry['name'] === $entryName){ | |||
$entry['size'] += $rootEntry['size']; | |||
} | |||
} | |||
$file['permissions'] = $permissions; | |||
} | |||
if ($directory == '' && OC_App::isEnabled('files_sharing')) { | |||
// Add 'Shared' folder | |||
$files = array_merge($files, OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT)); | |||
}else{ //mountpoint in this folder, add an entry for it | |||
$rootEntry['name'] = $relativePath; | |||
$files[] = $rootEntry; | |||
} | |||
} | |||
usort($files, "fileCmp");//TODO: remove this once ajax is merged | |||
return $files; | |||
} | |||
@@ -145,7 +143,7 @@ class OC_Files { | |||
set_time_limit(0); | |||
$zip = new ZipArchive(); | |||
$filename = OC_Helper::tmpFile('.zip'); | |||
if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { | |||
if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { | |||
exit("cannot open <$filename>\n"); | |||
} | |||
foreach($files as $file) { | |||
@@ -166,7 +164,7 @@ class OC_Files { | |||
set_time_limit(0); | |||
$zip = new ZipArchive(); | |||
$filename = OC_Helper::tmpFile('.zip'); | |||
if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { | |||
if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { | |||
exit("cannot open <$filename>\n"); | |||
} | |||
$file=$dir.'/'.$files; | |||
@@ -446,7 +444,7 @@ class OC_Files { | |||
$setting = 'php_value '.$key.' '.$size; | |||
$hasReplaced = 0; | |||
$content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced); | |||
if($content !== NULL) { | |||
if($content !== null) { | |||
$htaccess = $content; | |||
} | |||
if($hasReplaced == 0) { |
@@ -164,6 +164,43 @@ class Filesystem { | |||
return $foundMountPoint; | |||
} | |||
/** | |||
* get a list of all mount points in a directory | |||
* | |||
* @param string $path | |||
* @return string[] | |||
*/ | |||
static public function getMountPoints($path) { | |||
$path = self::normalizePath($path); | |||
if (strlen($path) > 1) { | |||
$path .= '/'; | |||
} | |||
$pathLength = strlen($path); | |||
$mountPoints = array_keys(self::$mounts); | |||
$result = array(); | |||
foreach ($mountPoints as $mountPoint) { | |||
if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) { | |||
$result[] = $mountPoint; | |||
} | |||
} | |||
return $result; | |||
} | |||
/** | |||
* get the storage mounted at $mountPoint | |||
* | |||
* @param string $mountPoint | |||
* @return \OC\Files\Storage\Storage | |||
*/ | |||
public static function getStorage($mountPoint) { | |||
if (!isset(self::$storages[$mountPoint])) { | |||
$mount = self::$mounts[$mountPoint]; | |||
self::$storages[$mountPoint] = self::createStorage($mount['class'], $mount['arguments']); | |||
} | |||
return self::$storages[$mountPoint]; | |||
} | |||
/** | |||
* resolve a path to a storage and internal path | |||
* | |||
@@ -173,14 +210,14 @@ class Filesystem { | |||
static public function resolvePath($path) { | |||
$mountpoint = self::getMountPoint($path); | |||
if ($mountpoint) { | |||
if (!isset(self::$storages[$mountpoint])) { | |||
$mount = self::$mounts[$mountpoint]; | |||
self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); | |||
$storage = self::getStorage($mountpoint); | |||
if ($mountpoint === $path) { | |||
$internalPath = ''; | |||
} else { | |||
$internalPath = substr($path, strlen($mountpoint)); | |||
} | |||
$storage = self::$storages[$mountpoint]; | |||
$internalPath = substr($path, strlen($mountpoint)); | |||
return array($storage, $internalPath); | |||
}else{ | |||
} else { | |||
return array(null, null); | |||
} | |||
} | |||
@@ -302,18 +339,22 @@ class Filesystem { | |||
/** | |||
* mount an \OC\Files\Storage\Storage in our virtual filesystem | |||
* | |||
* @param \OC\Files\Storage\Storage $storage | |||
* @param \OC\Files\Storage\Storage|string $class | |||
* @param array $arguments | |||
* @param string $mountpoint | |||
*/ | |||
static public function mount($class, $arguments, $mountpoint) { | |||
if ($mountpoint[0] != '/') { | |||
$mountpoint = '/' . $mountpoint; | |||
$mountpoint = self::normalizePath($mountpoint); | |||
if (strlen($mountpoint) > 1) { | |||
$mountpoint .= '/'; | |||
} | |||
if (substr($mountpoint, -1) !== '/') { | |||
$mountpoint = $mountpoint . '/'; | |||
if ($class instanceof \OC\Files\Storage\Storage) { | |||
self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); | |||
self::$storages[$mountpoint] = $class; | |||
} else { | |||
self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); | |||
} | |||
self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); | |||
} | |||
/** | |||
@@ -522,15 +563,15 @@ class Filesystem { | |||
static public function removeETagHook($params, $root = false) { | |||
if (isset($params['path'])) { | |||
$path=$params['path']; | |||
$path = $params['path']; | |||
} else { | |||
$path=$params['oldpath']; | |||
$path = $params['oldpath']; | |||
} | |||
if ($root) { // reduce path to the required part of it (no 'username/files') | |||
$fakeRootView = new OC_FilesystemView($root); | |||
$fakeRootView = new View($root); | |||
$count = 1; | |||
$path=str_replace(OC_App::getStorage("files")->getAbsolutePath(), "", $fakeRootView->getAbsolutePath($path), $count); | |||
$path = str_replace(\OC_App::getStorage("files")->getAbsolutePath(''), "", $fakeRootView->getAbsolutePath($path), $count); | |||
} | |||
$path = self::normalizePath($path); |
@@ -52,6 +52,13 @@ interface Storage{ | |||
* returning true for other changes in the folder is optional | |||
*/ | |||
public function hasUpdated($path,$time); | |||
/** | |||
* @return \OC\Files\Cache\Cache | |||
*/ | |||
public function getCache(); | |||
/** | |||
* @return \OC\Files\Cache\Scanner | |||
*/ | |||
public function getScanner(); | |||
} |
@@ -0,0 +1,87 @@ | |||
<?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. */ | |||
use \OC\Files\Filesystem as Filesystem; | |||
class Test_Files extends PHPUnit_Framework_TestCase { | |||
/** | |||
* @var \OC\Files\Storage\Storage[] $storages; | |||
*/ | |||
private $storages = array(); | |||
public function setUp() { | |||
Filesystem::clearMounts(); | |||
} | |||
public function tearDown() { | |||
foreach ($this->storages as $storage) { | |||
$cache = $storage->getCache(); | |||
$cache->clear(); | |||
} | |||
} | |||
public function testCacheAPI() { | |||
$storage1 = $this->getTestStorage(); | |||
$storage2 = $this->getTestStorage(); | |||
$storage3 = $this->getTestStorage(); | |||
Filesystem::mount($storage1, array(), '/'); | |||
Filesystem::mount($storage2, array(), '/substorage'); | |||
Filesystem::mount($storage3, array(), '/folder/anotherstorage'); | |||
$textSize = strlen("dummy file data\n"); | |||
$imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); | |||
$storageSize = $textSize * 2 + $imageSize; | |||
$cachedData = OC_Files::getFileInfo('/foo.txt'); | |||
$this->assertEquals($textSize, $cachedData['size']); | |||
$this->assertEquals('text/plain', $cachedData['mimetype']); | |||
$cachedData = OC_Files::getFileInfo('/'); | |||
$this->assertEquals($storageSize * 3, $cachedData['size']); | |||
$this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); | |||
$cachedData = OC_Files::getFileInfo('/folder'); | |||
$this->assertEquals($storageSize + $textSize, $cachedData['size']); | |||
$this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); | |||
$folderData = OC_Files::getDirectoryContent('/'); | |||
/** | |||
* expected entries: | |||
* folder | |||
* foo.png | |||
* foo.txt | |||
* substorage | |||
*/ | |||
$this->assertEquals(4, count($folderData)); | |||
$this->assertEquals('folder', $folderData[0]['name']); | |||
$this->assertEquals('foo.png', $folderData[1]['name']); | |||
$this->assertEquals('foo.txt', $folderData[2]['name']); | |||
$this->assertEquals('substorage', $folderData[3]['name']); | |||
$this->assertEquals($storageSize + $textSize, $folderData[0]['size']); | |||
$this->assertEquals($imageSize, $folderData[1]['size']); | |||
$this->assertEquals($textSize, $folderData[2]['size']); | |||
$this->assertEquals($storageSize, $folderData[3]['size']); | |||
} | |||
/** | |||
* @return OC\Files\Storage\Storage | |||
*/ | |||
private function getTestStorage() { | |||
$storage = new \OC\Files\Storage\Temporary(array()); | |||
$textData = "dummy file data\n"; | |||
$imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); | |||
$storage->mkdir('folder'); | |||
$storage->file_put_contents('foo.txt', $textData); | |||
$storage->file_put_contents('foo.png', $imgData); | |||
$storage->file_put_contents('folder/bar.txt', $textData); | |||
$scanner = $storage->getScanner(); | |||
$scanner->scan(''); | |||
$this->storages[] = $storage; | |||
return $storage; | |||
} | |||
} |