Skip to content

Commit 82b2ab2

Browse files
authored
Merge pull request #62476 from Dataport/feature/teams-auto-folder-creation
feat: introduce a function to bind a teamfolder to a team
2 parents c857bb9 + c6e9d20 commit 82b2ab2

9 files changed

Lines changed: 229 additions & 0 deletions

File tree

‎lib/composer/composer/autoload_classmap.php‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,9 +1024,11 @@
10241024
'OCP\\TaskProcessing\\TaskTypes\\TextToTextSummary' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php',
10251025
'OCP\\TaskProcessing\\TaskTypes\\TextToTextTopics' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php',
10261026
'OCP\\TaskProcessing\\TaskTypes\\TextToTextTranslate' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/TextToTextTranslate.php',
1027+
'OCP\\Teams\\ITeamFolderProvider' => $baseDir . '/lib/public/Teams/ITeamFolderProvider.php',
10271028
'OCP\\Teams\\ITeamManager' => $baseDir . '/lib/public/Teams/ITeamManager.php',
10281029
'OCP\\Teams\\ITeamResourceProvider' => $baseDir . '/lib/public/Teams/ITeamResourceProvider.php',
10291030
'OCP\\Teams\\Team' => $baseDir . '/lib/public/Teams/Team.php',
1031+
'OCP\\Teams\\TeamFolder' => $baseDir . '/lib/public/Teams/TeamFolder.php',
10301032
'OCP\\Teams\\TeamResource' => $baseDir . '/lib/public/Teams/TeamResource.php',
10311033
'OCP\\Template' => $baseDir . '/lib/public/Template.php',
10321034
'OCP\\Template\\ITemplate' => $baseDir . '/lib/public/Template/ITemplate.php',

‎lib/composer/composer/autoload_static.php‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,9 +1065,11 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
10651065
'OCP\\TaskProcessing\\TaskTypes\\TextToTextSummary' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php',
10661066
'OCP\\TaskProcessing\\TaskTypes\\TextToTextTopics' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php',
10671067
'OCP\\TaskProcessing\\TaskTypes\\TextToTextTranslate' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/TextToTextTranslate.php',
1068+
'OCP\\Teams\\ITeamFolderProvider' => __DIR__ . '/../../..' . '/lib/public/Teams/ITeamFolderProvider.php',
10681069
'OCP\\Teams\\ITeamManager' => __DIR__ . '/../../..' . '/lib/public/Teams/ITeamManager.php',
10691070
'OCP\\Teams\\ITeamResourceProvider' => __DIR__ . '/../../..' . '/lib/public/Teams/ITeamResourceProvider.php',
10701071
'OCP\\Teams\\Team' => __DIR__ . '/../../..' . '/lib/public/Teams/Team.php',
1072+
'OCP\\Teams\\TeamFolder' => __DIR__ . '/../../..' . '/lib/public/Teams/TeamFolder.php',
10711073
'OCP\\Teams\\TeamResource' => __DIR__ . '/../../..' . '/lib/public/Teams/TeamResource.php',
10721074
'OCP\\Template' => __DIR__ . '/../../..' . '/lib/public/Template.php',
10731075
'OCP\\Template\\ITemplate' => __DIR__ . '/../../..' . '/lib/public/Template/ITemplate.php',

‎lib/private/Teams/TeamManager.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use OCA\Circles\Model\Probes\CircleProbe;
1616
use OCP\IURLGenerator;
1717
use OCP\Server;
18+
use OCP\Teams\ITeamFolderProvider;
1819
use OCP\Teams\ITeamManager;
1920
use OCP\Teams\ITeamResourceProvider;
2021
use OCP\Teams\Team;
@@ -70,6 +71,17 @@ public function getProvider(string $providerId): ITeamResourceProvider {
7071
throw new \RuntimeException('No provider found for id ' . $providerId);
7172
}
7273

