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:
30
src/User/Command/ConfirmEmail.php
Normal file
30
src/User/Command/ConfirmEmail.php
Normal 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;
|
||||
}
|
||||
}
|
60
src/User/Command/ConfirmEmailHandler.php
Normal file
60
src/User/Command/ConfirmEmailHandler.php
Normal 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;
|
||||
}
|
||||
}
|
41
src/User/Command/DeleteAvatar.php
Normal file
41
src/User/Command/DeleteAvatar.php
Normal 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;
|
||||
}
|
||||
}
|
80
src/User/Command/DeleteAvatarHandler.php
Normal file
80
src/User/Command/DeleteAvatarHandler.php
Normal 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;
|
||||
}
|
||||
}
|
52
src/User/Command/DeleteUser.php
Normal file
52
src/User/Command/DeleteUser.php
Normal 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;
|
||||
}
|
||||
}
|
63
src/User/Command/DeleteUserHandler.php
Normal file
63
src/User/Command/DeleteUserHandler.php
Normal 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;
|
||||
}
|
||||
}
|
50
src/User/Command/EditUser.php
Normal file
50
src/User/Command/EditUser.php
Normal 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;
|
||||
}
|
||||
}
|
151
src/User/Command/EditUserHandler.php
Normal file
151
src/User/Command/EditUserHandler.php
Normal 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;
|
||||
}
|
||||
}
|
41
src/User/Command/RegisterUser.php
Normal file
41
src/User/Command/RegisterUser.php
Normal 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;
|
||||
}
|
||||
}
|
182
src/User/Command/RegisterUserHandler.php
Normal file
182
src/User/Command/RegisterUserHandler.php
Normal 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");
|
||||
}
|
||||
}
|
30
src/User/Command/RequestPasswordReset.php
Normal file
30
src/User/Command/RequestPasswordReset.php
Normal 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;
|
||||
}
|
||||
}
|
123
src/User/Command/RequestPasswordResetHandler.php
Normal file
123
src/User/Command/RequestPasswordResetHandler.php
Normal 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;
|
||||
}
|
||||
}
|
51
src/User/Command/UploadAvatar.php
Normal file
51
src/User/Command/UploadAvatar.php
Normal 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;
|
||||
}
|
||||
}
|
142
src/User/Command/UploadAvatarHandler.php
Normal file
142
src/User/Command/UploadAvatarHandler.php
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user