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

Extract new Flarum\User namespace

This commit is contained in:
Franz Liedke
2017-06-24 12:55:22 +02:00
parent fda8c597f4
commit 564ea8ff73
163 changed files with 405 additions and 394 deletions

View File

@@ -1,66 +0,0 @@
<?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\Core\Access;
use Flarum\Event\GetPermission;
use Flarum\Event\ScopeModelVisibility;
use Illuminate\Contracts\Events\Dispatcher;
abstract class AbstractPolicy
{
/**
* @var string
*/
protected $model;
/**
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(GetPermission::class, [$this, 'getPermission']);
$events->listen(GetPermission::class, [$this, 'getPermissionAfter'], -100);
$events->listen(ScopeModelVisibility::class, [$this, 'scopeModelVisibility']);
}
/**
* @param GetPermission $event
* @return bool|null
*/
public function getPermission(GetPermission $event)
{
if ($event->model instanceof $this->model && method_exists($this, $event->ability)) {
return call_user_func_array([$this, $event->ability], [$event->actor, $event->model]);
}
}
/**
* @param GetPermission $event
* @return bool|null
*/
public function getPermissionAfter(GetPermission $event)
{
if ($event->model instanceof $this->model && method_exists($this, 'after')) {
return call_user_func_array([$this, 'after'], [$event->actor, $event->ability, $event->model]);
}
}
/**
* @param ScopeModelVisibility $event
*/
public function scopeModelVisibility(ScopeModelVisibility $event)
{
if ($event->model instanceof $this->model && method_exists($this, 'find')) {
call_user_func_array([$this, 'find'], [$event->actor, $event->query]);
}
}
}

View File

