diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 1 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 1 | ||||
-rw-r--r-- | lib/l10n/es.js | 7 | ||||
-rw-r--r-- | lib/l10n/es.json | 7 | ||||
-rw-r--r-- | lib/private/Accounts/AccountManager.php | 58 | ||||
-rw-r--r-- | lib/private/AppFramework/App.php | 32 | ||||
-rw-r--r-- | lib/private/AppFramework/DependencyInjection/DIContainer.php | 4 | ||||
-rw-r--r-- | lib/private/AppFramework/Utility/SimpleContainer.php | 4 | ||||
-rw-r--r-- | lib/private/DB/Connection.php | 9 | ||||
-rw-r--r-- | lib/private/DB/ConnectionAdapter.php | 6 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/QueryBuilder.php | 2 | ||||
-rw-r--r-- | lib/private/Profile/Actions/BlueskyAction.php | 65 | ||||
-rw-r--r-- | lib/private/Profile/ProfileManager.php | 2 | ||||
-rw-r--r-- | lib/public/Accounts/IAccountManager.php | 7 | ||||
-rw-r--r-- | lib/public/IDBConnection.php | 13 | ||||
-rw-r--r-- | lib/public/Profile/IProfileManager.php | 1 |
16 files changed, 183 insertions, 36 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index fda8798fe43..ab0f12233d4 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -1904,6 +1904,7 @@ return array( 'OC\\Preview\\WatcherConnector' => $baseDir . '/lib/private/Preview/WatcherConnector.php', 'OC\\Preview\\WebP' => $baseDir . '/lib/private/Preview/WebP.php', 'OC\\Preview\\XBitmap' => $baseDir . '/lib/private/Preview/XBitmap.php', + 'OC\\Profile\\Actions\\BlueskyAction' => $baseDir . '/lib/private/Profile/Actions/BlueskyAction.php', 'OC\\Profile\\Actions\\EmailAction' => $baseDir . '/lib/private/Profile/Actions/EmailAction.php', 'OC\\Profile\\Actions\\FediverseAction' => $baseDir . '/lib/private/Profile/Actions/FediverseAction.php', 'OC\\Profile\\Actions\\PhoneAction' => $baseDir . '/lib/private/Profile/Actions/PhoneAction.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 69e3c41284b..3d32ee7e567 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -1945,6 +1945,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Preview\\WatcherConnector' => __DIR__ . '/../../..' . '/lib/private/Preview/WatcherConnector.php', 'OC\\Preview\\WebP' => __DIR__ . '/../../..' . '/lib/private/Preview/WebP.php', 'OC\\Preview\\XBitmap' => __DIR__ . '/../../..' . '/lib/private/Preview/XBitmap.php', + 'OC\\Profile\\Actions\\BlueskyAction' => __DIR__ . '/../../..' . '/lib/private/Profile/Actions/BlueskyAction.php', 'OC\\Profile\\Actions\\EmailAction' => __DIR__ . '/../../..' . '/lib/private/Profile/Actions/EmailAction.php', 'OC\\Profile\\Actions\\FediverseAction' => __DIR__ . '/../../..' . '/lib/private/Profile/Actions/FediverseAction.php', 'OC\\Profile\\Actions\\PhoneAction' => __DIR__ . '/../../..' . '/lib/private/Profile/Actions/PhoneAction.php', diff --git a/lib/l10n/es.js b/lib/l10n/es.js index 9c7ea8f5f41..a01ed7e43b8 100644 --- a/lib/l10n/es.js +++ b/lib/l10n/es.js @@ -275,6 +275,7 @@ OC.L10N.register( "A valid Login must be provided" : "Se debe proporcionar un usuario válido", "Login contains whitespace at the beginning or at the end" : "El usuario contiene espacios en blanco al inicio o al final", "Login must not consist of dots only" : "El usuario no debe consistir sólo de puntos", + "Username is too long" : "El nombre de usuario es demasiado largo", "Login is invalid because files already exist for this user" : "El nombre de inicio de sesión es inválido porque ya existen archivos para este usuario", "Account disabled" : "Cuenta deshabilitada", "Login canceled by app" : "Login cancelado por la app", @@ -328,13 +329,17 @@ OC.L10N.register( "Images" : "Imágenes", "Images to ask a question about" : "Imágenes sobre las cuales se formulará una pregunta", "Question" : "Pregunta", + "What to ask about the images." : "Que preguntar sobre las imágenes.", "Generated response" : "Respuesta generada", "The answer to the question" : "La respuesta a la pregunta", + "Audio chat" : "Chat de audio", "Voice chat with the assistant" : "Chat de voz con el asistente", "System prompt" : "Prompt del sistema", "Define rules and assumptions that the assistant should follow during the conversation." : "Definir las reglas y supuestos que el asistente debe seguir durante la conversación.", "Chat voice message" : "Mensaje de voz del chat", + "Describe a task that you want the assistant to do or ask a question." : "Describa una tarea que desea que el asistente realice o haga una pregunta.", "Chat history" : "Historial de la conversación", + "The history of chat messages before the current message, starting with a message by the user." : "El historial de mensajes de chat anterior al mensaje actual, comenzando con un mensaje de parte del usuario.", "Input transcript" : "Transcripción de entrada", "Transcription of the audio input" : "Transcripción de la entrada de audio", "Response voice message" : "Mensaje de voz de respuesta", @@ -347,6 +352,8 @@ OC.L10N.register( "The audio to transcribe" : "El audio a transcribir", "Transcription" : "Transcripción", "The transcribed text" : "El texto transcrito", + "Chat by voice with an agent" : "Chatear a través de voz con un agente", + "Describe a task that you want the agent to do or ask a question." : "Describa una tarea que desea que el asistente realice o haga una pregunta.", "Confirmation" : "Confirmación", "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Si se deben confirmar acciones solicitadas anteriormente: 0 para denegar y 1 para confirmar.", "Conversation token" : "Token de conversación", diff --git a/lib/l10n/es.json b/lib/l10n/es.json index 29ee23631f9..fc43c0e1d91 100644 --- a/lib/l10n/es.json +++ b/lib/l10n/es.json @@ -273,6 +273,7 @@ "A valid Login must be provided" : "Se debe proporcionar un usuario válido", "Login contains whitespace at the beginning or at the end" : "El usuario contiene espacios en blanco al inicio o al final", "Login must not consist of dots only" : "El usuario no debe consistir sólo de puntos", + "Username is too long" : "El nombre de usuario es demasiado largo", "Login is invalid because files already exist for this user" : "El nombre de inicio de sesión es inválido porque ya existen archivos para este usuario", "Account disabled" : "Cuenta deshabilitada", "Login canceled by app" : "Login cancelado por la app", @@ -326,13 +327,17 @@ "Images" : "Imágenes", "Images to ask a question about" : "Imágenes sobre las cuales se formulará una pregunta", "Question" : "Pregunta", + "What to ask about the images." : "Que preguntar sobre las imágenes.", "Generated response" : "Respuesta generada", "The answer to the question" : "La respuesta a la pregunta", + "Audio chat" : "Chat de audio", "Voice chat with the assistant" : "Chat de voz con el asistente", "System prompt" : "Prompt del sistema", "Define rules and assumptions that the assistant should follow during the conversation." : "Definir las reglas y supuestos que el asistente debe seguir durante la conversación.", "Chat voice message" : "Mensaje de voz del chat", + "Describe a task that you want the assistant to do or ask a question." : "Describa una tarea que desea que el asistente realice o haga una pregunta.", "Chat history" : "Historial de la conversación", + "The history of chat messages before the current message, starting with a message by the user." : "El historial de mensajes de chat anterior al mensaje actual, comenzando con un mensaje de parte del usuario.", "Input transcript" : "Transcripción de entrada", "Transcription of the audio input" : "Transcripción de la entrada de audio", "Response voice message" : "Mensaje de voz de respuesta", @@ -345,6 +350,8 @@ "The audio to transcribe" : "El audio a transcribir", "Transcription" : "Transcripción", "The transcribed text" : "El texto transcrito", + "Chat by voice with an agent" : "Chatear a través de voz con un agente", + "Describe a task that you want the agent to do or ask a question." : "Describa una tarea que desea que el asistente realice o haga una pregunta.", "Confirmation" : "Confirmación", "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Si se deben confirmar acciones solicitadas anteriormente: 0 para denegar y 1 para confirmar.", "Conversation token" : "Token de conversación", diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php index 9c7c35d4a6b..d00b1d2e9a3 100644 --- a/lib/private/Accounts/AccountManager.php +++ b/lib/private/Accounts/AccountManager.php @@ -78,6 +78,7 @@ class AccountManager implements IAccountManager { self::PROPERTY_PRONOUNS => self::SCOPE_FEDERATED, self::PROPERTY_ROLE => self::SCOPE_LOCAL, self::PROPERTY_TWITTER => self::SCOPE_LOCAL, + self::PROPERTY_BLUESKY => self::SCOPE_LOCAL, self::PROPERTY_WEBSITE => self::SCOPE_LOCAL, ]; @@ -564,6 +565,13 @@ class AccountManager implements IAccountManager { ], [ + 'name' => self::PROPERTY_BLUESKY, + 'value' => '', + 'scope' => $scopes[self::PROPERTY_BLUESKY], + 'verified' => self::NOT_VERIFIED, + ], + + [ 'name' => self::PROPERTY_FEDIVERSE, 'value' => '', 'scope' => $scopes[self::PROPERTY_FEDIVERSE], @@ -713,6 +721,47 @@ class AccountManager implements IAccountManager { } } + private function validateBlueSkyHandle(string $text): bool { + if ($text === '') { + return true; + } + + $lowerText = strtolower($text); + + if ($lowerText === 'bsky.social') { + // "bsky.social" itself is not a valid handle + return false; + } + + if (str_ends_with($lowerText, '.bsky.social')) { + $parts = explode('.', $lowerText); + + // Must be exactly: username.bsky.social → 3 parts + if (count($parts) !== 3 || $parts[1] !== 'bsky' || $parts[2] !== 'social') { + return false; + } + + $username = $parts[0]; + + // Must be 3–18 chars, alphanumeric/hyphen, no start/end hyphen + return preg_match('/^[a-z0-9][a-z0-9-]{2,17}$/', $username) === 1; + } + + // Allow custom domains (Bluesky handle via personal domain) + return filter_var($text, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) !== false; + } + + + private function sanitizePropertyBluesky(IAccountProperty $property): void { + if ($property->getName() === self::PROPERTY_BLUESKY) { + if (!$this->validateBlueSkyHandle($property->getValue())) { + throw new InvalidArgumentException(self::PROPERTY_BLUESKY); + } + + $property->setValue($property->getValue()); + } + } + /** * @throws InvalidArgumentException If the property value is not a valid fediverse handle (username@instance where instance is a valid domain) */ @@ -805,6 +854,15 @@ class AccountManager implements IAccountManager { } try { + $property = $account->getProperty(self::PROPERTY_BLUESKY); + if ($property->getValue() !== '') { + $this->sanitizePropertyBluesky($property); + } + } catch (PropertyDoesNotExistException $e) { + // valid case, nothing to do + } + + try { $property = $account->getProperty(self::PROPERTY_FEDIVERSE); if ($property->getValue() !== '') { $this->sanitizePropertyFediverse($property); diff --git a/lib/private/AppFramework/App.php b/lib/private/AppFramework/App.php index 77135986d5f..7bf32852209 100644 --- a/lib/private/AppFramework/App.php +++ b/lib/private/AppFramework/App.php @@ -71,7 +71,6 @@ class App { return null; } - /** * Shortcut for calling a controller method and printing the result * @@ -82,7 +81,12 @@ class App { * @param array $urlParams list of URL parameters (optional) * @throws HintException */ - public static function main(string $controllerName, string $methodName, DIContainer $container, ?array $urlParams = null) { + public static function main( + string $controllerName, + string $methodName, + DIContainer $container, + ?array $urlParams = null, + ): void { /** @var IProfiler $profiler */ $profiler = $container->get(IProfiler::class); $eventLogger = $container->get(IEventLogger::class); @@ -134,8 +138,7 @@ class App { $eventLogger->start('app:controller:dispatcher', 'Initialize dispatcher and pre-middleware'); // initialize the dispatcher and run all the middleware before the controller - /** @var Dispatcher $dispatcher */ - $dispatcher = $container['Dispatcher']; + $dispatcher = $container->get(Dispatcher::class); $eventLogger->end('app:controller:dispatcher'); @@ -211,25 +214,4 @@ class App { } } } - - /** - * Shortcut for calling a controller method and printing the result. - * Similar to App:main except that no headers will be sent. - * - * @param string $controllerName the name of the controller under which it is - * stored in the DI container - * @param string $methodName the method that you want to call - * @param array $urlParams an array with variables extracted from the routes - * @param DIContainer $container an instance of a pimple container. - */ - public static function part(string $controllerName, string $methodName, array $urlParams, - DIContainer $container) { - $container['urlParams'] = $urlParams; - $controller = $container[$controllerName]; - - $dispatcher = $container['Dispatcher']; - - [, , $output] = $dispatcher->dispatch($controller, $methodName); - return $output; - } } diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index 5ccc1b7d348..0bce8ac193b 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -63,7 +63,7 @@ use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; class DIContainer extends SimpleContainer implements IAppContainer { - private string $appName; + protected string $appName; private array $middleWares = []; private ServerContainer $server; @@ -152,7 +152,7 @@ class DIContainer extends SimpleContainer implements IAppContainer { $this->registerDeprecatedAlias('Dispatcher', Dispatcher::class); $this->registerService(Dispatcher::class, function (ContainerInterface $c) { return new Dispatcher( - $c->get('Protocol'), + $c->get(Http::class), $c->get(MiddlewareDispatcher::class), $c->get(IControllerMethodReflector::class), $c->get(IRequest::class), diff --git a/lib/private/AppFramework/Utility/SimpleContainer.php b/lib/private/AppFramework/Utility/SimpleContainer.php index ed26e75ec89..0db3bfc1c77 100644 --- a/lib/private/AppFramework/Utility/SimpleContainer.php +++ b/lib/private/AppFramework/Utility/SimpleContainer.php @@ -196,7 +196,9 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer { $this->registerService($alias, function (ContainerInterface $container) use ($target, $alias): mixed { try { $logger = $container->get(LoggerInterface::class); - $logger->debug('The requested alias "' . $alias . '" is deprecated. Please request "' . $target . '" directly. This alias will be removed in a future Nextcloud version.', ['app' => 'serverDI']); + $logger->debug('The requested alias "' . $alias . '" is deprecated. Please request "' . $target . '" directly. This alias will be removed in a future Nextcloud version.', [ + 'app' => $this->appName ?? 'serverDI', + ]); } catch (ContainerExceptionInterface $e) { // Could not get logger. Continue } diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php index 88bdc377e2b..f86cbc341a4 100644 --- a/lib/private/DB/Connection.php +++ b/lib/private/DB/Connection.php @@ -16,6 +16,7 @@ use Doctrine\DBAL\Driver; use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception\ConnectionLost; +use Doctrine\DBAL\Platforms\MariaDBPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform; @@ -915,11 +916,13 @@ class Connection extends PrimaryReadReplicaConnection { } /** - * @return IDBConnection::PLATFORM_MYSQL|IDBConnection::PLATFORM_ORACLE|IDBConnection::PLATFORM_POSTGRES|IDBConnection::PLATFORM_SQLITE + * @return IDBConnection::PLATFORM_MYSQL|IDBConnection::PLATFORM_ORACLE|IDBConnection::PLATFORM_POSTGRES|IDBConnection::PLATFORM_SQLITE|IDBConnection::PLATFORM_MARIADB */ - public function getDatabaseProvider(): string { + public function getDatabaseProvider(bool $strict = false): string { $platform = $this->getDatabasePlatform(); - if ($platform instanceof MySQLPlatform) { + if ($strict && $platform instanceof MariaDBPlatform) { + return IDBConnection::PLATFORM_MARIADB; + } elseif ($platform instanceof MySQLPlatform) { return IDBConnection::PLATFORM_MYSQL; } elseif ($platform instanceof OraclePlatform) { return IDBConnection::PLATFORM_ORACLE; diff --git a/lib/private/DB/ConnectionAdapter.php b/lib/private/DB/ConnectionAdapter.php index 78ca780f218..d9ccb3c54f2 100644 --- a/lib/private/DB/ConnectionAdapter.php +++ b/lib/private/DB/ConnectionAdapter.php @@ -237,10 +237,10 @@ class ConnectionAdapter implements IDBConnection { } /** - * @return self::PLATFORM_MYSQL|self::PLATFORM_ORACLE|self::PLATFORM_POSTGRES|self::PLATFORM_SQLITE + * @return self::PLATFORM_MYSQL|self::PLATFORM_ORACLE|self::PLATFORM_POSTGRES|self::PLATFORM_SQLITE|self::PLATFORM_MARIADB */ - public function getDatabaseProvider(): string { - return $this->inner->getDatabaseProvider(); + public function getDatabaseProvider(bool $strict = false): string { + return $this->inner->getDatabaseProvider($strict); } /** diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php index 1d1ccd29bf7..1d44c049793 100644 --- a/lib/private/DB/QueryBuilder/QueryBuilder.php +++ b/lib/private/DB/QueryBuilder/QueryBuilder.php @@ -96,6 +96,7 @@ class QueryBuilder implements IQueryBuilder { return match($this->connection->getDatabaseProvider()) { IDBConnection::PLATFORM_ORACLE => new OCIExpressionBuilder($this->connection, $this, $this->logger), IDBConnection::PLATFORM_POSTGRES => new PgSqlExpressionBuilder($this->connection, $this, $this->logger), + IDBConnection::PLATFORM_MARIADB, IDBConnection::PLATFORM_MYSQL => new MySqlExpressionBuilder($this->connection, $this, $this->logger), IDBConnection::PLATFORM_SQLITE => new SqliteExpressionBuilder($this->connection, $this, $this->logger), }; @@ -121,6 +122,7 @@ class QueryBuilder implements IQueryBuilder { return match($this->connection->getDatabaseProvider()) { IDBConnection::PLATFORM_ORACLE => new OCIFunctionBuilder($this->connection, $this, $this->helper), IDBConnection::PLATFORM_POSTGRES => new PgSqlFunctionBuilder($this->connection, $this, $this->helper), + IDBConnection::PLATFORM_MARIADB, IDBConnection::PLATFORM_MYSQL => new FunctionBuilder($this->connection, $this, $this->helper), IDBConnection::PLATFORM_SQLITE => new SqliteFunctionBuilder($this->connection, $this, $this->helper), }; diff --git a/lib/private/Profile/Actions/BlueskyAction.php b/lib/private/Profile/Actions/BlueskyAction.php new file mode 100644 index 00000000000..d05682aac1a --- /dev/null +++ b/lib/private/Profile/Actions/BlueskyAction.php @@ -0,0 +1,65 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OC\Profile\Actions; + +use OCP\Accounts\IAccountManager; +use OCP\IURLGenerator; +use OCP\IUser; +use OCP\L10N\IFactory; +use OCP\Profile\ILinkAction; + +class BlueskyAction implements ILinkAction { + private string $value = ''; + + public function __construct( + private IAccountManager $accountManager, + private IFactory $l10nFactory, + private IURLGenerator $urlGenerator, + ) { + } + + public function preload(IUser $targetUser): void { + $account = $this->accountManager->getAccount($targetUser); + $this->value = $account->getProperty(IAccountManager::PROPERTY_BLUESKY)->getValue(); + } + + public function getAppId(): string { + return 'core'; + } + + public function getId(): string { + return IAccountManager::PROPERTY_BLUESKY; + } + + public function getDisplayId(): string { + return $this->l10nFactory->get('lib')->t('Bluesky'); + } + + public function getTitle(): string { + $displayUsername = $this->value; + return $this->l10nFactory->get('lib')->t('View %s on Bluesky', [$displayUsername]); + } + + public function getPriority(): int { + return 60; + } + + public function getIcon(): string { + return $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/bluesky.svg')); + } + + public function getTarget(): ?string { + if (empty($this->value)) { + return null; + } + $username = $this->value; + return 'https://bsky.app/profile/' . $username; + } +} diff --git a/lib/private/Profile/ProfileManager.php b/lib/private/Profile/ProfileManager.php index 1ade208fbcf..7c15ed614aa 100644 --- a/lib/private/Profile/ProfileManager.php +++ b/lib/private/Profile/ProfileManager.php @@ -14,6 +14,7 @@ use OC\Core\Db\ProfileConfig; use OC\Core\Db\ProfileConfigMapper; use OC\Core\ResponseDefinitions; use OC\KnownUser\KnownUserService; +use OC\Profile\Actions\BlueskyAction; use OC\Profile\Actions\EmailAction; use OC\Profile\Actions\FediverseAction; use OC\Profile\Actions\PhoneAction; @@ -56,6 +57,7 @@ class ProfileManager implements IProfileManager { PhoneAction::class, WebsiteAction::class, TwitterAction::class, + BlueskyAction::class, FediverseAction::class, ]; diff --git a/lib/public/Accounts/IAccountManager.php b/lib/public/Accounts/IAccountManager.php index 92fc0002674..ae5535ef13b 100644 --- a/lib/public/Accounts/IAccountManager.php +++ b/lib/public/Accounts/IAccountManager.php @@ -97,10 +97,16 @@ interface IAccountManager { /** * @since 15.0.0 + * @deprecated 32.0.0 */ public const PROPERTY_TWITTER = 'twitter'; /** + * @since 32.0.0 + */ + public const PROPERTY_BLUESKY = 'bluesky'; + + /** * @since 26.0.0 */ public const PROPERTY_FEDIVERSE = 'fediverse'; @@ -160,6 +166,7 @@ interface IAccountManager { self::PROPERTY_PRONOUNS, self::PROPERTY_ROLE, self::PROPERTY_TWITTER, + self::PROPERTY_BLUESKY, self::PROPERTY_WEBSITE, ]; diff --git a/lib/public/IDBConnection.php b/lib/public/IDBConnection.php index e0fe603ec57..ea9b71d8958 100644 --- a/lib/public/IDBConnection.php +++ b/lib/public/IDBConnection.php @@ -45,6 +45,11 @@ interface IDBConnection { public const PLATFORM_SQLITE = 'sqlite'; /** + * @since 32.0.0 + */ + public const PLATFORM_MARIADB = 'mariadb'; + + /** * Gets the QueryBuilder for the connection. * * @return \OCP\DB\QueryBuilder\IQueryBuilder @@ -357,11 +362,15 @@ interface IDBConnection { /** * Returns the database provider name + * * @link https://github.com/nextcloud/server/issues/30877 + * + * @param bool $strict differentiate between database flavors, e.g. MySQL vs MariaDB + * @return self::PLATFORM_MYSQL|self::PLATFORM_ORACLE|self::PLATFORM_POSTGRES|self::PLATFORM_SQLITE|self::PLATFORM_MARIADB + * @since 32.0.0 Optional parameter $strict was added * @since 28.0.0 - * @return self::PLATFORM_MYSQL|self::PLATFORM_ORACLE|self::PLATFORM_POSTGRES|self::PLATFORM_SQLITE */ - public function getDatabaseProvider(): string; + public function getDatabaseProvider(bool $strict = false): string; /** * Get the shard definition by name, if configured diff --git a/lib/public/Profile/IProfileManager.php b/lib/public/Profile/IProfileManager.php index f4e90e39d12..aec06fb4c86 100644 --- a/lib/public/Profile/IProfileManager.php +++ b/lib/public/Profile/IProfileManager.php @@ -55,6 +55,7 @@ interface IProfileManager { IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_SHOW_USERS_ONLY, IAccountManager::PROPERTY_PHONE => self::VISIBILITY_SHOW_USERS_ONLY, IAccountManager::PROPERTY_TWITTER => self::VISIBILITY_SHOW, + IAccountManager::PROPERTY_BLUESKY => self::VISIBILITY_SHOW, IAccountManager::PROPERTY_WEBSITE => self::VISIBILITY_SHOW, IAccountManager::PROPERTY_PRONOUNS => self::VISIBILITY_SHOW, ]; |