Skip to content

Commit 203d029

Browse files
committed
feat: introduce a function to bind a teamfolder to a team
Assisted by: GitHub Copilot:Claude Sonnet 5 Assisted by: GitHub Copilot:GPT-5.6 Terra Assisted by: GitHub Copilot:Kimi K2.7 Code Signed-off-by: Stefan Dietrich <5716289+stediefan@users.noreply.github.com>
1 parent bff9aaf commit 203d029

6 files changed

Lines changed: 207 additions & 0 deletions

File tree

lib/private/Teams/TeamManager.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use OCP\IURLGenerator;
1717
use OCP\Server;
1818
use OCP\Teams\ITeamManager;
19+
use OCP\Teams\ITeamFolderProvider;
1920
use OCP\Teams\ITeamResourceProvider;
2021
use OCP\Teams\Team;
2122
use Psr\Container\ContainerExceptionInterface;
@@ -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: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
/**
13+
* Provides the exclusive folder belonging to a team.
14+
*
15+
* Register implementations through
16+
* {@see \OCP\AppFramework\Bootstrap\IRegistrationContext::registerTeamResourceProvider()}.
17+
*
18+
* @since 35.0.0
19+
*/
20+
interface ITeamFolderProvider extends ITeamResourceProvider {
21+
/**
22+
* Return the folder exclusively linked to the team.
23+
*
24+
* @since 35.0.0
25+
*/
26+
public function getTeamFolder(string $teamId): ?TeamFolder;
27+
28+
/**
29+
* Create the exclusive folder for a team, or return its existing folder.
30+
*
31+
* @param Team $team The team that owns the folder.
32+
* @param int $quota Quota in bytes; zero means unlimited.
33+
* @since 35.0.0
34+
*/
35+
public function createTeamFolder(Team $team, int $quota = 0): TeamFolder;
36+
37+
/**
38+
* Remove the exclusive relationship but retain the folder and its contents.
39+
*
40+
* @return TeamFolder|null The unlinked folder, if one existed.
41+
* @since 35.0.0
42+
*/
43+
public function unlinkTeamFolder(string $teamId): ?TeamFolder;
44+
45+
/**
46+
* Remove the team folder and its contents.
47+
*
48+
* @since 35.0.0
49+
*/
50+
public function removeTeamFolder(string $teamId): bool;
51+
}

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: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
/**
13+
* A folder exclusively linked to a team.
14+
*
15+
* @since 35.0.0
16+
*/
17+
class TeamFolder implements \JsonSerializable {
18+
/**
19+
* @since 35.0.0
20+
*/
21+
public function __construct(
22+
private int $id,
23+
private string $mountPoint,
24+
) {
25+
}
26+
27+
/**
28+
* @since 35.0.0
29+
*/
30+
public function getId(): int {
31+
return $this->id;
32+
}
33+
34+
/**
35+
* @since 35.0.0
36+
*/
37+
public function getMountPoint(): string {
38+
return $this->mountPoint;
39+
}
40+
41+
/**
42+
* @return array{id: int, mountPoint: string}
43+
* @since 35.0.0
44+
*/
45+
#[\Override]
46+
public function jsonSerialize(): array {
47+
return [
48+
'id' => $this->id,
49+
'mountPoint' => $this->mountPoint,
50+
];
51+
}
52+
}

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: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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 OCA\Circles\CirclesManager;
15+
use OCP\IURLGenerator;
16+
use OCP\Teams\ITeamFolderProvider;
17+
use OCP\Teams\ITeamResourceProvider;
18+
use Test\TestCase;
19+
20+
class TeamManagerTest extends TestCase {
21+
public function testGetTeamFolderProviderReturnsNullWithoutTeamSupport(): void {
22+
$teamManager = $this->createTeamManager(null);
23+
24+
$this->assertNull($teamManager->getTeamFolderProvider());
25+
}
26+
27+
public function testGetTeamFolderProviderReturnsNullWithoutFolderProvider(): void {
28+
$teamManager = $this->createTeamManager($this->createMock(CirclesManager::class));
29+
$this->setProviders($teamManager, [
30+
'other' => $this->createMock(ITeamResourceProvider::class),
31+
]);
32+
33+
$this->assertNull($teamManager->getTeamFolderProvider());
34+
}
35+
36+
public function testGetTeamFolderProviderReturnsRegisteredFolderProvider(): void {
37+
$teamManager = $this->createTeamManager($this->createMock(CirclesManager::class));
38+
$folderProvider = $this->createMock(ITeamFolderProvider::class);
39+
$this->setProviders($teamManager, [
40+
'other' => $this->createMock(ITeamResourceProvider::class),
41+
'folder' => $folderProvider,
42+
]);
43+
44+
$this->assertSame($folderProvider, $teamManager->getTeamFolderProvider());
45+
}
46+
47+
private function createTeamManager(?CirclesManager $circlesManager): TeamManager {
48+
return new TeamManager(
49+
$this->createMock(Coordinator::class),
50+
$this->createMock(IURLGenerator::class),
51+
$circlesManager,
52+
);
53+
}
54+
55+
/**
56+
* @param array<string, ITeamResourceProvider> $providers
57+
*/
58+
private function setProviders(TeamManager $teamManager, array $providers): void {
59+
(new \ReflectionProperty(TeamManager::class, 'providers'))->setValue($teamManager, $providers);
60+
}
61+
}

0 commit comments

Comments
 (0)