]> source.dussan.org Git - nextcloud-server.git/commitdiff
Refine profile backend for frontend visibility requirements
authorChristopher Ng <chrng8@gmail.com>
Thu, 28 Oct 2021 17:59:26 +0000 (17:59 +0000)
committerChristopher Ng <chrng8@gmail.com>
Thu, 4 Nov 2021 00:17:29 +0000 (00:17 +0000)
- Provide metadata
  - Dynamic displayId
  - Add appId
- Filter out unused parameter config properties from the existing profile config

Signed-off-by: Christopher Ng <chrng8@gmail.com>
apps/settings/lib/Settings/Personal/PersonalInfo.php
lib/private/Profile/ProfileManager.php

index 72c443ed1b6951a56f10b4b1f82556cc0c40c305..def7e19f0064f64f32f7febbe7ac35b9e896b281 100644 (file)
@@ -187,7 +187,7 @@ class PersonalInfo implements ISettings {
                ];
 
                $profileParameters = [
-                       'profileConfig' => $this->profileManager->getProfileConfig($user, $user),
+                       'profileConfig' => $this->profileManager->getProfileConfigWithMetadata($user, $user),
                ];
 
                $this->initialStateService->provideInitialState('personalInfoParameters', $personalInfoParameters);
index 4809a1112880a29aa5849e330f1ba1897b0db27a..f83de7fd358f28253c6990be4af6e46b257720b3 100644 (file)
@@ -26,6 +26,7 @@ declare(strict_types=1);
 
 namespace OC\Profile;
 
+use function Safe\array_flip;
 use function Safe\usort;
 use OC\AppFramework\Bootstrap\Coordinator;
 use OC\Core\Db\ProfileConfig;
