mirror of
https://github.com/flarum/core.git
synced 2025-07-23 17:51:24 +02:00
Use drivers for display names, add display name extender (#2174)
* Deprecate GetDisplayName event * Add interface for display name driver * Add username driver as default * Add code to register supported drivers / used driver as singletons * Configured User class to use new driver-based system for display names * Add extender for adding display name driver * Add integration test for user display name driver * Add frontend UI for selecting display name driver
This commit is contained in:
committed by
GitHub
parent
577aaa16d9
commit
f7985bac61
@@ -21,6 +21,7 @@ export default class BasicsPage extends Page {
|
|||||||
'default_route',
|
'default_route',
|
||||||
'welcome_title',
|
'welcome_title',
|
||||||
'welcome_message',
|
'welcome_message',
|
||||||
|
'display_name_driver',
|
||||||
];
|
];
|
||||||
this.values = {};
|
this.values = {};
|
||||||
|
|
||||||
@@ -33,6 +34,14 @@ export default class BasicsPage extends Page {
|
|||||||
this.localeOptions[i] = `${locales[i]} (${i})`;
|
this.localeOptions[i] = `${locales[i]} (${i})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.displayNameOptions = {};
|
||||||
|
const displayNameDrivers = app.data.displayNameDrivers;
|
||||||
|
displayNameDrivers.forEach(function (identifier) {
|
||||||
|
this.displayNameOptions[identifier] = identifier;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
if (!this.values.display_name_driver() && displayNameDrivers.includes('username')) this.values.display_name_driver('username');
|
||||||
|
|
||||||
if (typeof this.values.show_language_selector() !== 'number') this.values.show_language_selector(1);
|
if (typeof this.values.show_language_selector() !== 'number') this.values.show_language_selector(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +123,20 @@ export default class BasicsPage extends Page {
|
|||||||
],
|
],
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
{Object.keys(this.displayNameOptions).length > 1
|
||||||
|
? FieldSet.component({
|
||||||
|
label: app.translator.trans('core.admin.basics.display_name_heading'),
|
||||||
|
children: [
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.basics.display_name_text')}</div>,
|
||||||
|
Select.component({
|
||||||
|
options: this.displayNameOptions,
|
||||||
|
value: this.values.display_name_driver(),
|
||||||
|
onchange: this.values.display_name_driver,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
: ''}
|
||||||
|
|
||||||
{Button.component({
|
{Button.component({
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
className: 'Button Button--primary',
|
className: 'Button Button--primary',
|
||||||
|
@@ -14,12 +14,18 @@ use Flarum\Frontend\Document;
|
|||||||
use Flarum\Group\Permission;
|
use Flarum\Group\Permission;
|
||||||
use Flarum\Settings\Event\Deserializing;
|
use Flarum\Settings\Event\Deserializing;
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class AdminPayload
|
class AdminPayload
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var Container;
|
||||||
|
*/
|
||||||
|
protected $container;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var SettingsRepositoryInterface
|
* @var SettingsRepositoryInterface
|
||||||
*/
|
*/
|
||||||
@@ -36,13 +42,20 @@ class AdminPayload
|
|||||||
protected $db;
|
protected $db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param Container $container
|
||||||
* @param SettingsRepositoryInterface $settings
|
* @param SettingsRepositoryInterface $settings
|
||||||
* @param ExtensionManager $extensions
|
* @param ExtensionManager $extensions
|
||||||
* @param ConnectionInterface $db
|
* @param ConnectionInterface $db
|
||||||
* @param Dispatcher $events
|
* @param Dispatcher $events
|
||||||
*/
|
*/
|
||||||
public function __construct(SettingsRepositoryInterface $settings, ExtensionManager $extensions, ConnectionInterface $db, Dispatcher $events)
|
public function __construct(
|
||||||
{
|
Container $container,
|
||||||
|
SettingsRepositoryInterface $settings,
|
||||||
|
ExtensionManager $extensions,
|
||||||
|
ConnectionInterface $db,
|
||||||
|
Dispatcher $events
|
||||||
|
) {
|
||||||
|
$this->container = $container;
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->extensions = $extensions;
|
$this->extensions = $extensions;
|
||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
@@ -61,6 +74,8 @@ class AdminPayload
|
|||||||
$document->payload['permissions'] = Permission::map();
|
$document->payload['permissions'] = Permission::map();
|
||||||
$document->payload['extensions'] = $this->extensions->getExtensions()->toArray();
|
$document->payload['extensions'] = $this->extensions->getExtensions()->toArray();
|
||||||
|
|
||||||
|
$document->payload['displayNameDrivers'] = array_keys($this->container->make('flarum.user.display_name.supported_drivers'));
|
||||||
|
|
||||||
$document->payload['phpVersion'] = PHP_VERSION;
|
$document->payload['phpVersion'] = PHP_VERSION;
|
||||||
$document->payload['mysqlVersion'] = $this->db->selectOne('select version() as version')->version;
|
$document->payload['mysqlVersion'] = $this->db->selectOne('select version() as version')->version;
|
||||||
}
|
}
|
||||||
|
38
framework/core/src/Extend/User.php
Normal file
38
framework/core/src/Extend/User.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* For detailed copyright and license information, please view the
|
||||||
|
* LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Extend;
|
||||||
|
|
||||||
|
use Flarum\Extension\Extension;
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
|
||||||
|
class User implements ExtenderInterface
|
||||||
|
{
|
||||||
|
private $displayNameDrivers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a mail driver.
|
||||||
|
*
|
||||||
|
* @param string $identifier Identifier for display name driver. E.g. 'username' for UserNameDriver
|
||||||
|
* @param string $driver ::class attribute of driver class, which must implement Flarum\User\DisplayName\DriverInterface
|
||||||
|
*/
|
||||||
|
public function displayNameDriver(string $identifier, $driver)
|
||||||
|
{
|
||||||
|
$this->drivers[$identifier] = $driver;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extend(Container $container, Extension $extension = null)
|
||||||
|
{
|
||||||
|
$container->extend('flarum.user.display_name.supported_drivers', function ($existingDrivers) {
|
||||||
|
return array_merge($existingDrivers, $this->drivers);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
25
framework/core/src/User/DisplayName/DriverInterface.php
Normal file
25
framework/core/src/User/DisplayName/DriverInterface.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* For detailed copyright and license information, please view the
|
||||||
|
* LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\User\DisplayName;
|
||||||
|
|
||||||
|
use Flarum\User\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for a display name driver.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
interface DriverInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return a display name for a user.
|
||||||
|
*/
|
||||||
|
public function displayName(User $user): string;
|
||||||
|
}
|
23
framework/core/src/User/DisplayName/UsernameDriver.php
Normal file
23
framework/core/src/User/DisplayName/UsernameDriver.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* For detailed copyright and license information, please view the
|
||||||
|
* LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\User\DisplayName;
|
||||||
|
|
||||||
|
use Flarum\User\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default driver, which returns the user's username.
|
||||||
|
*/
|
||||||
|
class UsernameDriver implements DriverInterface
|
||||||
|
{
|
||||||
|
public function displayName(User $user): string
|
||||||
|
{
|
||||||
|
return $user->username;
|
||||||
|
}
|
||||||
|
}
|
@@ -11,6 +11,9 @@ namespace Flarum\User\Event;
|
|||||||
|
|
||||||
use Flarum\User\User;
|
use Flarum\User\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated beta 14, removed beta 15.
|
||||||
|
*/
|
||||||
class GetDisplayName
|
class GetDisplayName
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@@ -23,6 +23,7 @@ use Flarum\Http\AccessToken;
|
|||||||
use Flarum\Http\UrlGenerator;
|
use Flarum\Http\UrlGenerator;
|
||||||
use Flarum\Notification\Notification;
|
use Flarum\Notification\Notification;
|
||||||
use Flarum\Post\Post;
|
use Flarum\Post\Post;
|
||||||
|
use Flarum\User\DisplayName\DriverInterface;
|
||||||
use Flarum\User\Event\Activated;
|
use Flarum\User\Event\Activated;
|
||||||
use Flarum\User\Event\AvatarChanged;
|
use Flarum\User\Event\AvatarChanged;
|
||||||
use Flarum\User\Event\CheckingPassword;
|
use Flarum\User\Event\CheckingPassword;
|
||||||
@@ -93,6 +94,13 @@ class User extends AbstractModel
|
|||||||
*/
|
*/
|
||||||
protected static $preferences = [];
|
protected static $preferences = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A driver for getting display names.
|
||||||
|
*
|
||||||
|
* @var DriverInterface
|
||||||
|
*/
|
||||||
|
protected static $displayNameDriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The hasher with which to hash passwords.
|
* The hasher with which to hash passwords.
|
||||||
*
|
*
|
||||||
@@ -172,6 +180,16 @@ class User extends AbstractModel
|
|||||||
static::$gate = $gate;
|
static::$gate = $gate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the display name driver.
|
||||||
|
*
|
||||||
|
* @param DriverInterface $driver
|
||||||
|
*/
|
||||||
|
public static function setDisplayNameDriver(DriverInterface $driver)
|
||||||
|
{
|
||||||
|
static::$displayNameDriver = $driver;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename the user.
|
* Rename the user.
|
||||||
*
|
*
|
||||||
@@ -309,7 +327,8 @@ class User extends AbstractModel
|
|||||||
*/
|
*/
|
||||||
public function getDisplayNameAttribute()
|
public function getDisplayNameAttribute()
|
||||||
{
|
{
|
||||||
return static::$dispatcher->until(new GetDisplayName($this)) ?: $this->username;
|
// Event is deprecated in beta 14, remove in beta 15.
|
||||||
|
return static::$dispatcher->until(new GetDisplayName($this)) ?: static::$displayNameDriver->displayName($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,12 +12,16 @@ namespace Flarum\User;
|
|||||||
use Flarum\Event\ConfigureUserPreferences;
|
use Flarum\Event\ConfigureUserPreferences;
|
||||||
use Flarum\Event\GetPermission;
|
use Flarum\Event\GetPermission;
|
||||||
use Flarum\Foundation\AbstractServiceProvider;
|
use Flarum\Foundation\AbstractServiceProvider;
|
||||||
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
|
use Flarum\User\DisplayName\DriverInterface;
|
||||||
|
use Flarum\User\DisplayName\UsernameDriver;
|
||||||
use Flarum\User\Event\EmailChangeRequested;
|
use Flarum\User\Event\EmailChangeRequested;
|
||||||
use Flarum\User\Event\Registered;
|
use Flarum\User\Event\Registered;
|
||||||
use Flarum\User\Event\Saving;
|
use Flarum\User\Event\Saving;
|
||||||
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
|
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Illuminate\Contracts\Filesystem\Factory;
|
use Illuminate\Contracts\Filesystem\Factory;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use League\Flysystem\FilesystemInterface;
|
use League\Flysystem\FilesystemInterface;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
@@ -30,6 +34,30 @@ class UserServiceProvider extends AbstractServiceProvider
|
|||||||
{
|
{
|
||||||
$this->registerGate();
|
$this->registerGate();
|
||||||
$this->registerAvatarsFilesystem();
|
$this->registerAvatarsFilesystem();
|
||||||
|
$this->registerDisplayNameDrivers();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function registerDisplayNameDrivers()
|
||||||
|
{
|
||||||
|
$this->app->singleton('flarum.user.display_name.supported_drivers', function () {
|
||||||
|
return [
|
||||||
|
'username' => UsernameDriver::class,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->app->singleton('flarum.user.display_name.driver', function () {
|
||||||
|
$drivers = $this->app->make('flarum.user.display_name.supported_drivers');
|
||||||
|
$settings = $this->app->make(SettingsRepositoryInterface::class);
|
||||||
|
$driverName = $settings->get('display_name_driver', '');
|
||||||
|
|
||||||
|
$driverClass = Arr::get($drivers, $driverName);
|
||||||
|
|
||||||
|
return $driverClass
|
||||||
|
? $this->app->make($driverClass)
|
||||||
|
: $this->app->make(UsernameDriver::class);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->app->alias('flarum.user.display_name.driver', DriverInterface::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function registerGate()
|
protected function registerGate()
|
||||||
@@ -84,6 +112,7 @@ class UserServiceProvider extends AbstractServiceProvider
|
|||||||
|
|
||||||
User::setHasher($this->app->make('hash'));
|
User::setHasher($this->app->make('hash'));
|
||||||
User::setGate($this->app->make('flarum.gate'));
|
User::setGate($this->app->make('flarum.gate'));
|
||||||
|
User::setDisplayNameDriver($this->app->make('flarum.user.display_name.driver'));
|
||||||
|
|
||||||
$events = $this->app->make('events');
|
$events = $this->app->make('events');
|
||||||
|
|
||||||
|
69
framework/core/tests/integration/extenders/UserTest.php
Normal file
69
framework/core/tests/integration/extenders/UserTest.php
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* For detailed copyright and license information, please view the
|
||||||
|
* LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Tests\integration\extenders;
|
||||||
|
|
||||||
|
use Flarum\Extend;
|
||||||
|
use Flarum\Tests\integration\RetrievesAuthorizedUsers;
|
||||||
|
use Flarum\Tests\integration\TestCase;
|
||||||
|
use Flarum\User\DisplayName\DriverInterface;
|
||||||
|
use Flarum\User\User;
|
||||||
|
|
||||||
|
class UserTest extends TestCase
|
||||||
|
{
|
||||||
|
use RetrievesAuthorizedUsers;
|
||||||
|
|
||||||
|
protected function prepDb()
|
||||||
|
{
|
||||||
|
$this->prepareDatabase([
|
||||||
|
'users' => [
|
||||||
|
$this->adminUser(),
|
||||||
|
], 'settings' => [
|
||||||
|
['key' => 'display_name_driver', 'value' => 'custom'],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function username_display_name_driver_used_by_default()
|
||||||
|
{
|
||||||
|
$this->prepDb();
|
||||||
|
|
||||||
|
$user = User::find(1);
|
||||||
|
|
||||||
|
$this->assertEquals('admin', $user->displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function can_use_custom_display_name_driver()
|
||||||
|
{
|
||||||
|
$this->extend(
|
||||||
|
(new Extend\User)
|
||||||
|
->displayNameDriver('custom', CustomDisplayNameDriver::class)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->prepDb();
|
||||||
|
|
||||||
|
$user = User::find(1);
|
||||||
|
|
||||||
|
$this->assertEquals('admin@machine.local$$$suffix', $user->displayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomDisplayNameDriver implements DriverInterface
|
||||||
|
{
|
||||||
|
public function displayName(User $user): string
|
||||||
|
{
|
||||||
|
return $user->email.'$$$suffix';
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user