Skip to content

Commit 0cae89b

Browse files
committed
refactor(navigation-manager): Cleanup implementation and add type hinting
Signed-off-by: Carl Schwan <[email protected]>
1 parent 6db0764 commit 0cae89b

File tree

3 files changed

+61
-38
lines changed

3 files changed

+61
-38
lines changed

build/psalm-baseline.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,6 @@
663663
<code><![CDATA[resolvePath]]></code>
664664
<code><![CDATA[resolvePath]]></code>
665665
<code><![CDATA[resolvePath]]></code>
666-
<code><![CDATA[resolvePath]]></code>
667666
<code><![CDATA[touch]]></code>
668667
<code><![CDATA[unlink]]></code>
669668
</InternalMethod>

lib/private/NavigationManager.php

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,20 @@
1919
use OCP\IUserSession;
2020
use OCP\L10N\IFactory;
2121
use OCP\Navigation\Events\LoadAdditionalEntriesEvent;
22+
use Override;
2223
use Psr\Log\LoggerInterface;
2324

2425
/**
2526
* Manages the Nextcloud navigation
27+
* @psalm-import-type NavigationEntry from INavigationManager
28+
* @psalm-import-type NavigationEntryOutput from INavigationManager
2629
*/
2730
class NavigationManager implements INavigationManager {
31+
/** @var array<string, NavigationEntryOutput> */
2832
protected array $entries = [];
33+
/** @var list<callable(): NavigationEntry> */
2934
protected array $closureEntries = [];
30-
/** @var string $activeEntry */
31-
protected $activeEntry;
35+
protected ?string $activeEntry = null;
3236
protected array $unreadCounters = [];
3337
protected bool $init = false;
3438
/** User defined app order (cached for the `add` function) */
@@ -46,10 +50,8 @@ public function __construct(
4650
) {
4751
}
4852

49-
/**
50-
* @inheritDoc
51-
*/
52-
public function add($entry) {
53+
#[Override]
54+
public function add(array|callable $entry): void {
5355
if ($entry instanceof \Closure) {
5456
$this->closureEntries[] = $entry;
5557
return;
@@ -86,7 +88,7 @@ public function add($entry) {
8688
$this->updateDefaultEntries();
8789
}
8890

89-
private function updateDefaultEntries() {
91+
private function updateDefaultEntries(): void {
9092
$defaultEntryId = $this->getDefaultEntryIdForUser($this->userSession->getUser(), false);
9193
foreach ($this->entries as $id => $entry) {
9294
if ($entry['type'] === 'link') {
@@ -95,9 +97,7 @@ private function updateDefaultEntries() {
9597
}
9698
}
9799

98-
/**
99-
* @inheritDoc
100-
*/
100+
#[Override]
101101
public function getAll(string $type = 'link'): array {
102102
$this->init();
103103

@@ -114,8 +114,8 @@ public function getAll(string $type = 'link'): array {
114114
/**
115115
* Sort navigation entries default app is always sorted first, then by order, name and set active flag
116116
*
117-
* @param array $list
118-
* @return array
117+
* @param array<string, NavigationEntryOutput> $list
118+
* @return array<string, NavigationEntryOutput>
119119
*/
120120
private function proceedNavigation(array $list, string $type): array {
121121
uasort($list, function ($a, $b) {
@@ -136,7 +136,7 @@ private function proceedNavigation(array $list, string $type): array {
136136

137137
if ($type === 'all' || $type === 'link') {
138138
// There might be the case that no default app was set, in this case the first app is the default app.
139-
// Otherwise the default app is already the ordered first, so setting the default prop will make no difference.
139+
// Otherwise, the default app is already the ordered first, so setting the default prop will make no difference.
140140
foreach ($list as $index => &$navEntry) {
141141
if ($navEntry['type'] === 'link') {
142142
$navEntry['default'] = true;
@@ -165,23 +165,19 @@ private function proceedNavigation(array $list, string $type): array {
165165
/**
166166
* removes all the entries
167167
*/
168-
public function clear($loadDefaultLinks = true) {
168+
public function clear(bool $loadDefaultLinks = true): void {
169169
$this->entries = [];
170170
$this->closureEntries = [];
171171
$this->init = !$loadDefaultLinks;
172172
}
173173

174-
/**
175-
* @inheritDoc
176-
*/
177-
public function setActiveEntry($appId) {
174+
#[Override]
175+
public function setActiveEntry(string $appId): void {
178176
$this->activeEntry = $appId;
179177
}
180178

181-
/**
182-
* @inheritDoc
183-
*/
184-
public function getActiveEntry() {
179+
#[Override]
180+
public function getActiveEntry(): ?string {
185181
return $this->activeEntry;
186182
}
187183

@@ -377,31 +373,34 @@ private function init(bool $resolveClosures = true): void {
377373
}
378374
}
379375

380-
private function isAdmin() {
376+
private function isAdmin(): bool {
381377
$user = $this->userSession->getUser();
382378
if ($user !== null) {
383379
return $this->groupManager->isAdmin($user->getUID());
384380
}
385381
return false;
386382
}
387383

388-
private function isSubadmin() {
384+
private function isSubadmin(): bool {
389385
$user = $this->userSession->getUser();
390386
if ($user !== null && $this->groupManager instanceof Manager) {
391387
return $this->groupManager->getSubAdmin()->isSubAdmin($user);
392388
}
393389
return false;
394390
}
395391

392+
#[Override]
396393
public function setUnreadCounter(string $id, int $unreadCounter): void {
397394
$this->unreadCounters[$id] = $unreadCounter;
398395
}
399396

397+
#[Override]
400398
public function get(string $id): ?array {
401399
$this->init();
402400
return $this->entries[$id];
403401
}
404402

403+
#[Override]
405404
public function getDefaultEntryIdForUser(?IUser $user = null, bool $withFallbacks = true): string {
406405
$this->init();
407406
// Disable fallbacks here, as we need to override them with the user defaults if none are configured.
@@ -443,6 +442,7 @@ public function getDefaultEntryIdForUser(?IUser $user = null, bool $withFallback
443442
return $withFallbacks ? 'files' : '';
444443
}
445444

445+
#[Override]
446446
public function getDefaultEntryIds(bool $withFallbacks = true): array {
447447
$this->init();
448448
$storedIds = explode(',', $this->config->getSystemValueString('defaultapp', $withFallbacks ? 'dashboard,files' : ''));
@@ -457,6 +457,7 @@ public function getDefaultEntryIds(bool $withFallbacks = true): array {
457457
return array_filter($ids);
458458
}
459459

460+
#[Override]
460461
public function setDefaultEntryIds(array $ids): void {
461462
$this->init();
462463
$entryIds = array_keys($this->entries);

lib/public/INavigationManager.php

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,31 @@
1010

1111
namespace OCP;
1212

13+
use OCP\AppFramework\Attribute\Consumable;
14+
use OCP\AppFramework\Attribute\ExceptionalImplementable;
15+
1316
/**
14-
* Manages the ownCloud navigation
17+
* Manages the Nextcloud navigation
18+
*
1519
* @since 6.0.0
1620
*
1721
* @psalm-type NavigationEntry = array{id: string, order: int, href: string, name: string, app?: string, icon?: string, classes?: string, type?: string}
22+
* @psalm-type NavigationEntryOutput = array{
23+
* id: string,
24+
* order?: int,
25+
* href: string,
26+
* icon: string,
27+
* type: string,
28+
* name: string,
29+
* app?: string,
30+
* default?: bool,
31+
* active: bool,
32+
* classes: string,
33+
* unread: int,
34+
* }
1835
*/
36+
#[Consumable(since: '6.0.0')]
37+
#[ExceptionalImplementable(app: 'guest')]
1938
interface INavigationManager {
2039
/**
2140
* Navigation entries of the app navigation
@@ -35,39 +54,43 @@ interface INavigationManager {
3554
*/
3655
public const TYPE_GUEST = 'guest';
3756

57+
/**
58+
* All navigation entries
59+
* @since 33.0.0
60+
*/
61+
public const TYPE_ALL = 'all';
62+
3863
/**
3964
* Creates a new navigation entry
4065
*
41-
* @param array array|\Closure $entry Array containing: id, name, order, icon and href key
42-
* If a menu entry (type = 'link') is added, you shall also set app to the app that added the entry.
43-
* The use of a closure is preferred, because it will avoid
44-
* loading the routing of your app, unless required.
45-
* @psalm-param NavigationEntry|callable():NavigationEntry $entry
66+
* @param NavigationEntry|callable():NavigationEntry $entry If a menu entry (type = 'link') is added, you shall also set app to the app that
67+
* added the entry. The use of a closure is preferred, because it will avoid loading
68+
* the routing of your app, unless required.
4669
* @return void
4770
* @since 6.0.0
4871
*/
49-
public function add($entry);
72+
public function add(array|callable $entry): void;
5073

5174
/**
5275
* Sets the current navigation entry of the currently running app
5376
* @param string $appId id of the app entry to activate (from added $entry)
5477
* @return void
5578
* @since 6.0.0
5679
*/
57-
public function setActiveEntry($appId);
80+
public function setActiveEntry(string $appId): void;
5881

5982
/**
6083
* Get the current navigation entry of the currently running app
61-
* @return string
84+
* @return ?string
6285
* @since 20.0.0
6386
*/
64-
public function getActiveEntry();
87+
public function getActiveEntry(): ?string;
6588

6689
/**
6790
* Get a list of navigation entries
6891
*
69-
* @param string $type type of the navigation entries
70-
* @return array
92+
* @param self::TYPE_APPS|self::TYPE_SETTINGS|self::TYPE_GUEST|self::TYPE_ALL $type type of the navigation entries
93+
* @return array<string, NavigationEntryOutput>
7194
* @since 14.0.0
7295
*/
7396
public function getAll(string $type = self::TYPE_APPS): array;
@@ -92,7 +115,7 @@ public function get(string $id): ?array;
92115
/**
93116
* Returns the id of the user's default entry
94117
*
95-
* If `user` is not passed, the currently logged in user will be used
118+
* If `user` is not passed, the currently logged-in user will be used
96119
*
97120
* @param ?IUser $user User to query default entry for
98121
* @param bool $withFallbacks Include fallback values if no default entry was configured manually

0 commit comments

Comments
 (0)