mirror of
https://github.com/flarum/core.git
synced 2025-08-05 07:57:46 +02:00
chore: delete dead code
This commit is contained in:
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\DiscussionSerializer;
|
||||
use Flarum\Discussion\Command\ReadDiscussion;
|
||||
use Flarum\Discussion\Command\StartDiscussion;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class CreateDiscussionController extends AbstractCreateController
|
||||
{
|
||||
public ?string $serializer = DiscussionSerializer::class;
|
||||
|
||||
public array $include = [
|
||||
'posts',
|
||||
'user',
|
||||
'lastPostedUser',
|
||||
'firstPost',
|
||||
'lastPost'
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): Discussion
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$ipAddress = $request->getAttribute('ipAddress');
|
||||
|
||||
$discussion = $this->bus->dispatch(
|
||||
new StartDiscussion($actor, Arr::get($request->getParsedBody(), 'data', []), $ipAddress)
|
||||
);
|
||||
|
||||
// After creating the discussion, we assume that the user has seen all
|
||||
// the posts in the discussion; thus, we will mark the discussion
|
||||
// as read if they are logged in.
|
||||
if ($actor->exists) {
|
||||
$this->bus->dispatch(
|
||||
new ReadDiscussion($discussion->id, $actor, 1)
|
||||
);
|
||||
}
|
||||
|
||||
$this->loadRelations(new Collection([$discussion]), $this->extractInclude($request), $request);
|
||||
|
||||
return $discussion;
|
||||
}
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Discussion\Command\ReadDiscussion;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Post\Command\PostReply;
|
||||
use Flarum\Post\CommentPost;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class CreatePostController extends AbstractCreateController
|
||||
{
|
||||
public ?string $serializer = PostSerializer::class;
|
||||
|
||||
public array $include = [
|
||||
'user',
|
||||
'discussion',
|
||||
'discussion.posts',
|
||||
'discussion.lastPostedUser'
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): CommentPost
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||
$discussionId = (int) Arr::get($data, 'relationships.discussion.data.id');
|
||||
$ipAddress = $request->getAttribute('ipAddress');
|
||||
|
||||
/** @var CommentPost $post */
|
||||
$post = $this->bus->dispatch(
|
||||
new PostReply($discussionId, $actor, $data, $ipAddress)
|
||||
);
|
||||
|
||||
// After replying, we assume that the user has seen all of the posts
|
||||
// in the discussion; thus, we will mark the discussion as read if
|
||||
// they are logged in.
|
||||
if ($actor->exists) {
|
||||
$this->bus->dispatch(
|
||||
new ReadDiscussion($discussionId, $actor, $post->number)
|
||||
);
|
||||
}
|
||||
|
||||
$discussion = $post->discussion;
|
||||
$discussion->setRelation('posts', $discussion->posts()->whereVisibleTo($actor)->orderBy('created_at')->pluck('id'));
|
||||
|
||||
$this->loadRelations($post->newCollection([$post]), $this->extractInclude($request), $request);
|
||||
|
||||
return $post;
|
||||
}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\User\Command\RegisterUser;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class CreateUserController extends AbstractCreateController
|
||||
{
|
||||
public ?string $serializer = CurrentUserSerializer::class;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): User
|
||||
{
|
||||
return $this->bus->dispatch(
|
||||
new RegisterUser(RequestUtil::getActor($request), Arr::get($request->getParsedBody(), 'data', []))
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Discussion\Command\DeleteDiscussion;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class DeleteDiscussionController extends AbstractDeleteController
|
||||
{
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function delete(ServerRequestInterface $request): void
|
||||
{
|
||||
$id = Arr::get($request->getQueryParams(), 'id');
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$input = $request->getParsedBody();
|
||||
|
||||
$this->bus->dispatch(
|
||||
new DeleteDiscussion($id, $actor, $input)
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Post\Command\DeletePost;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class DeletePostController extends AbstractDeleteController
|
||||
{
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function delete(ServerRequestInterface $request): void
|
||||
{
|
||||
$this->bus->dispatch(
|
||||
new DeletePost(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request))
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\User\Command\DeleteUser;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class DeleteUserController extends AbstractDeleteController
|
||||
{
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function delete(ServerRequestInterface $request): void
|
||||
{
|
||||
$this->bus->dispatch(
|
||||
new DeleteUser(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request))
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\DiscussionSerializer;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Flarum\Search\SearchCriteria;
|
||||
use Flarum\Search\SearchManager;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class ListDiscussionsController extends AbstractListController
|
||||
{
|
||||
public ?string $serializer = DiscussionSerializer::class;
|
||||
|
||||
public array $include = [
|
||||
'user',
|
||||
'lastPostedUser',
|
||||
'mostRelevantPost',
|
||||
'mostRelevantPost.user'
|
||||
];
|
||||
|
||||
public array $optionalInclude = [
|
||||
'firstPost',
|
||||
'lastPost'
|
||||
];
|
||||
|
||||
public ?array $sort = ['lastPostedAt' => 'desc'];
|
||||
|
||||
public array $sortFields = ['lastPostedAt', 'commentCount', 'createdAt'];
|
||||
|
||||
public function __construct(
|
||||
protected SearchManager $search,
|
||||
protected UrlGenerator $url
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): iterable
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$filters = $this->extractFilter($request);
|
||||
$sort = $this->extractSort($request);
|
||||
$sortIsDefault = $this->sortIsDefault($request);
|
||||
|
||||
$limit = $this->extractLimit($request);
|
||||
$offset = $this->extractOffset($request);
|
||||
$include = array_merge($this->extractInclude($request), ['state']);
|
||||
|
||||
$results = $this->search->query(
|
||||
Discussion::class,
|
||||
new SearchCriteria($actor, $filters, $limit, $offset, $sort, $sortIsDefault)
|
||||
);
|
||||
|
||||
$this->addPaginationData(
|
||||
$document,
|
||||
$request,
|
||||
$this->url->to('api')->route('discussions.index'),
|
||||
$results->areMoreResults() ? null : 0
|
||||
);
|
||||
|
||||
Discussion::setStateUser($actor);
|
||||
|
||||
// Eager load groups for use in the policies (isAdmin check)
|
||||
if (in_array('mostRelevantPost.user', $include)) {
|
||||
$include[] = 'mostRelevantPost.user.groups';
|
||||
|
||||
// If the first level of the relationship wasn't explicitly included,
|
||||
// add it so the code below can look for it
|
||||
if (! in_array('mostRelevantPost', $include)) {
|
||||
$include[] = 'mostRelevantPost';
|
||||
}
|
||||
}
|
||||
|
||||
$results = $results->getResults();
|
||||
|
||||
$this->loadRelations($results, $include, $request);
|
||||
|
||||
if ($relations = array_intersect($include, ['firstPost', 'lastPost', 'mostRelevantPost'])) {
|
||||
foreach ($results as $discussion) {
|
||||
foreach ($relations as $relation) {
|
||||
if ($discussion->$relation) {
|
||||
$discussion->$relation->discussion = $discussion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
@@ -1,100 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\NotificationSerializer;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Flarum\Notification\NotificationRepository;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class ListNotificationsController extends AbstractListController
|
||||
{
|
||||
public ?string $serializer = NotificationSerializer::class;
|
||||
|
||||
public array $include = [
|
||||
'fromUser',
|
||||
'subject',
|
||||
'subject.discussion'
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
protected NotificationRepository $notifications,
|
||||
protected UrlGenerator $url
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): iterable
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
$actor->assertRegistered();
|
||||
|
||||
$actor->markNotificationsAsRead()->save();
|
||||
|
||||
$limit = $this->extractLimit($request);
|
||||
$offset = $this->extractOffset($request);
|
||||
$include = $this->extractInclude($request);
|
||||
|
||||
if (! in_array('subject', $include)) {
|
||||
$include[] = 'subject';
|
||||
}
|
||||
|
||||
$notifications = $this->notifications->findByUser($actor, $limit + 1, $offset);
|
||||
|
||||
$this->loadRelations($notifications, array_diff($include, ['subject.discussion']), $request);
|
||||
|
||||
$notifications = $notifications->all();
|
||||
|
||||
$areMoreResults = false;
|
||||
|
||||
if (count($notifications) > $limit) {
|
||||
array_pop($notifications);
|
||||
$areMoreResults = true;
|
||||
}
|
||||
|
||||
$this->addPaginationData(
|
||||
$document,
|
||||
$request,
|
||||
$this->url->to('api')->route('notifications.index'),
|
||||
$areMoreResults ? null : 0
|
||||
);
|
||||
|
||||
if (in_array('subject.discussion', $include)) {
|
||||
$this->loadSubjectDiscussions($notifications);
|
||||
}
|
||||
|
||||
return $notifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Flarum\Notification\Notification[] $notifications
|
||||
*/
|
||||
private function loadSubjectDiscussions(array $notifications): void
|
||||
{
|
||||
$ids = [];
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
if ($notification->subject && ($discussionId = $notification->subject->getAttribute('discussion_id'))) {
|
||||
$ids[] = $discussionId;
|
||||
}
|
||||
}
|
||||
|
||||
$discussions = Discussion::query()->find(array_unique($ids));
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
if ($notification->subject && ($discussionId = $notification->subject->getAttribute('discussion_id'))) {
|
||||
$notification->subject->setRelation('discussion', $discussions->find($discussionId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,124 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Post\PostRepository;
|
||||
use Flarum\Search\SearchCriteria;
|
||||
use Flarum\Search\SearchManager;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
use Tobscure\JsonApi\Exception\InvalidParameterException;
|
||||
|
||||
class ListPostsController extends AbstractListController
|
||||
{
|
||||
public ?string $serializer = PostSerializer::class;
|
||||
|
||||
public array $include = [
|
||||
'user',
|
||||
'user.groups',
|
||||
'editedUser',
|
||||
'hiddenUser',
|
||||
'discussion'
|
||||
];
|
||||
|
||||
public array $sortFields = ['number', 'createdAt'];
|
||||
|
||||
public function __construct(
|
||||
protected SearchManager $search,
|
||||
protected PostRepository $posts,
|
||||
protected UrlGenerator $url
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): iterable
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
$filters = $this->extractFilter($request);
|
||||
$sort = $this->extractSort($request);
|
||||
$sortIsDefault = $this->sortIsDefault($request);
|
||||
|
||||
$limit = $this->extractLimit($request);
|
||||
$offset = $this->extractOffset($request);
|
||||
$include = $this->extractInclude($request);
|
||||
|
||||
$results = $this->search->query(
|
||||
Post::class,
|
||||
new SearchCriteria($actor, $filters, $limit, $offset, $sort, $sortIsDefault)
|
||||
);
|
||||
|
||||
$document->addPaginationLinks(
|
||||
$this->url->to('api')->route('posts.index'),
|
||||
$request->getQueryParams(),
|
||||
$offset,
|
||||
$limit,
|
||||
$results->areMoreResults() ? null : 0
|
||||
);
|
||||
|
||||
// Eager load discussion for use in the policies,
|
||||
// eager loading does not affect the JSON response,
|
||||
// the response only includes relations included in the request.
|
||||
if (! in_array('discussion', $include)) {
|
||||
$include[] = 'discussion';
|
||||
}
|
||||
|
||||
if (in_array('user', $include)) {
|
||||
$include[] = 'user.groups';
|
||||
}
|
||||
|
||||
$results = $results->getResults();
|
||||
|
||||
$this->loadRelations($results, $include, $request);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://github.com/flarum/framework/pull/3506
|
||||
*/
|
||||
protected function extractSort(ServerRequestInterface $request): ?array
|
||||
{
|
||||
$sort = [];
|
||||
|
||||
foreach ((parent::extractSort($request) ?: []) as $field => $direction) {
|
||||
$sort["posts.$field"] = $direction;
|
||||
}
|
||||
|
||||
return $sort;
|
||||
}
|
||||
|
||||
protected function extractOffset(ServerRequestInterface $request): int
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$queryParams = $request->getQueryParams();
|
||||
$sort = $this->extractSort($request);
|
||||
$limit = $this->extractLimit($request);
|
||||
$filter = $this->extractFilter($request);
|
||||
|
||||
if (($near = Arr::get($queryParams, 'page.near')) > 1) {
|
||||
if (count($filter) > 1 || ! isset($filter['discussion']) || $sort) {
|
||||
throw new InvalidParameterException(
|
||||
'You can only use page[near] with filter[discussion] and the default sort order'
|
||||
);
|
||||
}
|
||||
|
||||
$offset = $this->posts->getIndexForNumber((int) $filter['discussion'], $near, $actor);
|
||||
|
||||
return max(0, $offset - $limit / 2);
|
||||
}
|
||||
|
||||
return parent::extractOffset($request);
|
||||
}
|
||||
}
|
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\UserSerializer;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Flarum\Search\SearchCriteria;
|
||||
use Flarum\Search\SearchManager;
|
||||
use Flarum\User\User;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class ListUsersController extends AbstractListController
|
||||
{
|
||||
public ?string $serializer = UserSerializer::class;
|
||||
|
||||
public array $include = ['groups'];
|
||||
|
||||
public array $sortFields = [
|
||||
'username',
|
||||
'commentCount',
|
||||
'discussionCount',
|
||||
'lastSeenAt',
|
||||
'joinedAt'
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
protected SearchManager $search,
|
||||
protected UrlGenerator $url
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): iterable
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
$actor->assertCan('searchUsers');
|
||||
|
||||
if (! $actor->hasPermission('user.viewLastSeenAt')) {
|
||||
// If a user cannot see everyone's last online date, we prevent them from sorting by it
|
||||
// Otherwise this sort field would defeat the privacy setting discloseOnline
|
||||
// We use remove instead of add so that extensions can still completely disable the sort using the extender
|
||||
$this->removeSortField('lastSeenAt');
|
||||
}
|
||||
|
||||
$filters = $this->extractFilter($request);
|
||||
$sort = $this->extractSort($request);
|
||||
$sortIsDefault = $this->sortIsDefault($request);
|
||||
|
||||
$limit = $this->extractLimit($request);
|
||||
$offset = $this->extractOffset($request);
|
||||
$include = $this->extractInclude($request);
|
||||
|
||||
$results = $this->search->query(
|
||||
User::class,
|
||||
new SearchCriteria($actor, $filters, $limit, $offset, $sort, $sortIsDefault)
|
||||
);
|
||||
|
||||
$document->addPaginationLinks(
|
||||
$this->url->to('api')->route('users.index'),
|
||||
$request->getQueryParams(),
|
||||
$offset,
|
||||
$limit,
|
||||
$results->areMoreResults() ? null : 0
|
||||
);
|
||||
|
||||
$results = $results->getResults();
|
||||
|
||||
$this->loadRelations($results, $include, $request);
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
@@ -1,178 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\DiscussionSerializer;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Discussion\DiscussionRepository;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Http\SlugManager;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Post\PostRepository;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class ShowDiscussionController extends AbstractShowController
|
||||
{
|
||||
public ?string $serializer = DiscussionSerializer::class;
|
||||
|
||||
public array $include = [
|
||||
'user',
|
||||
'posts',
|
||||
'posts.discussion',
|
||||
'posts.user',
|
||||
'posts.user.groups',
|
||||
'posts.editedUser',
|
||||
'posts.hiddenUser'
|
||||
];
|
||||
|
||||
public array $optionalInclude = [
|
||||
'user',
|
||||
'lastPostedUser',
|
||||
'firstPost',
|
||||
'lastPost'
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
protected DiscussionRepository $discussions,
|
||||
protected PostRepository $posts,
|
||||
protected SlugManager $slugManager
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): Discussion
|
||||
{
|
||||
$discussionId = Arr::get($request->getQueryParams(), 'id');
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$include = $this->extractInclude($request);
|
||||
|
||||
if (Arr::get($request->getQueryParams(), 'bySlug', false)) {
|
||||
$discussion = $this->slugManager->forResource(Discussion::class)->fromSlug($discussionId, $actor);
|
||||
} else {
|
||||
$discussion = $this->discussions->findOrFail($discussionId, $actor);
|
||||
}
|
||||
|
||||
// If posts is included or a sub relation of post is included.
|
||||
if (in_array('posts', $include) || Str::contains(implode(',', $include), 'posts.')) {
|
||||
$postRelationships = $this->getPostRelationships($include);
|
||||
|
||||
$this->includePosts($discussion, $request, $postRelationships);
|
||||
}
|
||||
|
||||
$this->loadRelations(new Collection([$discussion]), array_filter($include, function ($relationship) {
|
||||
return ! Str::startsWith($relationship, 'posts');
|
||||
}), $request);
|
||||
|
||||
return $discussion;
|
||||
}
|
||||
|
||||
private function includePosts(Discussion $discussion, ServerRequestInterface $request, array $include): void
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$limit = $this->extractLimit($request);
|
||||
$offset = $this->getPostsOffset($request, $discussion, $limit);
|
||||
|
||||
$allPosts = $this->loadPostIds($discussion, $actor);
|
||||
$loadedPosts = $this->loadPosts($discussion, $actor, $offset, $limit, $include, $request);
|
||||
|
||||
array_splice($allPosts, $offset, $limit, $loadedPosts);
|
||||
|
||||
$discussion->setRelation('posts', (new Post)->newCollection($allPosts));
|
||||
}
|
||||
|
||||
private function loadPostIds(Discussion $discussion, User $actor): array
|
||||
{
|
||||
return $discussion->posts()->whereVisibleTo($actor)->orderBy('number')->pluck('id')->all();
|
||||
}
|
||||
|
||||
private function getPostRelationships(array $include): array
|
||||
{
|
||||
$prefixLength = strlen($prefix = 'posts.');
|
||||
$relationships = [];
|
||||
|
||||
foreach ($include as $relationship) {
|
||||
if (substr($relationship, 0, $prefixLength) === $prefix) {
|
||||
$relationships[] = substr($relationship, $prefixLength);
|
||||
}
|
||||
}
|
||||
|
||||
return $relationships;
|
||||
}
|
||||
|
||||
private function getPostsOffset(ServerRequestInterface $request, Discussion $discussion, int $limit): int
|
||||
{
|
||||
$queryParams = $request->getQueryParams();
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
if (($near = Arr::get($queryParams, 'page.near')) > 1) {
|
||||
$offset = $this->posts->getIndexForNumber($discussion->id, $near, $actor);
|
||||
$offset = max(0, $offset - $limit / 2);
|
||||
} else {
|
||||
$offset = $this->extractOffset($request);
|
||||
}
|
||||
|
||||
return $offset;
|
||||
}
|
||||
|
||||
private function loadPosts(Discussion $discussion, User $actor, int $offset, int $limit, array $include, ServerRequestInterface $request): array
|
||||
{
|
||||
/** @var Builder $query */
|
||||
$query = $discussion->posts()->whereVisibleTo($actor);
|
||||
|
||||
$query->orderBy('number')->skip($offset)->take($limit);
|
||||
|
||||
$posts = $query->get();
|
||||
|
||||
/** @var Post $post */
|
||||
foreach ($posts as $post) {
|
||||
$post->setRelation('discussion', $discussion);
|
||||
}
|
||||
|
||||
$this->loadRelations($posts, $include, $request);
|
||||
|
||||
return $posts->all();
|
||||
}
|
||||
|
||||
protected function getRelationsToLoad(Collection $models): array
|
||||
{
|
||||
$addedRelations = parent::getRelationsToLoad($models);
|
||||
|
||||
if ($models->first() instanceof Discussion) {
|
||||
return $addedRelations;
|
||||
}
|
||||
|
||||
return $this->getPostRelationships($addedRelations);
|
||||
}
|
||||
|
||||
protected function getRelationCallablesToLoad(Collection $models): array
|
||||
{
|
||||
$addedCallableRelations = parent::getRelationCallablesToLoad($models);
|
||||
|
||||
if ($models->first() instanceof Discussion) {
|
||||
return $addedCallableRelations;
|
||||
}
|
||||
|
||||
$postCallableRelationships = $this->getPostRelationships(array_keys($addedCallableRelations));
|
||||
|
||||
$relationCallables = array_intersect_key($addedCallableRelations, array_flip(array_map(function ($relation) {
|
||||
return "posts.$relation";
|
||||
}, $postCallableRelationships)));
|
||||
|
||||
// remove posts. prefix from keys
|
||||
return array_combine(array_map(function ($relation) {
|
||||
return substr($relation, 6);
|
||||
}, array_keys($relationCallables)), array_values($relationCallables));
|
||||
}
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Endpoint\Show;
|
||||
use Flarum\Api\JsonApi;
|
||||
use Flarum\Api\Resource\ForumResource;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
class ShowForumController implements RequestHandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
protected JsonApi $api
|
||||
) {}
|
||||
|
||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
return $this->api
|
||||
->forResource(ForumResource::class)
|
||||
->forEndpoint(Show::class)
|
||||
->handle($request);
|
||||
}
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Post\PostRepository;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class ShowPostController extends AbstractShowController
|
||||
{
|
||||
public ?string $serializer = PostSerializer::class;
|
||||
|
||||
public array $include = [
|
||||
'user',
|
||||
'user.groups',
|
||||
'editedUser',
|
||||
'hiddenUser',
|
||||
'discussion'
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
protected PostRepository $posts
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): Post
|
||||
{
|
||||
$post = $this->posts->findOrFail(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request));
|
||||
|
||||
$include = $this->extractInclude($request);
|
||||
|
||||
$this->loadRelations(new Collection([$post]), $include, $request);
|
||||
|
||||
return $post;
|
||||
}
|
||||
}
|
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||
use Flarum\Api\Serializer\UserSerializer;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Http\SlugManager;
|
||||
use Flarum\User\User;
|
||||
use Flarum\User\UserRepository;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class ShowUserController extends AbstractShowController
|
||||
{
|
||||
public ?string $serializer = UserSerializer::class;
|
||||
|
||||
public array $include = ['groups'];
|
||||
|
||||
public function __construct(
|
||||
protected SlugManager $slugManager,
|
||||
protected UserRepository $users
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): User
|
||||
{
|
||||
$id = Arr::get($request->getQueryParams(), 'id');
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
if (Arr::get($request->getQueryParams(), 'bySlug', false)) {
|
||||
$user = $this->slugManager->forResource(User::class)->fromSlug($id, $actor);
|
||||
} else {
|
||||
$user = $this->users->findOrFail($id, $actor);
|
||||
}
|
||||
|
||||
if ($actor->id === $user->id) {
|
||||
$this->serializer = CurrentUserSerializer::class;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\NotificationSerializer;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Notification\Command\ReadNotification;
|
||||
use Flarum\Notification\Notification;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class UpdateNotificationController extends AbstractShowController
|
||||
{
|
||||
public ?string $serializer = NotificationSerializer::class;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): Notification
|
||||
{
|
||||
$id = Arr::get($request->getQueryParams(), 'id');
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
return $this->bus->dispatch(
|
||||
new ReadNotification($id, $actor)
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Post\Command\EditPost;
|
||||
use Flarum\Post\Post;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class UpdatePostController extends AbstractShowController
|
||||
{
|
||||
public ?string $serializer = PostSerializer::class;
|
||||
|
||||
public array $include = [
|
||||
'editedUser',
|
||||
'discussion'
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): Post
|
||||
{
|
||||
$id = Arr::get($request->getQueryParams(), 'id');
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||
|
||||
$post = $this->bus->dispatch(
|
||||
new EditPost($id, $actor, $data)
|
||||
);
|
||||
|
||||
$this->loadRelations($post->newCollection([$post]), $this->extractInclude($request), $request);
|
||||
|
||||
return $post;
|
||||
}
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||
use Flarum\Api\Serializer\UserSerializer;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\User\Command\EditUser;
|
||||
use Flarum\User\Exception\NotAuthenticatedException;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class UpdateUserController extends AbstractShowController
|
||||
{
|
||||
public ?string $serializer = UserSerializer::class;
|
||||
|
||||
public array $include = ['groups'];
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $bus
|
||||
) {
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document): User
|
||||
{
|
||||
$id = Arr::get($request->getQueryParams(), 'id');
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||
|
||||
if ($actor->id == $id) {
|
||||
$this->serializer = CurrentUserSerializer::class;
|
||||
}
|
||||
|
||||
// Require the user's current password if they are attempting to change
|
||||
// their own email address.
|
||||
if (isset($data['attributes']['email']) && $actor->id == $id) {
|
||||
$password = (string) Arr::get($request->getParsedBody(), 'meta.password');
|
||||
|
||||
if (! $actor->checkPassword($password)) {
|
||||
throw new NotAuthenticatedException;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->bus->dispatch(
|
||||
new EditUser($id, $actor, $data)
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Discussion\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class DeleteDiscussion
|
||||
{
|
||||
public function __construct(
|
||||
public int $discussionId,
|
||||
public User $actor,
|
||||
public array $data = []
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Discussion\Command;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Discussion\DiscussionRepository;
|
||||
use Flarum\Discussion\Event\Deleting;
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class DeleteDiscussionHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected DiscussionRepository $discussions
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(DeleteDiscussion $command): Discussion
|
||||
{
|
||||
$actor = $command->actor;
|
||||
|
||||
$discussion = $this->discussions->findOrFail($command->discussionId, $actor);
|
||||
|
||||
$actor->assertCan('delete', $discussion);
|
||||
|
||||
$this->events->dispatch(
|
||||
new Deleting($discussion, $actor, $command->data)
|
||||
);
|
||||
|
||||
$discussion->delete();
|
||||
|
||||
$this->dispatchEventsFor($discussion, $actor);
|
||||
|
||||
return $discussion;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Discussion\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class EditDiscussion
|
||||
{
|
||||
public function __construct(
|
||||
public int $discussionId,
|
||||
public User $actor,
|
||||
public array $data
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Discussion\Command;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Discussion\DiscussionRepository;
|
||||
use Flarum\Discussion\DiscussionValidator;
|
||||
use Flarum\Discussion\Event\Saving;
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class EditDiscussionHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected DiscussionRepository $discussions,
|
||||
protected DiscussionValidator $validator
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(EditDiscussion $command): Discussion
|
||||
{
|
||||
$actor = $command->actor;
|
||||
$data = $command->data;
|
||||
$attributes = Arr::get($data, 'attributes', []);
|
||||
|
||||
$discussion = $this->discussions->findOrFail($command->discussionId, $actor);
|
||||
|
||||
if (isset($attributes['title'])) {
|
||||
$actor->assertCan('rename', $discussion);
|
||||
|
||||
$discussion->rename($attributes['title']);
|
||||
}
|
||||
|
||||
if (isset($attributes['isHidden'])) {
|
||||
$actor->assertCan('hide', $discussion);
|
||||
|
||||
if ($attributes['isHidden']) {
|
||||
$discussion->hide($actor);
|
||||
} else {
|
||||
$discussion->restore();
|
||||
}
|
||||
}
|
||||
|
||||
$this->events->dispatch(
|
||||
new Saving($discussion, $actor, $data)
|
||||
);
|
||||
|
||||
$this->validator->assertValid($discussion->getDirty());
|
||||
|
||||
$discussion->save();
|
||||
|
||||
$this->dispatchEventsFor($discussion, $actor);
|
||||
|
||||
return $discussion;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Discussion\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class StartDiscussion
|
||||
{
|
||||
public function __construct(
|
||||
public User $actor,
|
||||
public array $data,
|
||||
public string $ipAddress
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,83 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Discussion\Command;
|
||||
|
||||
use Exception;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Discussion\DiscussionValidator;
|
||||
use Flarum\Discussion\Event\Saving;
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Post\Command\PostReply;
|
||||
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
|
||||
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class StartDiscussionHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected EventDispatcher $events,
|
||||
protected BusDispatcher $bus,
|
||||
protected DiscussionValidator $validator
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(StartDiscussion $command): Discussion
|
||||
{
|
||||
$actor = $command->actor;
|
||||
$data = $command->data;
|
||||
$ipAddress = $command->ipAddress;
|
||||
|
||||
$actor->assertCan('startDiscussion');
|
||||
|
||||
// Create a new Discussion entity, persist it, and dispatch domain
|
||||
// events. Before persistence, though, fire an event to give plugins
|
||||
// an opportunity to alter the discussion entity based on data in the
|
||||
// command they may have passed through in the controller.
|
||||
$discussion = Discussion::start(
|
||||
Arr::get($data, 'attributes.title'),
|
||||
$actor
|
||||
);
|
||||
|
||||
$this->events->dispatch(
|
||||
new Saving($discussion, $actor, $data)
|
||||
);
|
||||
|
||||
$this->validator->assertValid($discussion->getAttributes());
|
||||
|
||||
$discussion->save();
|
||||
|
||||
// Now that the discussion has been created, we can add the first post.
|
||||
// We will do this by running the PostReply command.
|
||||
try {
|
||||
$post = $this->bus->dispatch(
|
||||
new PostReply($discussion->id, $actor, $data, $ipAddress, true)
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$discussion->delete();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// Before we dispatch events, refresh our discussion instance's
|
||||
// attributes as posting the reply will have changed some of them (e.g.
|
||||
// last_time.)
|
||||
$discussion->setRawAttributes($post->discussion->getAttributes(), true);
|
||||
$discussion->setFirstPost($post);
|
||||
$discussion->setLastPost($post);
|
||||
|
||||
$this->dispatchEventsFor($discussion, $actor);
|
||||
|
||||
$discussion->save();
|
||||
|
||||
return $discussion;
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Group\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class CreateGroup
|
||||
{
|
||||
public function __construct(
|
||||
public User $actor,
|
||||
public array $data
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Group\Command;
|
||||
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Group\Event\Saving;
|
||||
use Flarum\Group\Group;
|
||||
use Flarum\Group\GroupValidator;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class CreateGroupHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected GroupValidator $validator
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(CreateGroup $command): Group
|
||||
{
|
||||
$actor = $command->actor;
|
||||
$data = $command->data;
|
||||
|
||||
$actor->assertRegistered();
|
||||
$actor->assertCan('createGroup');
|
||||
|
||||
$group = Group::build(
|
||||
Arr::get($data, 'attributes.nameSingular'),
|
||||
Arr::get($data, 'attributes.namePlural'),
|
||||
Arr::get($data, 'attributes.color'),
|
||||
Arr::get($data, 'attributes.icon'),
|
||||
Arr::get($data, 'attributes.isHidden', false)
|
||||
);
|
||||
|
||||
$this->events->dispatch(
|
||||
new Saving($group, $actor, $data)
|
||||
);
|
||||
|
||||
$this->validator->assertValid($group->getAttributes());
|
||||
|
||||
$group->save();
|
||||
|
||||
$this->dispatchEventsFor($group, $actor);
|
||||
|
||||
return $group;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Group\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class DeleteGroup
|
||||
{
|
||||
public function __construct(
|
||||
public int $groupId,
|
||||
public User $actor,
|
||||
public array $data = []
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Group\Command;
|
||||
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Group\Event\Deleting;
|
||||
use Flarum\Group\Group;
|
||||
use Flarum\Group\GroupRepository;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class DeleteGroupHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected GroupRepository $groups
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(DeleteGroup $command): Group
|
||||
{
|
||||
$actor = $command->actor;
|
||||
|
||||
$group = $this->groups->findOrFail($command->groupId, $actor);
|
||||
|
||||
$actor->assertCan('delete', $group);
|
||||
|
||||
$this->events->dispatch(
|
||||
new Deleting($group, $actor, $command->data)
|
||||
);
|
||||
|
||||
$group->delete();
|
||||
|
||||
$this->dispatchEventsFor($group, $actor);
|
||||
|
||||
return $group;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Group\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class EditGroup
|
||||
{
|
||||
public function __construct(
|
||||
public int $groupId,
|
||||
public User $actor,
|
||||
public array $data
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Group\Command;
|
||||
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Group\Event\Saving;
|
||||
use Flarum\Group\Group;
|
||||
use Flarum\Group\GroupRepository;
|
||||
use Flarum\Group\GroupValidator;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class EditGroupHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected GroupRepository $groups,
|
||||
protected GroupValidator $validator
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(EditGroup $command): Group
|
||||
{
|
||||
$actor = $command->actor;
|
||||
$data = $command->data;
|
||||
|
||||
$group = $this->groups->findOrFail($command->groupId, $actor);
|
||||
|
||||
$actor->assertCan('edit', $group);
|
||||
|
||||
$attributes = Arr::get($data, 'attributes', []);
|
||||
|
||||
if (isset($attributes['nameSingular']) && isset($attributes['namePlural'])) {
|
||||
$group->rename($attributes['nameSingular'], $attributes['namePlural']);
|
||||
}
|
||||
|
||||
if (isset($attributes['color'])) {
|
||||
$group->color = $attributes['color'];
|
||||
}
|
||||
|
||||
if (isset($attributes['icon'])) {
|
||||
$group->icon = $attributes['icon'];
|
||||
}
|
||||
|
||||
if (isset($attributes['isHidden'])) {
|
||||
$group->is_hidden = $attributes['isHidden'];
|
||||
}
|
||||
|
||||
$this->events->dispatch(
|
||||
new Saving($group, $actor, $data)
|
||||
);
|
||||
|
||||
$this->validator->assertValid($group->getDirty());
|
||||
|
||||
$group->save();
|
||||
|
||||
$this->dispatchEventsFor($group, $actor);
|
||||
|
||||
return $group;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Post\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class DeletePost
|
||||
{
|
||||
public function __construct(
|
||||
public int $postId,
|
||||
public User $actor,
|
||||
public array $data = []
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Post\Command;
|
||||
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Post\Event\Deleting;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Post\PostRepository;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class DeletePostHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected PostRepository $posts
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(DeletePost $command): Post
|
||||
{
|
||||
$actor = $command->actor;
|
||||
|
||||
$post = $this->posts->findOrFail($command->postId, $actor);
|
||||
|
||||
$actor->assertCan('delete', $post);
|
||||
|
||||
$this->events->dispatch(
|
||||
new Deleting($post, $actor, $command->data)
|
||||
);
|
||||
|
||||
$post->delete();
|
||||
|
||||
$this->dispatchEventsFor($post, $actor);
|
||||
|
||||
return $post;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Post\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class EditPost
|
||||
{
|
||||
public function __construct(
|
||||
public int $postId,
|
||||
public User $actor,
|
||||
public array $data
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Post\Command;
|
||||
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Post\CommentPost;
|
||||
use Flarum\Post\Event\Saving;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Post\PostRepository;
|
||||
use Flarum\Post\PostValidator;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class EditPostHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected PostRepository $posts,
|
||||
protected PostValidator $validator
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(EditPost $command): Post|CommentPost
|
||||
{
|
||||
$actor = $command->actor;
|
||||
$data = $command->data;
|
||||
|
||||
$post = $this->posts->findOrFail($command->postId, $actor);
|
||||
|
||||
if ($post instanceof CommentPost) {
|
||||
$attributes = Arr::get($data, 'attributes', []);
|
||||
|
||||
if (isset($attributes['content'])) {
|
||||
$actor->assertCan('edit', $post);
|
||||
|
||||
$post->revise($attributes['content'], $actor);
|
||||
}
|
||||
|
||||
if (isset($attributes['isHidden'])) {
|
||||
$actor->assertCan('hide', $post);
|
||||
|
||||
if ($attributes['isHidden']) {
|
||||
$post->hide($actor);
|
||||
} else {
|
||||
$post->restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->events->dispatch(
|
||||
new Saving($post, $actor, $data)
|
||||
);
|
||||
|
||||
$this->validator->assertValid($post->getDirty());
|
||||
|
||||
$post->save();
|
||||
|
||||
$this->dispatchEventsFor($post, $actor);
|
||||
|
||||
return $post;
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Post\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class PostReply
|
||||
{
|
||||
public function __construct(
|
||||
public int $discussionId,
|
||||
public User $actor,
|
||||
public array $data,
|
||||
public ?string $ipAddress = null,
|
||||
public bool $isFirstPost = false
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Post\Command;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Discussion\DiscussionRepository;
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Notification\NotificationSyncer;
|
||||
use Flarum\Post\CommentPost;
|
||||
use Flarum\Post\Event\Saving;
|
||||
use Flarum\Post\PostValidator;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class PostReplyHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected DiscussionRepository $discussions,
|
||||
protected NotificationSyncer $notifications,
|
||||
protected PostValidator $validator
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(PostReply $command): CommentPost
|
||||
{
|
||||
$actor = $command->actor;
|
||||
|
||||
// Make sure the user has permission to reply to this discussion. First,
|
||||
// make sure the discussion exists and that the user has permission to
|
||||
// view it; if not, fail with a ModelNotFound exception so we don't give
|
||||
// away the existence of the discussion. If the user is allowed to view
|
||||
// it, check if they have permission to reply.
|
||||
$discussion = $this->discussions->findOrFail($command->discussionId, $actor);
|
||||
|
||||
// If this is the first post in the discussion, it's technically not a
|
||||
// "reply", so we won't check for that permission.
|
||||
if (! $command->isFirstPost) {
|
||||
$actor->assertCan('reply', $discussion);
|
||||
}
|
||||
|
||||
// Create a new Post entity, persist it, and dispatch domain events.
|
||||
// Before persistence, though, fire an event to give plugins an
|
||||
// opportunity to alter the post entity based on data in the command.
|
||||
$post = CommentPost::reply(
|
||||
$discussion->id,
|
||||
Arr::get($command->data, 'attributes.content'),
|
||||
$actor->id,
|
||||
$command->ipAddress,
|
||||
$command->actor,
|
||||
);
|
||||
|
||||
if ($actor->isAdmin() && ($time = Arr::get($command->data, 'attributes.createdAt'))) {
|
||||
$post->created_at = new Carbon($time);
|
||||
}
|
||||
|
||||
$this->events->dispatch(
|
||||
new Saving($post, $actor, $command->data)
|
||||
);
|
||||
|
||||
$this->validator->assertValid($post->getAttributes());
|
||||
|
||||
$post->save();
|
||||
|
||||
$this->notifications->onePerUser(function () use ($post, $actor) {
|
||||
$this->dispatchEventsFor($post, $actor);
|
||||
});
|
||||
|
||||
return $post;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\User\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class DeleteUser
|
||||
{
|
||||
public function __construct(
|
||||
public int $userId,
|
||||
public User $actor,
|
||||
public array $data = []
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\User\Command;
|
||||
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\User\Event\Deleting;
|
||||
use Flarum\User\Exception\PermissionDeniedException;
|
||||
use Flarum\User\User;
|
||||
use Flarum\User\UserRepository;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class DeleteUserHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected UserRepository $users
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
public function handle(DeleteUser $command): User
|
||||
{
|
||||
$actor = $command->actor;
|
||||
$user = $this->users->findOrFail($command->userId, $actor);
|
||||
|
||||
$actor->assertCan('delete', $user);
|
||||
|
||||
$this->events->dispatch(
|
||||
new Deleting($user, $actor, $command->data)
|
||||
);
|
||||
|
||||
$user->delete();
|
||||
|
||||
$this->dispatchEventsFor($user, $actor);
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\User\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class EditUser
|
||||
{
|
||||
public function __construct(
|
||||
public int $userId,
|
||||
public User $actor,
|
||||
public array $data
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,128 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\User\Command;
|
||||
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
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;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class EditUserHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected UserRepository $users,
|
||||
protected UserValidator $validator
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(EditUser $command): User
|
||||
{
|
||||
$actor = $command->actor;
|
||||
$data = $command->data;
|
||||
|
||||
$user = $this->users->findOrFail($command->userId, $actor);
|
||||
|
||||
$isSelf = $actor->id === $user->id;
|
||||
|
||||
$attributes = Arr::get($data, 'attributes', []);
|
||||
$relationships = Arr::get($data, 'relationships', []);
|
||||
$validate = [];
|
||||
|
||||
if (isset($attributes['username'])) {
|
||||
$actor->assertCan('editCredentials', $user);
|
||||
$user->rename($attributes['username']);
|
||||
}
|
||||
|
||||
if (isset($attributes['email'])) {
|
||||
if ($isSelf) {
|
||||
$user->requestEmailChange($attributes['email']);
|
||||
|
||||
if ($attributes['email'] !== $user->email) {
|
||||
$validate['email'] = $attributes['email'];
|
||||
}
|
||||
} else {
|
||||
$actor->assertCan('editCredentials', $user);
|
||||
$user->changeEmail($attributes['email']);
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($attributes['isEmailConfirmed'])) {
|
||||
$actor->assertAdmin();
|
||||
$user->activate();
|
||||
}
|
||||
|
||||
if (isset($attributes['password'])) {
|
||||
$actor->assertCan('editCredentials', $user);
|
||||
$user->changePassword($attributes['password']);
|
||||
|
||||
$validate['password'] = $attributes['password'];
|
||||
}
|
||||
|
||||
if (! empty($attributes['markedAllAsReadAt'])) {
|
||||
$actor->assertPermission($isSelf);
|
||||
$user->markAllAsRead();
|
||||
}
|
||||
|
||||
if (! empty($attributes['preferences'])) {
|
||||
$actor->assertPermission($isSelf);
|
||||
|
||||
foreach ($attributes['preferences'] as $k => $v) {
|
||||
$user->setPreference($k, $v);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($relationships['groups']['data']) && is_array($relationships['groups']['data'])) {
|
||||
$actor->assertCan('editGroups', $user);
|
||||
|
||||
$oldGroups = $user->groups()->get()->all();
|
||||
$oldGroupIds = Arr::pluck($oldGroups, 'id');
|
||||
|
||||
$newGroupIds = [];
|
||||
foreach ($relationships['groups']['data'] as $group) {
|
||||
if ($id = Arr::get($group, 'id')) {
|
||||
$newGroupIds[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure non-admins aren't adding/removing admins
|
||||
$adminChanged = in_array('1', array_diff($oldGroupIds, $newGroupIds)) || in_array('1', array_diff($newGroupIds, $oldGroupIds));
|
||||
$actor->assertPermission(! $adminChanged || $actor->isAdmin());
|
||||
|
||||
$user->raise(
|
||||
new GroupsChanged($user, $oldGroups)
|
||||
);
|
||||
|
||||
$user->afterSave(function (User $user) use ($newGroupIds) {
|
||||
$user->groups()->sync($newGroupIds);
|
||||
$user->unsetRelation('groups');
|
||||
});
|
||||
}
|
||||
|
||||
$this->events->dispatch(
|
||||
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;
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\User\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class RegisterUser
|
||||
{
|
||||
public function __construct(
|
||||
public User $actor,
|
||||
public array $data
|
||||
) {
|
||||
}
|
||||
}
|
@@ -1,154 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\User\Command;
|
||||
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\User\AvatarUploader;
|
||||
use Flarum\User\Event\RegisteringFromProvider;
|
||||
use Flarum\User\Event\Saving;
|
||||
use Flarum\User\Exception\PermissionDeniedException;
|
||||
use Flarum\User\RegistrationToken;
|
||||
use Flarum\User\User;
|
||||
use Flarum\User\UserValidator;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Factory;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Intervention\Image\ImageManager;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class RegisterUserHandler
|
||||
{
|
||||
use DispatchEventsTrait;
|
||||
|
||||
public function __construct(
|
||||
protected Dispatcher $events,
|
||||
protected SettingsRepositoryInterface $settings,
|
||||
protected UserValidator $userValidator,
|
||||
protected AvatarUploader $avatarUploader,
|
||||
private readonly Factory $validator,
|
||||
protected ImageManager $imageManager
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PermissionDeniedException if signup is closed and the actor is
|
||||
* not an administrator.
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function handle(RegisterUser $command): User
|
||||
{
|
||||
$actor = $command->actor;
|
||||
$data = $command->data;
|
||||
|
||||
if (! $this->settings->get('allow_sign_up')) {
|
||||
$actor->assertAdmin();
|
||||
}
|
||||
|
||||
$password = Arr::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'])) {
|
||||
/** @var RegistrationToken $token */
|
||||
$token = RegistrationToken::validOrFail($data['attributes']['token']);
|
||||
|
||||
$password = $password ?: Str::random(20);
|
||||
}
|
||||
|
||||
$user = User::register(
|
||||
Arr::get($data, 'attributes.username'),
|
||||
Arr::get($data, 'attributes.email'),
|
||||
$password
|
||||
);
|
||||
|
||||
if (isset($token)) {
|
||||
$this->applyToken($user, $token);
|
||||
}
|
||||
|
||||
if ($actor->isAdmin() && Arr::get($data, 'attributes.isEmailConfirmed')) {
|
||||
$user->activate();
|
||||
}
|
||||
|
||||
$this->events->dispatch(
|
||||
new Saving($user, $actor, $data)
|
||||
);
|
||||
|
||||
$this->userValidator->assertValid(array_merge($user->getAttributes(), compact('password')));
|
||||
|
||||
$user->save();
|
||||
|
||||
if (isset($token)) {
|
||||
$this->fulfillToken($user, $token);
|
||||
}
|
||||
|
||||
$this->dispatchEventsFor($user, $actor);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
private function applyToken(User $user, RegistrationToken $token): void
|
||||
{
|
||||
foreach ($token->user_attributes as $k => $v) {
|
||||
if ($k === 'avatar_url') {
|
||||
$this->uploadAvatarFromUrl($user, $v);
|
||||
continue;
|
||||
}
|
||||
|
||||
$user->$k = $v;
|
||||
|
||||
if ($k === 'email') {
|
||||
$user->activate();
|
||||
}
|
||||
}
|
||||
|
||||
$this->events->dispatch(
|
||||
new RegisteringFromProvider($user, $token->provider, $token->payload)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function uploadAvatarFromUrl(User $user, string $url): void
|
||||
{
|
||||
$urlValidator = $this->validator->make(compact('url'), [
|
||||
'url' => 'required|active_url',
|
||||
]);
|
||||
|
||||
if ($urlValidator->fails()) {
|
||||
throw new InvalidArgumentException('Provided avatar URL must be a valid URI.', 503);
|
||||
}
|
||||
|
||||
$scheme = parse_url($url, PHP_URL_SCHEME);
|
||||
|
||||
if (! in_array($scheme, ['http', 'https'])) {
|
||||
throw new InvalidArgumentException("Provided avatar URL must have scheme http or https. Scheme provided was $scheme.", 503);
|
||||
}
|
||||
|
||||
$image = $this->imageManager->make($url);
|
||||
|
||||
$this->avatarUploader->upload($user, $image);
|
||||
}
|
||||
|
||||
private function fulfillToken(User $user, RegistrationToken $token): void
|
||||
{
|
||||
$token->delete();
|
||||
|
||||
if ($token->provider && $token->identifier) {
|
||||
$user->loginProviders()->create([
|
||||
'provider' => $token->provider,
|
||||
'identifier' => $token->identifier
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user