mirror of
https://github.com/flarum/framework.git
synced 2025-02-21 07:11:56 +08:00
Use new extenders (#34)
This commit is contained in:
parent
46fcc1c18b
commit
c6e14394fd
@ -7,17 +7,28 @@
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Flarum\Api\Event\Serializing;
|
||||
use Flarum\Api\Controller\AbstractSerializeController;
|
||||
use Flarum\Api\Controller\ListPostsController;
|
||||
use Flarum\Api\Controller\ShowDiscussionController;
|
||||
use Flarum\Api\Controller\ShowPostController;
|
||||
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||
use Flarum\Api\Serializer\ForumSerializer;
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Flags\AddCanFlagAttribute;
|
||||
use Flarum\Flags\AddFlagsApiAttributes;
|
||||
use Flarum\Flags\AddNewFlagCountAttribute;
|
||||
use Flarum\Flags\Api\Controller\CreateFlagController;
|
||||
use Flarum\Flags\Api\Controller\DeleteFlagsController;
|
||||
use Flarum\Flags\Api\Controller\ListFlagsController;
|
||||
use Flarum\Flags\Api\Serializer\FlagSerializer;
|
||||
use Flarum\Flags\Flag;
|
||||
use Flarum\Flags\Listener;
|
||||
use Flarum\Flags\PrepareFlagsApiData;
|
||||
use Flarum\Forum\Content\AssertRegistered;
|
||||
use Flarum\Post\Event\Deleted;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
return [
|
||||
(new Extend\Frontend('forum'))
|
||||
@ -39,11 +50,33 @@ return [
|
||||
(new Extend\Model(Post::class))
|
||||
->hasMany('flags', Flag::class, 'post_id'),
|
||||
|
||||
(new Extend\ApiSerializer(PostSerializer::class))
|
||||
->hasMany('flags', FlagSerializer::class)
|
||||
->attribute('canFlag', AddCanFlagAttribute::class),
|
||||
|
||||
(new Extend\ApiSerializer(CurrentUserSerializer::class))
|
||||
->attribute('newFlagCount', AddNewFlagCountAttribute::class),
|
||||
|
||||
(new Extend\ApiSerializer(ForumSerializer::class))
|
||||
->mutate(AddFlagsApiAttributes::class),
|
||||
|
||||
(new Extend\ApiController(ShowDiscussionController::class))
|
||||
->addInclude(['posts.flags', 'posts.flags.user']),
|
||||
|
||||
(new Extend\ApiController(ListPostsController::class))
|
||||
->addInclude(['flags', 'flags.user']),
|
||||
|
||||
(new Extend\ApiController(ShowPostController::class))
|
||||
->addInclude(['flags', 'flags.user']),
|
||||
|
||||
(new Extend\ApiController(AbstractSerializeController::class))
|
||||
->prepareDataForSerialization(PrepareFlagsApiData::class),
|
||||
|
||||
(new Extend\Settings())
|
||||
->serializeToForum('guidelinesUrl', 'flarum-flags.guidelines_url'),
|
||||
|
||||
(new Extend\Event())
|
||||
->listen(Deleted::class, Listener\DeleteFlags::class),
|
||||
|
||||
new Extend\Locales(__DIR__.'/locale'),
|
||||
|
||||
function (Dispatcher $events) {
|
||||
$events->listen(Serializing::class, Listener\AddFlagsApiAttributes::class);
|
||||
|
||||
$events->subscribe(Listener\AddPostFlagsRelationship::class);
|
||||
},
|
||||
];
|
||||
|
46
extensions/flags/src/AddCanFlagAttribute.php
Normal file
46
extensions/flags/src/AddCanFlagAttribute.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?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\Flags;
|
||||
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\User\User;
|
||||
|
||||
class AddCanFlagAttribute
|
||||
{
|
||||
/**
|
||||
* @var SettingsRepositoryInterface
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @param SettingsRepositoryInterface $settings
|
||||
*/
|
||||
public function __construct(SettingsRepositoryInterface $settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function __invoke(PostSerializer $serializer, Post $post)
|
||||
{
|
||||
return $serializer->getActor()->can('flag', $post) && $this->checkFlagOwnPostSetting($serializer->getActor(), $post);
|
||||
}
|
||||
|
||||
protected function checkFlagOwnPostSetting(User $actor, Post $post): bool
|
||||
{
|
||||
if ($actor->id === $post->user_id) {
|
||||
// If $actor is the post author, check to see if the setting is enabled
|
||||
return (bool) $this->settings->get('flarum-flags.can_flag_own');
|
||||
}
|
||||
// $actor is not the post author
|
||||
return true;
|
||||
}
|
||||
}
|
52
extensions/flags/src/AddFlagsApiAttributes.php
Executable file
52
extensions/flags/src/AddFlagsApiAttributes.php
Executable file
@ -0,0 +1,52 @@
|
||||
<?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\Flags;
|
||||
|
||||
use Flarum\Api\Serializer\ForumSerializer;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\User\User;
|
||||
|
||||
class AddFlagsApiAttributes
|
||||
{
|
||||
/**
|
||||
* @var SettingsRepositoryInterface
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @param SettingsRepositoryInterface $settings
|
||||
*/
|
||||
public function __construct(SettingsRepositoryInterface $settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function __invoke(ForumSerializer $serializer)
|
||||
{
|
||||
$attributes = [
|
||||
'canViewFlags' => $serializer->getActor()->hasPermissionLike('discussion.viewFlags')
|
||||
];
|
||||
|
||||
if ($attributes['canViewFlags']) {
|
||||
$attributes['flagCount'] = (int) $this->getFlagCount($serializer->getActor());
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @return int
|
||||
*/
|
||||
protected function getFlagCount(User $actor)
|
||||
{
|
||||
return Flag::whereVisibleTo($actor)->distinct()->count('flags.post_id');
|
||||
}
|
||||
}
|
36
extensions/flags/src/AddNewFlagCountAttribute.php
Normal file
36
extensions/flags/src/AddNewFlagCountAttribute.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?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\Flags;
|
||||
|
||||
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||
use Flarum\User\User;
|
||||
|
||||
class AddNewFlagCountAttribute
|
||||
{
|
||||
public function __invoke(CurrentUserSerializer $serializer, User $user)
|
||||
{
|
||||
return (int) $this->getNewFlagCount($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @return int
|
||||
*/
|
||||
protected function getNewFlagCount(User $actor)
|
||||
{
|
||||
$query = Flag::whereVisibleTo($actor);
|
||||
|
||||
if ($time = $actor->read_flags_at) {
|
||||
$query->where('flags.created_at', '>', $time);
|
||||
}
|
||||
|
||||
return $query->distinct()->count('flags.post_id');
|
||||
}
|
||||
}
|
@ -1,90 +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\Flags\Listener;
|
||||
|
||||
use Flarum\Api\Event\Serializing;
|
||||
use Flarum\Api\Serializer\CurrentUserSerializer;
|
||||
use Flarum\Api\Serializer\ForumSerializer;
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Flags\Flag;
|
||||
use Flarum\Post\Post;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\User\User;
|
||||
|
||||
class AddFlagsApiAttributes
|
||||
{
|
||||
/**
|
||||
* @var SettingsRepositoryInterface
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @param SettingsRepositoryInterface $settings
|
||||
*/
|
||||
public function __construct(SettingsRepositoryInterface $settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function handle(Serializing $event)
|
||||
{
|
||||
if ($event->isSerializer(ForumSerializer::class)) {
|
||||
$event->attributes['canViewFlags'] = $event->actor->hasPermissionLike('discussion.viewFlags');
|
||||
|
||||
if ($event->attributes['canViewFlags']) {
|
||||
$event->attributes['flagCount'] = (int) $this->getFlagCount($event->actor);
|
||||
}
|
||||
|
||||
$event->attributes['guidelinesUrl'] = $this->settings->get('flarum-flags.guidelines_url');
|
||||
}
|
||||
|
||||
if ($event->isSerializer(CurrentUserSerializer::class)) {
|
||||
$event->attributes['newFlagCount'] = (int) $this->getNewFlagCount($event->model);
|
||||
}
|
||||
|
||||
if ($event->isSerializer(PostSerializer::class)) {
|
||||
$event->attributes['canFlag'] = $event->actor->can('flag', $event->model) && $this->checkFlagOwnPostSetting($event->actor, $event->model);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @return int
|
||||
*/
|
||||
protected function getFlagCount(User $actor)
|
||||
{
|
||||
return Flag::whereVisibleTo($actor)->distinct()->count('flags.post_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @return int
|
||||
*/
|
||||
protected function getNewFlagCount(User $actor)
|
||||
{
|
||||
$query = Flag::whereVisibleTo($actor);
|
||||
|
||||
if ($time = $actor->read_flags_at) {
|
||||
$query->where('flags.created_at', '>', $time);
|
||||
}
|
||||
|
||||
return $query->distinct()->count('flags.post_id');
|
||||
}
|
||||
|
||||
protected function checkFlagOwnPostSetting(User $actor, Post $post): bool
|
||||
{
|
||||
if ($actor->id === $post->user_id) {
|
||||
// If $actor is the post author, check to see if the setting is enabled
|
||||
return (bool) $this->settings->get('flarum-flags.can_flag_own');
|
||||
}
|
||||
// $actor is not the post author
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,123 +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\Flags\Listener;
|
||||
|
||||
use Flarum\Api\Controller;
|
||||
use Flarum\Api\Event\WillGetData;
|
||||
use Flarum\Api\Event\WillSerializeData;
|
||||
use Flarum\Api\Serializer\PostSerializer;
|
||||
use Flarum\Event\GetApiRelationship;
|
||||
use Flarum\Flags\Api\Controller\CreateFlagController;
|
||||
use Flarum\Flags\Api\Serializer\FlagSerializer;
|
||||
use Flarum\Post\Event\Deleted;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class AddPostFlagsRelationship
|
||||
{
|
||||
/**
|
||||
* @param Dispatcher $events
|
||||
*/
|
||||
public function subscribe(Dispatcher $events)
|
||||
{
|
||||
$events->listen(Deleted::class, [$this, 'postWasDeleted']);
|
||||
$events->listen(GetApiRelationship::class, [$this, 'getApiRelationship']);
|
||||
$events->listen(WillGetData::class, [$this, 'includeFlagsRelationship']);
|
||||
$events->listen(WillSerializeData::class, [$this, 'prepareApiData']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Deleted $event
|
||||
*/
|
||||
public function postWasDeleted(Deleted $event)
|
||||
{
|
||||
$event->post->flags()->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GetApiRelationship $event
|
||||
* @return \Tobscure\JsonApi\Relationship|null
|
||||
*/
|
||||
public function getApiRelationship(GetApiRelationship $event)
|
||||
{
|
||||
if ($event->isRelationship(PostSerializer::class, 'flags')) {
|
||||
return $event->serializer->hasMany($event->model, FlagSerializer::class, 'flags');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WillGetData $event
|
||||
*/
|
||||
public function includeFlagsRelationship(WillGetData $event)
|
||||
{
|
||||
if ($event->isController(Controller\ShowDiscussionController::class)) {
|
||||
$event->addInclude([
|
||||
'posts.flags',
|
||||
'posts.flags.user'
|
||||
]);
|
||||
}
|
||||
|
||||
if ($event->isController(Controller\ListPostsController::class)
|
||||
|| $event->isController(Controller\ShowPostController::class)) {
|
||||
$event->addInclude([
|
||||
'flags',
|
||||
'flags.user'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WillSerializeData $event
|
||||
*/
|
||||
public function prepareApiData(WillSerializeData $event)
|
||||
{
|
||||
// For any API action that allows the 'flags' relationship to be
|
||||
// included, we need to preload this relationship onto the data (Post
|
||||
// models) so that we can selectively expose only the flags that the
|
||||
// user has permission to view.
|
||||
if ($event->isController(Controller\ShowDiscussionController::class)) {
|
||||
if ($event->data->relationLoaded('posts')) {
|
||||
$posts = $event->data->getRelation('posts');
|
||||
}
|
||||
}
|
||||
|
||||
if ($event->isController(Controller\ListPostsController::class)) {
|
||||
$posts = $event->data->all();
|
||||
}
|
||||
|
||||
if ($event->isController(Controller\ShowPostController::class)) {
|
||||
$posts = [$event->data];
|
||||
}
|
||||
|
||||
if ($event->isController(CreateFlagController::class)) {
|
||||
$posts = [$event->data->post];
|
||||
}
|
||||
|
||||
if (isset($posts)) {
|
||||
$actor = $event->request->getAttribute('actor');
|
||||
$postsWithPermission = [];
|
||||
|
||||
foreach ($posts as $post) {
|
||||
if (is_object($post)) {
|
||||
$post->setRelation('flags', null);
|
||||
|
||||
if ($actor->can('viewFlags', $post->discussion)) {
|
||||
$postsWithPermission[] = $post;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($postsWithPermission)) {
|
||||
(new Collection($postsWithPermission))
|
||||
->load('flags', 'flags.user');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
extensions/flags/src/Listener/DeleteFlags.php
Normal file
23
extensions/flags/src/Listener/DeleteFlags.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?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\Flags\Listener;
|
||||
|
||||
use Flarum\Post\Event\Deleted;
|
||||
|
||||
class DeleteFlags
|
||||
{
|
||||
/**
|
||||
* @param Deleted $event
|
||||
*/
|
||||
public function handle(Deleted $event)
|
||||
{
|
||||
$event->post->flags()->delete();
|
||||
}
|
||||
}
|
63
extensions/flags/src/PrepareFlagsApiData.php
Executable file
63
extensions/flags/src/PrepareFlagsApiData.php
Executable file
@ -0,0 +1,63 @@
|
||||
<?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\Flags;
|
||||
|
||||
use Flarum\Api\Controller;
|
||||
use Flarum\Flags\Api\Controller\CreateFlagController;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class PrepareFlagsApiData
|
||||
{
|
||||
public function __invoke(Controller\AbstractSerializeController $controller, $data, ServerRequestInterface $request)
|
||||
{
|
||||
// For any API action that allows the 'flags' relationship to be
|
||||
// included, we need to preload this relationship onto the data (Post
|
||||
// models) so that we can selectively expose only the flags that the
|
||||
// user has permission to view.
|
||||
if ($controller instanceof Controller\ShowDiscussionController) {
|
||||
if ($data->relationLoaded('posts')) {
|
||||
$posts = $data->getRelation('posts');
|
||||
}
|
||||
}
|
||||
|
||||
if ($controller instanceof Controller\ListPostsController) {
|
||||
$posts = $data->all();
|
||||
}
|
||||
|
||||
if ($controller instanceof Controller\ShowPostController) {
|
||||
$posts = [$data];
|
||||
}
|
||||
|
||||
if ($controller instanceof CreateFlagController) {
|
||||
$posts = [$data->post];
|
||||
}
|
||||
|
||||
if (isset($posts)) {
|
||||
$actor = $request->getAttribute('actor');
|
||||
$postsWithPermission = [];
|
||||
|
||||
foreach ($posts as $post) {
|
||||
if (is_object($post)) {
|
||||
$post->setRelation('flags', null);
|
||||
|
||||
if ($actor->can('viewFlags', $post->discussion)) {
|
||||
$postsWithPermission[] = $post;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($postsWithPermission)) {
|
||||
(new Collection($postsWithPermission))
|
||||
->load('flags', 'flags.user');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user