Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/profile/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
<id>profile</id>
<name>Profile</name>
<summary>This application provides the profile</summary>
<description>Provides a customisable user profile interface.</description>
<description>Provides a customizable user profile interface.</description>
<version>2.0.0-dev.0</version>
<licence>agpl</licence>
<licence>AGPL-3.0-or-later</licence>
<author>Nextcloud GmbH</author>
<namespace>Profile</namespace>
<category>social</category>
Expand Down
1 change: 1 addition & 0 deletions apps/profile/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'OCA\\Profile\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
'OCA\\Profile\\Controller\\ProfilePageController' => $baseDir . '/../lib/Controller/ProfilePageController.php',
'OCA\\Profile\\Listener\\LoadAdditionalEntriesListener' => $baseDir . '/../lib/Listener/LoadAdditionalEntriesListener.php',
'OCA\\Profile\\Listener\\ProfilePickerReferenceListener' => $baseDir . '/../lib/Listener/ProfilePickerReferenceListener.php',
'OCA\\Profile\\Reference\\ProfilePickerReferenceProvider' => $baseDir . '/../lib/Reference/ProfilePickerReferenceProvider.php',
);
1 change: 1 addition & 0 deletions apps/profile/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class ComposerStaticInitProfile
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'OCA\\Profile\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
'OCA\\Profile\\Controller\\ProfilePageController' => __DIR__ . '/..' . '/../lib/Controller/ProfilePageController.php',
'OCA\\Profile\\Listener\\LoadAdditionalEntriesListener' => __DIR__ . '/..' . '/../lib/Listener/LoadAdditionalEntriesListener.php',
'OCA\\Profile\\Listener\\ProfilePickerReferenceListener' => __DIR__ . '/..' . '/../lib/Listener/ProfilePickerReferenceListener.php',
'OCA\\Profile\\Reference\\ProfilePickerReferenceProvider' => __DIR__ . '/..' . '/../lib/Reference/ProfilePickerReferenceProvider.php',
);
Expand Down
36 changes: 3 additions & 33 deletions apps/profile/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@

namespace OCA\Profile\AppInfo;

use OCA\Profile\Listener\LoadAdditionalEntriesListener;
use OCA\Profile\Listener\ProfilePickerReferenceListener;
use OCA\Profile\Reference\ProfilePickerReferenceProvider;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Collaboration\Reference\RenderReferenceEvent;
use OCP\INavigationManager;
use OCP\IURLGenerator;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\Server;
use OCP\Navigation\Events\LoadAdditionalEntriesEvent;

