Fix mentioned filtering (#67)

This commit is contained in:
Alexander Skvortsov 2021-05-04 14:57:29 -04:00 committed by GitHub
parent e2b309ad95
commit 8ed08b63cd
4 changed files with 126 additions and 31 deletions

View File

@ -7,15 +7,12 @@
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Mentions;
use Flarum\Api\Controller;
use Flarum\Api\Serializer\BasicPostSerializer;
use Flarum\Api\Serializer\PostSerializer;
use Flarum\Event\ConfigurePostsQuery;
use Flarum\Extend;
use Flarum\Mentions\ConfigureMentions;
use Flarum\Mentions\FilterVisiblePosts;
use Flarum\Mentions\Formatter;
use Flarum\Mentions\Listener;
use Flarum\Mentions\Notification\PostMentionedBlueprint;
use Flarum\Mentions\Notification\UserMentionedBlueprint;
use Flarum\Post\Event\Deleted;
@ -23,6 +20,7 @@ use Flarum\Post\Event\Hidden;
use Flarum\Post\Event\Posted;
use Flarum\Post\Event\Restored;
use Flarum\Post\Event\Revised;
use Flarum\Post\Filter\PostFilterer;
use Flarum\Post\Post;
use Flarum\User\User;
@ -83,6 +81,8 @@ return [
->listen(Restored::class, Listener\UpdateMentionsMetadataWhenVisible::class)
->listen(Revised::class, Listener\UpdateMentionsMetadataWhenVisible::class)
->listen(Hidden::class, Listener\UpdateMentionsMetadataWhenInvisible::class)
->listen(Deleted::class, Listener\UpdateMentionsMetadataWhenInvisible::class)
->listen(ConfigurePostsQuery::class, Listener\AddFilterByMentions::class),
->listen(Deleted::class, Listener\UpdateMentionsMetadataWhenInvisible::class),
(new Extend\Filter(PostFilterer::class))
->addFilter(Filter\MentionedFilter::class),
];

View File

@ -0,0 +1,31 @@
<?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\Mentions\Filter;
use Flarum\Filter\FilterInterface;
use Flarum\Filter\FilterState;
class MentionedFilter implements FilterInterface
{
public function getFilterKey(): string
{
return 'mentioned';
}
public function filter(FilterState $filterState, string $filterValue, bool $negate)
{
$mentionedId = trim($filterValue, '"');
$filterState
->getQuery()
->join('post_mentions_user', 'posts.id', '=', 'post_mentions_user.post_id')
->where('post_mentions_user.mentions_user_id', $negate ? '!=' : '=', $mentionedId);
}
}

View File

@ -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\Mentions\Listener;
use Flarum\Event\ConfigurePostsQuery;
use Illuminate\Support\Arr;
class AddFilterByMentions
{
public function handle(ConfigurePostsQuery $event)
{
if ($mentionedId = Arr::get($event->filter, 'mentioned')) {
$event->query->join('post_mentions_user', 'posts.id', '=', 'post_mentions_user.post_id')
->where('post_mentions_user.mentions_user_id', '=', $mentionedId);
}
}
}

View File

@ -0,0 +1,88 @@
<?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\Tests\integration\api\discussions;
use Carbon\Carbon;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Illuminate\Support\Arr;
class ListTest extends TestCase
{
use RetrievesAuthorizedUsers;
/**
* @inheritDoc
*/
protected function setUp(): void
{
parent::setUp();
$this->extension('flarum-mentions');
$this->prepareDatabase([
'discussions' => [
['id' => 1, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1],
],
'posts' => [
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 2, 'discussion_id' => 1, 'created_at' => Carbon::now(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 3, 'discussion_id' => 1, 'created_at' => Carbon::now(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 4, 'discussion_id' => 1, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
],
'post_mentions_user' => [
['post_id' => 2, 'mentions_user_id' => 1],
['post_id' => 3, 'mentions_user_id' => 1],
['post_id' => 4, 'mentions_user_id' => 2]
],
'users' => [
$this->normalUser(),
]
]);
}
/**
* @test
*/
public function mentioned_filter_works()
{
$response = $this->send(
$this->request('GET', '/api/posts')
->withQueryParams([
'filter' => ['mentioned' => 1],
])
);
$data = json_decode($response->getBody()->getContents(), true)['data'];
// Order-independent comparison
$ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['2', '3'], $ids, 'IDs do not match');
}
/**
* @test
*/
public function mentioned_filter_works_negated()
{
$response = $this->send(
$this->request('GET', '/api/posts')
->withQueryParams([
'filter' => ['-mentioned' => 1],
])
);
$data = json_decode($response->getBody()->getContents(), true)['data'];
// Order-independent comparison
$ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['4'], $ids, 'IDs do not match');
}
}