@@ -11,8 +11,8 @@
namespace Flarum\Core\Access;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\Core\User;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\User\User;
trait AssertPermissionTrait
{
@@ -40,7 +40,7 @@ trait AssertPermissionTrait
/**
* @param User $actor
* @throws PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
protected function assertGuest(User $actor)
{

View File

@@ -13,10 +13,12 @@ namespace Flarum\Core\Access;
use Carbon\Carbon;
use Flarum\Core\Discussion;
use Flarum\Core\User;
use Flarum\Event\ScopeHiddenDiscussionVisibility;
use Flarum\Event\ScopePrivateDiscussionVisibility;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\AbstractPolicy;
use Flarum\User\Gate;
use Flarum\User\User;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\Eloquent\Builder;

View File

@@ -1,356 +0,0 @@
<?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\Core\Access;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Contracts\Container\Container;
use InvalidArgumentException;
/**
* @author Taylor Otwell
*/
class Gate implements GateContract
{
/**
* The container instance.
*
* @var Container
*/
protected $container;
/**
* The user resolver callable.
*
* @var callable
*/
protected $userResolver;
/**
* All of the defined abilities.
*
* @var array
*/
protected $abilities = [];
/**
* All of the defined policies.
*
* @var array
*/
protected $policies = [];
/**
* All of the registered before callbacks.
*
* @var array
*/
protected $beforeCallbacks = [];
/**
* Create a new gate instance.
*
* @param Container $container
* @param callable $userResolver
* @param array $abilities
* @param array $policies
* @param array $beforeCallbacks
* @return void
*/
public function __construct(Container $container, callable $userResolver, array $abilities = [], array $policies = [], array $beforeCallbacks = [])
{
$this->policies = $policies;
$this->container = $container;
$this->abilities = $abilities;
$this->userResolver = $userResolver;
$this->beforeCallbacks = $beforeCallbacks;
}
/**
* Determine if a given ability has been defined.
*
* @param string $ability
* @return bool
*/
public function has($ability)
{
return isset($this->abilities[$ability]);
}
/**
* Define a new ability.
*
* @param string $ability
* @param callable|string $callback
* @return $this
*
* @throws \InvalidArgumentException
*/
public function define($ability, $callback)
{
if (is_callable($callback)) {
$this->abilities[$ability] = $callback;
} elseif (is_string($callback) && str_contains($callback, '@')) {
$this->abilities[$ability] = $this->buildAbilityCallback($callback);
} else {
throw new InvalidArgumentException("Callback must be a callable or a 'Class@method' string.");
}
return $this;
}
/**
* Create the ability callback for a callback string.
*
* @param string $callback
* @return \Closure
*/
protected function buildAbilityCallback($callback)
{
return function () use ($callback) {
list($class, $method) = explode('@', $callback);
return call_user_func_array([$this->resolvePolicy($class), $method], func_get_args());
};
}
/**
* Define a policy class for a given class type.
*
* @param string $class
* @param string $policy
* @return $this
*/
public function policy($class, $policy)
{
$this->policies[$class] = $policy;
return $this;
}
/**
* Register a callback to run before all Gate checks.
*
* @param callable $callback
* @return $this
*/
public function before(callable $callback)
{
$this->beforeCallbacks[] = $callback;
return $this;
}
/**
* Determine if the given ability should be granted for the current user.
*
* @param string $ability
* @param array|mixed $arguments
* @return bool
*/
public function allows($ability, $arguments = [])
{
return $this->check($ability, $arguments);
}
/**
* Determine if the given ability should be denied for the current user.
*
* @param string $ability
* @param array|mixed $arguments
* @return bool
*/
public function denies($ability, $arguments = [])
{
return ! $this->allows($ability, $arguments);
}
/**
* Determine if the given ability should be granted for the current user.
*
* @param string $ability
* @param array|mixed $arguments
* @return bool
*/
public function check($ability, $arguments = [])
{
if (! $user = $this->resolveUser()) {
return false;
}
$arguments = is_array($arguments) ? $arguments : [$arguments];
if (! is_null($result = $this->callBeforeCallbacks($user, $ability, $arguments))) {
return $result;
}
$callback = $this->resolveAuthCallback($user, $ability, $arguments);
return call_user_func_array($callback, array_merge([$user], $arguments));
}
/**
* Call all of the before callbacks and return if a result is given.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $ability
* @param array $arguments
* @return bool|void
*/
protected function callBeforeCallbacks($user, $ability, array $arguments)
{
$arguments = array_merge([$user, $ability], $arguments);
foreach ($this->beforeCallbacks as $before) {
if (! is_null($result = call_user_func_array($before, $arguments))) {
return $result;
}
}
}
/**
* Resolve the callable for the given ability and arguments.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $ability
* @param array $arguments
* @return callable
*/
protected function resolveAuthCallback($user, $ability, array $arguments)
{
if ($this->firstArgumentCorrespondsToPolicy($arguments)) {
return $this->resolvePolicyCallback($user, $ability, $arguments);
} elseif (isset($this->abilities[$ability])) {
return $this->abilities[$ability];
} else {
return function () {
return false;
};
}
}
/**
* Determine if the first argument in the array corresponds to a policy.
*
* @param array $arguments
* @return bool
*/
protected function firstArgumentCorrespondsToPolicy(array $arguments)
{
if (! isset($arguments[0])) {
return false;
}
if (is_object($arguments[0])) {
return isset($this->policies[get_class($arguments[0])]);
}
return is_string($arguments[0]) && isset($this->policies[$arguments[0]]);
}
/**
* Resolve the callback for a policy check.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $ability
* @param array $arguments
* @return callable
*/
protected function resolvePolicyCallback($user, $ability, array $arguments)
{
return function () use ($user, $ability, $arguments) {
$instance = $this->getPolicyFor($arguments[0]);
if (method_exists($instance, 'before')) {
// We will prepend the user and ability onto the arguments so that the before
// callback can determine which ability is being called. Then we will call
// into the policy before methods with the arguments and get the result.
$beforeArguments = array_merge([$user, $ability], $arguments);
$result = call_user_func_array([$instance, 'before'], $beforeArguments);
// If we recieved a non-null result from the before method, we will return it
// as the result of a check. This allows developers to override the checks
// in the policy and return a result for all rules defined in the class.
if (! is_null($result)) {
return $result;
}
}
if (! is_callable([$instance, $ability])) {
return false;
}
return call_user_func_array([$instance, $ability], array_merge([$user], $arguments));
};
}
/**
* Get a policy instance for a given class.
*
* @param object|string $class
* @return mixed
*
* @throws \InvalidArgumentException
*/
public function getPolicyFor($class)
{
if (is_object($class)) {
$class = get_class($class);
}
if (! isset($this->policies[$class])) {
throw new InvalidArgumentException("Policy not defined for [{$class}].");
}
return $this->resolvePolicy($this->policies[$class]);
}
/**
* Build a policy class instance of the given type.
*
* @param object|string $class
* @return mixed
*/
public function resolvePolicy($class)
{
return $this->container->make($class);
}
/**
* Get a guard instance for the given user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable|mixed $user
* @return static
*/
public function forUser($user)
{
return new static(
$this->container,
function () use ($user) {
return $user;
},
$this->abilities,
$this->policies,
$this->beforeCallbacks
);
}
/**
* Resolve the user from the user resolver.
*
* @return mixed
*/
protected function resolveUser()
{
return call_user_func($this->userResolver);
}
}

View File

@@ -12,7 +12,8 @@
namespace Flarum\Core\Access;
use Flarum\Core\Group;
use Flarum\Core\User;
use Flarum\User\AbstractPolicy;
use Flarum\User\User;
class GroupPolicy extends AbstractPolicy
{

View File

@@ -13,10 +13,11 @@ namespace Flarum\Core\Access;
use Carbon\Carbon;
use Flarum\Core\Post;
use Flarum\Core\User;
use Flarum\Event\ScopePostVisibility;
use Flarum\Event\ScopePrivatePostVisibility;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\AbstractPolicy;
use Flarum\User\User;
use Illuminate\Contracts\Events\Dispatcher;
class PostPolicy extends AbstractPolicy

View File

@@ -1,46 +0,0 @@
<?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\Core\Access;
use Flarum\Core\User;
use Illuminate\Database\Eloquent\Builder;
class UserPolicy extends AbstractPolicy
{
/**
* {@inheritdoc}
*/
protected $model = User::class;
/**
* @param User $actor
* @param string $ability
* @return bool|null
*/
public function after(User $actor, $ability)
{
if ($actor->hasPermission('user.'.$ability)) {
return true;
}
}
/**
* @param User $actor
* @param Builder $query
*/
public function find(User $actor, Builder $query)
{
if ($actor->cannot('viewDiscussions')) {
$query->whereRaw('FALSE');
}
}
}

View File

@@ -1,99 +0,0 @@
<?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\Core;
use DateTime;
use Flarum\Core\Exception\InvalidConfirmationTokenException;
use Flarum\Database\AbstractModel;
/**
* @todo document database columns with @property
*/
class AuthToken extends AbstractModel
{
/**
* {@inheritdoc}
*/
protected $table = 'auth_tokens';
/**
* {@inheritdoc}
*/
protected $dates = ['created_at'];
/**
* Use a custom primary key for this model.
*
* @var bool
*/
public $incrementing = false;
/**
* Generate an email token for the specified user.
*
* @param string $email
*
* @return static
*/
public static function generate($payload)
{
$token = new static;
$token->id = str_random(40);
$token->payload = $payload;
$token->created_at = time();
return $token;
}
/**
* Unserialize the payload attribute from the database's JSON value.
*
* @param string $value
* @return string
*/
public function getPayloadAttribute($value)
{
return json_decode($value, true);
}
/**
* Serialize the payload attribute to be stored in the database as JSON.
*
* @param string $value
*/
public function setPayloadAttribute($value)
{
$this->attributes['payload'] = json_encode($value);
}
/**
* Find the token with the given ID, and assert that it has not expired.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $id
*
* @throws InvalidConfirmationTokenException
*
* @return static
*/
public function scopeValidOrFail($query, $id)
{
$token = $query->find($id);
if (! $token || $token->created_at < new DateTime('-1 day')) {
throw new InvalidConfirmationTokenException;
}
return $token;
}
}

View File

@@ -11,8 +11,8 @@
namespace Flarum\Core\Command;
use Flarum\Core\EmailToken;
use Flarum\Core\Repository\UserRepository;
use Flarum\User\EmailToken;
use Flarum\User\UserRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Illuminate\Contracts\Events\Dispatcher;
@@ -21,12 +21,12 @@ class ConfirmEmailHandler
use DispatchEventsTrait;
/**
* @var UserRepository
* @var \Flarum\User\UserRepository
*/
protected $users;
/**
* @param UserRepository $users
* @param \Flarum\User\UserRepository $users
*/
public function __construct(Dispatcher $events, UserRepository $users)
{
@@ -36,7 +36,7 @@ class ConfirmEmailHandler
/**
* @param ConfirmEmail $command
* @return \Flarum\Core\User
* @return \Flarum\User\User
*/
public function handle(ConfirmEmail $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class CreateGroup
{

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\Core\Group;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Core\Validator\GroupValidator;
@@ -42,7 +42,7 @@ class CreateGroupHandler
/**
* @param CreateGroup $command
* @return Group
* @throws PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(CreateGroup $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class DeleteAvatar
{

View File

@@ -12,8 +12,8 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\Core\Repository\UserRepository;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\User\UserRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Event\AvatarWillBeDeleted;
use Illuminate\Contracts\Events\Dispatcher;
@@ -48,8 +48,8 @@ class DeleteAvatarHandler
/**
* @param DeleteAvatar $command
* @return \Flarum\Core\User
* @throws PermissionDeniedException
* @return \Flarum\User\User
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(DeleteAvatar $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class DeleteDiscussion
{

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\Core\Repository\DiscussionRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Event\DiscussionWillBeDeleted;

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class DeleteGroup
{

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\Core\Repository\GroupRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Event\GroupWillBeDeleted;

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class DeletePost
{

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\Core\Repository\PostRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Event\PostWillBeDeleted;
@@ -41,7 +41,7 @@ class DeletePostHandler
/**
* @param DeletePost $command
* @return \Flarum\Core\Post
* @throws PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(DeletePost $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class DeleteUser
{

View File

@@ -12,10 +12,10 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\Core\Repository\UserRepository;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\User\UserRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Event\UserWillBeDeleted;
use Flarum\User\Event\Deleting;
use Illuminate\Contracts\Events\Dispatcher;
class DeleteUserHandler
@@ -40,7 +40,7 @@ class DeleteUserHandler
/**
* @param DeleteUser $command
* @return \Flarum\Core\User
* @return \Flarum\User\User
* @throws PermissionDeniedException
*/
public function handle(DeleteUser $command)
@@ -51,7 +51,7 @@ class DeleteUserHandler
$this->assertCan($actor, 'delete', $user);
$this->events->fire(
new UserWillBeDeleted($user, $actor, $command->data)
new Deleting($user, $actor, $command->data)
);
$user->delete();

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class EditDiscussion
{
@@ -25,7 +25,7 @@ class EditDiscussion
/**
* The user performing the action.
*
* @var \Flarum\Core\User
* @var \Flarum\User\User
*/
public $actor;
@@ -38,7 +38,7 @@ class EditDiscussion
/**
* @param int $discussionId The ID of the discussion to edit.
* @param \Flarum\Core\User $actor The user performing the action.
* @param \Flarum\User\User $actor The user performing the action.
* @param array $data The attributes to update on the discussion.
*/
public function __construct($discussionId, User $actor, array $data)

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\Core\Repository\DiscussionRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Core\Validator\DiscussionValidator;
@@ -49,7 +49,7 @@ class EditDiscussionHandler
/**
* @param EditDiscussion $command
* @return \Flarum\Core\Discussion
* @throws PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(EditDiscussion $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class EditGroup
{

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\Core\Group;
use Flarum\Core\Repository\GroupRepository;
use Flarum\Core\Support\DispatchEventsTrait;

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class EditPost
{

View File

@@ -49,7 +49,7 @@ class EditPostHandler
/**
* @param EditPost $command
* @return \Flarum\Core\Post
* @throws \Flarum\Core\Exception\PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(EditPost $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class EditUser
{

View File

@@ -12,12 +12,12 @@
namespace Flarum\Core\Command;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Repository\UserRepository;
use Flarum\User\UserRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Core\User;
use Flarum\Core\Validator\UserValidator;
use Flarum\Event\UserGroupsWereChanged;
use Flarum\Event\UserWillBeSaved;
use Flarum\User\User;
use Flarum\User\UserValidator;
use Flarum\User\Event\GroupsChanged;
use Flarum\User\Event\Saving;
use Illuminate\Contracts\Events\Dispatcher;
class EditUserHandler
@@ -26,7 +26,7 @@ class EditUserHandler
use AssertPermissionTrait;
/**
* @var UserRepository
* @var \Flarum\User\UserRepository
*/
protected $users;
@@ -37,7 +37,7 @@ class EditUserHandler
/**
* @param Dispatcher $events
* @param UserRepository $users
* @param \Flarum\User\UserRepository $users
* @param UserValidator $validator
*/
public function __construct(Dispatcher $events, UserRepository $users, UserValidator $validator)
@@ -50,7 +50,7 @@ class EditUserHandler
/**
* @param EditUser $command
* @return User
* @throws \Flarum\Core\Exception\PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(EditUser $command)
{
@@ -127,7 +127,7 @@ class EditUserHandler
}
$user->raise(
new UserGroupsWereChanged($user, $user->groups()->get()->all())
new GroupsChanged($user, $user->groups()->get()->all())
);
$user->afterSave(function (User $user) use ($newGroupIds) {
@@ -136,7 +136,7 @@ class EditUserHandler
}
$this->events->fire(
new UserWillBeSaved($user, $actor, $data)
new Saving($user, $actor, $data)
);
$this->validator->setUser($user);

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class PostReply
{

View File

@@ -62,7 +62,7 @@ class PostReplyHandler
/**
* @param PostReply $command
* @return CommentPost
* @throws \Flarum\Core\Exception\PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(PostReply $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class ReadAllNotifications
{

View File

@@ -33,7 +33,7 @@ class ReadAllNotificationsHandler
/**
* @param ReadAllNotifications $command
* @throws \Flarum\Core\Exception\PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(ReadAllNotifications $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class ReadDiscussion
{

View File

@@ -40,7 +40,7 @@ class ReadDiscussionHandler
/**
* @param ReadDiscussion $command
* @return \Flarum\Core\DiscussionState
* @throws \Flarum\Core\Exception\PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(ReadDiscussion $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class ReadNotification
{

View File

@@ -21,7 +21,7 @@ class ReadNotificationHandler
/**
* @param ReadNotification $command
* @return \Flarum\Core\Notification
* @throws \Flarum\Core\Exception\PermissionDeniedException
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(ReadNotification $command)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class RegisterUser
{

View File

@@ -13,12 +13,12 @@ namespace Flarum\Core\Command;
use Exception;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\AuthToken;
use Flarum\Core\Exception\PermissionDeniedException;
use Flarum\User\AuthToken;
use Flarum\User\Exception\PermissionDeniedException;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Core\User;
use Flarum\Core\Validator\UserValidator;
use Flarum\Event\UserWillBeSaved;
use Flarum\User\User;
use Flarum\User\UserValidator;
use Flarum\User\Event\Saving;
use Flarum\Foundation\Application;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Events\Dispatcher;
@@ -83,7 +83,7 @@ class RegisterUserHandler
* @param RegisterUser $command
* @throws PermissionDeniedException if signup is closed and the actor is
* not an administrator.
* @throws \Flarum\Core\Exception\InvalidConfirmationTokenException if an
* @throws \Flarum\User\Exception\InvalidConfirmationTokenException if an
* email confirmation token is provided but is invalid.
* @return User
*/
@@ -131,7 +131,7 @@ class RegisterUserHandler
}
$this->events->fire(
new UserWillBeSaved($user, $actor, $data)
new Saving($user, $actor, $data)
);
$this->validator->assertValid(array_merge($user->getAttributes(), compact('password')));

View File

@@ -12,8 +12,8 @@
namespace Flarum\Core\Command;
use Flarum\Core;
use Flarum\Core\PasswordToken;
use Flarum\Core\Repository\UserRepository;
use Flarum\User\PasswordToken;
use Flarum\User\UserRepository;
use Flarum\Forum\UrlGenerator;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Mail\Mailer;
@@ -56,7 +56,7 @@ class RequestPasswordResetHandler
protected $validatorFactory;
/**
* @param UserRepository $users
* @param \Flarum\User\UserRepository $users
* @param SettingsRepositoryInterface $settings
* @param Mailer $mailer
* @param UrlGenerator $url
@@ -81,7 +81,7 @@ class RequestPasswordResetHandler
/**
* @param RequestPasswordReset $command
* @return \Flarum\Core\User
* @return \Flarum\User\User
* @throws ModelNotFoundException
*/
public function handle(RequestPasswordReset $command)

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
class StartDiscussion
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Command;
use Flarum\Core\User;
use Flarum\User\User;
use Psr\Http\Message\UploadedFileInterface;
class UploadAvatar

View File

@@ -13,9 +13,9 @@ namespace Flarum\Core\Command;
use Exception;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Core\Repository\UserRepository;
use Flarum\User\UserRepository;
use Flarum\Core\Support\DispatchEventsTrait;
use Flarum\Core\Validator\AvatarValidator;
use Flarum\User\AvatarValidator;
use Flarum\Event\AvatarWillBeSaved;
use Flarum\Foundation\Application;
use Illuminate\Contracts\Events\Dispatcher;
@@ -33,7 +33,7 @@ class UploadAvatarHandler
use AssertPermissionTrait;
/**
* @var UserRepository
* @var \Flarum\User\UserRepository
*/
protected $users;
@@ -48,7 +48,7 @@ class UploadAvatarHandler
protected $app;
/**
* @var AvatarValidator
* @var \Flarum\User\AvatarValidator
*/
protected $validator;
@@ -57,7 +57,7 @@ class UploadAvatarHandler
* @param UserRepository $users
* @param FilesystemInterface $uploadDir
* @param Application $app
* @param AvatarValidator $validator
* @param \Flarum\User\AvatarValidator $validator
*/
public function __construct(Dispatcher $events, UserRepository $users, FilesystemInterface $uploadDir, Application $app, AvatarValidator $validator)
{
@@ -70,8 +70,8 @@ class UploadAvatarHandler
/**
* @param UploadAvatar $command
* @return \Flarum\Core\User
* @throws \Flarum\Core\Exception\PermissionDeniedException
* @return \Flarum\User\User
* @throws \Flarum\User\Exception\PermissionDeniedException
*/
public function handle(UploadAvatar $command)
{

View File

@@ -11,12 +11,13 @@
namespace Flarum\Core;
use Flarum\Core\Access\Gate;
use Flarum\Core\Post\CommentPost;
use Flarum\Event\ConfigurePostTypes;
use Flarum\Event\ConfigureUserPreferences;
use Flarum\Event\GetPermission;
use Flarum\Foundation\AbstractServiceProvider;
use Flarum\User\Gate;
use Flarum\User\User;
use Illuminate\Contracts\Container\Container;
use RuntimeException;
@@ -34,7 +35,7 @@ class CoreServiceProvider extends AbstractServiceProvider
});
$this->app->alias('flarum.gate', 'Illuminate\Contracts\Auth\Access\Gate');
$this->app->alias('flarum.gate', 'Flarum\Core\Access\Gate');
$this->app->alias('flarum.gate', 'Flarum\User\Gate');
$this->registerAvatarsFilesystem();
@@ -106,15 +107,15 @@ class CoreServiceProvider extends AbstractServiceProvider
$events->subscribe('Flarum\Core\Listener\SelfDemotionGuard');
$events->subscribe('Flarum\Core\Listener\DiscussionMetadataUpdater');
$events->subscribe('Flarum\Core\Listener\UserMetadataUpdater');
$events->subscribe('Flarum\User\UserMetadataUpdater');
$events->subscribe('Flarum\Core\Listener\ExtensionValidator');
$events->subscribe('Flarum\Core\Listener\EmailConfirmationMailer');
$events->subscribe('Flarum\User\EmailConfirmationMailer');
$events->subscribe('Flarum\Core\Listener\DiscussionRenamedNotifier');
$events->subscribe('Flarum\Core\Access\DiscussionPolicy');
$events->subscribe('Flarum\Core\Access\GroupPolicy');
$events->subscribe('Flarum\Core\Access\PostPolicy');
$events->subscribe('Flarum\Core\Access\UserPolicy');
$events->subscribe('Flarum\User\UserPolicy');
$events->listen(ConfigureUserPreferences::class, [$this, 'configureUserPreferences']);
}

View File

@@ -22,6 +22,8 @@ use Flarum\Event\DiscussionWasRestored;
use Flarum\Event\DiscussionWasStarted;
use Flarum\Event\PostWasDeleted;
use Flarum\Event\ScopePostVisibility;
use Flarum\User\Guest;
use Flarum\User\User;
use Flarum\Util\Str;
/**
@@ -363,7 +365,7 @@ class Discussion extends AbstractModel
*/
public function startUser()
{
return $this->belongsTo('Flarum\Core\User', 'start_user_id');
return $this->belongsTo('Flarum\User\User', 'start_user_id');
}
/**
@@ -383,7 +385,7 @@ class Discussion extends AbstractModel
*/
public function lastUser()
{
return $this->belongsTo('Flarum\Core\User', 'last_user_id');
return $this->belongsTo('Flarum\User\User', 'last_user_id');
}
/**
@@ -393,7 +395,7 @@ class Discussion extends AbstractModel
*/
public function readers()
{
return $this->belongsToMany('Flarum\Core\User', 'users_discussions');
return $this->belongsToMany('Flarum\User\User', 'users_discussions');
}
/**

View File

@@ -28,7 +28,7 @@ use Illuminate\Database\Eloquent\Builder;
* @property \Carbon\Carbon|null $read_time
* @property int|null $read_number
* @property Discussion $discussion
* @property \Flarum\Core\User $user
* @property \Flarum\User\User $user
*/
class DiscussionState extends AbstractModel
{
@@ -80,7 +80,7 @@ class DiscussionState extends AbstractModel
*/
public function user()
{
return $this->belongsTo('Flarum\Core\User', 'user_id');
return $this->belongsTo('Flarum\User\User', 'user_id');
}
/**

View File

@@ -1,88 +0,0 @@
<?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\Core;
use DateTime;
use Flarum\Core\Exception\InvalidConfirmationTokenException;
use Flarum\Database\AbstractModel;
/**
* @todo document database columns with @property
*/
class EmailToken extends AbstractModel
{
/**
* {@inheritdoc}
*/
protected $table = 'email_tokens';
/**
* {@inheritdoc}
*/
protected $dates = ['created_at'];
/**
* Use a custom primary key for this model.
*
* @var bool
*/
public $incrementing = false;
/**
* Generate an email token for the specified user.
*
* @param string $email
* @param int $userId
*
* @return static
*/
public static function generate($email, $userId)
{
$token = new static;
$token->id = str_random(40);
$token->user_id = $userId;
$token->email = $email;
$token->created_at = time();
return $token;
}
/**
* Define the relationship with the owner of this email token.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('Flarum\Core\User');
}
/**
* Find the token with the given ID, and assert that it has not expired.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $id
* @return static
* @throws InvalidConfirmationTokenException
*/
public function scopeValidOrFail($query, $id)
{
$token = $query->find($id);
if (! $token || $token->created_at < new DateTime('-1 day')) {
throw new InvalidConfirmationTokenException;
}
return $token;
}
}

View File

@@ -1,18 +0,0 @@
<?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\Core\Exception;
use Exception;
class InvalidConfirmationTokenException extends Exception
{
}

View File

@@ -1,22 +0,0 @@
<?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\Core\Exception;
use Exception;
class PermissionDeniedException extends Exception
{
public function __construct($message = null, $code = 403, Exception $previous = null)
{
parent::__construct($message, $code, $previous);
}
}

View File

@@ -120,7 +120,7 @@ class Group extends AbstractModel
*/
public function users()
{
return $this->belongsToMany('Flarum\Core\User', 'users_groups');
return $this->belongsToMany('Flarum\User\User', 'users_groups');
}
/**

View File

@@ -1,44 +0,0 @@
<?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\Core;
class Guest extends User
{
/**
* Override the ID of this user, as a guest does not have an ID.
*
* @var int
*/
public $id = 0;
/**
* Get the guest's group, containing only the 'guests' group model.
*
* @return Group
*/
public function getGroupsAttribute()
{
if (! isset($this->attributes['groups'])) {
$this->attributes['groups'] = $this->relations['groups'] = Group::where('id', Group::GUEST_ID)->get();
}
return $this->attributes['groups'];
}
/**
* {@inheritdoc}
*/
public function isGuest()
{
return true;
}
}

View File

@@ -1,138 +0,0 @@
<?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\Core\Listener;
use Flarum\Core;
use Flarum\Core\EmailToken;
use Flarum\Core\User;
use Flarum\Event\UserEmailChangeWasRequested;
use Flarum\Event\UserWasRegistered;
use Flarum\Forum\UrlGenerator;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Mail\Message;
use Symfony\Component\Translation\TranslatorInterface;
class EmailConfirmationMailer
{
/**
* @var SettingsRepositoryInterface
*/
protected $settings;
/**
* @var Mailer
*/
protected $mailer;
/**
* @var UrlGenerator
*/
protected $url;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @param \Flarum\Settings\SettingsRepositoryInterface $settings
* @param Mailer $mailer
* @param UrlGenerator $url
* @param TranslatorInterface $translator
*/
public function __construct(SettingsRepositoryInterface $settings, Mailer $mailer, UrlGenerator $url, TranslatorInterface $translator)
{
$this->settings = $settings;
$this->mailer = $mailer;
$this->url = $url;
$this->translator = $translator;
}
/**
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(UserWasRegistered::class, [$this, 'whenUserWasRegistered']);
$events->listen(UserEmailChangeWasRequested::class, [$this, 'whenUserEmailChangeWasRequested']);
}
/**
* @param \Flarum\Event\UserWasRegistered $event
*/
public function whenUserWasRegistered(UserWasRegistered $event)
{
$user = $event->user;
if ($user->is_activated) {
return;
}
$data = $this->getEmailData($user, $user->email);
$body = $this->translator->trans('core.email.activate_account.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.activate_account.subject'));
});
}
/**
* @param \Flarum\Event\UserEmailChangeWasRequested $event
*/
public function whenUserEmailChangeWasRequested(UserEmailChangeWasRequested $event)
{
$email = $event->email;
$data = $this->getEmailData($event->user, $email);
$body = $this->translator->trans('core.email.confirm_email.body', $data);
$this->mailer->raw($body, function (Message $message) use ($email, $data) {
$message->to($email);
$message->subject('['.$data['{forum}'].'] '.$this->translator->trans('core.email.confirm_email.subject'));
});
}
/**
* @param User $user
* @param string $email
* @return EmailToken
*/
protected function generateToken(User $user, $email)
{
$token = EmailToken::generate($email, $user->id);
$token->save();
return $token;
}
/**
* Get the data that should be made available to email templates.
*
* @param User $user
* @param string $email
* @return array
*/
protected function getEmailData(User $user, $email)
{
$token = $this->generateToken($user, $email);
return [
'{username}' => $user->username,
'{url}' => $this->url->toRoute('confirmEmail', ['token' => $token->id]),
'{forum}' => $this->settings->get('forum_title')
];
}
}

View File

@@ -1,114 +0,0 @@
<?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\Core\Listener;
use Flarum\Core\Discussion;
use Flarum\Core\Post;
use Flarum\Event\DiscussionWasDeleted;
use Flarum\Event\DiscussionWasStarted;
use Flarum\Event\PostWasDeleted;
use Flarum\Event\PostWasHidden;
use Flarum\Event\PostWasPosted;
use Flarum\Event\PostWasRestored;
use Illuminate\Contracts\Events\Dispatcher;
class UserMetadataUpdater
{
/**
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(PostWasPosted::class, [$this, 'whenPostWasPosted']);
$events->listen(PostWasDeleted::class, [$this, 'whenPostWasDeleted']);
$events->listen(PostWasHidden::class, [$this, 'whenPostWasHidden']);
$events->listen(PostWasRestored::class, [$this, 'whenPostWasRestored']);
$events->listen(DiscussionWasStarted::class, [$this, 'whenDiscussionWasStarted']);
$events->listen(DiscussionWasDeleted::class, [$this, 'whenDiscussionWasDeleted']);
}
/**
* @param PostWasPosted $event
*/
public function whenPostWasPosted(PostWasPosted $event)
{
$this->updateCommentsCount($event->post, 1);
}
/**
* @param \Flarum\Event\PostWasDeleted $event
*/
public function whenPostWasDeleted(PostWasDeleted $event)
{
$this->updateCommentsCount($event->post, -1);
}
/**
* @param PostWasHidden $event
*/
public function whenPostWasHidden(PostWasHidden $event)
{
$this->updateCommentsCount($event->post, -1);
}
/**
* @param \Flarum\Event\PostWasRestored $event
*/
public function whenPostWasRestored(PostWasRestored $event)
{
$this->updateCommentsCount($event->post, 1);
}
/**
* @param \Flarum\Events\DiscussionWasStarted $event
*/
public function whenDiscussionWasStarted(DiscussionWasStarted $event)
{
$this->updateDiscussionsCount($event->discussion, 1);
}
/**
* @param \Flarum\Event\DiscussionWasDeleted $event
*/
public function whenDiscussionWasDeleted(DiscussionWasDeleted $event)
{
$this->updateDiscussionsCount($event->discussion, -1);
}
/**
* @param Post $post
* @param int $amount
*/
protected function updateCommentsCount(Post $post, $amount)
{
$user = $post->user;
if ($user && $user->exists) {
$user->comments_count += $amount;
$user->save();
}
}
/**
* @param Discussion $discussion
* @param int $amount
*/
protected function updateDiscussionsCount(Discussion $discussion, $amount)
{
$user = $discussion->startUser;
if ($user && $user->exists) {
$user->discussions_count += $amount;
$user->save();
}
}
}

View File

@@ -36,8 +36,8 @@ use Flarum\Database\AbstractModel;
* @property \Carbon\Carbon $time
* @property bool $is_read
* @property bool $is_deleted
* @property \Flarum\Core\User|null $user
* @property \Flarum\Core\User|null $sender
* @property \Flarum\User\User|null $user
* @property \Flarum\User\User|null $sender
* @property \Flarum\Database\AbstractModel|null $subject
*/
class Notification extends AbstractModel
@@ -113,7 +113,7 @@ class Notification extends AbstractModel
*/
public function user()
{
return $this->belongsTo('Flarum\Core\User', 'user_id');
return $this->belongsTo('Flarum\User\User', 'user_id');
}
/**
@@ -123,7 +123,7 @@ class Notification extends AbstractModel
*/
public function sender()
{
return $this->belongsTo('Flarum\Core\User', 'sender_id');
return $this->belongsTo('Flarum\User\User', 'sender_id');
}
/**

View File

@@ -21,7 +21,7 @@ interface BlueprintInterface
/**
* Get the user that sent the notification.
*
* @return \Flarum\Core\User|null
* @return \Flarum\User\User|null
*/
public function getSender();

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Notification;
use Flarum\Core\User;
use Flarum\User\User;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Mail\Message;

View File

@@ -12,9 +12,9 @@
namespace Flarum\Core\Notification;
use Flarum\Core\Notification;
use Flarum\Core\User;
use Flarum\Event\ConfigureNotificationTypes;
use Flarum\Foundation\AbstractServiceProvider;
use Flarum\User\User;
use ReflectionClass;
class NotificationServiceProvider extends AbstractServiceProvider

View File

@@ -14,8 +14,8 @@ namespace Flarum\Core\Notification;
use Carbon\Carbon;
use Flarum\Core\Notification;
use Flarum\Core\Repository\NotificationRepository;
use Flarum\Core\User;
use Flarum\Event\NotificationWillBeSent;
use Flarum\User\User;
/**
* The Notification Syncer commits notification blueprints to the database, and

View File

@@ -1,64 +0,0 @@
<?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\Core;
use Flarum\Database\AbstractModel;
/**
* @todo document database columns with @property
*/
class PasswordToken extends AbstractModel
{
/**
* {@inheritdoc}
*/
protected $table = 'password_tokens';
/**
* {@inheritdoc}
*/
protected $dates = ['created_at'];
/**
* Use a custom primary key for this model.
*
* @var bool
*/
public $incrementing = false;
/**
* Generate a password token for the specified user.
*
* @param int $userId
* @return static
*/
public static function generate($userId)
{
$token = new static;
$token->id = str_random(40);
$token->user_id = $userId;
$token->created_at = time();
return $token;
}
/**
* Define the relationship with the owner of this password token.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('Flarum\Core\User');
}
}

View File

@@ -139,7 +139,7 @@ class Post extends AbstractModel
*/
public function user()
{
return $this->belongsTo('Flarum\Core\User', 'user_id');
return $this->belongsTo('Flarum\User\User', 'user_id');
}
/**
@@ -149,7 +149,7 @@ class Post extends AbstractModel
*/
public function editUser()
{
return $this->belongsTo('Flarum\Core\User', 'edit_user_id');
return $this->belongsTo('Flarum\User\User', 'edit_user_id');
}
/**
@@ -159,7 +159,7 @@ class Post extends AbstractModel
*/
public function hideUser()
{
return $this->belongsTo('Flarum\Core\User', 'hide_user_id');
return $this->belongsTo('Flarum\User\User', 'hide_user_id');
}
/**

View File

@@ -12,12 +12,12 @@
namespace Flarum\Core\Post;
use Flarum\Core\Post;
use Flarum\Core\User;
use Flarum\Event\PostWasHidden;
use Flarum\Event\PostWasPosted;
use Flarum\Event\PostWasRestored;
use Flarum\Event\PostWasRevised;
use Flarum\Formatter\Formatter;
use Flarum\User\User;
/**
* A standard comment in a discussion.

View File

@@ -14,7 +14,7 @@ namespace Flarum\Core\Post;
use DateTime;
use Flarum\Core\Exception\FloodingException;
use Flarum\Core\Post;
use Flarum\Core\User;
use Flarum\User\User;
class Floodgate
{

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Repository;
use Flarum\Core\Discussion;
use Flarum\Core\User;
use Flarum\User\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Expression;

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Repository;
use Flarum\Core\Group;
use Flarum\Core\User;
use Flarum\User\User;
use Illuminate\Database\Eloquent\Builder;
class GroupRepository

View File

@@ -12,7 +12,7 @@
namespace Flarum\Core\Repository;
use Flarum\Core\Notification;
use Flarum\Core\User;
use Flarum\User\User;
class NotificationRepository
{

View File

@@ -13,8 +13,8 @@ namespace Flarum\Core\Repository;
use Flarum\Core\Discussion;
use Flarum\Core\Post;
use Flarum\Core\User;
use Flarum\Event\ScopePostVisibility;
use Flarum\User\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;
class PostRepository
@@ -34,7 +34,7 @@ class PostRepository
* user, or throw an exception.
*
* @param int $id
* @param \Flarum\Core\User $actor
* @param \Flarum\User\User $actor
* @return \Flarum\Core\Post
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
@@ -55,7 +55,7 @@ class PostRepository
* are visible to a certain user, and/or using other criteria.
*
* @param array $where
* @param \Flarum\Core\User|null $actor
* @param \Flarum\User\User|null $actor
* @param array $sort
* @param int $count
* @param int $start
@@ -81,7 +81,7 @@ class PostRepository
* certain user.
*
* @param array $ids
* @param \Flarum\Core\User|null $actor
* @param \Flarum\User\User|null $actor
* @return \Illuminate\Database\Eloquent\Collection
*/
public function findByIds(array $ids, User $actor = null)
@@ -122,7 +122,7 @@ class PostRepository
*
* @param int $discussionId
* @param int $number
* @param \Flarum\Core\User|null $actor
* @param \Flarum\User\User|null $actor
* @return int
*/
public function getIndexForNumber($discussionId, $number, User $actor = null)

View File

@@ -1,116 +0,0 @@
<?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\Core\Repository;
use Flarum\Core\User;
use Illuminate\Database\Eloquent\Builder;
class UserRepository
{
/**
* Get a new query builder for the users table.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function query()
{
return User::query();
}
/**
* Find a user by ID, optionally making sure it is visible to a certain
* user, or throw an exception.
*
* @param int $id
* @param User $actor
* @return User
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function findOrFail($id, User $actor = null)
{
$query = User::where('id', $id);
return $this->scopeVisibleTo($query, $actor)->firstOrFail();
}
/**
* Find a user by an identification (username or email).
*
* @param string $identification
* @return User|null
*/
public function findByIdentification($identification)
{
$field = filter_var($identification, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
return User::where($field, $identification)->first();
}
/**
* Find a user by email.
*
* @param string $email
* @return User|null
*/
public function findByEmail($email)
{
return User::where('email', $email)->first();
}
/**
* Get the ID of a user with the given username.
*
* @param string $username
* @param User|null $actor
* @return int|null
*/
public function getIdForUsername($username, User $actor = null)
{
$query = User::where('username', 'like', $username);
return $this->scopeVisibleTo($query, $actor)->value('id');
}
/**
* Find users by matching a string of words against their username,
* optionally making sure they are visible to a certain user.
*
* @param string $string
* @param User|null $actor
* @return array
*/
public function getIdsForUsername($string, User $actor = null)
{
$query = User::where('username', 'like', '%'.$string.'%')
->orderByRaw('username = ? desc', [$string])
->orderByRaw('username like ? desc', [$string.'%']);
return $this->scopeVisibleTo($query, $actor)->lists('id');
}
/**
* Scope a query to only include records that are visible to a user.
*
* @param Builder $query
* @param User $actor
* @return Builder
*/
protected function scopeVisibleTo(Builder $query, User $actor = null)
{
if ($actor !== null) {
$query->whereVisibleTo($actor);
}
return $query;
}
}

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Search;
use Flarum\Core\User;
use Flarum\User\User;
use Illuminate\Database\Query\Builder;
/**

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Search\Discussion\Gambit;
use Flarum\Core\Repository\UserRepository;
use Flarum\User\UserRepository;
use Flarum\Core\Search\AbstractRegexGambit;
use Flarum\Core\Search\AbstractSearch;
use Flarum\Core\Search\Discussion\DiscussionSearch;
@@ -25,12 +25,12 @@ class AuthorGambit extends AbstractRegexGambit
protected $pattern = 'author:(.+)';
/**
* @var UserRepository
* @var \Flarum\User\UserRepository
*/
protected $users;
/**
* @param \Flarum\Core\Repository\UserRepository $users
* @param \Flarum\User\UserRepository $users
*/
public function __construct(UserRepository $users)
{

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Search;
use Flarum\Core\User;
use Flarum\User\User;
/**
* Represents the criteria that will determine the entire result set of a

View File

@@ -37,14 +37,14 @@ class SearchServiceProvider extends AbstractServiceProvider
public function registerUserGambits()
{
$this->app->when('Flarum\Core\Search\User\UserSearcher')
$this->app->when('Flarum\Core\User\Search\UserSearcher')
->needs('Flarum\Core\Search\GambitManager')
->give(function (Container $app) {
$gambits = new GambitManager($app);
$gambits->setFulltextGambit('Flarum\Core\Search\User\Gambit\FulltextGambit');
$gambits->add('Flarum\Core\Search\User\Gambit\EmailGambit');
$gambits->add('Flarum\Core\Search\User\Gambit\GroupGambit');
$gambits->setFulltextGambit('Flarum\Core\User\Search\Gambit\FulltextGambit');
$gambits->add('Flarum\Core\User\Search\Gambit\EmailGambit');
$gambits->add('Flarum\Core\User\Search\Gambit\GroupGambit');
$app->make('events')->fire(
new ConfigureUserGambits($gambits)

View File

@@ -1,67 +0,0 @@
<?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\Core\Search\User\Gambit;
use Flarum\Core\Repository\UserRepository;
use Flarum\Core\Search\AbstractRegexGambit;
use Flarum\Core\Search\AbstractSearch;
use Flarum\Core\Search\User\UserSearch;
use LogicException;
class EmailGambit extends AbstractRegexGambit
{
/**
* {@inheritdoc}
*/
protected $pattern = 'email:(.+)';
/**
* @var UserRepository
*/
protected $users;
/**
* @param \Flarum\Core\Repository\UserRepository $users
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
/**
* {@inheritdoc}
*/
public function apply(AbstractSearch $search, $bit)
{
if (! $search->getActor()->isAdmin()) {
return false;
}
return parent::apply($search, $bit);
}
/**
* {@inheritdoc}
*/
protected function conditions(AbstractSearch $search, array $matches, $negate)
{
if (! $search instanceof UserSearch) {
throw new LogicException('This gambit can only be applied on a UserSearch');
}
$email = trim($matches[1], '"');
$user = $this->users->findByEmail($email);
$search->getQuery()->where('id', $negate ? '!=' : '=', $user->id);
}
}

View File

@@ -1,44 +0,0 @@
<?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\Core\Search\User\Gambit;
use Flarum\Core\Repository\UserRepository;
use Flarum\Core\Search\AbstractSearch;
use Flarum\Core\Search\GambitInterface;
class FulltextGambit implements GambitInterface
{
/**
* @var UserRepository
*/
protected $users;
/**
* @param UserRepository $users
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
/**
* {@inheritdoc}
*/
public function apply(AbstractSearch $search, $bit)
{
$users = $this->users->getIdsForUsername($bit, $search->getActor());
$search->getQuery()->whereIn('id', $users);
$search->setDefaultSort(['id' => $users]);
}
}

View File

@@ -1,73 +0,0 @@
<?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\Core\Search\User\Gambit;
use Flarum\Core\Repository\GroupRepository;
use Flarum\Core\Search\AbstractRegexGambit;
use Flarum\Core\Search\AbstractSearch;
use Flarum\Core\Search\User\UserSearch;
use LogicException;
class GroupGambit extends AbstractRegexGambit
{
/**
* {@inheritdoc}
*/
protected $pattern = 'group:(.+)';
/**
* @var GroupRepository
*/
protected $groups;
/**
* @param \Flarum\Core\Repository\GroupRepository $groups
*/
public function __construct(GroupRepository $groups)
{
$this->groups = $groups;
}
/**
* {@inheritdoc}
*/
protected function conditions(AbstractSearch $search, array $matches, $negate)
{
if (! $search instanceof UserSearch) {
throw new LogicException('This gambit can only be applied on a UserSearch');
}
$groupNames = $this->extractGroupNames($matches);
// TODO: Use a JOIN instead (and don't forget to remove the findByName() method again)
$ids = [];
foreach ($groupNames as $name) {
$group = $this->groups->findByName($name);
if ($group && count($group->users)) {
$ids = array_merge($ids, $group->users->pluck('id')->all());
}
}
$search->getQuery()->whereIn('id', $ids, 'and', $negate);
}
/**
* Extract the group names from the pattern match.
*
* @param array $matches
* @return array
*/
protected function extractGroupNames(array $matches)
{
return explode(',', trim($matches[1], '"'));
}
}

View File

@@ -1,18 +0,0 @@
<?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\Core\Search\User;
use Flarum\Core\Search\AbstractSearch;
class UserSearch extends AbstractSearch
{
}

View File

@@ -1,87 +0,0 @@
<?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\Core\Search\User;
use Flarum\Core\Repository\UserRepository;
use Flarum\Core\Search\ApplySearchParametersTrait;
use Flarum\Core\Search\GambitManager;
use Flarum\Core\Search\SearchCriteria;
use Flarum\Core\Search\SearchResults;
use Flarum\Event\ConfigureUserSearch;
/**
* Takes a UserSearchCriteria object, performs a search using gambits,
* and spits out a UserSearchResults object.
*/
class UserSearcher
{
use ApplySearchParametersTrait;
/**
* @var GambitManager
*/
protected $gambits;
/**
* @var UserRepository
*/
protected $users;
/**
* @param GambitManager $gambits
* @param UserRepository $users
*/
public function __construct(GambitManager $gambits, UserRepository $users)
{
$this->gambits = $gambits;
$this->users = $users;
}
/**
* @param SearchCriteria $criteria
* @param int|null $limit
* @param int $offset
* @param array $load An array of relationships to load on the results.
* @return SearchResults
*/
public function search(SearchCriteria $criteria, $limit = null, $offset = 0, array $load = [])
{
$actor = $criteria->actor;
$query = $this->users->query()->whereVisibleTo($actor);
// Construct an object which represents this search for users.
// Apply gambits to it, sort, and paging criteria. Also give extensions
// an opportunity to modify it.
$search = new UserSearch($query->getQuery(), $actor);
$this->gambits->apply($search, $criteria->query);
$this->applySort($search, $criteria->sort);
$this->applyOffset($search, $offset);
$this->applyLimit($search, $limit + 1);
event(new ConfigureUserSearch($search, $criteria));
// Execute the search query and retrieve the results. We get one more
// results than the user asked for, so that we can say if there are more
// results. If there are, we will get rid of that extra result.
$users = $query->get();
if ($areMoreResults = ($limit > 0 && $users->count() > $limit)) {
$users->pop();
}
$users->load($load);
return new SearchResults($users, $areMoreResults);
}
}

View File

@@ -11,7 +11,7 @@
namespace Flarum\Core\Support;
use Flarum\Core\User;
use Flarum\User\User;
use Illuminate\Contracts\Events\Dispatcher;
trait DispatchEventsTrait

View File

@@ -1,749 +0,0 @@
<?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\Core;
use DomainException;
use Flarum\Core\Access\Gate;
use Flarum\Core\Support\EventGeneratorTrait;
use Flarum\Database\ScopeVisibilityTrait;
use Flarum\Database\AbstractModel;
use Flarum\Event\CheckUserPassword;
use Flarum\Event\ConfigureUserPreferences;
use Flarum\Event\PostWasDeleted;
use Flarum\Event\PrepareUserGroups;
use Flarum\Event\UserAvatarWasChanged;
use Flarum\Event\UserBioWasChanged;
use Flarum\Event\UserEmailChangeWasRequested;
use Flarum\Event\UserEmailWasChanged;
use Flarum\Event\UserPasswordWasChanged;
use Flarum\Event\UserWasActivated;
use Flarum\Event\UserWasDeleted;
use Flarum\Event\UserWasRegistered;
use Flarum\Event\UserWasRenamed;
use Flarum\Foundation\Application;
use Illuminate\Contracts\Hashing\Hasher;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
/**
* @property int $id
* @property string $username
* @property string $email
* @property bool $is_activated
* @property string $password
* @property string $locale
* @property string $bio
* @property string|null $avatar_path
* @property string $avatar_url
* @property array $preferences
* @property \Carbon\Carbon|null $join_time
* @property \Carbon\Carbon|null $last_seen_time
* @property \Carbon\Carbon|null $read_time
* @property \Carbon\Carbon|null $notifications_read_time
* @property int $discussions_count
* @property int $comments_count
*/
class User extends AbstractModel
{
use EventGeneratorTrait;
use ScopeVisibilityTrait;
/**
* {@inheritdoc}
*/
protected $table = 'users';
/**
* {@inheritdoc}
*/
protected $dates = [
'join_time',
'last_seen_time',
'read_time',
'notifications_read_time'
];
/**
* An array of permissions that this user has.
*
* @var string[]|null
*/
protected $permissions = null;
/**
* @var SessionInterface
*/
protected $session;
/**
* An array of registered user preferences. Each preference is defined with
* a key, and its value is an array containing the following keys:.
*
* - transformer: a callback that confines the value of the preference
* - default: a default value if the preference isn't set
*
* @var array
*/
protected static $preferences = [];
/**
* The hasher with which to hash passwords.
*
* @var Hasher
*/
protected static $hasher;
/**
* The access gate.
*
* @var Gate
*/
protected static $gate;
/**
* Boot the model.
*
* @return void
*/
public static function boot()
{
parent::boot();
// Don't allow the root admin to be deleted.
static::deleting(function (User $user) {
if ($user->id == 1) {
throw new DomainException('Cannot delete the root admin');
}
});
static::deleted(function (User $user) {
$user->raise(new UserWasDeleted($user));
// Delete all of the posts by the user. Before we delete them
// in a big batch query, we will loop through them and raise a
// PostWasDeleted event for each post.
$posts = $user->posts()->allTypes();
foreach ($posts->get() as $post) {
$user->raise(new PostWasDeleted($post));
}
$posts->delete();
$user->read()->detach();
$user->groups()->detach();
$user->accessTokens()->delete();
$user->notifications()->delete();
});
static::$dispatcher->fire(
new ConfigureUserPreferences
);
}
/**
* Register a new user.
*
* @param string $username
* @param string $email
* @param string $password
* @return static
*/
public static function register($username, $email, $password)
{
$user = new static;
$user->username = $username;
$user->email = $email;
$user->password = $password;
$user->join_time = time();
$user->raise(new UserWasRegistered($user));
return $user;
}
/**
* @return Gate
*/
public static function getGate()
{
return static::$gate;
}
/**
* @param Gate $gate
*/
public static function setGate($gate)
{
static::$gate = $gate;
}
/**
* Rename the user.
*
* @param string $username
* @return $this
*/
public function rename($username)
{
if ($username !== $this->username) {
$this->username = $username;
$this->raise(new UserWasRenamed($this));
}
return $this;
}
/**
* Change the user's email.
*
* @param string $email
* @return $this
*/
public function changeEmail($email)
{
if ($email !== $this->email) {
$this->email = $email;
$this->raise(new UserEmailWasChanged($this));
}
return $this;
}
/**
* Request that the user's email be changed.
*
* @param string $email
* @return $this
*/
public function requestEmailChange($email)
{
if ($email !== $this->email) {
$this->raise(new UserEmailChangeWasRequested($this, $email));
}
return $this;
}
/**
* Change the user's password.
*
* @param string $password
* @return $this
*/
public function changePassword($password)
{
$this->password = $password;
$this->raise(new UserPasswordWasChanged($this));
return $this;
}
/**
* Set the password attribute, storing it as a hash.
*
* @param string $value
*/
public function setPasswordAttribute($value)
{
$this->attributes['password'] = $value ? static::$hasher->make($value) : '';
}
/**
* Change the user's bio.
*
* @param string $bio
* @return $this
*/
public function changeBio($bio)
{
$this->bio = $bio;
$this->raise(new UserBioWasChanged($this));
return $this;
}
/**
* Mark all discussions as read.
*
* @return $this
*/
public function markAllAsRead()
{
$this->read_time = time();
return $this;
}
/**
* Mark all notifications as read.
*
* @return $this
*/
public function markNotificationsAsRead()
{
$this->notifications_read_time = time();
return $this;
}
/**
* Change the path of the user avatar.
*
* @param string $path
* @return $this
*/
public function changeAvatarPath($path)
{
$this->avatar_path = $path;
$this->raise(new UserAvatarWasChanged($this));
return $this;
}
/**
* Get the URL of the user's avatar.
*
* @todo Allow different storage locations to be used
* @return string
*/
public function getAvatarUrlAttribute()
{
$urlGenerator = app('Flarum\Forum\UrlGenerator');
return $this->avatar_path ? $urlGenerator->toPath('assets/avatars/'.$this->avatar_path) : null;
}
/**
* Get the user's locale, falling back to the forum's default if they
* haven't set one.
*
* @param string $value
* @return string
*/
public function getLocaleAttribute($value)
{
return $value ?: Application::config('locale', 'en');
}
/**
* Check if a given password matches the user's password.
*
* @param string $password
* @return bool
*/
public function checkPassword($password)
{
$valid = static::$dispatcher->until(new CheckUserPassword($this, $password));
if ($valid !== null) {
return $valid;
}
return static::$hasher->check($password, $this->password);
}
/**
* Activate the user's account.
*
* @return $this
*/
public function activate()
{
if ($this->is_activated !== true) {
$this->is_activated = true;
$this->raise(new UserWasActivated($this));
}
return $this;
}
/**
* Check whether the user has a certain permission based on their groups.
*
* @param string $permission
* @return bool
*/
public function hasPermission($permission)
{
if ($this->isAdmin()) {
return true;
}
if (is_null($this->permissions)) {
$this->permissions = $this->getPermissions();
}
return in_array($permission, $this->permissions);
}
/**
* Check whether the user has a permission that is like the given string,
* based on their groups.
*
* @param string $match
* @return bool
*/
public function hasPermissionLike($match)
{
if ($this->isAdmin()) {
return true;
}
if (is_null($this->permissions)) {
$this->permissions = $this->getPermissions();
}
foreach ($this->permissions as $permission) {
if (substr($permission, -strlen($match)) === $match) {
return true;
}
}
return false;
}
/**
* Get the notification types that should be alerted to this user, according
* to their preferences.
*
* @return array
*/
public function getAlertableNotificationTypes()
{
$types = array_keys(Notification::getSubjectModels());
return array_filter($types, [$this, 'shouldAlert']);
}
/**
* Get the number of unread notifications for the user.
*
* @return int
*/
public function getUnreadNotificationsCount()
{
return $this->getUnreadNotifications()->count();
}
/**
* Get all notifications that have not been read yet.
*
* @return \Illuminate\Database\Eloquent\Collection
*/
protected function getUnreadNotifications()
{
static $cached = null;
if (is_null($cached)) {
$cached = $this->notifications()
->whereIn('type', $this->getAlertableNotificationTypes())
->where('is_read', 0)
->where('is_deleted', 0)
->get();
}
return $cached;
}
/**
* Get the number of new, unseen notifications for the user.
*
* @return int
*/
public function getNewNotificationsCount()
{
return $this->getUnreadNotifications()->filter(function ($notification) {
return $notification->time > $this->notifications_read_time ?: 0;
})->count();
}
/**
* Get the values of all registered preferences for this user, by
* transforming their stored preferences and merging them with the defaults.
*
* @param string $value
* @return array
*/
public function getPreferencesAttribute($value)
{
$defaults = array_build(static::$preferences, function ($key, $value) {
return [$key, $value['default']];
});
$user = array_only((array) json_decode($value, true), array_keys(static::$preferences));
return array_merge($defaults, $user);
}
/**
* Encode an array of preferences for storage in the database.
*
* @param mixed $value
*/
public function setPreferencesAttribute($value)
{
$this->attributes['preferences'] = json_encode($value);
}
/**
* Check whether or not the user should receive an alert for a notification
* type.
*
* @param string $type
* @return bool
*/
public function shouldAlert($type)
{
return (bool) $this->getPreference(static::getNotificationPreferenceKey($type, 'alert'));
}
/**
* Check whether or not the user should receive an email for a notification
* type.
*
* @param string $type
* @return bool
*/
public function shouldEmail($type)
{
return (bool) $this->getPreference(static::getNotificationPreferenceKey($type, 'email'));
}
/**
* Get the value of a preference for this user.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function getPreference($key, $default = null)
{
return array_get($this->preferences, $key, $default);
}
/**
* Set the value of a preference for this user.
*
* @param string $key
* @param mixed $value
* @return $this
*/
public function setPreference($key, $value)
{
if (isset(static::$preferences[$key])) {
$preferences = $this->preferences;
if (! is_null($transformer = static::$preferences[$key]['transformer'])) {
$preferences[$key] = call_user_func($transformer, $value);
} else {
$preferences[$key] = $value;
}
$this->preferences = $preferences;
}
return $this;
}
/**
* Set the user as being last seen just now.
*
* @return $this
*/
public function updateLastSeen()
{
$this->last_seen_time = time();
return $this;
}
/**
* Check whether or not the user is an administrator.
*
* @return bool
*/
public function isAdmin()
{
return $this->groups->contains(Group::ADMINISTRATOR_ID);
}
/**
* Check whether or not the user is a guest.
*
* @return bool
*/
public function isGuest()
{
return false;
}
/**
* Define the relationship with the user's posts.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function posts()
{
return $this->hasMany('Flarum\Core\Post');
}
/**
* Define the relationship with the user's read discussions.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function read()
{
return $this->belongsToMany('Flarum\Core\Discussion', 'users_discussions');
}
/**
* Define the relationship with the user's groups.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function groups()
{
return $this->belongsToMany('Flarum\Core\Group', 'users_groups');
}
/**
* Define the relationship with the user's notifications.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function notifications()
{
return $this->hasMany('Flarum\Core\Notification');
}
/**
* Define the relationship with the permissions of all of the groups that
* the user is in.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function permissions()
{
$groupIds = [Group::GUEST_ID];
// If a user's account hasn't been activated, they are essentially no
// more than a guest. If they are activated, we can give them the
// standard 'member' group, as well as any other groups they've been
// assigned to.
if ($this->is_activated) {
$groupIds = array_merge($groupIds, [Group::MEMBER_ID], $this->groups->lists('id')->all());
}
event(new PrepareUserGroups($this, $groupIds));
return Permission::whereIn('group_id', $groupIds);
}
/**
* Get a list of permissions that the user has.
*
* @return string[]
*/
public function getPermissions()
{
return $this->permissions()->lists('permission')->all();
}
/**
* Define the relationship with the user's access tokens.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function accessTokens()
{
return $this->hasMany('Flarum\Http\AccessToken');
}
/**
* @param string $ability
* @param array|mixed $arguments
* @return bool
*/
public function can($ability, $arguments = [])
{
return static::$gate->forUser($this)->allows($ability, $arguments);
}
/**
* @param string $ability
* @param array|mixed $arguments
* @return bool
*/
public function cannot($ability, $arguments = [])
{
return ! $this->can($ability, $arguments);
}
/**
* @return SessionInterface
*/
public function getSession()
{
return $this->session;
}
/**
* @param SessionInterface $session
*/
public function setSession(SessionInterface $session)
{
$this->session = $session;
}
/**
* Set the hasher with which to hash passwords.
*
* @param Hasher $hasher
*/
public static function setHasher(Hasher $hasher)
{
static::$hasher = $hasher;
}
/**
* Register a preference with a transformer and a default value.
*
* @param string $key
* @param callable $transformer
* @param mixed $default
*/
public static function addPreference($key, callable $transformer = null, $default = null)
{
static::$preferences[$key] = compact('transformer', 'default');
}
/**
* Get the key for a preference which flags whether or not the user will
* receive a notification for $type via $method.
*
* @param string $type
* @param string $method
* @return string
*/
public static function getNotificationPreferenceKey($type, $method)
{
return 'notify_'.$type.'_'.$method;
}
}

View File

@@ -1,23 +0,0 @@
<?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\Core\Validator;
class AvatarValidator extends AbstractValidator
{
protected $rules = [
'avatar' => [
'required',
'mimes:jpeg,png,bmp,gif',
'max:2048'
]
];
}

View File

@@ -1,75 +0,0 @@
<?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\Core\Validator;
use Flarum\Core\User;
class UserValidator extends AbstractValidator
{
/**
* @var User
*/
protected $user;
/**
* @return User
*/
public function getUser()
{
return $this->user;
}
/**
* @param User $user
*/
public function setUser(User $user)
{
$this->user = $user;
}
/**
* {@inheritdoc}
*/
protected function getRules()
{
$idSuffix = $this->user ? ','.$this->user->id : '';
return [
'username' => [
'required',
'regex:/^[a-z0-9_-]+$/i',
'unique:users,username'.$idSuffix,
'min:3',
'max:30'
],
'email' => [
'required',
'email',
'unique:users,email'.$idSuffix
],
'password' => [
'required',
'min:8'
]
];
}
/**
* {@inheritdoc}
*/
protected function getMessages()
{
return [
'username.regex' => $this->translator->trans('core.api.invalid_username_message')
];
}
}