aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/provisioning_api/lib/Controller/AUserData.php1
-rw-r--r--apps/provisioning_api/lib/Controller/UsersController.php8
-rw-r--r--apps/provisioning_api/lib/ResponseDefinitions.php2
-rw-r--r--apps/provisioning_api/openapi-administration.json7
-rw-r--r--apps/provisioning_api/openapi-full.json7
-rw-r--r--apps/provisioning_api/openapi.json7
-rw-r--r--apps/provisioning_api/tests/Controller/UsersControllerTest.php18
-rw-r--r--apps/settings/lib/Controller/UsersController.php5
-rw-r--r--apps/settings/lib/Settings/Personal/PersonalInfo.php1
-rw-r--r--apps/settings/src/components/PersonalInfo/PronounsSection.vue45
-rw-r--r--apps/settings/src/constants/AccountPropertyConstants.js13
-rw-r--r--apps/settings/src/main-personal-info.js35
-rw-r--r--apps/settings/templates/settings/personal/personal.info.php3
-rw-r--r--apps/user_ldap/lib/Configuration.php6
-rw-r--r--apps/user_ldap/lib/Connection.php1
-rw-r--r--apps/user_ldap/lib/User/Manager.php1
-rw-r--r--apps/user_ldap/lib/User/User.php6
-rw-r--r--apps/user_ldap/templates/settings.php1
18 files changed, 144 insertions, 23 deletions
diff --git a/apps/provisioning_api/lib/Controller/AUserData.php b/apps/provisioning_api/lib/Controller/AUserData.php
index 44087a91791..eb881db45e0 100644
--- a/apps/provisioning_api/lib/Controller/AUserData.php
+++ b/apps/provisioning_api/lib/Controller/AUserData.php
@@ -179,6 +179,7 @@ abstract class AUserData extends OCSController {
IAccountManager::PROPERTY_HEADLINE,
IAccountManager::PROPERTY_BIOGRAPHY,
IAccountManager::PROPERTY_PROFILE_ENABLED,
+ IAccountManager::PROPERTY_PRONOUNS,
] as $propertyName) {
$property = $userAccount->getProperty($propertyName);
$data[$propertyName] = $property->getValue();
diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php
index 4cab2341b00..e65585902bc 100644
--- a/apps/provisioning_api/lib/Controller/UsersController.php
+++ b/apps/provisioning_api/lib/Controller/UsersController.php
@@ -761,6 +761,7 @@ class UsersController extends AUserData {
$permittedFields[] = IAccountManager::PROPERTY_HEADLINE;
$permittedFields[] = IAccountManager::PROPERTY_BIOGRAPHY;
$permittedFields[] = IAccountManager::PROPERTY_PROFILE_ENABLED;
+ $permittedFields[] = IAccountManager::PROPERTY_PRONOUNS;
return new DataResponse($permittedFields);
}
@@ -944,6 +945,8 @@ class UsersController extends AUserData {
$permittedFields[] = IAccountManager::PROPERTY_BIOGRAPHY;
$permittedFields[] = IAccountManager::PROPERTY_PROFILE_ENABLED;
$permittedFields[] = IAccountManager::PROPERTY_BIRTHDATE;
+ $permittedFields[] = IAccountManager::PROPERTY_PRONOUNS;
+
$permittedFields[] = IAccountManager::PROPERTY_PHONE . self::SCOPE_SUFFIX;
$permittedFields[] = IAccountManager::PROPERTY_ADDRESS . self::SCOPE_SUFFIX;
$permittedFields[] = IAccountManager::PROPERTY_WEBSITE . self::SCOPE_SUFFIX;
@@ -955,8 +958,8 @@ class UsersController extends AUserData {
$permittedFields[] = IAccountManager::PROPERTY_BIOGRAPHY . self::SCOPE_SUFFIX;
$permittedFields[] = IAccountManager::PROPERTY_PROFILE_ENABLED . self::SCOPE_SUFFIX;
$permittedFields[] = IAccountManager::PROPERTY_BIRTHDATE . self::SCOPE_SUFFIX;
-
$permittedFields[] = IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX;
+ $permittedFields[] = IAccountManager::PROPERTY_PRONOUNS . self::SCOPE_SUFFIX;
// If admin they can edit their own quota and manager
$isAdmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID());
@@ -997,6 +1000,7 @@ class UsersController extends AUserData {
$permittedFields[] = IAccountManager::PROPERTY_HEADLINE;
$permittedFields[] = IAccountManager::PROPERTY_BIOGRAPHY;
$permittedFields[] = IAccountManager::PROPERTY_PROFILE_ENABLED;
+ $permittedFields[] = IAccountManager::PROPERTY_PRONOUNS;
$permittedFields[] = self::USER_FIELD_QUOTA;
$permittedFields[] = self::USER_FIELD_NOTIFICATION_EMAIL;
$permittedFields[] = self::USER_FIELD_MANAGER;
@@ -1141,6 +1145,7 @@ class UsersController extends AUserData {
case IAccountManager::PROPERTY_HEADLINE:
case IAccountManager::PROPERTY_BIOGRAPHY:
case IAccountManager::PROPERTY_BIRTHDATE:
+ case IAccountManager::PROPERTY_PRONOUNS:
$userAccount = $this->accountManager->getAccount($targetUser);
try {
$userProperty = $userAccount->getProperty($key);
@@ -1189,6 +1194,7 @@ class UsersController extends AUserData {
case IAccountManager::PROPERTY_PROFILE_ENABLED . self::SCOPE_SUFFIX:
case IAccountManager::PROPERTY_BIRTHDATE . self::SCOPE_SUFFIX:
case IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX:
+ case IAccountManager::PROPERTY_PRONOUNS . self::SCOPE_SUFFIX:
$propertyName = substr($key, 0, strlen($key) - strlen(self::SCOPE_SUFFIX));
$userAccount = $this->accountManager->getAccount($targetUser);
$userProperty = $userAccount->getProperty($propertyName);
diff --git a/apps/provisioning_api/lib/ResponseDefinitions.php b/apps/provisioning_api/lib/ResponseDefinitions.php
index 90cc09b345b..fec68021209 100644
--- a/apps/provisioning_api/lib/ResponseDefinitions.php
+++ b/apps/provisioning_api/lib/ResponseDefinitions.php
@@ -56,6 +56,8 @@ namespace OCA\Provisioning_API;
* phoneScope?: Provisioning_APIUserDetailsScope,
* profile_enabled: string,
* profile_enabledScope?: Provisioning_APIUserDetailsScope,
+ * pronouns: string,
+ * pronounsScope?: Provisioning_APIUserDetailsScope,
* quota: Provisioning_APIUserDetailsQuota,
* role: string,
* roleScope?: Provisioning_APIUserDetailsScope,
diff --git a/apps/provisioning_api/openapi-administration.json b/apps/provisioning_api/openapi-administration.json
index 3834de8a700..3490e6829e9 100644
--- a/apps/provisioning_api/openapi-administration.json
+++ b/apps/provisioning_api/openapi-administration.json
@@ -99,6 +99,7 @@
"organisation",
"phone",
"profile_enabled",
+ "pronouns",
"quota",
"role",
"subadmin",
@@ -226,6 +227,12 @@
"profile_enabledScope": {
"$ref": "#/components/schemas/UserDetailsScope"
},
+ "pronouns": {
+ "type": "string"
+ },
+ "pronounsScope": {
+ "$ref": "#/components/schemas/UserDetailsScope"
+ },
"quota": {
"$ref": "#/components/schemas/UserDetailsQuota"
},
diff --git a/apps/provisioning_api/openapi-full.json b/apps/provisioning_api/openapi-full.json
index 6577efebed9..461a9b0734a 100644
--- a/apps/provisioning_api/openapi-full.json
+++ b/apps/provisioning_api/openapi-full.json
@@ -146,6 +146,7 @@
"organisation",
"phone",
"profile_enabled",
+ "pronouns",
"quota",
"role",
"subadmin",
@@ -273,6 +274,12 @@
"profile_enabledScope": {
"$ref": "#/components/schemas/UserDetailsScope"
},
+ "pronouns": {
+ "type": "string"
+ },
+ "pronounsScope": {
+ "$ref": "#/components/schemas/UserDetailsScope"
+ },
"quota": {
"$ref": "#/components/schemas/UserDetailsQuota"
},
diff --git a/apps/provisioning_api/openapi.json b/apps/provisioning_api/openapi.json
index ef07072460e..3a5f253d0b6 100644
--- a/apps/provisioning_api/openapi.json
+++ b/apps/provisioning_api/openapi.json
@@ -146,6 +146,7 @@
"organisation",
"phone",
"profile_enabled",
+ "pronouns",
"quota",
"role",
"subadmin",
@@ -273,6 +274,12 @@
"profile_enabledScope": {
"$ref": "#/components/schemas/UserDetailsScope"
},
+ "pronouns": {
+ "type": "string"
+ },
+ "pronounsScope": {
+ "$ref": "#/components/schemas/UserDetailsScope"
+ },
"quota": {
"$ref": "#/components/schemas/UserDetailsQuota"
},
diff --git a/apps/provisioning_api/tests/Controller/UsersControllerTest.php b/apps/provisioning_api/tests/Controller/UsersControllerTest.php
index 0f82fc53ba6..3fcac1290db 100644
--- a/apps/provisioning_api/tests/Controller/UsersControllerTest.php
+++ b/apps/provisioning_api/tests/Controller/UsersControllerTest.php
@@ -990,6 +990,7 @@ class UsersControllerTest extends TestCase {
IAccountManager::PROPERTY_HEADLINE => ['value' => 'headline'],
IAccountManager::PROPERTY_BIOGRAPHY => ['value' => 'biography'],
IAccountManager::PROPERTY_PROFILE_ENABLED => ['value' => '1'],
+ IAccountManager::PROPERTY_PRONOUNS => ['value' => 'they/them'],
]);
$this->config
->method('getUserValue')
@@ -1068,6 +1069,7 @@ class UsersControllerTest extends TestCase {
'profile_enabled' => '1',
'notify_email' => null,
'manager' => '',
+ 'pronouns' => 'they/them',
];
$this->assertEquals($expected, $this->invokePrivate($this->api, 'getUserData', ['UID']));
}
@@ -1171,6 +1173,7 @@ class UsersControllerTest extends TestCase {
IAccountManager::PROPERTY_HEADLINE => ['value' => 'headline'],
IAccountManager::PROPERTY_BIOGRAPHY => ['value' => 'biography'],
IAccountManager::PROPERTY_PROFILE_ENABLED => ['value' => '1'],
+ IAccountManager::PROPERTY_PRONOUNS => ['value' => 'they/them'],
]);
$this->l10nFactory
@@ -1209,6 +1212,7 @@ class UsersControllerTest extends TestCase {
'profile_enabled' => '1',
'notify_email' => null,
'manager' => '',
+ 'pronouns' => 'they/them',
];
$this->assertEquals($expected, $this->invokePrivate($this->api, 'getUserData', ['UID']));
}
@@ -1351,6 +1355,7 @@ class UsersControllerTest extends TestCase {
IAccountManager::PROPERTY_HEADLINE => ['value' => 'headline'],
IAccountManager::PROPERTY_BIOGRAPHY => ['value' => 'biography'],
IAccountManager::PROPERTY_PROFILE_ENABLED => ['value' => '1'],
+ IAccountManager::PROPERTY_PRONOUNS => ['value' => 'they/them'],
]);
$this->l10nFactory
@@ -1388,6 +1393,7 @@ class UsersControllerTest extends TestCase {
'profile_enabled' => '1',
'notify_email' => null,
'manager' => '',
+ 'pronouns' => 'they/them',
];
$this->assertEquals($expected, $this->invokePrivate($this->api, 'getUserData', ['UID']));
}
@@ -1729,6 +1735,7 @@ class UsersControllerTest extends TestCase {
[IAccountManager::PROPERTY_HEADLINE, 'Hi', 'Hello'],
[IAccountManager::PROPERTY_BIOGRAPHY, 'A biography', 'Another biography'],
[IAccountManager::PROPERTY_PROFILE_ENABLED, '1', '0'],
+ [IAccountManager::PROPERTY_PRONOUNS, 'they/them', 'he/him'],
];
}
@@ -1806,6 +1813,7 @@ class UsersControllerTest extends TestCase {
[IAccountManager::PROPERTY_HEADLINE, IAccountManager::SCOPE_LOCAL, IAccountManager::SCOPE_FEDERATED],
[IAccountManager::PROPERTY_BIOGRAPHY, IAccountManager::SCOPE_LOCAL, IAccountManager::SCOPE_FEDERATED],
[IAccountManager::PROPERTY_PROFILE_ENABLED, IAccountManager::SCOPE_LOCAL, IAccountManager::SCOPE_FEDERATED],
+ [IAccountManager::PROPERTY_PRONOUNS, IAccountManager::SCOPE_LOCAL, IAccountManager::SCOPE_FEDERATED],
];
}
@@ -3690,7 +3698,8 @@ class UsersControllerTest extends TestCase {
'role' => 'role',
'headline' => 'headline',
'biography' => 'biography',
- 'profile_enabled' => '1'
+ 'profile_enabled' => '1',
+ 'pronouns' => 'they/them',
]
);
@@ -3711,6 +3720,7 @@ class UsersControllerTest extends TestCase {
'headline' => 'headline',
'biography' => 'biography',
'profile_enabled' => '1',
+ 'pronouns' => 'they/them',
];
$this->assertSame($expected, $api->getCurrentUser()->getData());
@@ -3775,7 +3785,8 @@ class UsersControllerTest extends TestCase {
'role' => 'role',
'headline' => 'headline',
'biography' => 'biography',
- 'profile_enabled' => '1'
+ 'profile_enabled' => '1',
+ 'pronouns' => 'they/them',
];
$api->expects($this->exactly(2))
@@ -4115,6 +4126,7 @@ class UsersControllerTest extends TestCase {
IAccountManager::PROPERTY_HEADLINE,
IAccountManager::PROPERTY_BIOGRAPHY,
IAccountManager::PROPERTY_PROFILE_ENABLED,
+ IAccountManager::PROPERTY_PRONOUNS,
]],
[true, ISetDisplayNameBackend::class, [
IAccountManager::PROPERTY_DISPLAYNAME,
@@ -4130,6 +4142,7 @@ class UsersControllerTest extends TestCase {
IAccountManager::PROPERTY_HEADLINE,
IAccountManager::PROPERTY_BIOGRAPHY,
IAccountManager::PROPERTY_PROFILE_ENABLED,
+ IAccountManager::PROPERTY_PRONOUNS,
]],
[true, UserInterface::class, [
IAccountManager::PROPERTY_EMAIL,
@@ -4144,6 +4157,7 @@ class UsersControllerTest extends TestCase {
IAccountManager::PROPERTY_HEADLINE,
IAccountManager::PROPERTY_BIOGRAPHY,
IAccountManager::PROPERTY_PROFILE_ENABLED,
+ IAccountManager::PROPERTY_PRONOUNS,
]],
];
}
diff --git a/apps/settings/lib/Controller/UsersController.php b/apps/settings/lib/Controller/UsersController.php
index 4ee359b6fe9..eb401f85536 100644
--- a/apps/settings/lib/Controller/UsersController.php
+++ b/apps/settings/lib/Controller/UsersController.php
@@ -335,6 +335,8 @@ class UsersController extends Controller {
?string $fediverseScope = null,
?string $birthdate = null,
?string $birthdateScope = null,
+ ?string $pronouns = null,
+ ?string $pronounsScope = null
) {
$user = $this->userSession->getUser();
if (!$user instanceof IUser) {
@@ -375,6 +377,7 @@ class UsersController extends Controller {
IAccountManager::PROPERTY_TWITTER => ['value' => $twitter, 'scope' => $twitterScope],
IAccountManager::PROPERTY_FEDIVERSE => ['value' => $fediverse, 'scope' => $fediverseScope],
IAccountManager::PROPERTY_BIRTHDATE => ['value' => $birthdate, 'scope' => $birthdateScope],
+ IAccountManager::PROPERTY_PRONOUNS => ['value' => $pronouns, 'scope' => $pronounsScope],
];
$allowUserToChangeDisplayName = $this->config->getSystemValueBool('allow_user_to_change_display_name', true);
foreach ($updatable as $property => $data) {
@@ -418,6 +421,8 @@ class UsersController extends Controller {
'fediverseScope' => $userAccount->getProperty(IAccountManager::PROPERTY_FEDIVERSE)->getScope(),
'birthdate' => $userAccount->getProperty(IAccountManager::PROPERTY_BIRTHDATE)->getValue(),
'birthdateScope' => $userAccount->getProperty(IAccountManager::PROPERTY_BIRTHDATE)->getScope(),
+ 'pronouns' => $userAccount->getProperty(IAccountManager::PROPERTY_PRONOUNS)->getValue(),
+ 'pronounsScope' => $userAccount->getProperty(IAccountManager::PROPERTY_PRONOUNS)->getScope(),
'message' => $this->l10n->t('Settings saved'),
],
],
diff --git a/apps/settings/lib/Settings/Personal/PersonalInfo.php b/apps/settings/lib/Settings/Personal/PersonalInfo.php
index bfac996de2f..232fea8bd73 100644
--- a/apps/settings/lib/Settings/Personal/PersonalInfo.php
+++ b/apps/settings/lib/Settings/Personal/PersonalInfo.php
@@ -143,6 +143,7 @@ class PersonalInfo implements ISettings {
'biography' => $this->getProperty($account, IAccountManager::PROPERTY_BIOGRAPHY),
'birthdate' => $this->getProperty($account, IAccountManager::PROPERTY_BIRTHDATE),
'firstDayOfWeek' => $this->config->getUserValue($uid, 'core', AUserData::USER_FIELD_FIRST_DAY_OF_WEEK),
+ 'pronouns' => $this->getProperty($account, IAccountManager::PROPERTY_PRONOUNS),
];
$accountParameters = [
diff --git a/apps/settings/src/components/PersonalInfo/PronounsSection.vue b/apps/settings/src/components/PersonalInfo/PronounsSection.vue
new file mode 100644
index 00000000000..fb35b1800c5
--- /dev/null
+++ b/apps/settings/src/components/PersonalInfo/PronounsSection.vue
@@ -0,0 +1,45 @@
+<!--
+ - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+
+<template>
+ <AccountPropertySection v-bind.sync="pronouns"
+ :placeholder="randomPronounsPlaceholder" />
+</template>
+
+<script>
+import { loadState } from '@nextcloud/initial-state'
+
+import AccountPropertySection from './shared/AccountPropertySection.vue'
+
+import { NAME_READABLE_ENUM } from '../../constants/AccountPropertyConstants.js'
+
+const { pronouns } = loadState('settings', 'personalInfoParameters', {})
+
+export default {
+ name: 'PronounsSection',
+
+ components: {
+ AccountPropertySection,
+ },
+
+ data() {
+ return {
+ pronouns: { ...pronouns, readable: NAME_READABLE_ENUM[pronouns.name] },
+ }
+ },
+
+ computed: {
+ randomPronounsPlaceholder() {
+ const pronouns = [
+ this.t('settings', 'she/her'),
+ this.t('settings', 'he/him'),
+ this.t('settings', 'they/them'),
+ ]
+ const pronounsExample = pronouns[Math.floor(Math.random() * pronouns.length)]
+ return this.t('settings', `Your pronouns. E.g. ${pronounsExample}`, { pronounsExample })
+ },
+ },
+}
+</script>
diff --git a/apps/settings/src/constants/AccountPropertyConstants.js b/apps/settings/src/constants/AccountPropertyConstants.js
index 8ddfc867ec5..4b475b54ab4 100644
--- a/apps/settings/src/constants/AccountPropertyConstants.js
+++ b/apps/settings/src/constants/AccountPropertyConstants.js
@@ -15,19 +15,20 @@ export const ACCOUNT_PROPERTY_ENUM = Object.freeze({
ADDRESS: 'address',
AVATAR: 'avatar',
BIOGRAPHY: 'biography',
+ BIRTHDATE: 'birthdate',
DISPLAYNAME: 'displayname',
EMAIL_COLLECTION: 'additional_mail',
EMAIL: 'email',
+ FEDIVERSE: 'fediverse',
HEADLINE: 'headline',
NOTIFICATION_EMAIL: 'notify_email',
- FEDIVERSE: 'fediverse',
ORGANISATION: 'organisation',
PHONE: 'phone',
PROFILE_ENABLED: 'profile_enabled',
+ PRONOUNS: 'pronouns',
ROLE: 'role',
TWITTER: 'twitter',
WEBSITE: 'website',
- BIRTHDATE: 'birthdate',
})
/** Enum of account properties to human readable account property names */
@@ -35,18 +36,19 @@ export const ACCOUNT_PROPERTY_READABLE_ENUM = Object.freeze({
ADDRESS: t('settings', 'Location'),
AVATAR: t('settings', 'Profile picture'),
BIOGRAPHY: t('settings', 'About'),
+ BIRTHDATE: t('settings', 'Date of birth'),
DISPLAYNAME: t('settings', 'Full name'),
EMAIL_COLLECTION: t('settings', 'Additional email'),
EMAIL: t('settings', 'Email'),
+ FEDIVERSE: t('settings', 'Fediverse (e.g. Mastodon)'),
HEADLINE: t('settings', 'Headline'),
ORGANISATION: t('settings', 'Organisation'),
PHONE: t('settings', 'Phone number'),
PROFILE_ENABLED: t('settings', 'Profile'),
+ PRONOUNS: t('settings', 'Pronouns'),
ROLE: t('settings', 'Role'),
TWITTER: t('settings', 'X (formerly Twitter)'),
- FEDIVERSE: t('settings', 'Fediverse (e.g. Mastodon)'),
WEBSITE: t('settings', 'Website'),
- BIRTHDATE: t('settings', 'Date of birth'),
})
export const NAME_READABLE_ENUM = Object.freeze({
@@ -65,6 +67,7 @@ export const NAME_READABLE_ENUM = Object.freeze({
[ACCOUNT_PROPERTY_ENUM.FEDIVERSE]: ACCOUNT_PROPERTY_READABLE_ENUM.FEDIVERSE,
[ACCOUNT_PROPERTY_ENUM.WEBSITE]: ACCOUNT_PROPERTY_READABLE_ENUM.WEBSITE,
[ACCOUNT_PROPERTY_ENUM.BIRTHDATE]: ACCOUNT_PROPERTY_READABLE_ENUM.BIRTHDATE,
+ [ACCOUNT_PROPERTY_ENUM.PRONOUNS]: ACCOUNT_PROPERTY_READABLE_ENUM.PRONOUNS,
})
/** Enum of profile specific sections to human readable names */
@@ -89,6 +92,7 @@ export const PROPERTY_READABLE_KEYS_ENUM = Object.freeze({
[ACCOUNT_PROPERTY_READABLE_ENUM.FEDIVERSE]: ACCOUNT_PROPERTY_ENUM.FEDIVERSE,
[ACCOUNT_PROPERTY_READABLE_ENUM.WEBSITE]: ACCOUNT_PROPERTY_ENUM.WEBSITE,
[ACCOUNT_PROPERTY_READABLE_ENUM.BIRTHDATE]: ACCOUNT_PROPERTY_ENUM.BIRTHDATE,
+ [ACCOUNT_PROPERTY_READABLE_ENUM.PRONOUNS]: ACCOUNT_PROPERTY_ENUM.PRONOUNS,
})
/**
@@ -134,6 +138,7 @@ export const PROPERTY_READABLE_SUPPORTED_SCOPES_ENUM = Object.freeze({
[ACCOUNT_PROPERTY_READABLE_ENUM.FEDIVERSE]: [SCOPE_ENUM.LOCAL, SCOPE_ENUM.PRIVATE],
[ACCOUNT_PROPERTY_READABLE_ENUM.WEBSITE]: [SCOPE_ENUM.LOCAL, SCOPE_ENUM.PRIVATE],
[ACCOUNT_PROPERTY_READABLE_ENUM.BIRTHDATE]: [SCOPE_ENUM.LOCAL, SCOPE_ENUM.PRIVATE],
+ [ACCOUNT_PROPERTY_READABLE_ENUM.PRONOUNS]: [SCOPE_ENUM.LOCAL, SCOPE_ENUM.PRIVATE],
})
/** List of readable account properties which aren't published to the lookup server */
diff --git a/apps/settings/src/main-personal-info.js b/apps/settings/src/main-personal-info.js
index 0a1e983c576..c28f14ee477 100644
--- a/apps/settings/src/main-personal-info.js
+++ b/apps/settings/src/main-personal-info.js
@@ -9,24 +9,25 @@ import { loadState } from '@nextcloud/initial-state'
import { translate as t } from '@nextcloud/l10n'
import AvatarSection from './components/PersonalInfo/AvatarSection.vue'
+import BiographySection from './components/PersonalInfo/BiographySection.vue'
+import BirthdaySection from './components/PersonalInfo/BirthdaySection.vue'
import DetailsSection from './components/PersonalInfo/DetailsSection.vue'
import DisplayNameSection from './components/PersonalInfo/DisplayNameSection.vue'
import EmailSection from './components/PersonalInfo/EmailSection/EmailSection.vue'
-import PhoneSection from './components/PersonalInfo/PhoneSection.vue'
-import LocationSection from './components/PersonalInfo/LocationSection.vue'
-import WebsiteSection from './components/PersonalInfo/WebsiteSection.vue'
-import TwitterSection from './components/PersonalInfo/TwitterSection.vue'
import FediverseSection from './components/PersonalInfo/FediverseSection.vue'
+import FirstDayOfWeekSection from './components/PersonalInfo/FirstDayOfWeekSection.vue'
+import HeadlineSection from './components/PersonalInfo/HeadlineSection.vue'
import LanguageSection from './components/PersonalInfo/LanguageSection/LanguageSection.vue'
import LocaleSection from './components/PersonalInfo/LocaleSection/LocaleSection.vue'
-import ProfileSection from './components/PersonalInfo/ProfileSection/ProfileSection.vue'
+import LocationSection from './components/PersonalInfo/LocationSection.vue'
import OrganisationSection from './components/PersonalInfo/OrganisationSection.vue'
-import RoleSection from './components/PersonalInfo/RoleSection.vue'
-import HeadlineSection from './components/PersonalInfo/HeadlineSection.vue'
-import BiographySection from './components/PersonalInfo/BiographySection.vue'
+import PhoneSection from './components/PersonalInfo/PhoneSection.vue'
+import ProfileSection from './components/PersonalInfo/ProfileSection/ProfileSection.vue'
import ProfileVisibilitySection from './components/PersonalInfo/ProfileVisibilitySection/ProfileVisibilitySection.vue'
-import BirthdaySection from './components/PersonalInfo/BirthdaySection.vue'
-import FirstDayOfWeekSection from './components/PersonalInfo/FirstDayOfWeekSection.vue'
+import PronounsSection from './components/PersonalInfo/PronounsSection.vue'
+import RoleSection from './components/PersonalInfo/RoleSection.vue'
+import TwitterSection from './components/PersonalInfo/TwitterSection.vue'
+import WebsiteSection from './components/PersonalInfo/WebsiteSection.vue'
__webpack_nonce__ = getCSPNonce()
@@ -39,18 +40,19 @@ Vue.mixin({
})
const AvatarView = Vue.extend(AvatarSection)
+const BirthdayView = Vue.extend(BirthdaySection)
const DetailsView = Vue.extend(DetailsSection)
const DisplayNameView = Vue.extend(DisplayNameSection)
const EmailView = Vue.extend(EmailSection)
-const PhoneView = Vue.extend(PhoneSection)
-const LocationView = Vue.extend(LocationSection)
-const WebsiteView = Vue.extend(WebsiteSection)
-const TwitterView = Vue.extend(TwitterSection)
const FediverseView = Vue.extend(FediverseSection)
+const FirstDayOfWeekView = Vue.extend(FirstDayOfWeekSection)
const LanguageView = Vue.extend(LanguageSection)
const LocaleView = Vue.extend(LocaleSection)
-const BirthdayView = Vue.extend(BirthdaySection)
-const FirstDayOfWeekView = Vue.extend(FirstDayOfWeekSection)
+const LocationView = Vue.extend(LocationSection)
+const PhoneView = Vue.extend(PhoneSection)
+const PronounsView = Vue.extend(PronounsSection)
+const TwitterView = Vue.extend(TwitterSection)
+const WebsiteView = Vue.extend(WebsiteSection)
new AvatarView().$mount('#vue-avatar-section')
new DetailsView().$mount('#vue-details-section')
@@ -65,6 +67,7 @@ new LanguageView().$mount('#vue-language-section')
new LocaleView().$mount('#vue-locale-section')
new FirstDayOfWeekView().$mount('#vue-fdow-section')
new BirthdayView().$mount('#vue-birthday-section')
+new PronounsView().$mount('#vue-pronouns-section')
if (profileEnabledGlobally) {
const ProfileView = Vue.extend(ProfileSection)
diff --git a/apps/settings/templates/settings/personal/personal.info.php b/apps/settings/templates/settings/personal/personal.info.php
index 92b29961baf..e622663fba7 100644
--- a/apps/settings/templates/settings/personal/personal.info.php
+++ b/apps/settings/templates/settings/personal/personal.info.php
@@ -44,6 +44,9 @@ script('settings', [
<div id="vue-displayname-section"></div>
</div>
<div class="personal-settings-setting-box">
+ <div id="vue-pronouns-section"></div>
+ </div>
+ <div class="personal-settings-setting-box">
<div id="vue-email-section"></div>
</div>
<div class="personal-settings-setting-box">
diff --git a/apps/user_ldap/lib/Configuration.php b/apps/user_ldap/lib/Configuration.php
index d436c5c4240..9de180cad76 100644
--- a/apps/user_ldap/lib/Configuration.php
+++ b/apps/user_ldap/lib/Configuration.php
@@ -80,6 +80,8 @@ use Psr\Log\LoggerInterface;
* @property string $ldapAttributeHeadline
* @property string $ldapAttributeBiography
* @property string $ldapAdminGroup
+ * @property string $ldapAttributeBirthDate
+ * @property string $ldapAttributePronouns
*/
class Configuration {
public const AVATAR_PREFIX_DEFAULT = 'default';
@@ -179,6 +181,7 @@ class Configuration {
'ldapAdminGroup' => '',
'ldapAttributeBirthDate' => null,
'ldapAttributeAnniversaryDate' => null,
+ 'ldapAttributePronouns' => null,
];
public function __construct(string $configPrefix, bool $autoRead = true) {
@@ -315,6 +318,7 @@ class Configuration {
case 'ldapAttributeBiography':
case 'ldapAttributeBirthDate':
case 'ldapAttributeAnniversaryDate':
+ case 'ldapAttributePronouns':
$readMethod = 'getLcValue';
break;
case 'ldapUserDisplayName':
@@ -559,6 +563,7 @@ class Configuration {
'ldap_admin_group' => '',
'ldap_attr_birthdate' => '',
'ldap_attr_anniversarydate' => '',
+ 'ldap_attr_pronouns' => '',
];
}
@@ -638,6 +643,7 @@ class Configuration {
'ldap_admin_group' => 'ldapAdminGroup',
'ldap_attr_birthdate' => 'ldapAttributeBirthDate',
'ldap_attr_anniversarydate' => 'ldapAttributeAnniversaryDate',
+ 'ldap_attr_pronouns' => 'ldapAttributePronouns',
];
return $array;
}
diff --git a/apps/user_ldap/lib/Connection.php b/apps/user_ldap/lib/Connection.php
index 54dba6d858a..b74c964eb72 100644
--- a/apps/user_ldap/lib/Connection.php
+++ b/apps/user_ldap/lib/Connection.php
@@ -85,6 +85,7 @@ use Psr\Log\LoggerInterface;
* @property string $ldapAttributeBiography
* @property string $ldapAdminGroup
* @property string $ldapAttributeBirthDate
+ * @property string $ldapAttributePronouns
*/
class Connection extends LDAPUtility {
private ?\LDAP\Connection $ldapConnectionRes = null;
diff --git a/apps/user_ldap/lib/User/Manager.php b/apps/user_ldap/lib/User/Manager.php
index 227990401c2..bf1da54823c 100644
--- a/apps/user_ldap/lib/User/Manager.php
+++ b/apps/user_ldap/lib/User/Manager.php
@@ -142,6 +142,7 @@ class Manager {
$this->access->getConnection()->ldapAttributeHeadline,
$this->access->getConnection()->ldapAttributeBiography,
$this->access->getConnection()->ldapAttributeBirthDate,
+ $this->access->getConnection()->ldapAttributePronouns,
];
$homeRule = (string)$this->access->getConnection()->homeFolderNamingRule;
diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php
index 3423455e819..f2a9ba49f2f 100644
--- a/apps/user_ldap/lib/User/User.php
+++ b/apps/user_ldap/lib/User/User.php
@@ -320,6 +320,12 @@ class User {
]);
}
}
+ //User Profile Field - pronouns
+ $attr = strtolower($this->connection->ldapAttributePronouns);
+ if (!empty($attr)) {
+ $profileValues[\OCP\Accounts\IAccountManager::PROPERTY_PRONOUNS]
+ = $ldapEntry[$attr][0] ?? '';
+ }
// check for changed data and cache just for TTL checking
$checksum = hash('sha256', json_encode($profileValues));
$this->connection->writeToCache($cacheKey, $checksum // write array to cache. is waste of cache space
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index 4fb24655000..4be24095e99 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -139,6 +139,7 @@ style('user_ldap', 'settings');
<p><label for="ldap_attr_headline"> <?php p($l->t('Headline Field')); ?></label><input type="text" id="ldap_attr_headline" name="ldap_attr_headline" title="<?php p($l->t('User profile Headline will be set from the specified attribute')); ?>" data-default="<?php p($_['ldap_attr_headline_default']); ?>"></p>
<p><label for="ldap_attr_biography"> <?php p($l->t('Biography Field')); ?></label><input type="text" id="ldap_attr_biography" name="ldap_attr_biography" title="<?php p($l->t('User profile Biography will be set from the specified attribute')); ?>" data-default="<?php p($_['ldap_attr_biography_default']); ?>"></p>
<p><label for="ldap_attr_birthdate"> <?php p($l->t('Birthdate Field')); ?></label><input type="text" id="ldap_attr_birthdate" name="ldap_attr_birthdate" title="<?php p($l->t('User profile Date of birth will be set from the specified attribute')); ?>" data-default="<?php p($_['ldap_attr_birthdate_default']); ?>"></p>
+ <p></p><label for="ldap_attr_pronouns"> <?php p($l->t('Pronouns Field')); ?></label><input type="text" id="ldap_attr_pronouns" name="ldap_attr_pronouns" title="<?php p($l->t('User profile Pronouns will be set from the specified attribute')); ?>" data-default="<?php p($_['ldap_attr_pronouns_default']); ?>"></p>
</div>
</div>
<?php print_unescaped($_['settingControls']); ?>