mirror of
https://github.com/nextcloud/server.git
synced 2026-06-11 09:42:09 -04:00
refactor(AppManager): Deprecated default apps handling
Signed-off-by: provokateurin <kate@provokateurin.de>
This commit is contained in:
parent
b0baaaed9d
commit
70ed08daf1
3 changed files with 45 additions and 202 deletions
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
namespace OC\App;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use OC\AppConfig;
|
||||
use OC\AppFramework\Bootstrap\Coordinator;
|
||||
use OC\ServerNotAvailableException;
|
||||
|
|
@ -24,6 +23,7 @@ use OCP\ICacheFactory;
|
|||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\INavigationManager;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
|
|
@ -67,6 +67,7 @@ class AppManager implements IAppManager {
|
|||
|
||||
private ?AppConfig $appConfig = null;
|
||||
private ?IURLGenerator $urlGenerator = null;
|
||||
private ?INavigationManager $navigationManager = null;
|
||||
|
||||
/**
|
||||
* Be extremely careful when injecting classes here. The AppManager is used by the installer,
|
||||
|
|
@ -82,6 +83,13 @@ class AppManager implements IAppManager {
|
|||
) {
|
||||
}
|
||||
|
||||
private function getNavigationManager(): INavigationManager {
|
||||
if ($this->navigationManager === null) {
|
||||
$this->navigationManager = \OCP\Server::get(INavigationManager::class);
|
||||
}
|
||||
return $this->navigationManager;
|
||||
}
|
||||
|
||||
public function getAppIcon(string $appId, bool $dark = false): ?string {
|
||||
$possibleIcons = $dark ? [$appId . '-dark.svg', 'app-dark.svg'] : [$appId . '.svg', 'app.svg'];
|
||||
$icon = null;
|
||||
|
|
@ -820,60 +828,42 @@ class AppManager implements IAppManager {
|
|||
return $this->defaultEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDefaultAppForUser(?IUser $user = null, bool $withFallbacks = true): string {
|
||||
// Set fallback to always-enabled files app
|
||||
$appId = $withFallbacks ? 'files' : '';
|
||||
$defaultApps = explode(',', $this->config->getSystemValueString('defaultapp', ''));
|
||||
$defaultApps = array_filter($defaultApps);
|
||||
$id = $this->getNavigationManager()->getDefaultEntryIdForUser($user, $withFallbacks);
|
||||
$entry = $this->getNavigationManager()->get($id);
|
||||
return (string)$entry['app'];
|
||||
}
|
||||
|
||||
$user ??= $this->userSession->getUser();
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDefaultApps(): array {
|
||||
$ids = $this->getNavigationManager()->getDefaultEntryIds();
|
||||
|
||||
if ($user !== null) {
|
||||
$userDefaultApps = explode(',', $this->config->getUserValue($user->getUID(), 'core', 'defaultapp'));
|
||||
$defaultApps = array_filter(array_merge($userDefaultApps, $defaultApps));
|
||||
if (empty($defaultApps) && $withFallbacks) {
|
||||
/* Fallback on user defined apporder */
|
||||
$customOrders = json_decode($this->config->getUserValue($user->getUID(), 'core', 'apporder', '[]'), true, flags:JSON_THROW_ON_ERROR);
|
||||
if (!empty($customOrders)) {
|
||||
// filter only entries with app key (when added using closures or NavigationManager::add the app is not guranteed to be set)
|
||||
$customOrders = array_filter($customOrders, fn ($entry) => isset($entry['app']));
|
||||
// sort apps by order
|
||||
usort($customOrders, fn ($a, $b) => $a['order'] - $b['order']);
|
||||
// set default apps to sorted apps
|
||||
$defaultApps = array_map(fn ($entry) => $entry['app'], $customOrders);
|
||||
return array_values(array_unique(array_map(function (string $id) {
|
||||
$entry = $this->getNavigationManager()->get($id);
|
||||
return (string)$entry['app'];
|
||||
}, $ids)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setDefaultApps(array $defaultApps): void {
|
||||
$entries = $this->getNavigationManager()->getAll();
|
||||
$ids = [];
|
||||
foreach ($defaultApps as $defaultApp) {
|
||||
foreach ($entries as $entry) {
|
||||
if ((string)$entry['app'] === $defaultApp) {
|
||||
$ids[] = (string)$entry['id'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($defaultApps) && $withFallbacks) {
|
||||
$defaultApps = ['dashboard','files'];
|
||||
}
|
||||
|
||||
// Find the first app that is enabled for the current user
|
||||
foreach ($defaultApps as $defaultApp) {
|
||||
$defaultApp = \OC_App::cleanAppId(strip_tags($defaultApp));
|
||||
if ($this->isEnabledForUser($defaultApp, $user)) {
|
||||
$appId = $defaultApp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $appId;
|
||||
}
|
||||
|
||||
public function getDefaultApps(): array {
|
||||
return explode(',', $this->config->getSystemValueString('defaultapp', 'dashboard,files'));
|
||||
}
|
||||
|
||||
public function setDefaultApps(array $defaultApps): void {
|
||||
foreach ($defaultApps as $app) {
|
||||
if (!$this->isInstalled($app)) {
|
||||
$this->logger->debug('Can not set not installed app as default app', ['missing_app' => $app]);
|
||||
throw new InvalidArgumentException('App is not installed');
|
||||
}
|
||||
}
|
||||
|
||||
$this->config->setSystemValue('defaultapp', join(',', $defaultApps));
|
||||
$this->getNavigationManager()->setDefaultEntryIds($ids);
|
||||
}
|
||||
|
||||
public function isBackendRequired(string $backend): bool {
|
||||
|
|
|
|||
|
|
@ -247,6 +247,8 @@ interface IAppManager {
|
|||
*
|
||||
* @since 25.0.6
|
||||
* @since 28.0.0 Added optional $withFallbacks parameter
|
||||
* @deprecated 31.0.0
|
||||
* Use @see \OCP\INavigationManager::getDefaultEntryIdForUser() instead
|
||||
*/
|
||||
public function getDefaultAppForUser(?IUser $user = null, bool $withFallbacks = true): string;
|
||||
|
||||
|
|
@ -255,6 +257,8 @@ interface IAppManager {
|
|||
*
|
||||
* @return string[] The default applications
|
||||
* @since 28.0.0
|
||||
* @deprecated 31.0.0
|
||||
* Use @see \OCP\INavigationManager::getDefaultEntryIds() instead
|
||||
*/
|
||||
public function getDefaultApps(): array;
|
||||
|
||||
|
|
@ -264,6 +268,8 @@ interface IAppManager {
|
|||
* @param string[] $appId
|
||||
* @throws \InvalidArgumentException If any of the apps is not installed
|
||||
* @since 28.0.0
|
||||
* @deprecated 31.0.0
|
||||
* Use @see \OCP\INavigationManager::setDefaultEntryIds() instead
|
||||
*/
|
||||
public function setDefaultApps(array $defaultApps): void;
|
||||
|
||||
|
|
|
|||
|
|
@ -733,159 +733,6 @@ class AppManagerTest extends TestCase {
|
|||
$this->assertEquals(['foo'], $this->manager->getAppRestriction('test3'));
|
||||
}
|
||||
|
||||
public function provideDefaultApps(): array {
|
||||
return [
|
||||
// none specified, default to files
|
||||
[
|
||||
'',
|
||||
'',
|
||||
'{}',
|
||||
true,
|
||||
'files',
|
||||
],
|
||||
// none specified, without fallback
|
||||
[
|
||||
'',
|
||||
'',
|
||||
'{}',
|
||||
false,
|
||||
'',
|
||||
],
|
||||
// unexisting or inaccessible app specified, default to files
|
||||
[
|
||||
'unexist',
|
||||
'',
|
||||
'{}',
|
||||
true,
|
||||
'files',
|
||||
],
|
||||
// unexisting or inaccessible app specified, without fallbacks
|
||||
[
|
||||
'unexist',
|
||||
'',
|
||||
'{}',
|
||||
false,
|
||||
'',
|
||||
],
|
||||
// non-standard app
|
||||
[
|
||||
'settings',
|
||||
'',
|
||||
'{}',
|
||||
true,
|
||||
'settings',
|
||||
],
|
||||
// non-standard app, without fallback
|
||||
[
|
||||
'settings',
|
||||
'',
|
||||
'{}',
|
||||
false,
|
||||
'settings',
|
||||
],
|
||||
// non-standard app with fallback
|
||||
[
|
||||
'unexist,settings',
|
||||
'',
|
||||
'{}',
|
||||
true,
|
||||
'settings',
|
||||
],
|
||||
// system default app and user apporder
|
||||
[
|
||||
// system default is settings
|
||||
'unexist,settings',
|
||||
'',
|
||||
// apporder says default app is files (order is lower)
|
||||
'{"files_id":{"app":"files","order":1},"settings_id":{"app":"settings","order":2}}',
|
||||
true,
|
||||
// system default should override apporder
|
||||
'settings'
|
||||
],
|
||||
// user-customized defaultapp
|
||||
[
|
||||
'',
|
||||
'files',
|
||||
'',
|
||||
true,
|
||||
'files',
|
||||
],
|
||||
// user-customized defaultapp with systemwide
|
||||
[
|
||||
'unexist,settings',
|
||||
'files',
|
||||
'',
|
||||
true,
|
||||
'files',
|
||||
],
|
||||
// user-customized defaultapp with system wide and apporder
|
||||
[
|
||||
'unexist,settings',
|
||||
'files',
|
||||
'{"settings_id":{"app":"settings","order":1},"files_id":{"app":"files","order":2}}',
|
||||
true,
|
||||
'files',
|
||||
],
|
||||
// user-customized apporder fallback
|
||||
[
|
||||
'',
|
||||
'',
|
||||
'{"settings_id":{"app":"settings","order":1},"files":{"app":"files","order":2}}',
|
||||
true,
|
||||
'settings',
|
||||
],
|
||||
// user-customized apporder fallback with missing app key (entries added by closures does not always have an app key set (Nextcloud 27 spreed app for example))
|
||||
[
|
||||
'',
|
||||
'',
|
||||
'{"spreed":{"order":1},"files":{"app":"files","order":2}}',
|
||||
true,
|
||||
'files',
|
||||
],
|
||||
// user-customized apporder, but called without fallback
|
||||
[
|
||||
'',
|
||||
'',
|
||||
'{"settings":{"app":"settings","order":1},"files":{"app":"files","order":2}}',
|
||||
false,
|
||||
'',
|
||||
],
|
||||
// user-customized apporder with an app that has multiple routes
|
||||
[
|
||||
'',
|
||||
'',
|
||||
'{"settings_id":{"app":"settings","order":1},"settings_id_2":{"app":"settings","order":3},"id_files":{"app":"files","order":2}}',
|
||||
true,
|
||||
'settings',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDefaultApps
|
||||
*/
|
||||
public function testGetDefaultAppForUser($defaultApps, $userDefaultApps, $userApporder, $withFallbacks, $expectedApp) {
|
||||
$user = $this->newUser('user1');
|
||||
|
||||
$this->userSession->expects($this->once())
|
||||
->method('getUser')
|
||||
->willReturn($user);
|
||||
|
||||
$this->config->expects($this->once())
|
||||
->method('getSystemValueString')
|
||||
->with('defaultapp', $this->anything())
|
||||
->willReturn($defaultApps);
|
||||
|
||||
$this->config->expects($this->atLeastOnce())
|
||||
->method('getUserValue')
|
||||
->willReturnMap([
|
||||
['user1', 'core', 'defaultapp', '', $userDefaultApps],
|
||||
['user1', 'core', 'apporder', '[]', $userApporder],
|
||||
]);
|
||||
|
||||
$this->assertEquals($expectedApp, $this->manager->getDefaultAppForUser(null, $withFallbacks));
|
||||
}
|
||||
|
||||
public static function isBackendRequiredDataProvider(): array {
|
||||
return [
|
||||
// backend available
|
||||
|
|
|
|||
Loading…
Reference in a new issue