aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
authorPytal <24800714+Pytal@users.noreply.github.com>2021-10-18 23:03:58 -0700
committerGitHub <noreply@github.com>2021-10-18 23:03:58 -0700
commitf7b3d521f866a949f457f31f8f8480aebd3c9934 (patch)
tree0c4a6cd0e03b85c37b75f8baebc77aee17f0eae0 /lib/private
parent7cebde242c9f45d46f45bdd3b2a186bccd12434b (diff)
parent3be9d3ca8fca4fb743a4d2f2ffe44a45fa9ffa6e (diff)
downloadnextcloud-server-f7b3d521f866a949f457f31f8f8480aebd3c9934.tar.gz
nextcloud-server-f7b3d521f866a949f457f31f8f8480aebd3c9934.zip
Merge pull request #28751 from nextcloud/feat/28139/profile-page
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Accounts/AccountManager.php60
-rw-r--r--lib/private/Accounts/TAccountsHelper.php6
-rw-r--r--lib/private/AppFramework/Bootstrap/Coordinator.php21
-rw-r--r--lib/private/AppFramework/Bootstrap/RegistrationContext.php28
-rw-r--r--lib/private/Contacts/ContactsMenu/ActionProviderStore.php6
-rw-r--r--lib/private/Contacts/ContactsMenu/ContactsStore.php54
-rw-r--r--lib/private/Contacts/ContactsMenu/Entry.php37
-rw-r--r--lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php93
-rw-r--r--lib/private/L10N/Factory.php44
-rw-r--r--lib/private/Profile/Actions/EmailAction.php94
-rw-r--r--lib/private/Profile/Actions/PhoneAction.php94
-rw-r--r--lib/private/Profile/Actions/TwitterAction.php97
-rw-r--r--lib/private/Profile/Actions/WebsiteAction.php94
-rw-r--r--lib/private/Profile/ProfileManager.php333
-rw-r--r--lib/private/Profile/TProfileHelper.php46
-rw-r--r--lib/private/Setup.php3
-rw-r--r--lib/private/Template/SCSSCacher.php9
17 files changed, 1063 insertions, 56 deletions
diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php
index a3f971df6a1..3416db56ba5 100644
--- a/lib/private/Accounts/AccountManager.php
+++ b/lib/private/Accounts/AccountManager.php
@@ -1,4 +1,5 @@
<?php
+
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @copyright Copyright (c) 2016, Björn Schießle
@@ -30,6 +31,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Accounts;
use Exception;
@@ -337,7 +339,7 @@ class AccountManager implements IAccountManager {
return $this->buildDefaultUserRecord($user);
}
- return $this->addMissingDefaultValues($userDataArray);
+ return $this->addMissingDefaultValues($userDataArray, $this->buildDefaultUserRecord($user));
}
public function searchUsers(string $property, array $values): array {
@@ -384,7 +386,8 @@ class AccountManager implements IAccountManager {
}
$oldMail = isset($oldData[self::PROPERTY_EMAIL]) ? $oldData[self::PROPERTY_EMAIL]['value']['value'] : '';
if ($oldMail !== $property->getValue()) {
- $this->jobList->add(VerifyUserData::class,
+ $this->jobList->add(
+ VerifyUserData::class,
[
'verificationCode' => '',
'data' => $property->getValue(),
@@ -416,12 +419,14 @@ class AccountManager implements IAccountManager {
$key = $this->crypto->encrypt($email);
$token = $this->verificationToken->create($user, 'verifyMail' . $ref, $email);
- $link = $this->urlGenerator->linkToRouteAbsolute('provisioning_api.Verification.verifyMail',
+ $link = $this->urlGenerator->linkToRouteAbsolute(
+ 'provisioning_api.Verification.verifyMail',
[
'userId' => $user->getUID(),
'token' => $token,
'key' => $key
- ]);
+ ]
+ );
$emailTemplate = $this->mailer->createEMailTemplate('core.EmailVerification', [
'link' => $link,
@@ -465,14 +470,18 @@ class AccountManager implements IAccountManager {
}
/**
- * make sure that all expected data are set
- *
+ * Make sure that all expected data are set
*/
- protected function addMissingDefaultValues(array $userData): array {
- foreach ($userData as $i => $value) {
- if (!isset($value['verified'])) {
- $userData[$i]['verified'] = self::NOT_VERIFIED;
+ protected function addMissingDefaultValues(array $userData, array $defaultUserData): array {
+ foreach ($defaultUserData as $i => $value) {
+ // If property doesn't exists, initialize it
+ if (!array_key_exists($i, $userData)) {
+ $userData[$i] = [];
}
+
+ // Merge and extend default missing values
+ $defaultValueIndex = array_search($value['name'], array_column($defaultUserData, 'name'));
+ $userData[$i] = array_merge($defaultUserData[$defaultValueIndex], $userData[$i]);
}
return $userData;
@@ -499,7 +508,7 @@ class AccountManager implements IAccountManager {
|| $property->getValue() !== $oldData[$propertyName]['value'])
&& ($property->getVerified() !== self::NOT_VERIFIED
|| $wasVerified)
- ) {
+ ) {
$property->setVerified(self::NOT_VERIFIED);
}
}
@@ -629,7 +638,6 @@ class AccountManager implements IAccountManager {
*/
protected function buildDefaultUserRecord(IUser $user) {
return [
-
[
'name' => self::PROPERTY_DISPLAYNAME,
'value' => $user->getDisplayName(),
@@ -677,6 +685,34 @@ class AccountManager implements IAccountManager {
'verified' => self::NOT_VERIFIED,
],
+ [
+ 'name' => self::PROPERTY_ORGANISATION,
+ 'value' => '',
+ 'scope' => self::SCOPE_LOCAL,
+ ],
+
+ [
+ 'name' => self::PROPERTY_ROLE,
+ 'value' => '',
+ 'scope' => self::SCOPE_LOCAL,
+ ],
+
+ [
+ 'name' => self::PROPERTY_HEADLINE,
+ 'value' => '',
+ 'scope' => self::SCOPE_LOCAL,
+ ],
+
+ [
+ 'name' => self::PROPERTY_BIOGRAPHY,
+ 'value' => '',
+ 'scope' => self::SCOPE_LOCAL,
+ ],
+
+ [
+ 'name' => self::PROPERTY_PROFILE_ENABLED,
+ 'value' => '1',
+ ],
];
}
diff --git a/lib/private/Accounts/TAccountsHelper.php b/lib/private/Accounts/TAccountsHelper.php
index 530204b451f..f3be6523d29 100644
--- a/lib/private/Accounts/TAccountsHelper.php
+++ b/lib/private/Accounts/TAccountsHelper.php
@@ -29,8 +29,12 @@ namespace OC\Accounts;
use OCP\Accounts\IAccountManager;
trait TAccountsHelper {
+ /**
+ * returns whether the property is a collection
+ */
protected function isCollection(string $propertyName): bool {
- return in_array($propertyName,
+ return in_array(
+ $propertyName,
[
IAccountManager::COLLECTION_EMAIL,
],
diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php
index 8ffe54a2575..6e05b7fdc88 100644
--- a/lib/private/AppFramework/Bootstrap/Coordinator.php
+++ b/lib/private/AppFramework/Bootstrap/Coordinator.php
@@ -27,10 +27,14 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\AppFramework\Bootstrap;
-use OC\Support\CrashReport\Registry;
+use function class_exists;
+use function class_implements;
+use function in_array;
use OC_App;
+use OC\Support\CrashReport\Registry;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\QueryException;
@@ -39,9 +43,6 @@ use OCP\EventDispatcher\IEventDispatcher;
use OCP\IServerContainer;
use Psr\Log\LoggerInterface;
use Throwable;
-use function class_exists;
-use function class_implements;
-use function in_array;
class Coordinator {
@@ -66,11 +67,13 @@ class Coordinator {
/** @var string[] */
private $bootedApps = [];
- public function __construct(IServerContainer $container,
- Registry $registry,
- IManager $dashboardManager,
- IEventDispatcher $eventListener,
- LoggerInterface $logger) {
+ public function __construct(
+ IServerContainer $container,
+ Registry $registry,
+ IManager $dashboardManager,
+ IEventDispatcher $eventListener,
+ LoggerInterface $logger
+ ) {
$this->serverContainer = $container;
$this->registry = $registry;
$this->dashboardManager = $dashboardManager;
diff --git a/lib/private/AppFramework/Bootstrap/RegistrationContext.php b/lib/private/AppFramework/Bootstrap/RegistrationContext.php
index 8eed6a5bde4..c638af94c84 100644
--- a/lib/private/AppFramework/Bootstrap/RegistrationContext.php
+++ b/lib/private/AppFramework/Bootstrap/RegistrationContext.php
@@ -26,9 +26,11 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\AppFramework\Bootstrap;
use Closure;
+use function array_shift;
use OC\Support\CrashReport\Registry;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
@@ -43,11 +45,11 @@ use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Template\ICustomTemplateProvider;
use OCP\Http\WellKnown\IHandler;
use OCP\Notification\INotifier;
+use OCP\Profile\ILinkAction;
use OCP\Search\IProvider;
use OCP\Support\CrashReport\IReporter;
use Psr\Log\LoggerInterface;
use Throwable;
-use function array_shift;
class RegistrationContext {
@@ -60,6 +62,9 @@ class RegistrationContext {
/** @var ServiceRegistration<IWidget>[] */
private $dashboardPanels = [];
+ /** @var ServiceRegistration<ILinkAction>[] */
+ private $profileActions = [];
+
/** @var ServiceFactoryRegistration[] */
private $services = [];
@@ -236,6 +241,13 @@ class RegistrationContext {
$class
);
}
+
+ public function registerProfileAction(string $actionClass): void {
+ $this->context->registerProfileAction(
+ $this->appId,
+ $actionClass
+ );
+ }
};
}
@@ -316,6 +328,13 @@ class RegistrationContext {
}
/**
+ * @psalm-param class-string<ILinkAction> $capability
+ */
+ public function registerProfileAction(string $appId, string $actionClass): void {
+ $this->profileActions[] = new ServiceRegistration($appId, $actionClass);
+ }
+
+ /**
* @param App[] $apps
*/
public function delegateCapabilityRegistrations(array $apps): void {
@@ -552,4 +571,11 @@ class RegistrationContext {
public function getCalendarProviders(): array {
return $this->calendarProviders;
}
+
+ /**
+ * @return ServiceRegistration<ILinkAction>[]
+ */
+ public function getProfileActions(): array {
+ return $this->profileActions;
+ }
}
diff --git a/lib/private/Contacts/ContactsMenu/ActionProviderStore.php b/lib/private/Contacts/ContactsMenu/ActionProviderStore.php
index a984f9d6dfb..1db99497a21 100644
--- a/lib/private/Contacts/ContactsMenu/ActionProviderStore.php
+++ b/lib/private/Contacts/ContactsMenu/ActionProviderStore.php
@@ -24,11 +24,13 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Contacts\ContactsMenu;
use Exception;
use OC\App\AppManager;
use OC\Contacts\ContactsMenu\Providers\EMailProvider;
+use OC\Contacts\ContactsMenu\Providers\ProfileProvider;
use OCP\AppFramework\QueryException;
use OCP\Contacts\ContactsMenu\IProvider;
use OCP\IServerContainer;
@@ -67,7 +69,8 @@ class ActionProviderStore {
try {
$providers[] = $this->serverContainer->query($class);
} catch (QueryException $ex) {
- $this->logger->error('Could not load contacts menu action provider ' . $class,
+ $this->logger->error(
+ 'Could not load contacts menu action provider ' . $class,
[
'app' => 'core',
'exception' => $ex,
@@ -85,6 +88,7 @@ class ActionProviderStore {
*/
private function getServerProviderClasses(): array {
return [
+ ProfileProvider::class,
EMailProvider::class,
];
}
diff --git a/lib/private/Contacts/ContactsMenu/ContactsStore.php b/lib/private/Contacts/ContactsMenu/ContactsStore.php
index 31e13bbe8f2..a4a53bf8774 100644
--- a/lib/private/Contacts/ContactsMenu/ContactsStore.php
+++ b/lib/private/Contacts/ContactsMenu/ContactsStore.php
@@ -1,4 +1,5 @@
<?php
+
/**
* @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
* @copyright 2017 Lukas Reschke <lukas@statuscode.ch>
@@ -27,18 +28,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Contacts\ContactsMenu;
use OC\KnownUser\KnownUserService;
+use OCP\Accounts\IAccountManager;
use OCP\Contacts\ContactsMenu\IContactsStore;
use OCP\Contacts\ContactsMenu\IEntry;
use OCP\Contacts\IManager;
use OCP\IConfig;
use OCP\IGroupManager;
+use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
+use OCP\L10N\IFactory as IL10NFactory;
class ContactsStore implements IContactsStore {
+ use \OC\Profile\TProfileHelper;
+
+ /** @var IAccountManager */
+ private $accountManager;
/** @var IManager */
private $contactsManager;
@@ -49,22 +58,36 @@ class ContactsStore implements IContactsStore {
/** @var IUserManager */
private $userManager;
+ /** @var IURLGenerator */
+ private $urlGenerator;
+
/** @var IGroupManager */
private $groupManager;
/** @var KnownUserService */
private $knownUserService;
- public function __construct(IManager $contactsManager,
- IConfig $config,
- IUserManager $userManager,
- IGroupManager $groupManager,
- KnownUserService $knownUserService) {
+ /** @var IL10NFactory */
+ private $l10nFactory;
+
+ public function __construct(
+ IAccountManager $accountManager,
+ IManager $contactsManager,
+ IConfig $config,
+ IUserManager $userManager,
+ IURLGenerator $urlGenerator,
+ IGroupManager $groupManager,
+ KnownUserService $knownUserService,
+ IL10NFactory $l10nFactory
+ ) {
+ $this->accountManager = $accountManager;
$this->contactsManager = $contactsManager;
$this->config = $config;
$this->userManager = $userManager;
+ $this->urlGenerator = $urlGenerator;
$this->groupManager = $groupManager;
$this->knownUserService = $knownUserService;
+ $this->l10nFactory = $l10nFactory;
}
/**
@@ -116,9 +139,11 @@ class ContactsStore implements IContactsStore {
* @param string $filter
* @return Entry[] the filtered contacts
*/
- private function filterContacts(IUser $self,
- array $entries,
- $filter) {
+ private function filterContacts(
+ IUser $self,
+ array $entries,
+ $filter
+ ) {
$disallowEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') !== 'yes';
$restrictEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
$restrictEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
@@ -302,6 +327,19 @@ class ContactsStore implements IContactsStore {
}
}
+ // Provide profile parameters for core/src/OC/contactsmenu/contact.handlebars template
+ if (isset($contact['UID']) && isset($contact['FN'])) {
+ $targetUserId = $contact['UID'];
+ $user = $this->userManager->get($targetUserId);
+ if (!empty($user)) {
+ $account = $this->accountManager->getAccount($user);
+ if ($this->isProfileEnabled($account)) {
+ $entry->setProfileTitle($this->l10nFactory->get('core')->t('View profile'));
+ $entry->setProfileUrl($this->urlGenerator->linkToRouteAbsolute('core.ProfilePage.index', ['targetUserId' => $targetUserId]));
+ }
+ }
+ }
+
// Attach all other properties to the entry too because some
// providers might make use of it.
$entry->setProperties($contact);
diff --git a/lib/private/Contacts/ContactsMenu/Entry.php b/lib/private/Contacts/ContactsMenu/Entry.php
index aea71df2968..915a0434cc8 100644
--- a/lib/private/Contacts/ContactsMenu/Entry.php
+++ b/lib/private/Contacts/ContactsMenu/Entry.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Contacts\ContactsMenu;
use OCP\Contacts\ContactsMenu\IAction;
@@ -43,6 +44,12 @@ class Entry implements IEntry {
/** @var string|null */
private $avatar;
+ /** @var string|null */
+ private $profileTitle;
+
+ /** @var string|null */
+ private $profileUrl;
+
/** @var IAction[] */
private $actions = [];
@@ -99,6 +106,34 @@ class Entry implements IEntry {
}
/**
+ * @param string $profileTitle
+ */
+ public function setProfileTitle(string $profileTitle): void {
+ $this->profileTitle = $profileTitle;
+ }
+
+ /**
+ * @return string
+ */
+ public function getProfileTitle(): ?string {
+ return $this->profileTitle;
+ }
+
+ /**
+ * @param string $profileUrl
+ */
+ public function setProfileUrl(string $profileUrl): void {
+ $this->profileUrl = $profileUrl;
+ }
+
+ /**
+ * @return string
+ */
+ public function getProfileUrl(): ?string {
+ return $this->profileUrl;
+ }
+
+ /**
* @param IAction $action
*/
public function addAction(IAction $action): void {
@@ -166,6 +201,8 @@ class Entry implements IEntry {
'actions' => $otherActions,
'lastMessage' => '',
'emailAddresses' => $this->getEMailAddresses(),
+ 'profileTitle' => $this->profileTitle,
+ 'profileUrl' => $this->profileUrl,
];
}
}
diff --git a/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php b/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php
new file mode 100644
index 00000000000..4882c0ac883
--- /dev/null
+++ b/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Contacts\ContactsMenu\Providers;
+
+use OCP\Accounts\IAccountManager;
+use OCP\Contacts\ContactsMenu\IActionFactory;
+use OCP\Contacts\ContactsMenu\IEntry;
+use OCP\Contacts\ContactsMenu\IProvider;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\L10N\IFactory as IL10NFactory;
+
+class ProfileProvider implements IProvider {
+ use \OC\Profile\TProfileHelper;
+
+ /** @var IAccountManager */
+ private $accountManager;
+
+ /** @var IActionFactory */
+ private $actionFactory;
+
+ /** @var IL10NFactory */
+ private $l10nFactory;
+
+ /** @var IURLGenerator */
+ private $urlGenerator;
+
+ /** @var IUserManager */
+ private $userManager;
+
+ /**
+ * @param IAccountManager $accountManager
+ * @param IActionFactory $actionFactory
+ * @param IL10NFactory $l10nFactory
+ * @param IURLGenerator $urlGenerator
+ * @param IUserManager $userManager
+ */
+ public function __construct(
+ IAccountManager $accountManager,
+ IActionFactory $actionFactory,
+ IL10NFactory $l10nFactory,
+ IURLGenerator $urlGenerator,
+ IUserManager $userManager
+ ) {
+ $this->accountManager = $accountManager;
+ $this->actionFactory = $actionFactory;
+ $this->l10nFactory = $l10nFactory;
+ $this->urlGenerator = $urlGenerator;
+ $this->userManager = $userManager;
+ }
+
+ /**
+ * @param IEntry $entry
+ */
+ public function process(IEntry $entry) {
+ $targetUserId = $entry->getProperty('UID');
+ $targetUser = $this->userManager->get($targetUserId);
+ if (!empty($targetUser)) {
+ $account = $this->accountManager->getAccount($targetUser);
+ if ($this->isProfileEnabled($account)) {
+ $iconUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/profile.svg'));
+ $profileActionText = $this->l10nFactory->get('core')->t('View profile');
+ $profileUrl = $this->urlGenerator->linkToRouteAbsolute('core.ProfilePage.index', ['targetUserId' => $targetUserId]);
+ $action = $this->actionFactory->newLinkAction($iconUrl, $profileActionText, $profileUrl);
+ // Set highest priority (by descending order), other actions have the default priority 10 as defined in lib/private/Contacts/ContactsMenu/Actions/LinkAction.php
+ $action->setPriority(20);
+ $entry->addAction($action);
+ }
+ }
+ }
+}
diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php
index 8aa09ab87bc..a3ff7bf70e2 100644
--- a/lib/private/L10N/Factory.php
+++ b/lib/private/L10N/Factory.php
@@ -37,6 +37,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\L10N;
use OCP\IConfig;
@@ -104,10 +105,12 @@ class Factory implements IFactory {
* @param IUserSession $userSession
* @param string $serverRoot
*/
- public function __construct(IConfig $config,
- IRequest $request,
- IUserSession $userSession,
- $serverRoot) {
+ public function __construct(
+ IConfig $config,
+ IRequest $request,
+ IUserSession $userSession,
+ $serverRoot
+ ) {
$this->config = $config;
$this->request = $request;
$this->userSession = $userSession;
@@ -149,7 +152,10 @@ class Factory implements IFactory {
if (!isset($this->instances[$lang][$app])) {
$this->instances[$lang][$app] = new L10N(
- $this, $app, $lang, $locale,
+ $this,
+ $app,
+ $lang,
+ $locale,
$this->getL10nFilesForApp($app, $lang)
);
}
@@ -391,7 +397,7 @@ class Factory implements IFactory {
* @return bool
*/
public function languageExists($app, $lang) {
- if ($lang === 'en') {//english is always available
+ if ($lang === 'en') { //english is always available
return true;
}
@@ -493,7 +499,8 @@ class Factory implements IFactory {
// use formal version of german ("Sie" instead of "Du") if the default
// language is set to 'de_DE' if possible
- if (is_string($defaultLanguage) &&
+ if (
+ is_string($defaultLanguage) &&
strtolower($lang) === 'de' &&
strtolower($defaultLanguage) === 'de_de' &&
$this->languageExists($app, 'de_DE')
@@ -542,9 +549,9 @@ class Factory implements IFactory {
if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
|| $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
- || $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
- )
- && file_exists($transFile)) {
+ || $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/'))
+ && file_exists($transFile)
+ ) {
// load the translations file
$languageFiles[] = $transFile;
}
@@ -599,9 +606,9 @@ class Factory implements IFactory {
$plural = preg_replace('#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2]);
$body = str_replace(
- [ 'plural', 'n', '$n$plurals', ],
- [ '$plural', '$n', '$nplurals', ],
- 'nplurals='. $nplurals . '; plural=' . $plural
+ ['plural', 'n', '$n$plurals',],
+ ['$plural', '$n', '$nplurals',],
+ 'nplurals=' . $nplurals . '; plural=' . $plural
);
// add parents
@@ -645,12 +652,9 @@ class Factory implements IFactory {
}
/**
- * returns the common language and other languages in an
- * associative array
- *
- * @return array
+ * @inheritDoc
*/
- public function getLanguages() {
+ public function getLanguages(): array {
$forceLanguage = $this->config->getSystemValue('force_language', false);
if ($forceLanguage !== false) {
$l = $this->get('lib', $forceLanguage);
@@ -674,7 +678,7 @@ class Factory implements IFactory {
$l = $this->get('lib', $lang);
// TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
$potentialName = $l->t('__language_name__');
- if ($l->getLanguageCode() === $lang && $potentialName[0] !== '_') {//first check if the language name is in the translation file
+ if ($l->getLanguageCode() === $lang && $potentialName[0] !== '_') { //first check if the language name is in the translation file
$ln = [
'code' => $lang,
'name' => $potentialName
@@ -684,7 +688,7 @@ class Factory implements IFactory {
'code' => $lang,
'name' => 'English (US)'
];
- } else {//fallback to language code
+ } else { //fallback to language code
$ln = [
'code' => $lang,
'name' => $lang
diff --git a/lib/private/Profile/Actions/EmailAction.php b/lib/private/Profile/Actions/EmailAction.php
new file mode 100644
index 00000000000..1eef1236630
--- /dev/null
+++ b/lib/private/Profile/Actions/EmailAction.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Profile\Actions;
+
+use OCP\Accounts\IAccountManager;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\L10N\IFactory;
+use OCP\Profile\ILinkAction;
+
+class EmailAction implements ILinkAction {
+
+ /** @var string */
+ private $value;
+
+ /** @var IAccountManager */
+ private $accountManager;
+
+ /** @var IFactory */
+ private $l10nFactory;
+
+ /** @var IUrlGenerator */
+ private $urlGenerator;
+
+ public function __construct(
+ IAccountManager $accountManager,
+ IFactory $l10nFactory,
+ IURLGenerator $urlGenerator
+ ) {
+ $this->accountManager = $accountManager;
+ $this->l10nFactory = $l10nFactory;
+ $this->urlGenerator = $urlGenerator;
+ }
+
+ public function preload(IUser $targetUser): void {
+ $account = $this->accountManager->getAccount($targetUser);
+ $this->value = $account->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue();
+ }
+
+ public function getAppId(): string {
+ return 'core';
+ }
+
+ public function getId(): string {
+ return IAccountManager::PROPERTY_EMAIL;
+ }
+
+ public function getDisplayId(): string {
+ return $this->l10nFactory->get('core')->t('Email');
+ }
+
+ public function getTitle(): string {
+ return $this->l10nFactory->get('core')->t('Mail %s', [$this->value]);
+ }
+
+ public function getPriority(): int {
+ return 20;
+ }
+
+ public function getIcon(): string {
+ return $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/mail.svg'));
+ }
+
+ public function getTarget(): ?string {
+ if (empty($this->value)) {
+ return null;
+ }
+ return 'mailto:' . $this->value;
+ }
+}
diff --git a/lib/private/Profile/Actions/PhoneAction.php b/lib/private/Profile/Actions/PhoneAction.php
new file mode 100644
index 00000000000..df0e30cd277
--- /dev/null
+++ b/lib/private/Profile/Actions/PhoneAction.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Profile\Actions;
+
+use OCP\Accounts\IAccountManager;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\L10N\IFactory;
+use OCP\Profile\ILinkAction;
+
+class PhoneAction implements ILinkAction {
+
+ /** @var string */
+ private $value;
+
+ /** @var IAccountManager */
+ private $accountManager;
+
+ /** @var IFactory */
+ private $l10nFactory;
+
+ /** @var IUrlGenerator */
+ private $urlGenerator;
+
+ public function __construct(
+ IAccountManager $accountManager,
+ IFactory $l10nFactory,
+ IURLGenerator $urlGenerator
+ ) {
+ $this->accountManager = $accountManager;
+ $this->l10nFactory = $l10nFactory;
+ $this->urlGenerator = $urlGenerator;
+ }
+
+ public function preload(IUser $targetUser): void {
+ $account = $this->accountManager->getAccount($targetUser);
+ $this->value = $account->getProperty(IAccountManager::PROPERTY_PHONE)->getValue();
+ }
+
+ public function getAppId(): string {
+ return 'core';
+ }
+
+ public function getId(): string {
+ return IAccountManager::PROPERTY_PHONE;
+ }
+
+ public function getDisplayId(): string {
+ return $this->l10nFactory->get('core')->t('Phone');
+ }
+
+ public function getTitle(): string {
+ return $this->l10nFactory->get('core')->t('Call %s', [$this->value]);
+ }
+
+ public function getPriority(): int {
+ return 30;
+ }
+
+ public function getIcon(): string {
+ return $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/phone.svg'));
+ }
+
+ public function getTarget(): ?string {
+ if (empty($this->value)) {
+ return null;
+ }
+ return 'tel:' . $this->value;
+ }
+}
diff --git a/lib/private/Profile/Actions/TwitterAction.php b/lib/private/Profile/Actions/TwitterAction.php
new file mode 100644
index 00000000000..3dcfa8aaf12
--- /dev/null
+++ b/lib/private/Profile/Actions/TwitterAction.php
@@ -0,0 +1,97 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Profile\Actions;
+
+use function Safe\substr;
+use OCP\Accounts\IAccountManager;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\L10N\IFactory;
+use OCP\Profile\ILinkAction;
+
+class TwitterAction implements ILinkAction {
+
+ /** @var string */
+ private $value;
+
+ /** @var IAccountManager */
+ private $accountManager;
+
+ /** @var IFactory */
+ private $l10nFactory;
+
+ /** @var IUrlGenerator */
+ private $urlGenerator;
+
+ public function __construct(
+ IAccountManager $accountManager,
+ IFactory $l10nFactory,
+ IURLGenerator $urlGenerator
+ ) {
+ $this->accountManager = $accountManager;
+ $this->l10nFactory = $l10nFactory;
+ $this->urlGenerator = $urlGenerator;
+ }
+
+ public function preload(IUser $targetUser): void {
+ $account = $this->accountManager->getAccount($targetUser);
+ $this->value = $account->getProperty(IAccountManager::PROPERTY_TWITTER)->getValue();
+ }
+
+ public function getAppId(): string {
+ return 'core';
+ }
+
+ public function getId(): string {
+ return IAccountManager::PROPERTY_TWITTER;
+ }
+
+ public function getDisplayId(): string {
+ return $this->l10nFactory->get('core')->t('Twitter');
+ }
+
+ public function getTitle(): string {
+ $displayUsername = $this->value[0] === '@' ? $this->value : '@' . $this->value;
+ return $this->l10nFactory->get('core')->t('View %s on Twitter', [$displayUsername]);
+ }
+
+ public function getPriority(): int {
+ return 50;
+ }
+
+ public function getIcon(): string {
+ return $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/twitter.svg'));
+ }
+
+ public function getTarget(): ?string {
+ if (empty($this->value)) {
+ return null;
+ }
+ $username = $this->value[0] === '@' ? substr($this->value, 1) : $this->value;
+ return 'https://twitter.com/' . $username;
+ }
+}
diff --git a/lib/private/Profile/Actions/WebsiteAction.php b/lib/private/Profile/Actions/WebsiteAction.php
new file mode 100644
index 00000000000..ea1daeee20e
--- /dev/null
+++ b/lib/private/Profile/Actions/WebsiteAction.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Profile\Actions;
+
+use OCP\Accounts\IAccountManager;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\L10N\IFactory;
+use OCP\Profile\ILinkAction;
+
+class WebsiteAction implements ILinkAction {
+
+ /** @var string */
+ private $value;
+
+ /** @var IAccountManager */
+ private $accountManager;
+
+ /** @var IFactory */
+ private $l10nFactory;
+
+ /** @var IUrlGenerator */
+ private $urlGenerator;
+
+ public function __construct(
+ IAccountManager $accountManager,
+ IFactory $l10nFactory,
+ IURLGenerator $urlGenerator
+ ) {
+ $this->accountManager = $accountManager;
+ $this->l10nFactory = $l10nFactory;
+ $this->urlGenerator = $urlGenerator;
+ }
+
+ public function preload(IUser $targetUser): void {
+ $account = $this->accountManager->getAccount($targetUser);
+ $this->value = $account->getProperty(IAccountManager::PROPERTY_WEBSITE)->getValue();
+ }
+
+ public function getAppId(): string {
+ return 'core';
+ }
+
+ public function getId(): string {
+ return IAccountManager::PROPERTY_WEBSITE;
+ }
+
+ public function getDisplayId(): string {
+ return $this->l10nFactory->get('core')->t('Website');
+ }
+
+ public function getTitle(): string {
+ return $this->l10nFactory->get('core')->t('Visit %s', [$this->value]);
+ }
+
+ public function getPriority(): int {
+ return 40;
+ }
+
+ public function getIcon(): string {
+ return $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/timezone.svg'));
+ }
+
+ public function getTarget(): ?string {
+ if (empty($this->value)) {
+ return null;
+ }
+ return $this->value;
+ }
+}
diff --git a/lib/private/Profile/ProfileManager.php b/lib/private/Profile/ProfileManager.php
new file mode 100644
index 00000000000..6a38f4ae16d
--- /dev/null
+++ b/lib/private/Profile/ProfileManager.php
@@ -0,0 +1,333 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Profile;
+
+use function Safe\usort;
+
+use OC\AppFramework\Bootstrap\Coordinator;
+use OC\Core\Db\ProfileConfig;
+use OC\Core\Db\ProfileConfigMapper;
+use OC\KnownUser\KnownUserService;
+use OC\Profile\Actions\EmailAction;
+use OC\Profile\Actions\PhoneAction;
+use OC\Profile\Actions\TwitterAction;
+use OC\Profile\Actions\WebsiteAction;
+use OCP\Accounts\IAccountManager;
+use OCP\Accounts\PropertyDoesNotExistException;
+use OCP\App\IAppManager;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\IUser;
+use OCP\L10N\IFactory;
+use OCP\Profile\ILinkAction;
+use Psr\Container\ContainerInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * @inheritDoc
+ */
+class ProfileManager {
+
+ /** @var IAccountManager */
+ private $accountManager;
+
+ /** @var IAppManager */
+ private $appManager;
+
+ /** @var ProfileConfigMapper */
+ private $configMapper;
+
+ /** @var ContainerInterface */
+ private $container;
+
+ /** @var KnownUserService */
+ private $knownUserService;
+
+ /** @var IFactory */
+ private $l10nFactory;
+
+ /** @var LoggerInterface */
+ private $logger;
+
+ /** @var Coordinator */
+ private $coordinator;
+
+ /** @var ILinkAction[] */
+ private $actions = [];
+
+ private const ACCOUNT_PROPERTY_ACTIONS = [
+ EmailAction::class,
+ PhoneAction::class,
+ WebsiteAction::class,
+ TwitterAction::class,
+ ];
+
+ /**
+ * Array of account properties displayed on the profile
+ */
+ private const PROFILE_PROPERTIES = [
+ IAccountManager::PROPERTY_ADDRESS,
+ IAccountManager::PROPERTY_BIOGRAPHY,
+ IAccountManager::PROPERTY_DISPLAYNAME,
+ IAccountManager::PROPERTY_HEADLINE,
+ IAccountManager::PROPERTY_ORGANISATION,
+ IAccountManager::PROPERTY_ROLE,
+ ];
+
+ public function __construct(
+ IAccountManager $accountManager,
+ IAppManager $appManager,
+ ProfileConfigMapper $configMapper,
+ ContainerInterface $container,
+ KnownUserService $knownUserService,
+ IFactory $l10nFactory,
+ LoggerInterface $logger,
+ Coordinator $coordinator
+ ) {
+ $this->accountManager = $accountManager;
+ $this->appManager = $appManager;
+ $this->configMapper = $configMapper;
+ $this->container = $container;
+ $this->knownUserService = $knownUserService;
+ $this->l10nFactory = $l10nFactory;
+ $this->logger = $logger;
+ $this->coordinator = $coordinator;
+ }
+
+ /**
+ * Register an action for the user
+ */
+ private function registerAction(IUser $targetUser, ?IUser $visitingUser, ILinkAction $action): void {
+ $action->preload($targetUser);
+
+ if ($action->getTarget() === null) {
+ // Actions without a target are not registered
+ return;
+ }
+
+ if (isset($this->actions[$action->getId()])) {
+ $this->logger->error('Cannot register duplicate action: ' . $action->getId());
+ return;
+ }
+
+ if ($action->getAppId() !== 'core') {
+ 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');
+ return;
+ }
+ if (!$this->appManager->isEnabledForUser($action->getAppId(), $visitingUser)) {
+ $this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the visiting user: ' . $visitingUser->getUID());
+ return;
+ }
+ }
+
+ // Add action to associative array of actions
+ $this->actions[$action->getId()] = $action;
+ }
+
+ /**
+ * Return an array of registered profile actions for the user
+ *
+ * @return ILinkAction[]
+ */
+ private function getActions(IUser $targetUser, ?IUser $visitingUser): array {
+ $context = $this->coordinator->getRegistrationContext();
+ if ($context === null) {
+ return [];
+ }
+
+ foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
+ /** @var ILinkAction $provider */
+ $provider = $this->container->get($actionClass);
+ $this->registerAction($targetUser, $visitingUser, $provider);
+ }
+
+ foreach ($context->getProfileActions() as $registration) {
+ /** @var ILinkAction $provider */
+ $provider = $this->container->get($registration->getService());
+ $this->registerAction($targetUser, $visitingUser, $provider);
+ }
+
+ $actionsClone = $this->actions;
+ // Sort associative array into indexed array in ascending order of priority
+ usort($actionsClone, function (ILinkAction $a, ILinkAction $b) {
+ return $a->getPriority() === $b->getPriority() ? 0 : ($a->getPriority() < $b->getPriority() ? -1 : 1);
+ });
+ return $actionsClone;
+ }
+
+ /**
+ * Return whether the profile parameter is visible to the visiting user
+ */
+ private function isParameterVisible(IUser $targetUser, ?IUser $visitingUser, string $paramId): bool {
+ try {
+ $account = $this->accountManager->getAccount($targetUser);
+ $scope = $account->getProperty($paramId)->getScope();
+ } catch (PropertyDoesNotExistException $e) {
+ // Allow the exception as not all profile parameters are account properties
+ }
+
+ $visibility = $this->getProfileConfig($targetUser, $visitingUser)[$paramId]['visibility'];
+ // Handle profile visibility and account property scope
+ switch ($visibility) {
+ case ProfileConfig::VISIBILITY_HIDE:
+ return false;
+ case ProfileConfig::VISIBILITY_SHOW_USERS_ONLY:
+ if (!empty($scope)) {
+ switch ($scope) {
+ case IAccountManager::SCOPE_PRIVATE:
+ return $visitingUser !== null && $this->knownUserService->isKnownToUser($targetUser->getUID(), $visitingUser->getUID());
+ case IAccountManager::SCOPE_LOCAL:
+ case IAccountManager::SCOPE_FEDERATED:
+ case IAccountManager::SCOPE_PUBLISHED:
+ return $visitingUser !== null;
+ default:
+ return false;
+ }
+ }
+ return $visitingUser !== null;
+ case ProfileConfig::VISIBILITY_SHOW:
+ if (!empty($scope)) {
+ switch ($scope) {
+ case IAccountManager::SCOPE_PRIVATE:
+ return $visitingUser !== null && $this->knownUserService->isKnownToUser($targetUser->getUID(), $visitingUser->getUID());
+ case IAccountManager::SCOPE_LOCAL:
+ case IAccountManager::SCOPE_FEDERATED:
+ case IAccountManager::SCOPE_PUBLISHED:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getProfileParams(IUser $targetUser, ?IUser $visitingUser): array {
+ $account = $this->accountManager->getAccount($targetUser);
+ // Initialize associative array of profile parameters
+ $profileParameters = [
+ 'userId' => $account->getUser()->getUID(),
+ ];
+
+ // Add account properties
+ foreach (self::PROFILE_PROPERTIES as $property) {
+ $profileParameters[$property] =
+ $this->isParameterVisible($targetUser, $visitingUser, $property)
+ // Explicitly set to null when value is empty string
+ ? ($account->getProperty($property)->getValue() ?: null)
+ : null;
+ }
+
+ // Add avatar visibility
+ $profileParameters['isUserAvatarVisible'] = $this->isParameterVisible($targetUser, $visitingUser, IAccountManager::PROPERTY_AVATAR);
+
+ // Add actions
+ $profileParameters['actions'] = array_map(
+ function (ILinkAction $action) {
+ return [
+ 'id' => $action->getId(),
+ 'icon' => $action->getIcon(),
+ 'title' => $action->getTitle(),
+ 'target' => $action->getTarget(),
+ ];
+ },
+ // This is needed to reindex the array after filtering
+ array_values(
+ array_filter(
+ $this->getActions($targetUser, $visitingUser),
+ function (ILinkAction $action) use ($targetUser, $visitingUser) {
+ return $this->isParameterVisible($targetUser, $visitingUser, $action->getId());
+ }
+ ),
+ )
+ );
+
+ return $profileParameters;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getProfileConfig(IUser $targetUser, ?IUser $visitingUser): array {
+ try {
+ $configArray = $this->configMapper->getArray($targetUser->getUID());
+ } catch (DoesNotExistException $e) {
+ $config = new ProfileConfig();
+ $config->setUserId($targetUser->getUID());
+
+ // 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] ?: ProfileConfig::DEFAULT_VISIBILITY,
+ ];
+ }
+
+ // Contruct the default config for actions
+ $actionsConfig = [];
+ /** @var ILinkAction $action */
+ foreach ($this->getActions($targetUser, $visitingUser) as $action) {
+ $actionsConfig[$action->getId()] = [
+ 'displayId' => $action->getDisplayId(),
+ 'visibility' => ProfileConfig::DEFAULT_VISIBILITY,
+ ];
+ }
+
+ // Set the default config
+ $config->setConfigArray(array_merge($propertiesConfig, $actionsConfig));
+ $this->configMapper->insert($config);
+ $configArray = $config->getConfigArray();
+ }
+
+ return $configArray;
+ }
+}
diff --git a/lib/private/Profile/TProfileHelper.php b/lib/private/Profile/TProfileHelper.php
new file mode 100644
index 00000000000..0d4b5c6286e
--- /dev/null
+++ b/lib/private/Profile/TProfileHelper.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Profile;
+
+use OCP\Accounts\IAccount;
+use OCP\Accounts\IAccountManager;
+
+trait TProfileHelper {
+
+ /**
+ * Returns whether the profile is enabled for the account
+ *
+ * @since 23.0.0
+ */
+ protected function isProfileEnabled(IAccount $account): ?bool {
+ return filter_var(
+ $account->getProperty(IAccountManager::PROPERTY_PROFILE_ENABLED)->getValue(),
+ FILTER_VALIDATE_BOOLEAN,
+ FILTER_NULL_ON_FAILURE,
+ );
+ }
+}
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index c24d417f8cf..a7f0f190fa2 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -425,6 +425,9 @@ class Setup {
//and we are done
$config->setSystemValue('installed', true);
+ $bootstrapCoordinator = \OC::$server->query(\OC\AppFramework\Bootstrap\Coordinator::class);
+ $bootstrapCoordinator->runInitialRegistration();
+
// Create a session token for the newly created user
// The token provider requires a working db, so it's not injected on setup
/* @var $userSession User\Session */
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
index 0543427f997..c1bd556de60 100644
--- a/lib/private/Template/SCSSCacher.php
+++ b/lib/private/Template/SCSSCacher.php
@@ -32,6 +32,7 @@ namespace OC\Template;
use OC\AppConfig;
use OC\Files\AppData\Factory;
use OC\Memcache\NullCache;
+use OCA\Theming\ThemingDefaults;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
@@ -62,7 +63,7 @@ class SCSSCacher {
/** @var IConfig */
protected $config;
- /** @var \OC_Defaults */
+ /** @var ThemingDefaults */
private $defaults;
/** @var string */
@@ -96,7 +97,7 @@ class SCSSCacher {
* @param Factory $appDataFactory
* @param IURLGenerator $urlGenerator
* @param IConfig $config
- * @param \OC_Defaults $defaults
+ * @param ThemingDefaults $defaults
* @param string $serverRoot
* @param ICacheFactory $cacheFactory
* @param IconsCacher $iconsCacher
@@ -106,7 +107,7 @@ class SCSSCacher {
Factory $appDataFactory,
IURLGenerator $urlGenerator,
IConfig $config,
- \OC_Defaults $defaults,
+ ThemingDefaults $defaults,
$serverRoot,
ICacheFactory $cacheFactory,
IconsCacher $iconsCacher,
@@ -406,7 +407,7 @@ class SCSSCacher {
}
/**
- * @return string SCSS code for variables from OC_Defaults
+ * @return string SCSS code for variables from ThemingDefaults
*/
private function getInjectedVariables(string $cache = ''): string {
if ($this->injectedVariables !== null) {