Switch to using file cache ids instead of paths for file sharing
This commit is contained in:
parent
cfec290ad9
commit
36487246ed
7 changed files with 69 additions and 66 deletions
|
@ -9,7 +9,7 @@
|
|||
$name = str_replace('%2F','/', $name);
|
||||
$directory = str_replace('+','%20',urlencode($file['directory']));
|
||||
$directory = str_replace('%2F','/', $directory); ?>
|
||||
<tr data-file="<?php echo $name;?>" data-type="<?php echo ($file['type'] == 'dir')?'dir':'file'?>" data-mime="<?php echo $file['mimetype']?>" data-size='<?php echo $file['size'];?>' data-permissions='<?php echo $file['permissions']; ?>'>
|
||||
<tr data-id="<?php echo $file['id']; ?>" data-file="<?php echo $name;?>" data-type="<?php echo ($file['type'] == 'dir')?'dir':'file'?>" data-mime="<?php echo $file['mimetype']?>" data-size='<?php echo $file['size'];?>' data-permissions='<?php echo $file['permissions']; ?>'>
|
||||
<td class="filename svg" style="background-image:url(<?php if($file['type'] == 'dir') echo OCP\mimetype_icon('dir'); else echo OCP\mimetype_icon($file['mimetype']); ?>)">
|
||||
<?php if(!isset($_['readonly']) || !$_['readonly']) { ?><input type="checkbox" /><?php } ?>
|
||||
<a class="name" href="<?php if($file['type'] == 'dir') echo $_['baseURL'].$directory.'/'.$name; else echo $_['downloadURL'].$directory.'/'.$name; ?>" title="">
|
||||
|
|
|
@ -43,20 +43,20 @@ $(document).ready(function() {
|
|||
var itemType = 'file';
|
||||
}
|
||||
var possiblePermissions = $(tr).data('permissions');
|
||||
var appendTo = $('tr').filterAttr('data-file', filename).find('td.filename');
|
||||
var appendTo = $(tr).find('td.filename');
|
||||
// Check if drop down is already visible for a different file
|
||||
if (OC.Share.droppedDown) {
|
||||
if (item != $('#dropdown').data('item')) {
|
||||
OC.Share.hideDropDown(function () {
|
||||
$('tr').filterAttr('data-file', filename).addClass('mouseOver');
|
||||
OC.Share.showDropDown(itemType, item, appendTo, true, possiblePermissions);
|
||||
$(tr).addClass('mouseOver');
|
||||
OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions);
|
||||
});
|
||||
} else {
|
||||
OC.Share.hideDropDown();
|
||||
}
|
||||
} else {
|
||||
$('tr').filterAttr('data-file',filename).addClass('mouseOver');
|
||||
OC.Share.showDropDown(itemType, item, appendTo, true, possiblePermissions);
|
||||
$(tr).addClass('mouseOver');
|
||||
OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,30 +26,40 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
|||
const FORMAT_FILE_APP_ROOT = 2;
|
||||
const FORMAT_OPENDIR = 3;
|
||||
|
||||
public function isValidSource($item, $uid) {
|
||||
if (OC_Filesystem::file_exists($item)) {
|
||||
private $path;
|
||||
|
||||
public function isValidSource($itemSource, $uidOwner) {
|
||||
$path = OC_FileCache::getPath($itemSource, $uidOwner);
|
||||
if (OC_Filesystem::file_exists($path)) {
|
||||
$this->path = $path;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFilePath($item, $uid) {
|
||||
return $item;
|
||||
public function getFilePath($itemSource, $uidOwner) {
|
||||
if (isset($this->path)) {
|
||||
$path = $this->path;
|
||||
$this->path = null;
|
||||
return $path;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function generateTarget($item, $uid, $exclude = null) {
|
||||
public function generateTarget($itemSource, $shareWith, $exclude = null) {
|
||||
// TODO Make sure target path doesn't exist already
|
||||
return $item;
|
||||
return $itemSource;
|
||||
}
|
||||
|
||||
public function formatItems($items, $format, $parameters = null) {
|
||||
if ($format == self::FORMAT_SHARED_STORAGE) {
|
||||
// Only 1 item should come through for this format call
|
||||
return array('path' => $items[key($items)]['file_source'], 'permissions' => $items[key($items)]['permissions']);
|
||||
return array('path' => $items[key($items)]['path'], 'permissions' => $items[key($items)]['permissions']);
|
||||
} else if ($format == self::FORMAT_FILE_APP) {
|
||||
$files = array();
|
||||
foreach ($items as $item) {
|
||||
$file = array();
|
||||
$file['id'] = $item['file_source'];
|
||||
$file['path'] = $item['file_target'];
|
||||
$file['name'] = basename($item['file_target']);
|
||||
$file['ctime'] = $item['ctime'];
|
||||
|
@ -77,7 +87,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
|||
}
|
||||
$size += $item['size'];
|
||||
}
|
||||
return array(0 => array('name' => 'Shared', 'mtime' => $mtime, 'mimetype' => 'httpd/unix-directory', 'size' => $size, 'writable' => false, 'type' => 'dir', 'directory' => '', 'permissions' => OCP\Share::PERMISSION_READ));
|
||||
return array(0 => array('id' => -1, 'name' => 'Shared', 'mtime' => $mtime, 'mimetype' => 'httpd/unix-directory', 'size' => $size, 'writable' => false, 'type' => 'dir', 'directory' => '', 'permissions' => OCP\Share::PERMISSION_READ));
|
||||
} else if ($format == self::FORMAT_OPENDIR) {
|
||||
$files = array();
|
||||
foreach ($items as $item) {
|
||||
|
|
|
@ -24,7 +24,7 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File {
|
|||
public function formatItems($items, $format, $parameters = null) {
|
||||
if ($format == self::FORMAT_SHARED_STORAGE) {
|
||||
// Only 1 item should come through for this format call
|
||||
return array('path' => $items[key($items)]['file_source'], 'permissions' => $items[key($items)]['permissions']);
|
||||
return array('path' => $items[key($items)]['path'], 'permissions' => $items[key($items)]['permissions']);
|
||||
} else if ($format == self::FORMAT_FILE_APP && isset($parameters['folder'])) {
|
||||
// Only 1 item should come through for this format call
|
||||
$folder = $items[key($items)];
|
||||
|
@ -33,7 +33,7 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File {
|
|||
} else {
|
||||
$mimetype_filter = '';
|
||||
}
|
||||
$path = $folder['file_source'].substr($parameters['folder'], 7 + strlen($folder['file_target']));
|
||||
$path = $folder['path'].substr($parameters['folder'], 7 + strlen($folder['file_target']));
|
||||
$files = OC_FileCache::getFolderContent($path, '', $mimetype_filter);
|
||||
foreach ($files as &$file) {
|
||||
$file['directory'] = $parameters['folder'];
|
||||
|
|
|
@ -32,7 +32,18 @@ OC.Share={
|
|||
},
|
||||
loadItem:function(itemType, itemSource) {
|
||||
var data = '';
|
||||
if (typeof OC.Share.statuses[itemSource] === 'undefined') {
|
||||
// Switch file sources to path to check if status is set
|
||||
if (itemType == 'file' || itemType == 'folder') {
|
||||
var filename = $('tr').filterAttr('data-id', String(itemSource)).data('file');
|
||||
if ($('#dir').val() == '/') {
|
||||
var item = $('#dir').val() + filename;
|
||||
} else {
|
||||
var item = $('#dir').val() + '/' + filename;
|
||||
}
|
||||
} else {
|
||||
var item = itemSource;
|
||||
}
|
||||
if (typeof OC.Share.statuses[item] === 'undefined') {
|
||||
checkShares = false;
|
||||
} else {
|
||||
checkShares = true;
|
||||
|
|
|
@ -58,7 +58,7 @@ class OC_FileCache_Cached{
|
|||
if($parent==-1){
|
||||
return array();
|
||||
}
|
||||
$query=OC_DB::prepare('SELECT path,name,ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE parent=? AND (mimetype LIKE ? OR mimetype = ?)');
|
||||
$query=OC_DB::prepare('SELECT id,path,name,ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE parent=? AND (mimetype LIKE ? OR mimetype = ?)');
|
||||
$result=$query->execute(array($parent, $mimetype_filter.'%', 'httpd/unix-directory'))->fetchAll();
|
||||
if(is_array($result)){
|
||||
return $result;
|
||||
|
|
|
@ -237,8 +237,16 @@ class Share {
|
|||
// Continue scanning into child folders
|
||||
array_push($files, $children);
|
||||
} else {
|
||||
// Check file extension for an equivalent item type to convert to
|
||||
$extension = strtolower(substr($itemSource, strrpos($itemSource, '.') + 1));
|
||||
foreach (self::$backends as $type => $backend) {
|
||||
if (isset($backend->dependsOn) && $backend->dependsOn == 'file' && isset($backend->supportedFileExtensions) && in_array($extension, $backend->supportedFileExtensions)) {
|
||||
$itemType = $type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Pass on to put() to check if this item should be converted, the item won't be inserted into the database unless it can be converted
|
||||
self::put('file', $name, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder);
|
||||
self::put($itemType, $name, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -425,7 +433,7 @@ class Share {
|
|||
} else {
|
||||
$fileDependent = false;
|
||||
$root = '';
|
||||
if ($includeCollections && !isset($item) && $collectionTypes = self::getCollectionItemTypes($itemType)) {
|
||||
if ($includeCollections && !isset($item) && ($collectionTypes = self::getCollectionItemTypes($itemType))) {
|
||||
// If includeCollections is true, find collections of this item type, e.g. a music album contains songs
|
||||
$itemTypes = array_merge(array($itemType), $collectionTypes);
|
||||
$placeholders = join(',', array_fill(0, count($itemTypes), '?'));
|
||||
|
@ -481,12 +489,11 @@ class Share {
|
|||
if (isset($uidOwner) || $itemShareWithBySource) {
|
||||
// If item type is a file, file source needs to be checked in case the item was converted
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
$where .= " AND path = ?";
|
||||
$queryArgs[] = $root.$item;
|
||||
$where .= ' AND file_source = ?';
|
||||
$column = 'file_source';
|
||||
} else {
|
||||
$where .= " AND item_source = ?";
|
||||
$column = 'item_source';
|
||||
$queryArgs[] = $item;
|
||||
}
|
||||
} else {
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
|
@ -494,8 +501,8 @@ class Share {
|
|||
} else {
|
||||
$where .= " AND item_target = ?";
|
||||
}
|
||||
$queryArgs[] = $item;
|
||||
}
|
||||
$queryArgs[] = $item;
|
||||
if ($includeCollections && $collectionTypes = self::getCollectionItemTypes($itemType)) {
|
||||
// TODO Bart - this doesn't work with only one argument
|
||||
// $placeholders = join(',', array_fill(0, count($collectionTypes), '?'));
|
||||
|
@ -519,23 +526,23 @@ class Share {
|
|||
// TODO Optimize selects
|
||||
if ($format == self::FORMAT_STATUSES) {
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
$select = '*PREFIX*share.id, item_type, *PREFIX*share.parent, share_type, *PREFIX*fscache.path as file_source';
|
||||
$select = '*PREFIX*share.id, item_type, *PREFIX*share.parent, share_type, file_source, path';
|
||||
} else {
|
||||
$select = 'id, item_type, item_source, parent, share_type';
|
||||
}
|
||||
} else {
|
||||
if (isset($uidOwner)) {
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
$select = '*PREFIX*share.id, item_type, *PREFIX*fscache.path as file_source, *PREFIX*share.parent, share_type, share_with, permissions, stime';
|
||||
$select = '*PREFIX*share.id, item_type, *PREFIX*share.parent, share_type, share_with, file_source, path, permissions, stime';
|
||||
} else {
|
||||
$select = 'id, item_type, item_source, parent, share_type, share_with, permissions, stime, file_source';
|
||||
}
|
||||
} else {
|
||||
if ($fileDependent) {
|
||||
if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_FILE_APP || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) {
|
||||
$select = '*PREFIX*share.id, item_type, *PREFIX*share.parent, share_type, share_with, permissions, file_target, *PREFIX*fscache.id, path as file_source, name, ctime, mtime, mimetype, size, encrypted, versioned, writable';
|
||||
$select = '*PREFIX*share.id, item_type, *PREFIX*share.parent, share_type, share_with, file_source, path, file_target, permissions, name, ctime, mtime, mimetype, size, encrypted, versioned, writable';
|
||||
} else {
|
||||
$select = '*PREFIX*share.id, item_type, item_source, item_target, *PREFIX*share.parent, share_type, share_with, uid_owner, permissions, stime, path as file_source, file_target';
|
||||
$select = '*PREFIX*share.id, item_type, item_source, item_target, *PREFIX*share.parent, share_type, share_with, uid_owner, file_source, path, file_target, permissions, stime';
|
||||
}
|
||||
} else {
|
||||
$select = '*';
|
||||
|
@ -580,11 +587,11 @@ class Share {
|
|||
}
|
||||
}
|
||||
// Remove root from file source paths if retrieving own shared items
|
||||
if (isset($uidOwner) && isset($row['file_source'])) {
|
||||
if (isset($uidOwner) && isset($row['path'])) {
|
||||
if (isset($row['parent'])) {
|
||||
$row['file_source'] = '/Shared/'.basename($row['file_source']);
|
||||
$row['path'] = '/Shared/'.basename($row['path']);
|
||||
} else {
|
||||
$row['file_source'] = substr($row['file_source'], $root);
|
||||
$row['path'] = substr($row['path'], $root);
|
||||
}
|
||||
}
|
||||
$items[$row['id']] = $row;
|
||||
|
@ -601,7 +608,7 @@ class Share {
|
|||
}
|
||||
}
|
||||
// Check if this is a collection of the requested item type
|
||||
if ($includeCollections && $row['item_type'] != $itemType && $collectionBackend = self::getBackend($row['item_type']) && $collectionBackend instanceof Share_Backend_Collection) {
|
||||
if ($includeCollections && $row['item_type'] != $itemType && ($collectionBackend = self::getBackend($row['item_type'])) && $collectionBackend instanceof Share_Backend_Collection) {
|
||||
$row['collection'] = array('item_type' => $itemType, $column => $row[$column]);
|
||||
// Fetch all of the children sources
|
||||
$children = $collectionBackend->getChildren($row[$column]);
|
||||
|
@ -636,6 +643,10 @@ class Share {
|
|||
return $items;
|
||||
} else if ($format == self::FORMAT_STATUSES) {
|
||||
$statuses = array();
|
||||
// Switch column to path for files and folders, used for determining statuses inside of folders
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
$column = 'path';
|
||||
}
|
||||
foreach ($items as $item) {
|
||||
if ($item['share_type'] == self::SHARE_TYPE_PRIVATE_LINK) {
|
||||
$statuses[$item[$column]] = true;
|
||||
|
@ -664,20 +675,6 @@ class Share {
|
|||
* @return bool Returns true on success or false on failure
|
||||
*/
|
||||
private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder = null) {
|
||||
// Check file extension for an equivalent item type to convert to
|
||||
if ($itemType == 'file') {
|
||||
$extension = strtolower(substr($itemSource, strrpos($itemSource, '.') + 1));
|
||||
foreach (self::$backends as $type => $backend) {
|
||||
if (isset($backend->dependsOn) && $backend->dependsOn == 'file' && isset($backend->supportedFileExtensions) && in_array($extension, $backend->supportedFileExtensions)) {
|
||||
$itemType = $type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Exit if this is being called for a file inside a folder, and no equivalent item type is found
|
||||
if (isset($parentFolder) && $itemType == 'file') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$backend = self::getBackend($itemType);
|
||||
// Check if this is a reshare
|
||||
if ($checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true)) {
|
||||
|
@ -686,24 +683,6 @@ class Share {
|
|||
$message = 'Sharing '.$itemSource.' failed, because the user '.$shareWith.' is the original sharer';
|
||||
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
|
||||
throw new \Exception($message);
|
||||
// Check if attempting to share back to group TODO Check unique user target
|
||||
} else if ($shareType == self::SHARE_TYPE_GROUP && $checkReshare['share_with'] == $shareWith['group']) {
|
||||
$message = 'Sharing '.$itemSource.' failed, because the item was orignally shared with the group '.$shareWith['group'];
|
||||
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
|
||||
throw new \Exception($message);
|
||||
// Check if attempting to share back a group share to a member of the same group
|
||||
} else if (($checkReshare['share_type'] == self::SHARE_TYPE_GROUP || $checkReshare['share_type'] == self::$shareTypeGroupUserUnique) && $shareType == self::SHARE_TYPE_USER) {
|
||||
if ($checkReshare['share_type'] == self::$shareTypeGroupUserUnique) {
|
||||
$query = \OC_DB::prepare('SELECT share_with FROM *PREFIX*share WHERE id = ?');
|
||||
$group = $query->execute(array($checkReshare['parent']))->fetchOne();
|
||||
} else {
|
||||
$group = $checkReshare['share_with'];
|
||||
}
|
||||
if (\OC_Group::inGroup($shareWith, $group)) {
|
||||
$message = 'Sharing '.$itemSource.' failed, because the user '.$shareWith.' is a member of the original group share';
|
||||
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
|
||||
throw new \Exception($message);
|
||||
}
|
||||
}
|
||||
// Check if share permissions is granted
|
||||
if ((int)$checkReshare['permissions'] & self::PERMISSION_SHARE) {
|
||||
|
@ -734,9 +713,12 @@ class Share {
|
|||
}
|
||||
$parent = null;
|
||||
if ($backend instanceof Share_Backend_File_Dependent) {
|
||||
// NOTE Apps should start using the file cache ids in their tables
|
||||
$filePath = $backend->getFilePath($itemSource, $uidOwner);
|
||||
$fileSource = \OC_FileCache::getId($filePath);
|
||||
if ($itemType == 'file' && $itemType == 'folder') {
|
||||
$fileSource = $itemSource;
|
||||
} else {
|
||||
$fileSource = \OC_FileCache::getId($filePath);
|
||||
}
|
||||
if ($fileSource == -1) {
|
||||
$message = 'Sharing '.$itemSource.' failed, because the file could not be found in the file cache';
|
||||
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
|
||||
|
|
Loading…
Reference in a new issue