Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>tags/v28.0.0beta1
return $this->defaultEnabled; | return $this->defaultEnabled; | ||||
} | } | ||||
public function getDefaultAppForUser(?IUser $user = null): string { | |||||
public function getDefaultAppForUser(?IUser $user = null, bool $withFallbacks = true): string { | |||||
// Set fallback to always-enabled files app | // Set fallback to always-enabled files app | ||||
$appId = 'files'; | |||||
$appId = $withFallbacks ? 'files' : ''; | |||||
$defaultApps = explode(',', $this->config->getSystemValueString('defaultapp', '')); | $defaultApps = explode(',', $this->config->getSystemValueString('defaultapp', '')); | ||||
$defaultApps = array_filter($defaultApps); | $defaultApps = array_filter($defaultApps); | ||||
if ($user !== null) { | if ($user !== null) { | ||||
$userDefaultApps = explode(',', $this->config->getUserValue($user->getUID(), 'core', 'defaultapp')); | $userDefaultApps = explode(',', $this->config->getUserValue($user->getUID(), 'core', 'defaultapp')); | ||||
$defaultApps = array_filter(array_merge($userDefaultApps, $defaultApps)); | $defaultApps = array_filter(array_merge($userDefaultApps, $defaultApps)); | ||||
if (empty($defaultApps)) { | |||||
if (empty($defaultApps) && $withFallbacks) { | |||||
/* Fallback on user defined apporder */ | /* Fallback on user defined apporder */ | ||||
$customOrders = json_decode($this->config->getUserValue($user->getUID(), 'core', 'apporder', '[]'), true, flags:JSON_THROW_ON_ERROR); | $customOrders = json_decode($this->config->getUserValue($user->getUID(), 'core', 'apporder', '[]'), true, flags:JSON_THROW_ON_ERROR); | ||||
if (!empty($customOrders)) { | if (!empty($customOrders)) { | ||||
} | } | ||||
} | } | ||||
if (empty($defaultApps)) { | |||||
if (empty($defaultApps) && $withFallbacks) { | |||||
$defaultApps = ['dashboard','files']; | $defaultApps = ['dashboard','files']; | ||||
} | } | ||||
}); | }); | ||||
} | } | ||||
return $this->proceedNavigation($result); | |||||
return $this->proceedNavigation($result, $type); | |||||
} | } | ||||
/** | /** | ||||
* Sort navigation entries by order, name and set active flag | |||||
* Sort navigation entries default app is always sorted first, then by order, name and set active flag | |||||
* | * | ||||
* @param array $list | * @param array $list | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
private function proceedNavigation(array $list): array { | |||||
private function proceedNavigation(array $list, string $type): array { | |||||
uasort($list, function ($a, $b) { | uasort($list, function ($a, $b) { | ||||
if (isset($a['order']) && isset($b['order'])) { | |||||
if (($a['default'] ?? false) xor ($b['default'] ?? false)) { | |||||
// Always sort the default app first | |||||
return ($a['default'] ?? false) ? -1 : 1; | |||||
} elseif (isset($a['order']) && isset($b['order'])) { | |||||
// Sort by order | |||||
return ($a['order'] < $b['order']) ? -1 : 1; | return ($a['order'] < $b['order']) ? -1 : 1; | ||||
} elseif (isset($a['order']) || isset($b['order'])) { | } elseif (isset($a['order']) || isset($b['order'])) { | ||||
// Sort the one that has an order property first | |||||
return isset($a['order']) ? -1 : 1; | return isset($a['order']) ? -1 : 1; | ||||
} else { | } else { | ||||
// Sort by name otherwise | |||||
return ($a['name'] < $b['name']) ? -1 : 1; | return ($a['name'] < $b['name']) ? -1 : 1; | ||||
} | } | ||||
}); | }); | ||||
if ($type === 'all' || $type === 'link') { | |||||
// There might be the case that no default app was set, in this case the first app is the default app. | |||||
// Otherwise the default app is already the ordered first, so setting the default prop will make no difference. | |||||
foreach ($list as $index => &$navEntry) { | |||||
if ($navEntry['type'] === 'link') { | |||||
$navEntry['default'] = true; | |||||
break; | |||||
} | |||||
} | |||||
unset($navEntry); | |||||
} | |||||
$activeApp = $this->getActiveEntry(); | $activeApp = $this->getActiveEntry(); | ||||
if ($activeApp !== null) { | if ($activeApp !== null) { | ||||
foreach ($list as $index => &$navEntry) { | foreach ($list as $index => &$navEntry) { | ||||
$customOrders = []; | $customOrders = []; | ||||
} | } | ||||
// The default app of the current user without fallbacks | |||||
$defaultApp = $this->appManager->getDefaultAppForUser($this->userSession->getUser(), false); | |||||
foreach ($apps as $app) { | foreach ($apps as $app) { | ||||
if (!$this->userSession->isLoggedIn() && !$this->appManager->isEnabledForUser($app, $this->userSession->getUser())) { | if (!$this->userSession->isLoggedIn() && !$this->appManager->isEnabledForUser($app, $this->userSession->getUser())) { | ||||
$icon = $this->urlGenerator->imagePath('core', 'default-app-icon'); | $icon = $this->urlGenerator->imagePath('core', 'default-app-icon'); | ||||
} | } | ||||
$this->add([ | |||||
$this->add(array_merge([ | |||||
// Navigation id | |||||
'id' => $id, | 'id' => $id, | ||||
// Order where this entry should be shown | |||||
'order' => $order, | 'order' => $order, | ||||
// Target of the navigation entry | |||||
'href' => $route, | 'href' => $route, | ||||
// The icon used for the naviation entry | |||||
'icon' => $icon, | 'icon' => $icon, | ||||
// Type of the navigation entry ('link' vs 'settings') | |||||
'type' => $type, | 'type' => $type, | ||||
// Localized name of the navigation entry | |||||
'name' => $l->t($nav['name']), | 'name' => $l->t($nav['name']), | ||||
]); | |||||
], $type === 'link' ? [ | |||||
// This is the default app that will always be shown first | |||||
'default' => $defaultApp === $id, | |||||
// App that registered this navigation entry (not necessarly the same as the id) | |||||
'app' => $app, | |||||
// The key used to identify this entry in the navigations entries | |||||
'key' => $key, | |||||
] : [] | |||||
)); | |||||
} | } | ||||
} | } | ||||
} | } |
* | * | ||||
* If `user` is not passed, the currently logged in user will be used | * If `user` is not passed, the currently logged in user will be used | ||||
* | * | ||||
* @param ?IUser $user User to query default app for | |||||
* @param bool $withFallbacks Include fallback values if no default app was configured manually | |||||
* | |||||
* @since 25.0.6 | * @since 25.0.6 | ||||
* @since 28.0.0 Added optional $withFallbacks parameter | |||||
*/ | */ | ||||
public function getDefaultAppForUser(?IUser $user = null): string; | |||||
public function getDefaultAppForUser(?IUser $user = null, bool $withFallbacks = true): string; | |||||
/** | /** | ||||
* Get the global default apps with fallbacks | * Get the global default apps with fallbacks |
//'icon' => 'optional', | //'icon' => 'optional', | ||||
'href' => 'url', | 'href' => 'url', | ||||
'active' => true, | 'active' => true, | ||||
'unread' => 0 | |||||
'unread' => 0, | |||||
], | ], | ||||
'entry id2' => [ | 'entry id2' => [ | ||||
'id' => 'entry id', | 'id' => 'entry id', | ||||
'active' => false, | 'active' => false, | ||||
'type' => 'link', | 'type' => 'link', | ||||
'classes' => '', | 'classes' => '', | ||||
'unread' => 0 | |||||
'unread' => 0, | |||||
'default' => true, | |||||
] | ] | ||||
] | ] | ||||
]; | ]; | ||||
'active' => false, | 'active' => false, | ||||
'type' => 'link', | 'type' => 'link', | ||||
'classes' => '', | 'classes' => '', | ||||
'unread' => 0 | |||||
'unread' => 0, | |||||
'default' => true, | |||||
'app' => 'test', | |||||
'key' => 0, | |||||
]], | ]], | ||||
['logout' => $defaults['logout']] | ['logout' => $defaults['logout']] | ||||
), | ), | ||||
'active' => false, | 'active' => false, | ||||
'type' => 'settings', | 'type' => 'settings', | ||||
'classes' => '', | 'classes' => '', | ||||
'unread' => 0 | |||||
'unread' => 0, | |||||
]], | ]], | ||||
['logout' => $defaults['logout']] | ['logout' => $defaults['logout']] | ||||
), | ), | ||||
], | ], | ||||
]] | ]] | ||||
], | ], | ||||
'with-multiple' => [ | |||||
array_merge( | |||||
['accessibility_settings' => $defaults['accessibility_settings']], | |||||
['settings' => $defaults['settings']], | |||||
['test' => [ | |||||
'id' => 'test', | |||||
'order' => 100, | |||||
'href' => '/apps/test/', | |||||
'icon' => '/apps/test/img/app.svg', | |||||
'name' => 'Test', | |||||
'active' => false, | |||||
'type' => 'link', | |||||
'classes' => '', | |||||
'unread' => 0, | |||||
'default' => false, | |||||
'app' => 'test', | |||||
'key' => 0, | |||||
], | |||||
'test1' => [ | |||||
'id' => 'test1', | |||||
'order' => 50, | |||||
'href' => '/apps/test/', | |||||
'icon' => '/apps/test/img/app.svg', | |||||
'name' => 'Other test', | |||||
'active' => false, | |||||
'type' => 'link', | |||||
'classes' => '', | |||||
'unread' => 0, | |||||
'default' => true, // because of order | |||||
'app' => 'test', | |||||
'key' => 1, | |||||
]], | |||||
['logout' => $defaults['logout']] | |||||
), | |||||
['navigations' => [ | |||||
'navigation' => [ | |||||
['route' => 'test.page.index', 'name' => 'Test'], | |||||
['route' => 'test.page.index', 'name' => 'Other test', 'order' => 50], | |||||
] | |||||
]] | |||||
], | |||||
'admin' => [ | 'admin' => [ | ||||
array_merge( | array_merge( | ||||
$adminSettings, | $adminSettings, | ||||
'active' => false, | 'active' => false, | ||||
'type' => 'link', | 'type' => 'link', | ||||
'classes' => '', | 'classes' => '', | ||||
'unread' => 0 | |||||
'unread' => 0, | |||||
'default' => true, | |||||
'app' => 'test', | |||||
'key' => 0, | |||||
]], | ]], | ||||
['logout' => $defaults['logout']] | ['logout' => $defaults['logout']] | ||||
), | ), | ||||
'active' => false, | 'active' => false, | ||||
'classes' => '', | 'classes' => '', | ||||
'unread' => 0, | 'unread' => 0, | ||||
'default' => true, | |||||
'app' => 'test', | |||||
'key' => 0, | |||||
], | ], | ||||
]; | ]; | ||||
$navigation = ['navigations' => [ | $navigation = ['navigations' => [ |