Merge pull request #52507 from nextcloud/backport/52434/stable31

[stable31] fix(navigation): Fix default app entry registered as closure
This commit is contained in:
Joas Schilling 2025-04-28 23:34:32 +02:00 committed by GitHub
commit 15d3a12f40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 50 additions and 14 deletions

View file

@ -77,7 +77,7 @@ class NavigationManager implements INavigationManager {
$this->closureEntries[] = $entry;
return;
}
$this->init();
$this->init(false);
$id = $entry['id'];
@ -122,10 +122,6 @@ class NavigationManager implements INavigationManager {
*/
public function getAll(string $type = 'link'): array {
$this->init();
foreach ($this->closureEntries as $c) {
$this->add($c());
}
$this->closureEntries = [];
$result = $this->entries;
if ($type !== 'all') {
@ -211,7 +207,13 @@ class NavigationManager implements INavigationManager {
return $this->activeEntry;
}
private function init() {
private function init(bool $resolveClosures = true): void {
if ($resolveClosures) {
while ($c = array_pop($this->closureEntries)) {
$this->add($c());
}
}
if ($this->init) {
return;
}
@ -419,11 +421,6 @@ class NavigationManager implements INavigationManager {
public function get(string $id): ?array {
$this->init();
foreach ($this->closureEntries as $c) {
$this->add($c());
}
$this->closureEntries = [];
return $this->entries[$id];
}

View file

@ -304,6 +304,11 @@ class URLGenerator implements IURLGenerator {
if ($href === '') {
throw new \InvalidArgumentException('Default navigation entry is missing href: ' . $entryId);
}
if (str_starts_with($href, $this->getBaseUrl())) {
return $href;
}
if (str_starts_with($href, '/index.php/') && ($this->config->getSystemValueBool('htaccess.IgnoreFrontController', false) || getenv('front_controller_active') === 'true')) {
$href = substr($href, 10);
}

View file

@ -704,30 +704,64 @@ class NavigationManagerTest extends TestCase {
true,
'settings',
],
// closure navigation entries are also resolved
[
'closure2',
'',
'',
true,
'closure2',
],
[
'',
'closure2',
'',
true,
'closure2',
],
[
'',
'',
'{"closure2":{"order":1,"app":"closure2","href":"/closure2"}}',
true,
'closure2',
],
];
}
/**
* @dataProvider provideDefaultEntries
*/
public function testGetDefaultEntryIdForUser($defaultApps, $userDefaultApps, $userApporder, $withFallbacks, $expectedApp): void {
public function testGetDefaultEntryIdForUser(string $defaultApps, string $userDefaultApps, string $userApporder, bool $withFallbacks, string $expectedApp): void {
$this->navigationManager->add([
'id' => 'files',
]);
$this->navigationManager->add([
'id' => 'settings',
]);
$this->navigationManager->add(static function (): array {
return [
'id' => 'closure1',
'href' => '/closure1',
];
});
$this->navigationManager->add(static function (): array {
return [
'id' => 'closure2',
'href' => '/closure2',
];
});
$this->appManager->method('getInstalledApps')->willReturn([]);
$user = $this->createMock(IUser::class);
$user->method('getUID')->willReturn('user1');
$this->userSession->expects($this->once())
$this->userSession->expects($this->atLeastOnce())
->method('getUser')
->willReturn($user);
$this->config->expects($this->once())
$this->config->expects($this->atLeastOnce())
->method('getSystemValueString')
->with('defaultapp', $this->anything())
->willReturn($defaultApps);