Skip to content

Commit 43878e0

Browse files
committed
Refine profile backend for frontend visibility requirements
- 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>
1 parent 5018aa1 commit 43878e0

2 files changed

Lines changed: 109 additions & 46 deletions

File tree

apps/settings/lib/Settings/Personal/PersonalInfo.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ public function getForm(): TemplateResponse {
187187
];
188188

189189
$profileParameters = [
190-
'profileConfig' => $this->profileManager->getProfileConfig($user, $user),
190+
'profileConfig' => $this->profileManager->getProfileConfig($user, $user, true),
191191
];
192192

193193
$this->initialStateService->provideInitialState('personalInfoParameters', $personalInfoParameters);

lib/private/Profile/ProfileManager.php

Lines changed: 108 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
namespace OC\Profile;
2828

29+
use function Safe\array_flip;
2930
use function Safe\usort;
3031
use OC\AppFramework\Bootstrap\Coordinator;
3132
use OC\Core\Db\ProfileConfig;
@@ -77,6 +78,8 @@ class ProfileManager {
7778
/** @var null|ILinkAction[] */
7879
private $sortedActions = null;
7980

81+
private const CORE_APP_ID = 'core';
82+
8083
/**
8184
* Array of account property actions
8285
*/
@@ -123,26 +126,17 @@ public function __construct(
123126
/**
124127
* Register an action for the user
125128
*/
126-
private function registerAction(IUser $targetUser, ?IUser $visitingUser, ILinkAction $action): void {
129+
private function registerAction(ILinkAction $action, IUser $targetUser, ?IUser $visitingUser): void {
127130
$action->preload($targetUser);
128131

129132
if ($action->getTarget() === null) {
130133
// Actions without a target are not registered
131134
return;
132135
}
133136

134-
if (isset($this->actions[$action->getId()])) {
135-
$this->logger->error('Cannot register duplicate action: ' . $action->getId());
136-
return;
137-
}
138-
139-
if ($action->getAppId() !== 'core') {
137+
if ($action->getAppId() !== self::CORE_APP_ID) {
140138
if (!$this->appManager->isEnabledForUser($action->getAppId(), $targetUser)) {
141-
$this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the user: ' . $targetUser->getUID());
142-
return;
143-
}
144-
if ($visitingUser === null) {
145-
$this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not available to non logged in users');
139+
$this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the target user: ' . $targetUser->getUID());
146140
return;
147141
}
148142
if (!$this->appManager->isEnabledForUser($action->getAppId(), $visitingUser)) {
@@ -156,6 +150,11 @@ private function registerAction(IUser $targetUser, ?IUser $visitingUser, ILinkAc
156150
return;
157151
}
158152

153+
if (isset($this->actions[$action->getId()])) {
154+
$this->logger->error('Cannot register duplicate action: ' . $action->getId());
155+
return;
156+
}
157+
159158
// Add action to associative array of actions
160159
$this->actions[$action->getId()] = $action;
161160
}
@@ -174,7 +173,7 @@ private function getActions(IUser $targetUser, ?IUser $visitingUser): array {
174173
foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
175174
/** @var ILinkAction $action */
176175
$action = $this->container->get($actionClass);
177-
$this->registerAction($targetUser, $visitingUser, $action);
176+
$this->registerAction($action, $targetUser, $visitingUser);
178177
}
179178

180179
$context = $this->coordinator->getRegistrationContext();
@@ -183,7 +182,7 @@ private function getActions(IUser $targetUser, ?IUser $visitingUser): array {
183182
foreach ($context->getProfileLinkActions() as $registration) {
184183
/** @var ILinkAction $action */
185184
$action = $this->container->get($registration->getService());
186-
$this->registerAction($targetUser, $visitingUser, $action);
185+
$this->registerAction($action, $targetUser, $visitingUser);
187186
}
188187
}
189188

@@ -201,7 +200,7 @@ private function getActions(IUser $targetUser, ?IUser $visitingUser): array {
201200
* Return whether the profile parameter of the target user
202201
* is visible to the visiting user
203202
*/
204-
private function isParameterVisible(IUser $targetUser, ?IUser $visitingUser, string $paramId): bool {
203+
private function isParameterVisible(string $paramId, IUser $targetUser, ?IUser $visitingUser): bool {
205204
try {
206205
$account = $this->accountManager->getAccount($targetUser);
207206
$scope = $account->getProperty($paramId)->getScope();
@@ -253,6 +252,7 @@ private function isParameterVisible(IUser $targetUser, ?IUser $visitingUser, str
253252
*/
254253
public function getProfileParams(IUser $targetUser, ?IUser $visitingUser): array {
255254
$account = $this->accountManager->getAccount($targetUser);
255+
256256
// Initialize associative array of profile parameters
257257
$profileParameters = [
258258
'userId' => $account->getUser()->getUID(),
@@ -268,14 +268,14 @@ public function getProfileParams(IUser $targetUser, ?IUser $visitingUser): array
268268
case IAccountManager::PROPERTY_ORGANISATION:
269269
case IAccountManager::PROPERTY_ROLE:
270270
$profileParameters[$property] =
271-
$this->isParameterVisible($targetUser, $visitingUser, $property)
271+
$this->isParameterVisible($property, $targetUser, $visitingUser)
272272
// Explicitly set to null when value is empty string
273273
? ($account->getProperty($property)->getValue() ?: null)
274274
: null;
275275
break;
276276
case IAccountManager::PROPERTY_AVATAR:
277277
// Add avatar visibility
278-
$profileParameters['isUserAvatarVisible'] = $this->isParameterVisible($targetUser, $visitingUser, $property);
278+
$profileParameters['isUserAvatarVisible'] = $this->isParameterVisible($property, $targetUser, $visitingUser);
279279
break;
280280
}
281281
}
@@ -295,7 +295,7 @@ function (ILinkAction $action) {
295295
array_filter(
296296
$this->getActions($targetUser, $visitingUser),
297297
function (ILinkAction $action) use ($targetUser, $visitingUser) {
298-
return $this->isParameterVisible($targetUser, $visitingUser, $action->getId());
298+
return $this->isParameterVisible($action->getId(), $targetUser, $visitingUser);
299299
}
300300
),
301301
)
@@ -304,55 +304,56 @@ function (ILinkAction $action) use ($targetUser, $visitingUser) {
304304
return $profileParameters;
305305
}
306306

307+
/**
308+
* Return the filtered profile config containing only
309+
* the properties to be stored on the database
310+
*/
311+
private function filterProfileConfig(array $profileConfig): array {
312+
$dbParamConfigProperties = [
313+
'visibility',
314+
];
315+
316+
foreach ($profileConfig as $paramId => $paramConfig) {
317+
$profileConfig[$paramId] = array_intersect_key($paramConfig, array_flip($dbParamConfigProperties));
318+
}
319+
320+
return $profileConfig;
321+
}
322+
307323
/**
308324
* Return the default profile config
309325
*/
310326
private function getDefaultProfileConfig(IUser $targetUser, ?IUser $visitingUser): array {
311327
// Contruct the default config for actions
312328
$actionsConfig = [];
313329
foreach ($this->getActions($targetUser, $visitingUser) as $action) {
314-
$actionsConfig[$action->getId()] = [
315-
'displayId' => $action->getDisplayId(),
316-
'visibility' => ProfileConfig::DEFAULT_VISIBILITY,
317-
];
330+
$actionsConfig[$action->getId()] = ['visibility' => ProfileConfig::DEFAULT_VISIBILITY];
318331
}
319332

320-
// Map of account properties to display IDs
321-
$propertyDisplayMap = [
322-
IAccountManager::PROPERTY_ADDRESS => $this->l10nFactory->get('core')->t('Address'),
323-
IAccountManager::PROPERTY_AVATAR => $this->l10nFactory->get('core')->t('Avatar'),
324-
IAccountManager::PROPERTY_BIOGRAPHY => $this->l10nFactory->get('core')->t('About'),
325-
IAccountManager::PROPERTY_DISPLAYNAME => $this->l10nFactory->get('core')->t('Full name'),
326-
IAccountManager::PROPERTY_HEADLINE => $this->l10nFactory->get('core')->t('Headline'),
327-
IAccountManager::PROPERTY_ORGANISATION => $this->l10nFactory->get('core')->t('Organisation'),
328-
IAccountManager::PROPERTY_ROLE => $this->l10nFactory->get('core')->t('Role'),
329-
IAccountManager::PROPERTY_EMAIL => $this->l10nFactory->get('core')->t('Email'),
330-
IAccountManager::PROPERTY_PHONE => $this->l10nFactory->get('core')->t('Phone'),
331-
IAccountManager::PROPERTY_TWITTER => $this->l10nFactory->get('core')->t('Twitter'),
332-
IAccountManager::PROPERTY_WEBSITE => $this->l10nFactory->get('core')->t('Website'),
333-
];
334-
335333
// Contruct the default config for account properties
336334
$propertiesConfig = [];
337-
foreach ($propertyDisplayMap as $property => $displayId) {
338-
$propertiesConfig[$property] = [
339-
'displayId' => $displayId,
340-
'visibility' => ProfileConfig::DEFAULT_PROPERTY_VISIBILITY[$property],
341-
];
335+
foreach (ProfileConfig::DEFAULT_PROPERTY_VISIBILITY as $property => $visibility) {
336+
$propertiesConfig[$property] = ['visibility' => $visibility];
342337
}
343338

344339
return array_merge($actionsConfig, $propertiesConfig);
345340
}
346341

347342
/**
348-
* Return the profile config
343+
* Return the profile config of the target user,
344+
* if a config does not already exist a default config is created and returned
345+
*
346+
* Passing true to `$includeMetadata` will return additional metadata
349347
*/
350-
public function getProfileConfig(IUser $targetUser, ?IUser $visitingUser): array {
348+
public function getProfileConfig(IUser $targetUser, ?IUser $visitingUser, bool $includeMetadata = false): array {
351349
$defaultProfileConfig = $this->getDefaultProfileConfig($targetUser, $visitingUser);
352350
try {
353351
$config = $this->configMapper->get($targetUser->getUID());
354352
// Merge defaults with the existing config in case the defaults are missing
355-
$config->setConfigArray(array_merge($defaultProfileConfig, $config->getConfigArray()));
353+
$config->setConfigArray(array_merge(
354+
$defaultProfileConfig,
355+
$this->filterProfileConfig($config->getConfigArray()),
356+
));
356357
$this->configMapper->update($config);
357358
$configArray = $config->getConfigArray();
358359
} catch (DoesNotExistException $e) {
@@ -364,6 +365,68 @@ public function getProfileConfig(IUser $targetUser, ?IUser $visitingUser): array
364365
$configArray = $config->getConfigArray();
365366
}
366367

368+
if ($includeMetadata) {
369+
$actionsMetadata = [];
370+
foreach ($this->getActions($targetUser, $visitingUser) as $action) {
371+
$actionsMetadata[$action->getId()] = [
372+
'appId' => $action->getAppId(),
373+
'displayId' => $action->getDisplayId(),
374+
];
375+
}
376+
377+
// Add metadata for account property actions which are always configurable
378+
foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
379+
/** @var ILinkAction $action */
380+
$action = $this->container->get($actionClass);
381+
$actionsMetadata[$action->getId()] = [
382+
'appId' => $action->getAppId(),
383+
'displayId' => $action->getDisplayId(),
384+
];
385+
}
386+
387+
$propertiesMetadata = [
388+
IAccountManager::PROPERTY_ADDRESS => [
389+
'appId' => self::CORE_APP_ID,
390+
'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Address'),
391+
],
392+
IAccountManager::PROPERTY_AVATAR => [
393+
'appId' => self::CORE_APP_ID,
394+
'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Profile picture'),
395+
],
396+
IAccountManager::PROPERTY_BIOGRAPHY => [
397+
'appId' => self::CORE_APP_ID,
398+
'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('About'),
399+
],
400+
IAccountManager::PROPERTY_DISPLAYNAME => [
401+
'appId' => self::CORE_APP_ID,
402+
'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Full name'),
403+
],
404+
IAccountManager::PROPERTY_HEADLINE => [
405+
'appId' => self::CORE_APP_ID,
406+
'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Headline'),
407+
],
408+
IAccountManager::PROPERTY_ORGANISATION => [
409+
'appId' => self::CORE_APP_ID,
410+
'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Organisation'),
411+
],
412+
IAccountManager::PROPERTY_ROLE => [
413+
'appId' => self::CORE_APP_ID,
414+
'displayId' => $this->l10nFactory->get(self::CORE_APP_ID)->t('Role'),
415+
],
416+
];
417+
418+
$paramMetadata = array_merge($actionsMetadata, $propertiesMetadata);
419+
420+
foreach ($configArray as $paramId => $paramConfig) {
421+
if (isset($paramMetadata[$paramId])) {
422+
$configArray[$paramId] = array_merge(
423+
$paramConfig,
424+
$paramMetadata[$paramId],
425+
);
426+
}
427+
}
428+
}
429+
367430
return $configArray;
368431
}
369432
}

0 commit comments

Comments
 (0)