Group shares with same source and target
Fixes #24575 Note that this is a very limited solution and eventually we want smarter merging!
This commit is contained in:
parent
f4f43dddf5
commit
39ebf120c2
|
@ -75,16 +75,21 @@ class MountProvider implements IMountProvider {
|
|||
return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
|
||||
});
|
||||
|
||||
$mounts = [];
|
||||
foreach ($shares as $share) {
|
||||
$groupedShares = $this->groupShares($shares);
|
||||
|
||||
$superShares = $this->superShares($groupedShares);
|
||||
|
||||
|
||||
$mounts = [];
|
||||
foreach ($superShares as $share) {
|
||||
try {
|
||||
$mounts[] = new SharedMount(
|
||||
'\OC\Files\Storage\Shared',
|
||||
$mounts,
|
||||
[
|
||||
'user' => $user->getUID(),
|
||||
'newShare' => $share,
|
||||
'superShare' => $share[0],
|
||||
'groupedShares' => $share[1],
|
||||
],
|
||||
$storageFactory
|
||||
);
|
||||
|
@ -97,4 +102,63 @@ class MountProvider implements IMountProvider {
|
|||
// array_filter removes the null values from the array
|
||||
return array_filter($mounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \OCP\Share\IShare[] $shares
|
||||
* @return \OCP\Share\IShare[]
|
||||
*/
|
||||
private function groupShares(array $shares) {
|
||||
$tmp = [];
|
||||
|
||||
foreach ($shares as $share) {
|
||||
if (!isset($tmp[$share->getNodeId()])) {
|
||||
$tmp[$share->getNodeId()] = [];
|
||||
}
|
||||
$tmp[$share->getNodeId()][$share->getTarget()][] = $share;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($tmp as $tmp2) {
|
||||
foreach ($tmp2 as $item) {
|
||||
$result[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract super shares
|
||||
*
|
||||
* @param array $shares Array of \OCP\Share\IShare[]
|
||||
* @return array Tuple of [superShare, groupedShares]
|
||||
*/
|
||||
private function superShares(array $groupedShares) {
|
||||
$result = [];
|
||||
|
||||
/** @var \OCP\Share\IShare[] $shares */
|
||||
foreach ($groupedShares as $shares) {
|
||||
if (count($shares) === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$superShare = $this->shareManager->newShare();
|
||||
|
||||
$superShare->setId($shares[0]->getId())
|
||||
->setShareOwner($shares[0]->getShareOwner())
|
||||
->setNodeId($shares[0]->getNodeId())
|
||||
->setTarget($shares[0]->getTarget());
|
||||
|
||||
$permissions = 0;
|
||||
foreach ($shares as $share) {
|
||||
$permissions |= $share->getPermissions();
|
||||
}
|
||||
|
||||
$superShare->setPermissions($permissions);
|
||||
|
||||
$result[] = [$superShare, $shares];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,10 @@ class SharedMount extends MountPoint implements MoveableMount {
|
|||
private $user;
|
||||
|
||||
/** @var \OCP\Share\IShare */
|
||||
private $share;
|
||||
private $superShare;
|
||||
|
||||
/** @var \OCP\Share\IShare[] */
|
||||
private $groupedShares;
|
||||
|
||||
/**
|
||||
* @param string $storage
|
||||
|
@ -63,10 +66,13 @@ class SharedMount extends MountPoint implements MoveableMount {
|
|||
public function __construct($storage, array $mountpoints, $arguments = null, $loader = null) {
|
||||
$this->user = $arguments['user'];
|
||||
$this->recipientView = new View('/' . $this->user . '/files');
|
||||
$this->share = $arguments['newShare'];
|
||||
$newMountPoint = $this->verifyMountPoint($this->share, $mountpoints);
|
||||
|
||||
$this->superShare = $arguments['superShare'];
|
||||
$this->groupedShares = $arguments['groupedShares'];
|
||||
|
||||
$newMountPoint = $this->verifyMountPoint($this->superShare, $mountpoints);
|
||||
$absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
|
||||
$arguments['ownerView'] = new View('/' . $this->share->getShareOwner() . '/files');
|
||||
$arguments['ownerView'] = new View('/' . $this->superShare->getShareOwner() . '/files');
|
||||
parent::__construct($storage, $absMountPoint, $arguments, $loader);
|
||||
}
|
||||
|
||||
|
@ -108,7 +114,11 @@ class SharedMount extends MountPoint implements MoveableMount {
|
|||
*/
|
||||
private function updateFileTarget($newPath, &$share) {
|
||||
$share->setTarget($newPath);
|
||||
\OC::$server->getShareManager()->moveShare($share, $this->user);
|
||||
|
||||
foreach ($this->groupedShares as $share) {
|
||||
$share->setTarget($newPath);
|
||||
\OC::$server->getShareManager()->moveShare($share, $this->user);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,7 +224,7 @@ class SharedMount extends MountPoint implements MoveableMount {
|
|||
* @return \OCP\Share\IShare
|
||||
*/
|
||||
public function getShare() {
|
||||
return $this->share;
|
||||
return $this->superShare;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -223,6 +233,6 @@ class SharedMount extends MountPoint implements MoveableMount {
|
|||
* @return int
|
||||
*/
|
||||
public function getStorageRootId() {
|
||||
return $this->share->getNodeId();
|
||||
return $this->getShare()->getNodeId();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,11 +43,11 @@ use OCP\Lock\ILockingProvider;
|
|||
* Convert target path to source path and pass the function call to the correct storage provider
|
||||
*/
|
||||
class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||
|
||||
private $share; // the shared resource
|
||||
|
||||
/** @var \OCP\Share\IShare */
|
||||
private $newShare;
|
||||
private $superShare;
|
||||
|
||||
/** @var \OCP\Share\IShare[] */
|
||||
private $groupedShares;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\View
|
||||
|
@ -77,11 +77,14 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
public function __construct($arguments) {
|
||||
$this->ownerView = $arguments['ownerView'];
|
||||
$this->logger = \OC::$server->getLogger();
|
||||
$this->newShare = $arguments['newShare'];
|
||||
|
||||
$this->superShare = $arguments['superShare'];
|
||||
$this->groupedShares = $arguments['groupedShares'];
|
||||
|
||||
$this->user = $arguments['user'];
|
||||
|
||||
Filesystem::initMountPoints($this->newShare->getShareOwner());
|
||||
$sourcePath = $this->ownerView->getPath($this->newShare->getNodeId());
|
||||
Filesystem::initMountPoints($this->superShare->getShareOwner());
|
||||
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
|
||||
list($storage, $internalPath) = $this->ownerView->resolvePath($sourcePath);
|
||||
|
||||
parent::__construct([
|
||||
|
@ -96,8 +99,8 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
}
|
||||
$this->initialized = true;
|
||||
try {
|
||||
Filesystem::initMountPoints($this->newShare->getShareOwner());
|
||||
$sourcePath = $this->ownerView->getPath($this->newShare->getNodeId());
|
||||
Filesystem::initMountPoints($this->superShare->getShareOwner());
|
||||
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
|
||||
list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath);
|
||||
$this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath);
|
||||
} catch (\Exception $e) {
|
||||
|
@ -105,6 +108,13 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getShareId() {
|
||||
return $this->superShare->getId();
|
||||
}
|
||||
|
||||
private function isValid() {
|
||||
$this->init();
|
||||
return $this->sourceRootInfo && ($this->sourceRootInfo->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE;
|
||||
|
@ -119,15 +129,6 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
return 'shared::' . $this->getMountPoint();
|
||||
}
|
||||
|
||||
/**
|
||||
* get file cache of the shared item source
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSourceId() {
|
||||
return $this->newShare->getNodeId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions granted for a shared file
|
||||
*
|
||||
|
@ -138,7 +139,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
if (!$this->isValid()) {
|
||||
return 0;
|
||||
}
|
||||
$permissions = $this->newShare->getPermissions();
|
||||
$permissions = $this->superShare->getPermissions();
|
||||
// part files and the mount point always have delete permissions
|
||||
if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') {
|
||||
$permissions |= \OCP\Constants::PERMISSION_DELETE;
|
||||
|
@ -260,30 +261,18 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
* @return string
|
||||
*/
|
||||
public function getMountPoint() {
|
||||
return $this->newShare->getTarget();
|
||||
return $this->superShare->getTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*/
|
||||
public function setMountPoint($path) {
|
||||
$this->newShare->setTarget($path);
|
||||
}
|
||||
$this->superShare->setTarget($path);
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getShareType() {
|
||||
return $this->newShare->getShareType();
|
||||
}
|
||||
|
||||
/**
|
||||
* get share ID
|
||||
*
|
||||
* @return integer unique share ID
|
||||
*/
|
||||
public function getShareId() {
|
||||
return $this->newShare->getId();
|
||||
foreach ($this->groupedShares as $share) {
|
||||
$share->setTarget($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,14 +281,14 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
* @return string
|
||||
*/
|
||||
public function getSharedFrom() {
|
||||
return $this->newShare->getShareOwner();
|
||||
return $this->superShare->getShareOwner();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \OCP\Share\IShare
|
||||
*/
|
||||
public function getShare() {
|
||||
return $this->newShare;
|
||||
return $this->superShare;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -308,7 +297,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
* @return string
|
||||
*/
|
||||
public function getItemType() {
|
||||
return $this->newShare->getNodeType();
|
||||
return $this->superShare->getNodeType();
|
||||
}
|
||||
|
||||
public function getCache($path = '', $storage = null) {
|
||||
|
@ -337,7 +326,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
}
|
||||
|
||||
public function getOwner($path) {
|
||||
return $this->newShare->getShareOwner();
|
||||
return $this->superShare->getShareOwner();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -346,7 +335,9 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
* @return bool
|
||||
*/
|
||||
public function unshareStorage() {
|
||||
\OC::$server->getShareManager()->deleteFromSelf($this->newShare, $this->user);
|
||||
foreach ($this->groupedShares as $share) {
|
||||
\OC::$server->getShareManager()->deleteFromSelf($share, $this->user);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -362,7 +353,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
$targetStorage->acquireLock($targetInternalPath, $type, $provider);
|
||||
// lock the parent folders of the owner when locking the share as recipient
|
||||
if ($path === '') {
|
||||
$sourcePath = $this->ownerView->getPath($this->newShare->getNodeId());
|
||||
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
|
||||
$this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
|
||||
}
|
||||
}
|
||||
|
@ -378,7 +369,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
|||
$targetStorage->releaseLock($targetInternalPath, $type, $provider);
|
||||
// unlock the parent folders of the owner when unlocking the share as recipient
|
||||
if ($path === '') {
|
||||
$sourcePath = $this->ownerView->getPath($this->newShare->getNodeId());
|
||||
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
|
||||
$this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue