mirror of
https://github.com/flarum/core.git
synced 2025-08-06 08:27:42 +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