Signed-off-by: Robin Appelman <icewind@owncloud.com>tags/v11.0RC2
@@ -136,6 +136,30 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin { | |||
return $shareTypes; | |||
} | |||
private function getSharesTypesInFolder(\OCP\Files\Folder $node) { | |||
$shares = $this->shareManager->getSharesInFolder( | |||
$this->userId, | |||
$node, | |||
false | |||
); | |||
$children = $node->getDirectoryListing(); | |||
$values = array_map(function (\OCP\Files\Node $node) use ($shares) { | |||
/** @var IShare[] $shares */ | |||
$shares = (isset($shares[$node->getId()])) ? $shares[$node->getId()] : []; | |||
return array_map(function(IShare $share) { | |||
return $share->getShareType(); | |||
}, $shares); | |||
}, $children); | |||
$keys = array_map(function (\OCP\Files\Node $node) { | |||
return $node->getId(); | |||
}, $children); | |||
return array_combine($keys, $values); | |||
} | |||
/** | |||
* Adds shares to propfind response | |||
* | |||
@@ -156,15 +180,15 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin { | |||
&& !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME)) | |||
) { | |||
$folderNode = $this->userFolder->get($sabreNode->getPath()); | |||
$children = $folderNode->getDirectoryListing(); | |||
$childShares = $this->getSharesTypesInFolder($folderNode); | |||
$this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode); | |||
foreach ($children as $childNode) { | |||
$this->cachedShareTypes[$childNode->getId()] = $this->getShareTypes($childNode); | |||
foreach ($childShares as $id => $shares) { | |||
$this->cachedShareTypes[$id] = $shares; | |||
} | |||
} | |||
$propFind->handle(self::SHARETYPES_PROPERTYNAME, function() use ($sabreNode) { | |||
$propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode) { | |||
if (isset($this->cachedShareTypes[$sabreNode->getId()])) { | |||
$shareTypes = $this->cachedShareTypes[$sabreNode->getId()]; | |||
} else { |
@@ -206,6 +206,14 @@ class SharesPluginTest extends \Test\TestCase { | |||
->method('get') | |||
->with('/subdir') | |||
->will($this->returnValue($node)); | |||
$dummyShares = array_map(function($type) { | |||
$share = $this->getMock('\OCP\Share\IShare'); | |||
$share->expects($this->any()) | |||
->method('getShareType') | |||
->will($this->returnValue($type)); | |||
return $share; | |||
}, $shareTypes); | |||
$this->shareManager->expects($this->any()) | |||
->method('getSharesBy') | |||
@@ -224,6 +232,17 @@ class SharesPluginTest extends \Test\TestCase { | |||
return []; | |||
})); | |||
$this->shareManager->expects($this->any()) | |||
->method('getSharesInFolder') | |||
->with( | |||
$this->equalTo('user1'), | |||
$this->anything(), | |||
$this->equalTo(false) | |||
) | |||
->will($this->returnCallback(function ($userId, $node, $flag) use ($shareTypes, $dummyShares) { | |||
return [111 => $dummyShares]; | |||
})); | |||
// simulate sabre recursive PROPFIND traversal | |||
$propFindRoot = new \Sabre\DAV\PropFind( | |||
'/subdir', |
@@ -563,6 +563,11 @@ class FederatedShareProvider implements IShareProvider { | |||
return; | |||
} | |||
public function getSharesInFolder($userId, $node, $reshares) { | |||
return [];//TODO | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ |
@@ -454,6 +454,49 @@ class DefaultShareProvider implements IShareProvider { | |||
return $share; | |||
} | |||
public function getSharesInFolder($userId, $node, $reshares) { | |||
$qb = $this->dbConn->getQueryBuilder(); | |||
$qb->select('*') | |||
->from('share', 's') | |||
->andWhere($qb->expr()->orX( | |||
$qb->expr()->eq('item_type', $qb->createNamedParameter('file')), | |||
$qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) | |||
)); | |||
$qb->andWhere($qb->expr()->orX( | |||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)), | |||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)) | |||
)); | |||
/** | |||
* Reshares for this user are shares where they are the owner. | |||
*/ | |||
if ($reshares === false) { | |||
$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))); | |||
} else { | |||
$qb->andWhere( | |||
$qb->expr()->orX( | |||
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), | |||
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) | |||
) | |||
); | |||
} | |||
$qb->innerJoin('s', 'filecache' ,'f', 's.file_source = f.fileid'); | |||
$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId()))); | |||
$qb->orderBy('id'); | |||
$cursor = $qb->execute(); | |||
$shares = []; | |||
while ($data = $cursor->fetch()) { | |||
$shares[$data['fileid']][] = $this->createShare($data); | |||
} | |||
$cursor->closeCursor(); | |||
return $shares; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ |
@@ -34,6 +34,7 @@ use OCP\Files\File; | |||
use OCP\Files\Folder; | |||
use OCP\Files\IRootFolder; | |||
use OCP\Files\Mount\IMountManager; | |||
use OCP\Files\Node; | |||
use OCP\Files\NotFoundException; | |||
use OCP\IConfig; | |||
use OCP\IGroupManager; | |||
@@ -48,6 +49,7 @@ use OCP\Share\IManager; | |||
use OCP\Share\IProviderFactory; | |||
use Symfony\Component\EventDispatcher\EventDispatcher; | |||
use Symfony\Component\EventDispatcher\GenericEvent; | |||
use OCP\Share\IShareProvider; | |||
/** | |||
* This class is the communication hub for all sharing related operations. | |||
@@ -881,6 +883,14 @@ class Manager implements IManager { | |||
$provider->move($share, $recipientId); | |||
} | |||
public function getSharesInFolder($userId, Node $node, $reshares = false) { | |||
$providers = $this->factory->getAllProviders(); | |||
return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) { | |||
return $shares + $provider->getSharesInFolder($userId, $node, $reshares); | |||
}, []); | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ |
@@ -163,4 +163,8 @@ class ProviderFactory implements IProviderFactory { | |||
return $provider; | |||
} | |||
public function getAllProviders() { | |||
return [$this->defaultShareProvider(), $this->federatedShareProvider()]; | |||
} | |||
} |
@@ -87,6 +87,17 @@ interface IManager { | |||
*/ | |||
public function moveShare(IShare $share, $recipientId); | |||
/** | |||
* Get all shares shared by (initiated) by the provided user in a folder. | |||
* | |||
* @param string $userId | |||
* @param Node|null $node | |||
* @param bool $reshares | |||
* @return IShare[] | |||
* @since 9.2.0 | |||
*/ | |||
public function getSharesInFolder($userId, Node $node, $reshares = false); | |||
/** | |||
* Get shares shared by (initiated) by the provided user. | |||
* |
@@ -55,4 +55,10 @@ interface IProviderFactory { | |||
* @since 9.0.0 | |||
*/ | |||
public function getProviderForType($shareType); | |||
/** | |||
* @return IShareProvider[] | |||
* @since 9.2.0 | |||
*/ | |||
public function getAllProviders(); | |||
} |
@@ -91,6 +91,17 @@ interface IShareProvider { | |||
*/ | |||
public function move(\OCP\Share\IShare $share, $recipient); | |||
/** | |||
* Get all shares by the given user in a folder | |||
* | |||
* @param string $userId | |||
* @param Node|null $node | |||
* @param bool $reshares Also get the shares where $user is the owner instead of just the shares where $user is the initiator | |||
* @return \OCP\Share\IShare[] | |||
* @since 9.2.0 | |||
*/ | |||
public function getSharesInFolder($userId, $node, $reshares); | |||
/** | |||
* Get all shares by the given user | |||
* |
@@ -2564,4 +2564,13 @@ class DummyFactory implements IProviderFactory { | |||
public function getProviderForType($shareType) { | |||
return $this->provider; | |||
} | |||
/** | |||
* @return IShareProvider[] | |||
*/ | |||
public function getAllProviders() { | |||
return [$this->provider]; | |||
} | |||
} |