1
0
mirror of https://github.com/flarum/core.git synced 2025-10-18 18:26:07 +02:00

Move command classes to domain namespaces

They will probably be refactored away at a later stage (when we get
rid of the command bus). Until then, this lets us remove the
Flarum\Core namespace and actually feels quite clean.
This commit is contained in:
Franz Liedke
2017-06-24 15:21:07 +02:00
parent 95dc7e71f4
commit 5b0d0d9f0f
57 changed files with 115 additions and 119 deletions

View File

@@ -0,0 +1,30 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
class ConfirmEmail
{
/**
* The email confirmation token.
*
* @var string
*/
public $token;
/**
* @param string $token The email confirmation token.
*/
public function __construct($token)
{
$this->token = $token;
}
}

View File

@@ -0,0 +1,60 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\Foundation\DispatchEventsTrait;
use Flarum\User\EmailToken;
use Flarum\User\UserRepository;
use Illuminate\Contracts\Events\Dispatcher;
class ConfirmEmailHandler
{
use DispatchEventsTrait;
/**
* @var \Flarum\User\UserRepository
*/
protected $users;
/**
* @param \Flarum\User\UserRepository $users
*/
public function __construct(Dispatcher $events, UserRepository $users)
{
$this->events = $events;
$this->users = $users;
}
/**
* @param ConfirmEmail $command
* @return \Flarum\User\User
*/
public function handle(ConfirmEmail $command)
{
/** @var EmailToken $token */
$token = EmailToken::validOrFail($command->token);
$user = $token->user;
$user->changeEmail($token->email);
if (! $user->is_activated) {
$user->activate();
}
$user->save();
$this->dispatchEventsFor($user);
$token->delete();
return $user;
}
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\User\User;
class DeleteAvatar
{
/**
* The ID of the user to delete the avatar of.
*
* @var int
*/
public $userId;
/**
* The user performing the action.
*
* @var User
*/
public $actor;
/**
* @param int $userId The ID of the user to delete the avatar of.
* @param User $actor The user performing the action.
*/
public function __construct($userId, User $actor)
{
$this->userId = $userId;
$this->actor = $actor;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\Event\AvatarWillBeDeleted;
use Flarum\Foundation\DispatchEventsTrait;
use Flarum\User\AssertPermissionTrait;
use Flarum\User\UserRepository;
use Illuminate\Contracts\Events\Dispatcher;
use League\Flysystem\FilesystemInterface;
class DeleteAvatarHandler
{
use DispatchEventsTrait;
use AssertPermissionTrait;
/**
* @var UserRepository
*/
protected $users;
/**
* @var FilesystemInterface
*/
protected $uploadDir;
/**
* @param Dispatcher $events
* @param UserRepository $users
* @param FilesystemInterface $uploadDir
*/
public function __construct(Dispatcher $events, UserRepository $users, FilesystemInterface $uploadDir)
{
$this->events = $events;
$this->users = $users;
$this->uploadDir = $uploadDir;
}
/**
* @param DeleteAvatar $command
* @return \Flarum\User\User
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(DeleteAvatar $command)
{
$actor = $command->actor;
$user = $this->users->findOrFail($command->userId);
if ($actor->id !== $user->id) {
$this->assertCan($actor, 'edit', $user);
}
$avatarPath = $user->avatar_path;
$user->changeAvatarPath(null);
$this->events->fire(
new AvatarWillBeDeleted($user, $actor)
);
$user->save();
if ($this->uploadDir->has($avatarPath)) {
$this->uploadDir->delete($avatarPath);
}
$this->dispatchEventsFor($user, $actor);
return $user;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\User\User;
class DeleteUser
{
/**
* The ID of the user to delete.
*
* @var int
*/
public $userId;
/**
* The user performing the action.
*
* @var User
*/
public $actor;
/**
* Any other user input associated with the action. This is unused by
* default, but may be used by extensions.
*
* @var array
*/
public $data;
/**
* @param int $userId The ID of the user to delete.
* @param User $actor The user performing the action.
* @param array $data Any other user input associated with the action. This
* is unused by default, but may be used by extensions.
*/
public function __construct($userId, User $actor, array $data = [])
{
$this->userId = $userId;
$this->actor = $actor;
$this->data = $data;
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\Foundation\DispatchEventsTrait;
use Flarum\User\AssertPermissionTrait;
use Flarum\User\Event\Deleting;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\User\UserRepository;
use Illuminate\Contracts\Events\Dispatcher;
class DeleteUserHandler
{
use DispatchEventsTrait;
use AssertPermissionTrait;
/**
* @var UserRepository
*/
protected $users;
/**
* @param Dispatcher $events
* @param UserRepository $users
*/
public function __construct(Dispatcher $events, UserRepository $users)
{
$this->events = $events;
$this->users = $users;
}
/**
* @param DeleteUser $command
* @return \Flarum\User\User
* @throws PermissionDeniedException
*/
public function handle(DeleteUser $command)
{
$actor = $command->actor;
$user = $this->users->findOrFail($command->userId, $actor);
$this->assertCan($actor, 'delete', $user);
$this->events->fire(
new Deleting($user, $actor, $command->data)
);
$user->delete();
$this->dispatchEventsFor($user, $actor);
return $user;
}
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\User\User;
class EditUser
{
/**
* The ID of the user to edit.
*
* @var int
*/
public $userId;
/**
* The user performing the action.
*
* @var User
*/
public $actor;
/**
* The attributes to update on the user.
*
* @var array
*/
public $data;
/**
* @param int $userId The ID of the user to edit.
* @param User $actor The user performing the action.
* @param array $data The attributes to update on the user.
*/
public function __construct($userId, User $actor, array $data)
{
$this->userId = $userId;
$this->actor = $actor;
$this->data = $data;
}
}

View File

@@ -0,0 +1,151 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\Foundation\DispatchEventsTrait;
use Flarum\User\AssertPermissionTrait;
use Flarum\User\Event\GroupsChanged;
use Flarum\User\Event\Saving;
use Flarum\User\User;
use Flarum\User\UserRepository;
use Flarum\User\UserValidator;
use Illuminate\Contracts\Events\Dispatcher;
class EditUserHandler
{
use DispatchEventsTrait;
use AssertPermissionTrait;
/**
* @var \Flarum\User\UserRepository
*/
protected $users;
/**
* @var UserValidator
*/
protected $validator;
/**
* @param Dispatcher $events
* @param \Flarum\User\UserRepository $users
* @param UserValidator $validator
*/
public function __construct(Dispatcher $events, UserRepository $users, UserValidator $validator)
{
$this->events = $events;
$this->users = $users;
$this->validator = $validator;
}
/**
* @param EditUser $command
* @return User
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(EditUser $command)
{
$actor = $command->actor;
$data = $command->data;
$user = $this->users->findOrFail($command->userId, $actor);
$canEdit = $actor->can('edit', $user);
$isSelf = $actor->id === $user->id;
$attributes = array_get($data, 'attributes', []);
$relationships = array_get($data, 'relationships', []);
$validate = [];
if (isset($attributes['username'])) {
$this->assertPermission($canEdit);
$user->rename($attributes['username']);
}
if (isset($attributes['email'])) {
if ($isSelf) {
$user->requestEmailChange($attributes['email']);
if ($attributes['email'] !== $user->email) {
$validate['email'] = $attributes['email'];
}
} else {
$this->assertPermission($canEdit);
$user->changeEmail($attributes['email']);
}
}
if ($actor->isAdmin() && ! empty($attributes['isActivated'])) {
$user->activate();
}
if (isset($attributes['password'])) {
$this->assertPermission($canEdit);
$user->changePassword($attributes['password']);
$validate['password'] = $attributes['password'];
}
if (isset($attributes['bio'])) {
if (! $isSelf) {
$this->assertPermission($canEdit);
}
$user->changeBio($attributes['bio']);
}
if (! empty($attributes['readTime'])) {
$this->assertPermission($isSelf);
$user->markAllAsRead();
}
if (! empty($attributes['preferences'])) {
$this->assertPermission($isSelf);
foreach ($attributes['preferences'] as $k => $v) {
$user->setPreference($k, $v);
}
}
if (isset($relationships['groups']['data']) && is_array($relationships['groups']['data'])) {
$this->assertPermission($canEdit);
$newGroupIds = [];
foreach ($relationships['groups']['data'] as $group) {
if ($id = array_get($group, 'id')) {
$newGroupIds[] = $id;
}
}
$user->raise(
new GroupsChanged($user, $user->groups()->get()->all())
);
$user->afterSave(function (User $user) use ($newGroupIds) {
$user->groups()->sync($newGroupIds);
});
}
$this->events->fire(
new Saving($user, $actor, $data)
);
$this->validator->setUser($user);
$this->validator->assertValid(array_merge($user->getDirty(), $validate));
$user->save();
$this->dispatchEventsFor($user, $actor);
return $user;
}
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\User\User;
class RegisterUser
{
/**
* The user performing the action.
*
* @var User
*/
public $actor;
/**
* The attributes of the new user.
*
* @var array
*/
public $data;
/**
* @param User $actor The user performing the action.
* @param array $data The attributes of the new user.
*/
public function __construct(User $actor, array $data)
{
$this->actor = $actor;
$this->data = $data;
}
}

View File

@@ -0,0 +1,182 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Exception;
use Flarum\Foundation\Application;
use Flarum\Foundation\DispatchEventsTrait;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\AssertPermissionTrait;
use Flarum\User\AuthToken;
use Flarum\User\Event\Saving;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\User\User;
use Flarum\User\UserValidator;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Contracts\Validation\ValidationException;
use Illuminate\Support\Str;
use Intervention\Image\ImageManager;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;
use League\Flysystem\FilesystemInterface;
use League\Flysystem\MountManager;
class RegisterUserHandler
{
use DispatchEventsTrait;
use AssertPermissionTrait;
/**
* @var SettingsRepositoryInterface
*/
protected $settings;
/**
* @var UserValidator
*/
protected $validator;
/**
* @var Application
*/
protected $app;
/**
* @var FilesystemInterface
*/
protected $uploadDir;
/**
* @var Factory
*/
private $validatorFactory;
/**
* @param Dispatcher $events
* @param SettingsRepositoryInterface $settings
* @param UserValidator $validator
* @param Application $app
* @param FilesystemInterface $uploadDir
* @param Factory $validatorFactory
*/
public function __construct(Dispatcher $events, SettingsRepositoryInterface $settings, UserValidator $validator, Application $app, FilesystemInterface $uploadDir, Factory $validatorFactory)
{
$this->events = $events;
$this->settings = $settings;
$this->validator = $validator;
$this->app = $app;
$this->uploadDir = $uploadDir;
$this->validatorFactory = $validatorFactory;
}
/**
* @param RegisterUser $command
* @throws PermissionDeniedException if signup is closed and the actor is
* not an administrator.
* @throws \Flarum\User\Exception\InvalidConfirmationTokenException if an
* email confirmation token is provided but is invalid.
* @return User
*/
public function handle(RegisterUser $command)
{
$actor = $command->actor;
$data = $command->data;
if (! $this->settings->get('allow_sign_up')) {
$this->assertAdmin($actor);
}
$username = array_get($data, 'attributes.username');
$email = array_get($data, 'attributes.email');
$password = array_get($data, 'attributes.password');
// If a valid authentication token was provided as an attribute,
// then we won't require the user to choose a password.
if (isset($data['attributes']['token'])) {
$token = AuthToken::validOrFail($data['attributes']['token']);
$password = $password ?: str_random(20);
}
$user = User::register($username, $email, $password);
// If a valid authentication token was provided, then we will assign
// the attributes associated with it to the user's account. If this
// includes an email address, then we will activate the user's account
// from the get-go.
if (isset($token)) {
foreach ($token->payload as $k => $v) {
if (in_array($user->$k, ['', null], true)) {
$user->$k = $v;
}
}
if (isset($token->payload['email'])) {
$user->activate();
}
}
if ($actor->isAdmin() && array_get($data, 'attributes.isActivated')) {
$user->activate();
}
$this->events->fire(
new Saving($user, $actor, $data)
);
$this->validator->assertValid(array_merge($user->getAttributes(), compact('password')));
if ($avatarUrl = array_get($data, 'attributes.avatarUrl')) {
$validation = $this->validatorFactory->make(compact('avatarUrl'), ['avatarUrl' => 'url']);
if ($validation->fails()) {
throw new ValidationException($validation);
}
try {
$this->saveAvatarFromUrl($user, $avatarUrl);
} catch (Exception $e) {
//
}
}
$user->save();
if (isset($token)) {
$token->delete();
}
$this->dispatchEventsFor($user, $actor);
return $user;
}
private function saveAvatarFromUrl(User $user, $url)
{
$tmpFile = tempnam($this->app->storagePath().'/tmp', 'avatar');
$manager = new ImageManager;
$manager->make($url)->fit(100, 100)->save($tmpFile);
$mount = new MountManager([
'source' => new Filesystem(new Local(pathinfo($tmpFile, PATHINFO_DIRNAME))),
'target' => $this->uploadDir,
]);
$uploadName = Str::lower(Str::quickRandom()).'.png';
$user->changeAvatarPath($uploadName);
$mount->move('source://'.pathinfo($tmpFile, PATHINFO_BASENAME), "target://$uploadName");
}
}

View File

@@ -0,0 +1,30 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
class RequestPasswordReset
{
/**
* The email of the user to request a password reset for.
*
* @var string
*/
public $email;
/**
* @param string $email The email of the user to request a password reset for.
*/
public function __construct($email)
{
$this->email = $email;
}
}

View File

@@ -0,0 +1,123 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\Forum\UrlGenerator;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\PasswordToken;
use Flarum\User\UserRepository;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Contracts\Validation\ValidationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Mail\Message;
use Symfony\Component\Translation\TranslatorInterface;
class RequestPasswordResetHandler
{
/**
* @var UserRepository
*/
protected $users;
/**
* @var SettingsRepositoryInterface
*/
protected $settings;
/**
* @var Mailer
*/
protected $mailer;
/**
* @var UrlGenerator
*/
protected $url;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @var Factory
*/
protected $validatorFactory;
/**
* @param \Flarum\User\UserRepository $users
* @param SettingsRepositoryInterface $settings
* @param Mailer $mailer
* @param UrlGenerator $url
* @param TranslatorInterface $translator
* @param Factory $validatorFactory
*/
public function __construct(
UserRepository $users,
SettingsRepositoryInterface $settings,
Mailer $mailer,
UrlGenerator $url,
TranslatorInterface $translator,
Factory $validatorFactory
) {
$this->users = $users;
$this->settings = $settings;
$this->mailer = $mailer;
$this->url = $url;
$this->translator = $translator;
$this->validatorFactory = $validatorFactory;
}
/**
* @param RequestPasswordReset $command
* @return \Flarum\User\User
* @throws ModelNotFoundException
*/
public function handle(RequestPasswordReset $command)
{
$email = $command->email;
$validation = $this->validatorFactory->make(
compact('email'),
['email' => 'required|email']
);
if ($validation->fails()) {
throw new ValidationException($validation);
}
$user = $this->users->findByEmail($email);
if (! $user) {
throw new ModelNotFoundException;
}
$token = PasswordToken::generate($user->id);
$token->save();
$data = [
'{username}' => $user->username,
'{url}' => $this->url->toRoute('resetPassword', ['token' => $token->id]),
'{forum}' => $this->settings->get('forum_title'),
];
$body = $this->translator->trans('core.email.reset_password.body', $data);
$this->mailer->raw($body, function (Message $message) use ($user, $data) {
$message->to($user->email);
$message->subject('['.$data['{forum}'].'] '.$this->translator->trans('core.email.reset_password.subject'));
});
return $user;
}
}

View File

@@ -0,0 +1,51 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Flarum\User\User;
use Psr\Http\Message\UploadedFileInterface;
class UploadAvatar
{
/**
* The ID of the user to upload the avatar for.
*
* @var int
*/
public $userId;
/**
* The avatar file to upload.
*
* @var UploadedFileInterface
*/
public $file;
/**
* The user performing the action.
*
* @var User
*/
public $actor;
/**
* @param int $userId The ID of the user to upload the avatar for.
* @param UploadedFileInterface $file The avatar file to upload.
* @param User $actor The user performing the action.
*/
public function __construct($userId, UploadedFileInterface $file, User $actor)
{
$this->userId = $userId;
$this->file = $file;
$this->actor = $actor;
}
}

View File

@@ -0,0 +1,142 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\User\Command;
use Exception;
use Flarum\Event\AvatarWillBeSaved;
use Flarum\Foundation\Application;
use Flarum\Foundation\DispatchEventsTrait;
use Flarum\User\AssertPermissionTrait;
use Flarum\User\UserRepository;
use Flarum\User\AvatarValidator;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Support\Str;
use Intervention\Image\ImageManager;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;
use League\Flysystem\FilesystemInterface;
use League\Flysystem\MountManager;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class UploadAvatarHandler
{
use DispatchEventsTrait;
use AssertPermissionTrait;
/**
* @var \Flarum\User\UserRepository
*/
protected $users;
/**
* @var FilesystemInterface
*/
protected $uploadDir;
/**
* @var Application
*/
protected $app;
/**
* @var \Flarum\User\AvatarValidator
*/
protected $validator;
/**
* @param Dispatcher $events
* @param UserRepository $users
* @param FilesystemInterface $uploadDir
* @param Application $app
* @param \Flarum\User\AvatarValidator $validator
*/
public function __construct(Dispatcher $events, UserRepository $users, FilesystemInterface $uploadDir, Application $app, AvatarValidator $validator)
{
$this->events = $events;
$this->users = $users;
$this->uploadDir = $uploadDir;
$this->app = $app;
$this->validator = $validator;
}
/**
* @param UploadAvatar $command
* @return \Flarum\User\User
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(UploadAvatar $command)
{
$actor = $command->actor;
$user = $this->users->findOrFail($command->userId);
if ($actor->id !== $user->id) {
$this->assertCan($actor, 'edit', $user);
}
$tmpFile = tempnam($this->app->storagePath().'/tmp', 'avatar');
$command->file->moveTo($tmpFile);
try {
$file = new UploadedFile(
$tmpFile,
$command->file->getClientFilename(),
$command->file->getClientMediaType(),
$command->file->getSize(),
$command->file->getError(),
true
);
$this->validator->assertValid(['avatar' => $file]);
$manager = new ImageManager;
// Explicitly tell Intervention to encode the image as PNG (instead of having to guess from the extension)
// Read exif data to orientate avatar only if EXIF extension is enabled
if (extension_loaded('exif')) {
$encodedImage = $manager->make($tmpFile)->orientate()->fit(100, 100)->encode('png', 100);
} else {
$encodedImage = $manager->make($tmpFile)->fit(100, 100)->encode('png', 100);
}
file_put_contents($tmpFile, $encodedImage);
$this->events->fire(
new AvatarWillBeSaved($user, $actor, $tmpFile)
);
$mount = new MountManager([
'source' => new Filesystem(new Local(pathinfo($tmpFile, PATHINFO_DIRNAME))),
'target' => $this->uploadDir,
]);
if ($user->avatar_path && $mount->has($file = "target://$user->avatar_path")) {
$mount->delete($file);
}
$uploadName = Str::lower(Str::quickRandom()).'.png';
$user->changeAvatarPath($uploadName);
$mount->move('source://'.pathinfo($tmpFile, PATHINFO_BASENAME), "target://$uploadName");
$user->save();
$this->dispatchEventsFor($user, $actor);
return $user;
} catch (Exception $e) {
@unlink($tmpFile);
throw $e;
}
}
}

View File

@@ -41,15 +41,15 @@ class UserServiceProvider extends AbstractServiceProvider
return $app->make('Illuminate\Contracts\Filesystem\Factory')->disk('flarum-avatars')->getDriver();
};
$this->app->when('Flarum\Core\Command\UploadAvatarHandler')
$this->app->when('Flarum\User\Command\UploadAvatarHandler')
->needs('League\Flysystem\FilesystemInterface')
->give($avatarsFilesystem);
$this->app->when('Flarum\Core\Command\DeleteAvatarHandler')
$this->app->when('Flarum\User\Command\DeleteAvatarHandler')
->needs('League\Flysystem\FilesystemInterface')
->give($avatarsFilesystem);
$this->app->when('Flarum\Core\Command\RegisterUserHandler')
$this->app->when('Flarum\User\Command\RegisterUserHandler')
->needs('League\Flysystem\FilesystemInterface')
->give($avatarsFilesystem);
}