Skip to content

Commit 0ccc152

Browse files
committed
fixup! fix(NavigationManager): only resolve navigations of booted apps
1 parent 3ea0f02 commit 0ccc152

2 files changed

Lines changed: 22 additions & 10 deletions

File tree

lib/private/NavigationManager.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,6 @@ private function resolveAppNavigationEntries(): void {
211211
$this->add($c());
212212
}
213213

214-
// Resolve dynamically added navigation entries via event listeners
215-
if ($this->loadedAppInfo === []) {
216-
$this->eventDispatcher->dispatchTyped(new LoadAdditionalEntriesEvent());
217-
}
218-
219214
// Resolve classic info.xml based navigation entries
220215
if ($this->userSession->isLoggedIn()) {
221216
$user = $this->userSession->getUser();
@@ -224,11 +219,12 @@ private function resolveAppNavigationEntries(): void {
224219
$apps = $this->appManager->getEnabledApps();
225220
}
226221

222+
if (count($apps) === count($this->loadedAppInfo)) {
223+
// All apps that are loaded for the user have already been resolved
224+
return;
225+
}
226+
227227
foreach ($apps as $app) {
228-
if ($this->appManager->isAppLoaded($app)) {
229-
// the app is not yet booted thus its routes do not yet exist
230-
continue;
231-
}
232228
if (in_array($app, $this->loadedAppInfo)) {
233229
// the apps navigations were already resolved
234230
continue;
@@ -237,8 +233,16 @@ private function resolveAppNavigationEntries(): void {
237233
// load plugins and collections from info.xml
238234
$info = $this->appManager->getAppInfo($app);
239235
if (!isset($info['navigations']['navigation'])) {
236+
// this app does not have any navigation entries, skip it
237+
$this->loadedAppInfo[] = $app;
238+
continue;
239+
}
240+
241+
if (!$this->appManager->isAppLoaded($app)) {
242+
// the app is not yet booted thus its routes do not yet exist
240243
continue;
241244
}
245+
242246
foreach ($info['navigations']['navigation'] as $key => $nav) {
243247
$nav['type'] = $nav['type'] ?? 'link';
244248
if (!isset($nav['name'])) {
@@ -298,6 +302,9 @@ private function resolveAppNavigationEntries(): void {
298302
));
299303
}
300304
}
305+
306+
// Resolve dynamically added navigation entries via event listeners
307+
$this->eventDispatcher->dispatchTyped(new LoadAdditionalEntriesEvent());
301308
}
302309

303310
private function isAdmin(): bool {

tests/lib/NavigationManagerTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ public function testWithAppManager($expected, $navigation, $isAdmin = false): vo
233233
->method('getAppInfo')
234234
->with('test')
235235
->willReturn($navigation);
236+
$this->appManager->expects($this->any())
237+
->method('isAppLoaded')
238+
->with('test')
239+
->willReturn(true);
236240
$this->urlGenerator->expects($this->any())
237241
->method('imagePath')
238242
->willReturnCallback(function ($appName, $file) {
@@ -259,7 +263,7 @@ public function testWithAppManager($expected, $navigation, $isAdmin = false): vo
259263
$this->groupManager->expects($this->any())->method('isAdmin')->willReturn($isAdmin);
260264

261265
$this->navigationManager->clear();
262-
$this->dispatcher->expects($this->once())
266+
$this->dispatcher->expects($this->atLeastOnce())
263267
->method('dispatchTyped')
264268
->willReturnCallback(function ($event): void {
265269
$this->assertInstanceOf(LoadAdditionalEntriesEvent::class, $event);
@@ -428,6 +432,7 @@ function (string $userId, string $appName, string $key, mixed $default = '') use
428432
->with('theming')
429433
->willReturn(true);
430434
$this->appManager->expects($this->once())->method('getAppInfo')->with('test')->willReturn($navigation);
435+
$this->appManager->expects($this->any())->method('isAppLoaded')->with('test')->willReturn(true);
431436
$this->appManager->expects($this->once())->method('getAppIcon')->with('test')->willReturn('/apps/test/img/app.svg');
432437
$this->l10nFac->expects($this->any())->method('get')->willReturn($l);
433438
$this->urlGenerator->expects($this->any())->method('imagePath')->willReturnCallback(function ($appName, $file) {

0 commit comments

Comments
 (0)