@@ -77,6 +78,8 @@ class ProfileManager {
        /** @var null|ILinkAction[] */
        private $sortedActions = null;
 
+       private const CORE_APP_ID = 'core';
+
        /**
         * Array of account property actions
         */
@@ -123,7 +126,7 @@ class ProfileManager {
        /**
         * Register an action for the user
         */
-       private function registerAction(IUser $targetUser, ?IUser $visitingUser, ILinkAction $action): void {
+       private function registerAction(ILinkAction $action, IUser $targetUser, ?IUser $visitingUser): void {
                $action->preload($targetUser);
 
                if ($action->getTarget() === null) {
@@ -131,18 +134,9 @@ class ProfileManager {
                        return;
                }
 
-               if (isset($this->actions[$action->getId()])) {
-                       $this->logger->error('Cannot register duplicate action: ' . $action->getId());
-                       return;
-               }
-
-               if ($action->getAppId() !== 'core') {
+               if ($action->getAppId() !== self::CORE_APP_ID) {
                        if (!$this->appManager->isEnabledForUser($action->getAppId(), $targetUser)) {
-                               $this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the user: ' . $targetUser->getUID());
-                               return;
-                       }
-                       if ($visitingUser === null) {
-                               $this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not available to non logged in users');
+                               $this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the target user: ' . $targetUser->getUID());
                                return;
                        }
                        if (!$this->appManager->isEnabledForUser($action->getAppId(), $visitingUser)) {
@@ -156,6 +150,11 @@ class ProfileManager {
                        return;
                }
 
+               if (isset($this->actions[$action->getId()])) {
+                       $this->logger->error('Cannot register duplicate action: ' . $action->getId());
+                       return;
+               }
+
                // Add action to associative array of actions
                $this->actions[$action->getId()] = $action;
        }
@@ -174,7 +173,7 @@ class ProfileManager {
                foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
                        /** @var ILinkAction $action */
                        $action = $this->container->get($actionClass);
-                       $this->registerAction($targetUser, $visitingUser, $action);
+                       $this->registerAction($action, $targetUser, $visitingUser);
                }
 
                $context = $this->coordinator->getRegistrationContext();
@@ -183,7 +182,7 @@ class ProfileManager {
                        foreach ($context->getProfileLinkActions() as $registration) {
                                /** @var ILinkAction $action */
                                $action = $this->container->get($registration->getService());
-                               $this->registerAction($targetUser, $visitingUser, $action);
+                               $this->registerAction($action, $targetUser, $visitingUser);
                        }
                }
 
@@ -201,7 +200,7 @@ class ProfileManager {
         * Return whether the profile parameter of the target user
         * is visible to the visiting user
         */
-       private function isParameterVisible(IUser $targetUser, ?IUser $visitingUser, string $paramId): bool {
+       private function isParameterVisible(string $paramId, IUser $targetUser, ?IUser $visitingUser): bool {
                try {
                        $account = $this->accountManager->getAccount($targetUser);
                        $scope = $account->getProperty($paramId)->getScope();
@@ -253,6 +252,7 @@ class ProfileManager {
         */
        public function getProfileParams(IUser $targetUser, ?IUser $visitingUser): array {
                $account = $this->accountManager->getAccount($targetUser);
+
                // Initialize associative array of profile parameters
                $profileParameters = [
                        'userId' => $account->getUser()->getUID(),
@@ -268,14 +268,14 @@ class ProfileManager {
                                case IAccountManager::PROPERTY_ORGANISATION:
                                case IAccountManager::PROPERTY_ROLE:
                                        $profileParameters[$property] =
-                                               $this->isParameterVisible($targetUser, $visitingUser, $property)
+                                               $this->isParameterVisible($property, $targetUser, $visitingUser)
                                                // Explicitly set to null when value is empty string
                                                ? ($account->getProperty($property)->getValue() ?: null)
                                                : null;
                                        break;
                                case IAccountManager::PROPERTY_AVATAR:
                                        // Add avatar visibility
-                                       $profileParameters['isUserAvatarVisible'] = $this->isParameterVisible($targetUser, $visitingUser, $property);
+                                       $profileParameters['isUserAvatarVisible'] = $this->isParameterVisible($property, $targetUser, $visitingUser);
                                        break;
                        }
                }
@@ -295,7 +295,7 @@ class ProfileManager {
                                array_filter(
                                        $this->getActions($targetUser, $visitingUser),
                                        function (ILinkAction $action) use ($targetUser, $visitingUser) {
-                                               return $this->isParameterVisible($targetUser, $visitingUser, $action->getId());
+                                               return $this->isParameterVisible($action->getId(), $targetUser, $visitingUser);
                                        }
                                ),
                        )
@@ -304,6 +304,22 @@ class ProfileManager {
                return $profileParameters;
        }
 
+       /**
+        * Return the filtered profile config containing only
+        * the properties to be stored on the database
+        */
+       private function filterNotStoredProfileConfig(array $profileConfig): array {
+               $dbParamConfigProperties = [
+                       'visibility',
+               ];
+
+               foreach ($profileConfig as $paramId => $paramConfig) {
+                       $profileConfig[$paramId] = array_intersect_key($paramConfig, array_flip($dbParamConfigProperties));
+               }
+
+               return $profileConfig;
+       }
+
        /**
         * Return the default profile config
         */
@@ -311,48 +327,31 @@ class ProfileManager {
                // Contruct the default config for actions
                $actionsConfig = [];
                foreach ($this->getActions($targetUser, $visitingUser) as $action) {
-                       $actionsConfig[$action->getId()] = [
-                               'displayId' => $action->getDisplayId(),
-                               'visibility' => ProfileConfig::DEFAULT_VISIBILITY,
-                       ];
+                       $actionsConfig[$action->getId()] = ['visibility' => ProfileConfig::DEFAULT_VISIBILITY];
                }
 
-               // Map of account properties to display IDs
-               $propertyDisplayMap = [
-                       IAccountManager::PROPERTY_ADDRESS => $this->l10nFactory->get('core')->t('Address'),
-                       IAccountManager::PROPERTY_AVATAR => $this->l10nFactory->get('core')->t('Avatar'),
-                       IAccountManager::PROPERTY_BIOGRAPHY => $this->l10nFactory->get('core')->t('About'),
-                       IAccountManager::PROPERTY_DISPLAYNAME => $this->l10nFactory->get('core')->t('Full name'),
-                       IAccountManager::PROPERTY_HEADLINE => $this->l10nFactory->get('core')->t('Headline'),
-                       IAccountManager::PROPERTY_ORGANISATION => $this->l10nFactory->get('core')->t('Organisation'),
-                       IAccountManager::PROPERTY_ROLE => $this->l10nFactory->get('core')->t('Role'),
-                       IAccountManager::PROPERTY_EMAIL => $this->l10nFactory->get('core')->t('Email'),
-                       IAccountManager::PROPERTY_PHONE => $this->l10nFactory->get('core')->t('Phone'),
-                       IAccountManager::PROPERTY_TWITTER => $this->l10nFactory->get('core')->t('Twitter'),
-                       IAccountManager::PROPERTY_WEBSITE => $this->l10nFactory->get('core')->t('Website'),
-               ];
-
                // Contruct the default config for account properties
                $propertiesConfig = [];
-               foreach ($propertyDisplayMap as $property => $displayId) {
-                       $propertiesConfig[$property] = [
-                               'displayId' => $displayId,
-                               'visibility' => ProfileConfig::DEFAULT_PROPERTY_VISIBILITY[$property],
-                       ];
+               foreach (ProfileConfig::DEFAULT_PROPERTY_VISIBILITY as $property => $visibility) {
+                       $propertiesConfig[$property] = ['visibility' => $visibility];
                }
 
                return array_merge($actionsConfig, $propertiesConfig);
        }
 
        /**
-        * Return the profile config
+        * Return the profile config of the target user,
+        * if a config does not already exist a default config is created and returned
         */
        public function getProfileConfig(IUser $targetUser, ?IUser $visitingUser): array {
                $defaultProfileConfig = $this->getDefaultProfileConfig($targetUser, $visitingUser);
                try {
                        $config = $this->configMapper->get($targetUser->getUID());
                        // Merge defaults with the existing config in case the defaults are missing
-                       $config->setConfigArray(array_merge($defaultProfileConfig, $config->getConfigArray()));
+                       $config->setConfigArray(array_merge(
+                               $defaultProfileConfig,
+                               $this->filterNotStoredProfileConfig($config->getConfigArray()),
+                       ));
                        $this->configMapper->update($config);
                        $configArray = $config->getConfigArray();
                } catch (DoesNotExistException $e) {
@@ -366,4 +365,76 @@ class ProfileManager {
 
                return $configArray;
        }
+
+       /**
+        * Return the profile config of the target user with additional medatata,
+        * if a config does not already exist a default config is created and returned
+        */
+       public function getProfileConfigWithMetadata(IUser $targetUser, ?IUser $visitingUser): array {
+               $configArray = $this->getProfileConfig($targetUser, $visitingUser);
+
+               $actionsMetadata = [];
+               foreach ($this->getActions($targetUser, $visitingUser) as $action) {
+                       $actionsMetadata[$action->getId()] = [
+                               'appId' => $action->getAppId(),
+                               'displayId' => $action->getDisplayId(),
+                       ];
+               }
+
+               // Add metadata for account property actions which are always configurable
+               foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
+                       /** @var ILinkAction $action */
+                       $action = $this->container->get($actionClass);
+                       if (!isset($actionsMetadata[$action->getId()])) {
+                               $actionsMetadata[$action->getId()] = [
+                                       'appId' => $action->getAppId(),
+                                       'displayId' => $action->getDisplayId(),
+                               ];
+                       }
+               }
+
+               $propertiesMetadata = [
+                       IAccountManager::PROPERTY_ADDRESS => [
+                               'appId' => self::CORE_APP_ID,
+                               'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Address'),
+                       ],
+                       IAccountManager::PROPERTY_AVATAR => [
+                               'appId' => self::CORE_APP_ID,
+                               'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Profile picture'),
+                       ],
+                       IAccountManager::PROPERTY_BIOGRAPHY => [
+                               'appId' => self::CORE_APP_ID,
+                               'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('About'),
+                       ],
+                       IAccountManager::PROPERTY_DISPLAYNAME => [
+                               'appId' => self::CORE_APP_ID,
+                               'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Full name'),
+                       ],
+                       IAccountManager::PROPERTY_HEADLINE => [
+                               'appId' => self::CORE_APP_ID,
+                               'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Headline'),
+                       ],
+                       IAccountManager::PROPERTY_ORGANISATION => [
+                               'appId' => self::CORE_APP_ID,
+                               'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Organisation'),
+                       ],
+                       IAccountManager::PROPERTY_ROLE => [
+                               'appId' => self::CORE_APP_ID,
+                               'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Role'),
+                       ],
+               ];
+
+               $paramMetadata = array_merge($actionsMetadata, $propertiesMetadata);
+
+               foreach ($configArray as $paramId => $paramConfig) {
+                       if (isset($paramMetadata[$paramId])) {
+                               $configArray[$paramId] = array_merge(
+                                       $paramConfig,
+                                       $paramMetadata[$paramId],
+                               );
+                       }
+               }
+
+               return $configArray;
+       }
 }