class Application extends App implements IBootstrap {
public const APP_ID = 'profile';
Expand All @@ -33,37 +30,10 @@ public function __construct(array $urlParams = []) {
public function register(IRegistrationContext $context): void {
$context->registerReferenceProvider(ProfilePickerReferenceProvider::class);
$context->registerEventListener(RenderReferenceEvent::class, ProfilePickerReferenceListener::class);
$context->registerEventListener(LoadAdditionalEntriesEvent::class, LoadAdditionalEntriesListener::class);
}

#[\Override]
public function boot(IBootContext $context): void {
$context->injectFn($this->registerNavigationEntry(...));
}

/**
* Registers the navigation entry for the profile app in the user settings.
* Needed as the href is dynamic and thus we cannot use the appinfo/info.xml
*/
public function registerNavigationEntry(
INavigationManager $navigationManager,
IUserSession $userSession,
IURLGenerator $urlGenerator,
): void {
if (!$userSession->isLoggedIn()) {
return;
}

$l = Server::get(IFactory::class)->get('profile');
// Profile
$navigationManager->add([
'type' => 'settings',
'id' => 'profile',
'order' => 1,
'href' => $urlGenerator->linkToRoute(
'profile.ProfilePage.index',
['targetUserId' => $userSession->getUser()->getUID()],
),
'name' => $l->t('View profile'),
]);
}
}
67 changes: 67 additions & 0 deletions apps/profile/lib/Listener/LoadAdditionalEntriesListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Profile\Listener;

use OCA\Settings\AppInfo\Application;
use OCP\App\IAppManager;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\IL10N;
use OCP\INavigationManager;
use OCP\IURLGenerator;
use OCP\IUserSession;
use OCP\Navigation\Events\LoadAdditionalEntriesEvent;

/** @template-implements IEventListener<LoadAdditionalEntriesEvent> */
class LoadAdditionalEntriesListener implements IEventListener {

public function __construct(
private readonly IL10N $l10n,
private readonly IAppManager $appManger,
private readonly INavigationManager $navigationManager,
private readonly IURLGenerator $urlGenerator,
private readonly IUserSession $userSession,
) {
}

#[\Override]
public function handle(Event $event): void {
if (!($event instanceof LoadAdditionalEntriesEvent)) {
return;
}

if (!$this->userSession->isLoggedIn()) {
return;
}

if ($this->appManger->isAppLoaded(Application::APP_ID)) {
$this->registerNavigationEntries();
}

}

private function registerNavigationEntries(): void {
$user = $this->userSession->getUser();
if ($user === null) {
return;
}

$this->navigationManager->add([
'type' => 'settings',
'id' => 'profile',
'order' => 1,
'href' => $this->urlGenerator->linkToRoute(
'profile.ProfilePage.index',
['targetUserId' => $user->getUID()],
),
'name' => $this->l10n->t('View profile'),
]);
}

}
1 change: 1 addition & 0 deletions apps/settings/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
'OCA\\Settings\\Hooks' => $baseDir . '/../lib/Hooks.php',
'OCA\\Settings\\Listener\\AppPasswordCreatedActivityListener' => $baseDir . '/../lib/Listener/AppPasswordCreatedActivityListener.php',
'OCA\\Settings\\Listener\\GroupRemovedListener' => $baseDir . '/../lib/Listener/GroupRemovedListener.php',
'OCA\\Settings\\Listener\\LoadAdditionalEntriesListener' => $baseDir . '/../lib/Listener/LoadAdditionalEntriesListener.php',
'OCA\\Settings\\Listener\\MailProviderListener' => $baseDir . '/../lib/Listener/MailProviderListener.php',
'OCA\\Settings\\Listener\\UserAddedToGroupActivityListener' => $baseDir . '/../lib/Listener/UserAddedToGroupActivityListener.php',
'OCA\\Settings\\Listener\\UserRemovedFromGroupActivityListener' => $baseDir . '/../lib/Listener/UserRemovedFromGroupActivityListener.php',
Expand Down
1 change: 1 addition & 0 deletions apps/settings/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ComposerStaticInitSettings
'OCA\\Settings\\Hooks' => __DIR__ . '/..' . '/../lib/Hooks.php',
'OCA\\Settings\\Listener\\AppPasswordCreatedActivityListener' => __DIR__ . '/..' . '/../lib/Listener/AppPasswordCreatedActivityListener.php',
'OCA\\Settings\\Listener\\GroupRemovedListener' => __DIR__ . '/..' . '/../lib/Listener/GroupRemovedListener.php',
'OCA\\Settings\\Listener\\LoadAdditionalEntriesListener' => __DIR__ . '/..' . '/../lib/Listener/LoadAdditionalEntriesListener.php',
'OCA\\Settings\\Listener\\MailProviderListener' => __DIR__ . '/..' . '/../lib/Listener/MailProviderListener.php',
'OCA\\Settings\\Listener\\UserAddedToGroupActivityListener' => __DIR__ . '/..' . '/../lib/Listener/UserAddedToGroupActivityListener.php',
'OCA\\Settings\\Listener\\UserRemovedFromGroupActivityListener' => __DIR__ . '/..' . '/../lib/Listener/UserRemovedFromGroupActivityListener.php',
Expand Down
95 changes: 3 additions & 92 deletions apps/settings/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use OCA\Settings\Hooks;
use OCA\Settings\Listener\AppPasswordCreatedActivityListener;
use OCA\Settings\Listener\GroupRemovedListener;
use OCA\Settings\Listener\LoadAdditionalEntriesListener;
use OCA\Settings\Listener\MailProviderListener;
use OCA\Settings\Listener\UserAddedToGroupActivityListener;
use OCA\Settings\Listener\UserRemovedFromGroupActivityListener;
Expand Down Expand Up @@ -91,14 +92,11 @@
use OCP\Group\Events\GroupDeletedEvent;
use OCP\Group\Events\UserAddedEvent;
use OCP\Group\Events\UserRemovedEvent;
use OCP\Group\ISubAdmin;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\INavigationManager;
use OCP\IURLGenerator;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\Mail\IMailer;
use OCP\Navigation\Events\LoadAdditionalEntriesEvent;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
use OCP\Server;
Expand Down Expand Up @@ -134,6 +132,7 @@ public function register(IRegistrationContext $context): void {
$context->registerEventListener(GroupDeletedEvent::class, GroupRemovedListener::class);
$context->registerEventListener(PasswordUpdatedEvent::class, Hooks::class);
$context->registerEventListener(UserChangedEvent::class, Hooks::class);
$context->registerEventListener(LoadAdditionalEntriesEvent::class, LoadAdditionalEntriesListener::class);

// Register Mail Provider listeners
$context->registerEventListener(DeclarativeSettingsGetValueEvent::class, MailProviderListener::class);
Expand Down Expand Up @@ -231,93 +230,5 @@ public function register(IRegistrationContext $context): void {

#[\Override]
public function boot(IBootContext $context): void {
$context->injectFn($this->registerNavigationEntries(...));
}

/**
* Registers the navigation entries for the user settings.
* Needed as some entries are dynamic and thus we cannot use the appinfo/info.xml
*
* Registers the following entries:
* - Appearance and accessibility
* - Personal settings (named "Settings" for non-admins)
* - Accounts (only for subadmins)
* - Help & privacy (conditionally enabled based on config)
*/
public function registerNavigationEntries(
INavigationManager $navigationManager,
IURLGenerator $urlGenerator,
IUserSession $userSession,
IConfig $config,
): void {
if ($userSession->getUser() === null) {
return;
}

$l = Server::get(IFactory::class)
->get('settings');
$groupManager = Server::get(IGroupManager::class);
$subAdmin = Server::get(ISubAdmin::class);
$isAdmin = $groupManager->isAdmin($userSession->getUser()->getUID());
$isSubAdmin = $subAdmin->isSubAdmin($userSession->getUser());

// Accessibility settings - the URL is dynamic (route parameters) which is currently not supported by appinfo.xml
$navigationManager->add([
'type' => 'settings',
'id' => 'accessibility_settings',
'order' => 2,
'href' => $urlGenerator->linkToRoute('settings.PersonalSettings.index', ['section' => 'theming']),
'name' => $l->t('Appearance and accessibility'),
'icon' => $urlGenerator->imagePath('theming', 'accessibility-dark.svg'),
]);

// Personal settings - this entry is dynamic so we cannot use appinfo
$navigationManager->add([
'type' => 'settings',
'id' => 'settings_personal',
'order' => 3,
'href' => $urlGenerator->linkToRoute('settings.PersonalSettings.index'),
'name' => $isAdmin
? $l->t('Personal settings')
: $l->t('Settings'),
'icon' => $isAdmin
? $urlGenerator->imagePath('settings', 'personal.svg')
: $urlGenerator->imagePath('settings', 'admin.svg'),
]);

if ($isAdmin) {
$navigationManager->add([
'type' => 'settings',
'id' => 'settings_administration',
'order' => 4,
'href' => $urlGenerator->linkToRoute('settings.adminSettings.index'),
'name' => $l->t('Administration settings'),
'icon' => $urlGenerator->imagePath('settings', 'admin.svg'),
]);
}

// User management is conditionally enabled for subadmins, but appinfo currently only supports full admins
if ($isSubAdmin) {
$navigationManager->add([
'type' => 'settings',
'id' => 'core_users',
'order' => 6,
'href' => $urlGenerator->linkToRoute('settings.Users.usersList'),
'name' => $l->t('Accounts'),
'icon' => $urlGenerator->imagePath('settings', 'users.svg'),
]);
}

// conditionally enabled navigation entry
if ($config->getSystemValueBool('knowledgebaseenabled', true)) {
$navigationManager->add([
'type' => 'settings',
'id' => 'help',
'order' => 99998,
'href' => $urlGenerator->linkToRoute('settings.Help.help'),
'name' => $l->t('Help & privacy'),
'icon' => $urlGenerator->imagePath('settings', 'help.svg'),
]);
}
}
}
Loading
Loading