74+
#[\Override]
75+
public function getTeamFolderProvider(): ?ITeamFolderProvider {
76+
foreach ($this->getProviders() as $provider) {
77+
if ($provider instanceof ITeamFolderProvider) {
78+
return $provider;
79+
}
80+
}
81+
82+
return null;
83+
}
84+
7385
#[\Override]
7486
public function getSharedWith(string $teamId, string $userId): array {
7587
if (!$this->hasTeamSupport()) {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCP\Teams;
11+
12+
use OCP\AppFramework\Attribute\Consumable;
13+
use OCP\AppFramework\Attribute\Implementable;
14+
15+
/**
16+
* Provides the exclusive folder belonging to a team.
17+
*
18+
* Register implementations through
19+
* {@see \OCP\AppFramework\Bootstrap\IRegistrationContext::registerTeamResourceProvider()}.
20+
*
21+
* @since 35.0.0
22+
*/
23+
#[Consumable(since: '35.0.0')]
24+
#[Implementable(since: '35.0.0')]
25+
interface ITeamFolderProvider extends ITeamResourceProvider {
26+
/**
27+
* Return the folder exclusively linked to the team.
28+
*
29+
* @since 35.0.0
30+
*/
31+
public function getTeamFolder(string $teamId): ?TeamFolder;
32+
33+
/**
34+
* Create the exclusive folder for a team, or return its existing folder.
35+
*
36+
* @param Team $team The team that owns the folder.
37+
* @param int $quota Quota in bytes; zero means unlimited.
38+
* @since 35.0.0
39+
*/
40+
public function createTeamFolder(Team $team, int $quota = 0): TeamFolder;
41+
42+
/**
43+
* Remove the exclusive relationship but retain the folder and its contents.
44+
*
45+
* @return TeamFolder|null The unlinked folder, if one existed.
46+
* @since 35.0.0
47+
*/
48+
public function unlinkTeamFolder(string $teamId): ?TeamFolder;
49+
50+
/**
51+
* Remove the team folder and its contents.
52+
*
53+
* @since 35.0.0
54+
*/
55+
public function removeTeamFolder(string $teamId): bool;
56+
}

‎lib/public/Teams/ITeamManager.php‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ public function getProviders(): array;
2626
*/
2727
public function getProvider(string $providerId): ITeamResourceProvider;
2828

29+
/**
30+
* Get the registered provider of exclusive team folders.
31+
*
32+
* @return ITeamFolderProvider|null Null when no folder provider is enabled.
33+
* @since 35.0.0
34+
*/
35+
public function getTeamFolderProvider(): ?ITeamFolderProvider;
36+
2937
/**
3038
* Returns all team resources for a given team and user
3139
*

‎lib/public/Teams/TeamFolder.php‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCP\Teams;
11+
12+
use OCP\AppFramework\Attribute\Consumable;
13+
14+
/**
15+
* A folder exclusively linked to a team.
16+
*
17+
* @since 35.0.0
18+
*/
19+
#[Consumable(since: '35.0.0')]
20+
class TeamFolder implements \JsonSerializable {
21+
/**
22+
* @since 35.0.0
23+
*/
24+
public function __construct(
25+
private int $id,
26+
private string $mountPoint,
27+
) {
28+
}
29+
30+
/**
31+
* @since 35.0.0
32+
*/
33+
public function getId(): int {
34+
return $this->id;
35+
}
36+
37+
/**
38+
* @since 35.0.0
39+
*/
40+
public function getMountPoint(): string {
41+
return $this->mountPoint;
42+
}
43+
44+
/**
45+
* @return array{id: int, mountPoint: string}
46+
* @since 35.0.0
47+
*/
48+
#[\Override]
49+
public function jsonSerialize(): array {
50+
return [
51+
'id' => $this->id,
52+
'mountPoint' => $this->mountPoint,
53+
];
54+
}
55+
}

‎tests/lib/Sharing/AbstractSharingManagerTests.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3159,6 +3159,7 @@ public function testGetShareUniqueDisplayNames(): void {
31593159
$this->dbConnection->commit();
31603160

31613161
$share = $this->getShare($accessContext, $id);
3162+
usort($share['recipients'], fn (array $a, array $b): int => $a['value'] <=> $b['value']);
31623163
$this->assertEquals([
31633164
[
31643165
'class' => TestShareSourceType1::class,

‎tests/lib/Teams/TeamFolderTest.php‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace Test\Teams;
11+
12+
use OCP\Teams\TeamFolder;
13+
use Test\TestCase;
14+
15+
class TeamFolderTest extends TestCase {
16+
public function testSerializesFolderIdentity(): void {
17+
$folder = new TeamFolder(42, 'Engineering');
18+
19+
$this->assertSame(42, $folder->getId());
20+
$this->assertSame('Engineering', $folder->getMountPoint());
21+
$this->assertSame(['id' => 42, 'mountPoint' => 'Engineering'], $folder->jsonSerialize());
22+
}
23+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace Test\Teams;
11+
12+
use OC\AppFramework\Bootstrap\Coordinator;
13+
use OC\Teams\TeamManager;
14+
use OCP\IURLGenerator;
15+
use OCP\Teams\ITeamFolderProvider;
16+
use OCP\Teams\ITeamResourceProvider;
17+
use Test\TestCase;
18+
19+
class TeamManagerTest extends TestCase {
20+
public function testGetTeamFolderProviderReturnsNullWithoutTeamSupport(): void {
21+
$teamManager = $this->createTeamManager();
22+
23+
$this->assertNull($teamManager->getTeamFolderProvider());
24+
}
25+
26+
public function testGetTeamFolderProviderReturnsNullWithoutFolderProvider(): void {
27+
$teamManager = $this->createTeamManager(true);
28+
$this->setProviders($teamManager, [
29+
'other' => $this->createMock(ITeamResourceProvider::class),
30+
]);
31+
32+
$this->assertNull($teamManager->getTeamFolderProvider());
33+
}
34+
35+
public function testGetTeamFolderProviderReturnsRegisteredFolderProvider(): void {
36+
$teamManager = $this->createTeamManager(true);
37+
$folderProvider = $this->createMock(ITeamFolderProvider::class);
38+
$this->setProviders($teamManager, [
39+
'other' => $this->createMock(ITeamResourceProvider::class),
40+
'folder' => $folderProvider,
41+
]);
42+
43+
$this->assertSame($folderProvider, $teamManager->getTeamFolderProvider());
44+
}
45+
46+
private function createTeamManager(bool $hasTeamSupport = false): TeamManager {
47+
return new class($this->createMock(Coordinator::class), $this->createMock(IURLGenerator::class), null, $hasTeamSupport, ) extends TeamManager {
48+
public function __construct(
49+
Coordinator $bootContext,
50+
IURLGenerator $urlGenerator,
51+
null $circlesManager,
52+
private bool $hasTeamSupport,
53+
) {
54+
parent::__construct($bootContext, $urlGenerator, $circlesManager);
55+
}
56+
57+
#[\Override]
58+
public function hasTeamSupport(): bool {
59+
return $this->hasTeamSupport;
60+
}
61+
};
62+
}
63+
64+
/**
65+
* @param array<string, ITeamResourceProvider> $providers
66+
*/
67+
private function setProviders(TeamManager $teamManager, array $providers): void {
68+
(new \ReflectionProperty(TeamManager::class, 'providers'))->setValue($teamManager, $providers);
69+
}
70+
}

0 commit comments

Comments
 (0)