1
0
mirror of https://github.com/flarum/core.git synced 2025-08-09 01:46:35 +02:00

feat: add support for PgSQL (#3985)

* feat: add support for `PgSQL`
* chore: generate dump
* feat: query exception errors db driver hint
* feat: allow defining supported databases
* chore: review comments
* feat: setting for pgsql preferred search config
This commit is contained in:
Sami Mazouz
2024-06-22 08:03:56 +01:00
committed by GitHub
parent d04cda6ca3
commit 379298acb0
76 changed files with 2097 additions and 261 deletions

View File

@@ -11,8 +11,12 @@ namespace Flarum\Approval\Tests\integration\api;
use Carbon\Carbon;
use Flarum\Approval\Tests\integration\InteractsWithUnapprovedContent;
use Flarum\Discussion\Discussion;
use Flarum\Group\Group;
use Flarum\Post\Post;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
class ApprovePostsTest extends TestCase
{
@@ -26,23 +30,23 @@ class ApprovePostsTest extends TestCase
$this->extension('flarum-approval');
$this->prepareDatabase([
'users' => [
User::class => [
['id' => 1, 'username' => 'Muralf', 'email' => 'muralf@machine.local', 'is_email_confirmed' => 1],
$this->normalUser(),
['id' => 3, 'username' => 'acme', 'email' => 'acme@machine.local', 'is_email_confirmed' => 1],
['id' => 4, 'username' => 'luceos', 'email' => 'luceos@machine.local', 'is_email_confirmed' => 1],
],
'discussions' => [
Discussion::class => [
['id' => 1, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 4, 'first_post_id' => 1, 'comment_count' => 1, 'is_approved' => 1],
],
'posts' => [
['id' => 1, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => 0, 'is_approved' => 1, 'number' => 1],
['id' => 2, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => 0, 'is_approved' => 1, 'number' => 2],
['id' => 3, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => 0, 'is_approved' => 0, 'number' => 3],
Post::class => [
['id' => 1, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => null, 'is_approved' => 1, 'number' => 1],
['id' => 2, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => null, 'is_approved' => 1, 'number' => 2],
['id' => 3, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => null, 'is_approved' => 0, 'number' => 3],
['id' => 4, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => Carbon::now(), 'is_approved' => 1, 'number' => 4],
['id' => 5, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => 0, 'is_approved' => 0, 'number' => 5],
['id' => 5, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'hidden_at' => null, 'is_approved' => 0, 'number' => 5],
],
'groups' => [
Group::class => [
['id' => 4, 'name_singular' => 'Acme', 'name_plural' => 'Acme', 'is_hidden' => 0],
['id' => 5, 'name_singular' => 'Acme', 'name_plural' => 'Acme', 'is_hidden' => 0],
],

View File

@@ -11,9 +11,12 @@ namespace Flarum\Approval\Tests\integration\api;
use Carbon\Carbon;
use Flarum\Approval\Tests\integration\InteractsWithUnapprovedContent;
use Flarum\Discussion\Discussion;
use Flarum\Group\Group;
use Flarum\Post\Post;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
class CreatePostsTest extends TestCase
{
@@ -27,18 +30,18 @@ class CreatePostsTest extends TestCase
$this->extension('flarum-flags', 'flarum-approval');
$this->prepareDatabase([
'users' => [
User::class => [
['id' => 1, 'username' => 'Muralf', 'email' => 'muralf@machine.local', 'is_email_confirmed' => 1],
$this->normalUser(),
['id' => 3, 'username' => 'acme', 'email' => 'acme@machine.local', 'is_email_confirmed' => 1],
['id' => 4, 'username' => 'luceos', 'email' => 'luceos@machine.local', 'is_email_confirmed' => 1],
],
'discussions' => [
Discussion::class => [
['id' => 1, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 4, 'first_post_id' => 1, 'comment_count' => 1, 'is_approved' => 1],
['id' => 2, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 4, 'first_post_id' => 2, 'comment_count' => 1, 'is_approved' => 0],
['id' => 3, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 4, 'first_post_id' => 3, 'comment_count' => 1, 'is_approved' => 0],
],
'posts' => [
Post::class => [
['id' => 1, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'is_private' => 0, 'is_approved' => 1, 'number' => 1],
['id' => 2, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'is_private' => 0, 'is_approved' => 1, 'number' => 2],
['id' => 3, 'discussion_id' => 1, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'is_private' => 0, 'is_approved' => 1, 'number' => 3],
@@ -49,7 +52,7 @@ class CreatePostsTest extends TestCase
['id' => 8, 'discussion_id' => 3, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'is_private' => 0, 'is_approved' => 1, 'number' => 2],
['id' => 9, 'discussion_id' => 3, 'user_id' => 4, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'is_private' => 0, 'is_approved' => 0, 'number' => 3],
],
'groups' => [
Group::class => [
['id' => 4, 'name_singular' => 'Acme', 'name_plural' => 'Acme', 'is_hidden' => 0],
['id' => 5, 'name_singular' => 'Acme', 'name_plural' => 'Acme', 'is_hidden' => 0],
],
@@ -60,6 +63,7 @@ class CreatePostsTest extends TestCase
'group_permission' => [
['group_id' => 4, 'permission' => 'discussion.startWithoutApproval'],
['group_id' => 5, 'permission' => 'discussion.replyWithoutApproval'],
['group_id' => Group::MEMBER_ID, 'permission' => 'postWithoutThrottle'],
]
]);
}

View File

@@ -53,7 +53,10 @@ class FlagResource extends AbstractDatabaseResource
public function query(Context $context): object
{
if ($context->listing(self::class)) {
$query = Flag::query()->groupBy('post_id');
$query = Flag::query()->whenPgSql(
fn (Builder $query) => $query->distinct('post_id')->orderBy('post_id'),
else: fn (Builder $query) => $query->groupBy('post_id')
);
$this->scope($query, $context);

View File

@@ -9,6 +9,7 @@
namespace Flarum\Flags\Tests\integration\api\flags;
use Carbon\Carbon;
use Flarum\Discussion\Discussion;
use Flarum\Flags\Flag;
use Flarum\Group\Group;
@@ -16,6 +17,7 @@ use Flarum\Post\Post;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
use Illuminate\Database\PostgresConnection;
use Illuminate\Support\Arr;
class ListTest extends TestCase
@@ -58,12 +60,12 @@ class ListTest extends TestCase
['id' => 4, 'discussion_id' => 1, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p></p></t>', 'is_private' => true],
],
Flag::class => [
['id' => 1, 'post_id' => 1, 'user_id' => 1],
['id' => 2, 'post_id' => 1, 'user_id' => 2],
['id' => 3, 'post_id' => 1, 'user_id' => 3],
['id' => 4, 'post_id' => 2, 'user_id' => 2],
['id' => 5, 'post_id' => 3, 'user_id' => 1],
['id' => 6, 'post_id' => 4, 'user_id' => 1],
['id' => 1, 'post_id' => 1, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(2)],
['id' => 2, 'post_id' => 1, 'user_id' => 2, 'created_at' => Carbon::now()->addMinutes(3)],
['id' => 3, 'post_id' => 1, 'user_id' => 3, 'created_at' => Carbon::now()->addMinutes(4)],
['id' => 4, 'post_id' => 2, 'user_id' => 2, 'created_at' => Carbon::now()->addMinutes(5)],
['id' => 5, 'post_id' => 3, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(6)],
['id' => 6, 'post_id' => 4, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(7)],
]
]);
}
@@ -79,12 +81,19 @@ class ListTest extends TestCase
])
);
$this->assertEquals(200, $response->getStatusCode(), $body = $response->getBody()->getContents());
$body = $response->getBody()->getContents();
$this->assertEquals(200, $response->getStatusCode(), $body);
$data = json_decode($body, true)['data'];
$ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '4', '5'], $ids);
if ($this->database() instanceof PostgresConnection) {
$this->assertEqualsCanonicalizing(['3', '4', '5'], $ids);
} else {
$this->assertEqualsCanonicalizing(['1', '4', '5'], $ids);
}
}
/**
@@ -122,7 +131,7 @@ class ListTest extends TestCase
$data = json_decode($response->getBody()->getContents(), true)['data'];
$ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '4', '5'], $ids);
$this->assertCount(3, $data);
}
/**

View File

@@ -18,6 +18,7 @@ use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
class ListWithTagsTest extends TestCase
{
@@ -86,16 +87,16 @@ class ListWithTagsTest extends TestCase
],
Flag::class => [
// From regular ListTest
['id' => 1, 'post_id' => 1, 'user_id' => 1],
['id' => 2, 'post_id' => 1, 'user_id' => 2],
['id' => 3, 'post_id' => 1, 'user_id' => 3],
['id' => 4, 'post_id' => 2, 'user_id' => 2],
['id' => 5, 'post_id' => 3, 'user_id' => 1],
['id' => 1, 'post_id' => 1, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(2)],
['id' => 2, 'post_id' => 1, 'user_id' => 2, 'created_at' => Carbon::now()->addMinutes(3)],
['id' => 3, 'post_id' => 1, 'user_id' => 3, 'created_at' => Carbon::now()->addMinutes(4)],
['id' => 4, 'post_id' => 2, 'user_id' => 2, 'created_at' => Carbon::now()->addMinutes(5)],
['id' => 5, 'post_id' => 3, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(6)],
// In tags
['id' => 6, 'post_id' => 4, 'user_id' => 1],
['id' => 7, 'post_id' => 5, 'user_id' => 1],
['id' => 8, 'post_id' => 6, 'user_id' => 1],
['id' => 9, 'post_id' => 7, 'user_id' => 1],
['id' => 6, 'post_id' => 4, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(7)],
['id' => 7, 'post_id' => 5, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(8)],
['id' => 8, 'post_id' => 6, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(9)],
['id' => 9, 'post_id' => 7, 'user_id' => 1, 'created_at' => Carbon::now()->addMinutes(10)],
]
]);
}
@@ -111,12 +112,14 @@ class ListWithTagsTest extends TestCase
])
);
$this->assertEquals(200, $response->getStatusCode());
$body = $response->getBody()->getContents();
$data = json_decode($response->getBody()->getContents(), true)['data'];
$this->assertEquals(200, $response->getStatusCode(), $body);
$data = json_decode($body, true)['data'];
$ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '4', '5', '6', '7', '8', '9'], $ids);
$this->assertCount(7, $data);
}
/**
@@ -154,7 +157,9 @@ class ListWithTagsTest extends TestCase
$data = json_decode($response->getBody()->getContents(), true)['data'];
$ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '4', '5', '8', '9'], $ids);
// 7 is included, even though mods can't view discussions.
// This is because the UI doesnt allow discussions.viewFlags without viewDiscussions.
$this->assertCount(5, $data);
}
/**

View File

@@ -9,9 +9,14 @@
namespace Flarum\Flags\Tests\integration\api\posts;
use Flarum\Discussion\Discussion;
use Flarum\Flags\Flag;
use Flarum\Group\Group;
use Flarum\Post\Post;
use Flarum\Tags\Tag;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
use Illuminate\Support\Arr;
class IncludeFlagsVisibilityTest extends TestCase
@@ -28,7 +33,7 @@ class IncludeFlagsVisibilityTest extends TestCase
$this->extension('flarum-tags', 'flarum-flags');
$this->prepareDatabase([
'users' => [
User::class => [
$this->normalUser(),
[
'id' => 3,
@@ -56,7 +61,7 @@ class IncludeFlagsVisibilityTest extends TestCase
['group_id' => 5, 'user_id' => 2],
['group_id' => 6, 'user_id' => 3],
],
'groups' => [
Group::class => [
['id' => 5, 'name_singular' => 'group5', 'name_plural' => 'group5', 'color' => null, 'icon' => 'fas fa-crown', 'is_hidden' => false],
['id' => 6, 'name_singular' => 'group1', 'name_plural' => 'group1', 'color' => null, 'icon' => 'fas fa-cog', 'is_hidden' => false],
],
@@ -67,11 +72,11 @@ class IncludeFlagsVisibilityTest extends TestCase
['group_id' => 6, 'permission' => 'tag1.discussion.viewFlags'],
['group_id' => 6, 'permission' => 'tag1.viewForum'],
],
'tags' => [
Tag::class => [
['id' => 1, 'name' => 'Tag 1', 'slug' => 'tag-1', 'is_primary' => false, 'position' => null, 'parent_id' => null, 'is_restricted' => true],
['id' => 2, 'name' => 'Tag 2', 'slug' => 'tag-2', 'is_primary' => true, 'position' => 2, 'parent_id' => null, 'is_restricted' => false],
],
'discussions' => [
Discussion::class => [
['id' => 1, 'title' => 'Test1', 'user_id' => 1, 'comment_count' => 1],
['id' => 2, 'title' => 'Test2', 'user_id' => 1, 'comment_count' => 1],
],
@@ -79,7 +84,7 @@ class IncludeFlagsVisibilityTest extends TestCase
['discussion_id' => 1, 'tag_id' => 1],
['discussion_id' => 2, 'tag_id' => 2],
],
'posts' => [
Post::class => [
['id' => 1, 'discussion_id' => 1, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p></p></t>'],
['id' => 2, 'discussion_id' => 1, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p></p></t>'],
['id' => 3, 'discussion_id' => 1, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p></p></t>'],
@@ -87,7 +92,7 @@ class IncludeFlagsVisibilityTest extends TestCase
['id' => 4, 'discussion_id' => 2, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p></p></t>'],
['id' => 5, 'discussion_id' => 2, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p></p></t>'],
],
'flags' => [
Flag::class => [
['id' => 1, 'post_id' => 1, 'user_id' => 1],
['id' => 2, 'post_id' => 1, 'user_id' => 5],
['id' => 3, 'post_id' => 1, 'user_id' => 3],

View File

@@ -58,6 +58,7 @@ class PostResourceFields
// So that we can tell if the current user has liked the post.
$query
->orderBy(new Expression($grammar->wrap('user_id').' = '.$actor->id), 'desc')
->orderBy('created_at')
->limit(static::$maxLikes);
}),
];

View File

@@ -54,17 +54,17 @@ class ListPostsTest extends TestCase
['id' => 112, 'username' => 'user112', 'email' => '112@machine.local', 'is_email_confirmed' => 1],
],
'post_likes' => [
['user_id' => 102, 'post_id' => 101],
['user_id' => 104, 'post_id' => 101],
['user_id' => 105, 'post_id' => 101],
['user_id' => 106, 'post_id' => 101],
['user_id' => 107, 'post_id' => 101],
['user_id' => 108, 'post_id' => 101],
['user_id' => 109, 'post_id' => 101],
['user_id' => 110, 'post_id' => 101],
['user_id' => 2, 'post_id' => 101],
['user_id' => 111, 'post_id' => 101],
['user_id' => 112, 'post_id' => 101],
['user_id' => 102, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(2)],
['user_id' => 104, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(3)],
['user_id' => 105, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(4)],
['user_id' => 106, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(5)],
['user_id' => 107, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(6)],
['user_id' => 108, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(7)],
['user_id' => 109, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(8)],
['user_id' => 110, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(9)],
['user_id' => 2, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(10)],
['user_id' => 111, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(11)],
['user_id' => 112, 'post_id' => 101, 'created_at' => Carbon::now()->addMinutes(12)],
],
'group_permission' => [
['group_id' => Group::GUEST_ID, 'permission' => 'searchUsers'],

View File

@@ -12,7 +12,7 @@ namespace Flarum\Lock\Filter;
use Flarum\Search\Database\DatabaseSearchState;
use Flarum\Search\Filter\FilterInterface;
use Flarum\Search\SearchState;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent\Builder;
/**
* @implements FilterInterface<DatabaseSearchState>

View File

@@ -249,9 +249,11 @@ class GroupMentionsTest extends TestCase
])
);
$this->assertEquals(201, $response->getStatusCode());
$body = $response->getBody()->getContents();
$response = json_decode($response->getBody(), true);
$this->assertEquals(201, $response->getStatusCode(), $body);
$response = json_decode($body, true);
$this->assertStringNotContainsString('@Members', $response['data']['attributes']['contentHtml']);
$this->assertStringNotContainsString('@Guests', $response['data']['attributes']['contentHtml']);

View File

@@ -116,35 +116,35 @@ class ListPostsTest extends TestCase
{
$this->prepareDatabase([
Discussion::class => [
['id' => 100, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 101, 'comment_count' => 12],
['id' => 100, 'title' => __CLASS__, 'created_at' => Carbon::parse('2024-05-04'), 'user_id' => 1, 'first_post_id' => 101, 'comment_count' => 12],
],
Post::class => [
['id' => 101, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 102, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 103, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>', 'is_private' => 1],
['id' => 104, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 105, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 106, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 107, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 108, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 109, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 110, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 111, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 112, 'discussion_id' => 100, 'created_at' => Carbon::now(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 101, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04'), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 102, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(2), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 103, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(3), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>', 'is_private' => 1],
['id' => 104, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(4), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 105, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(5), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 106, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(6), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 107, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(7), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 108, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(8), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 109, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(9), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 110, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(10), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 111, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(11), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
['id' => 112, 'discussion_id' => 100, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(12), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>text</p></t>'],
],
'post_mentions_post' => [
['post_id' => 102, 'mentions_post_id' => 101],
['post_id' => 103, 'mentions_post_id' => 101],
['post_id' => 104, 'mentions_post_id' => 101],
['post_id' => 105, 'mentions_post_id' => 101],
['post_id' => 106, 'mentions_post_id' => 101],
['post_id' => 107, 'mentions_post_id' => 101],
['post_id' => 108, 'mentions_post_id' => 101],
['post_id' => 109, 'mentions_post_id' => 101],
['post_id' => 110, 'mentions_post_id' => 101],
['post_id' => 111, 'mentions_post_id' => 101],
['post_id' => 112, 'mentions_post_id' => 101],
['post_id' => 103, 'mentions_post_id' => 112],
['post_id' => 102, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(2)],
['post_id' => 103, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(3)],
['post_id' => 104, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(4)],
['post_id' => 105, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(5)],
['post_id' => 106, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(6)],
['post_id' => 107, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(7)],
['post_id' => 108, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(8)],
['post_id' => 109, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(9)],
['post_id' => 110, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(10)],
['post_id' => 111, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(11)],
['post_id' => 112, 'mentions_post_id' => 101, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(12)],
['post_id' => 103, 'mentions_post_id' => 112, 'created_at' => Carbon::parse('2024-05-04')->addMinutes(13)],
],
]);
}
@@ -187,10 +187,11 @@ class ListPostsTest extends TestCase
])->withQueryParams([
'filter' => ['discussion' => 100],
'include' => 'mentionedBy',
'sort' => 'createdAt',
])
);
$data = json_decode($body = $response->getBody()->getContents(), true)['data'] ?? [];
$data = json_decode($body = $response->getBody()->getContents(), true)['data'];
$this->assertEquals(200, $response->getStatusCode(), $body);

View File

@@ -51,7 +51,7 @@ class PostMentionsTest extends TestCase
['id' => 8, 'number' => 6, 'discussion_id' => 2, 'created_at' => Carbon::now(), 'user_id' => 4, 'type' => 'comment', 'content' => '<r><POSTMENTION displayname="i_am_a_deleted_user" id="2020" number="8" discussionid="2" username="i_am_a_deleted_user">@"i_am_a_deleted_user"#p2020</POSTMENTION></r>'],
['id' => 9, 'number' => 10, 'discussion_id' => 2, 'created_at' => Carbon::now(), 'user_id' => 5, 'type' => 'comment', 'content' => '<r><p>I am bad</p></r>'],
['id' => 10, 'number' => 11, 'discussion_id' => 2, 'created_at' => Carbon::now(), 'user_id' => 4, 'type' => 'comment', 'content' => '<r><POSTMENTION displayname="Bad &quot;#p6 User" id="9" number="10" discussionid="2">@"Bad "#p6 User"#p9</POSTMENTION></r>'],
['id' => 11, 'number' => 12, 'discussion_id' => 2, 'created_at' => Carbon::now(), 'user_id' => 40, 'type' => 'comment', 'content' => '<r><POSTMENTION displayname="Bad &quot;#p6 User" id="9" number="10" discussionid="2">@"Bad "#p6 User"#p9</POSTMENTION></r>'],
['id' => 11, 'number' => 12, 'discussion_id' => 2, 'created_at' => Carbon::now(), 'user_id' => null, 'type' => 'comment', 'content' => '<r><POSTMENTION displayname="Bad &quot;#p6 User" id="9" number="10" discussionid="2">@"Bad "#p6 User"#p9</POSTMENTION></r>'],
['id' => 12, 'number' => 13, 'discussion_id' => 2, 'created_at' => Carbon::now(), 'user_id' => 4, 'type' => 'comment', 'content' => '<r><POSTMENTION displayname="deleted_user" id="11" number="12" discussionid="2">@"acme"#p11</POSTMENTION></r>'],
// Restricted access
@@ -95,9 +95,11 @@ class PostMentionsTest extends TestCase
])
);
$this->assertEquals(201, $response->getStatusCode());
$body = $response->getBody()->getContents();
$response = json_decode($response->getBody(), true);
$this->assertEquals(201, $response->getStatusCode(), $body);
$response = json_decode($body, true);
$this->assertStringNotContainsString('POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@potato#4', $response['data']['attributes']['content']);
@@ -191,9 +193,11 @@ class PostMentionsTest extends TestCase
])
);
$this->assertEquals(201, $response->getStatusCode());
$body = $response->getBody()->getContents();
$response = json_decode($response->getBody(), true);
$this->assertEquals(201, $response->getStatusCode(), $body);
$response = json_decode($body, true);
$this->assertStringContainsString('POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"POTATO$"#p4', $response['data']['attributes']['content']);
@@ -514,9 +518,11 @@ class PostMentionsTest extends TestCase
])
);
$this->assertEquals(200, $response->getStatusCode());
$body = $response->getBody()->getContents();
$response = json_decode($response->getBody(), true);
$this->assertEquals(200, $response->getStatusCode(), $body);
$response = json_decode($body, true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"Bad _ User"#p9', $response['data']['attributes']['content']);

View File

@@ -38,6 +38,7 @@ class UserMentionsTest extends TestCase
['id' => 3, 'username' => 'potato', 'email' => 'potato@machine.local', 'is_email_confirmed' => 1],
['id' => 4, 'username' => 'toby', 'email' => 'toby@machine.local', 'is_email_confirmed' => 1],
['id' => 5, 'username' => 'bad_user', 'email' => 'bad_user@machine.local', 'is_email_confirmed' => 1],
['id' => 50]
],
Discussion::class => [
['id' => 2, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 3, 'first_post_id' => 4, 'comment_count' => 2],
@@ -500,9 +501,11 @@ class UserMentionsTest extends TestCase
])
);
$this->assertEquals(200, $response->getStatusCode());
$body = $response->getBody()->getContents();
$response = json_decode($response->getBody(), true);
$this->assertEquals(200, $response->getStatusCode(), $body);
$response = json_decode($body, true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"Bad _ User"#5', $response['data']['attributes']['content']);

View File

@@ -11,6 +11,7 @@ namespace Flarum\Statistics\Api\Controller;
use Carbon\Carbon;
use DateTime;
use Exception;
use Flarum\Discussion\Discussion;
use Flarum\Http\Exception\InvalidParameterException;
use Flarum\Http\RequestUtil;
@@ -130,11 +131,19 @@ class ShowStatisticsData implements RequestHandlerInterface
$endDate = new DateTime();
}
$formats = match ($query->getConnection()->getDriverName()) {
'pgsql' => ['YYYY-MM-DD HH24:00:00', 'YYYY-MM-DD'],
default => ['%Y-%m-%d %H:00:00', '%Y-%m-%d'],
};
// if within the last 24 hours, group by hour
$format = 'CASE WHEN '.$column.' > ? THEN \'%Y-%m-%d %H:00:00\' ELSE \'%Y-%m-%d\' END';
$format = "CASE WHEN $column > ? THEN '$formats[0]' ELSE '$formats[1]' END";
$dbFormattedDatetime = match ($query->getConnection()->getDriverName()) {
'sqlite' => 'strftime('.$format.', '.$column.')',
default => 'DATE_FORMAT('.$column.', '.$format.')',
'sqlite' => "strftime($format, $column)",
'pgsql' => "TO_CHAR($column, $format)",
'mysql' => "DATE_FORMAT($column, $format)",
default => throw new Exception('Unsupported database driver'),
};
$results = $query

View File

@@ -9,6 +9,7 @@
namespace Flarum\Sticky;
use DateTime;
use Flarum\Search\Database\DatabaseSearchState;
use Flarum\Search\SearchCriteria;
use Flarum\Tags\Search\Filter\TagFilter;
@@ -19,7 +20,7 @@ class PinStickiedDiscussionsToTop
public function __invoke(DatabaseSearchState $state, SearchCriteria $criteria): void
{
if ($criteria->sortIsDefault && ! $state->isFulltextSearch()) {
$query = $state->getQuery();
$query = $state->getQuery()->getQuery();
// If we are viewing a specific tag, then pin all stickied
// discussions to the top no matter what.
@@ -46,6 +47,8 @@ class PinStickiedDiscussionsToTop
$sticky->where('is_sticky', true);
unset($sticky->orders);
$epochTime = (new DateTime('@0'))->format('Y-m-d H:i:s');
/** @var Builder $q */
foreach ([$sticky, $query] as $q) {
$read = $q->newQuery()
@@ -58,7 +61,7 @@ class PinStickiedDiscussionsToTop
// Add the bindings manually (rather than as the second
// argument in orderByRaw) for now due to a bug in Laravel which
// would add the bindings in the wrong order.
$q->selectRaw('(is_sticky and not exists ('.$read->toSql().') and last_posted_at > ?) as is_unread_sticky', array_merge($read->getBindings(), [$state->getActor()->marked_all_as_read_at ?: 0]));
$q->selectRaw('(is_sticky and not exists ('.$read->toSql().') and last_posted_at > ?) as is_unread_sticky', array_merge($read->getBindings(), [$state->getActor()->marked_all_as_read_at ?: $epochTime]));
}
$query->union($sticky);

View File

@@ -12,7 +12,7 @@ namespace Flarum\Sticky\Query;
use Flarum\Search\Database\DatabaseSearchState;
use Flarum\Search\Filter\FilterInterface;
use Flarum\Search\SearchState;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent\Builder;
/**
* @implements FilterInterface<DatabaseSearchState>

View File

@@ -62,11 +62,13 @@ class ListDiscussionsTest extends TestCase
$this->request('GET', '/api/discussions')
);
$this->assertEquals(200, $response->getStatusCode(), $body = $response->getBody()->getContents());
$body = $response->getBody()->getContents();
$this->assertEquals(200, $response->getStatusCode(), $body);
$data = json_decode($body, true);
$this->assertEqualsCanonicalizing([3, 1, 2, 4], Arr::pluck($data['data'], 'id'));
$this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id'));
}
/** @test */
@@ -114,10 +116,12 @@ class ListDiscussionsTest extends TestCase
])
);
$this->assertEquals(200, $response->getStatusCode(), $body = $response->getBody()->getContents());
$body = $response->getBody()->getContents();
$this->assertEquals(200, $response->getStatusCode(), $body);
$data = json_decode($body, true);
$this->assertEqualsCanonicalizing([3, 1, 2, 4], Arr::pluck($data['data'], 'id'));
$this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id'));
}
}

View File

@@ -10,8 +10,12 @@
namespace Flarum\Sticky\Tests\integration\api;
use Carbon\Carbon;
use Flarum\Discussion\Discussion;
use Flarum\Group\Group;
use Flarum\Post\Post;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
class StickyDiscussionsTest extends TestCase
{
@@ -24,18 +28,24 @@ class StickyDiscussionsTest extends TestCase
$this->extension('flarum-sticky');
$this->prepareDatabase([
'users' => [
User::class => [
['id' => 1, 'username' => 'Muralf', 'email' => 'muralf@machine.local', 'is_email_confirmed' => 1],
$this->normalUser(),
['id' => 3, 'username' => 'Muralf_', 'email' => 'muralf_@machine.local', 'is_email_confirmed' => 1],
],
'discussions' => [
Discussion::class => [
['id' => 1, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'is_sticky' => true, 'last_post_number' => 1],
['id' => 2, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinutes(2), 'last_posted_at' => Carbon::now()->addMinutes(5), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'is_sticky' => false, 'last_post_number' => 1],
['id' => 3, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinutes(3), 'last_posted_at' => Carbon::now()->addMinute(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'is_sticky' => true, 'last_post_number' => 1],
['id' => 4, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinutes(4), 'last_posted_at' => Carbon::now()->addMinutes(2), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'is_sticky' => false, 'last_post_number' => 1],
['id' => 2, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinutes(2), 'last_posted_at' => Carbon::now()->addMinutes(5), 'user_id' => 1, 'first_post_id' => 2, 'comment_count' => 1, 'is_sticky' => false, 'last_post_number' => 1],
['id' => 3, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinutes(3), 'last_posted_at' => Carbon::now()->addMinute(), 'user_id' => 1, 'first_post_id' => 3, 'comment_count' => 1, 'is_sticky' => true, 'last_post_number' => 1],
['id' => 4, 'title' => __CLASS__, 'created_at' => Carbon::now()->addMinutes(4), 'last_posted_at' => Carbon::now()->addMinutes(2), 'user_id' => 1, 'first_post_id' => 4, 'comment_count' => 1, 'is_sticky' => false, 'last_post_number' => 1],
],
'groups' => [
Post::class => [
['id' => 1, 'discussion_id' => 1, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'number' => 1],
['id' => 2, 'discussion_id' => 2, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'number' => 1],
['id' => 3, 'discussion_id' => 3, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'number' => 1],
['id' => 4, 'discussion_id' => 4, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>Text</p></t>', 'number' => 1],
],
Group::class => [
['id' => 5, 'name_singular' => 'Group', 'name_plural' => 'Groups', 'color' => 'blue'],
],
'group_user' => [

View File

@@ -14,7 +14,7 @@ use Flarum\Search\Filter\FilterInterface;
use Flarum\Search\SearchState;
use Flarum\Search\ValidateFilterTrait;
use Flarum\User\User;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent\Builder;
/**
* @implements FilterInterface<DatabaseSearchState>

View File

@@ -41,15 +41,15 @@ class ReplyNotificationTest extends TestCase
['id' => 33, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 33, 'comment_count' => 6, 'last_post_number' => 6, 'last_post_id' => 38],
],
Post::class => [
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 1],
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 1],
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::createFromDate(1975, 5, 21)->addMinutes(1)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 1],
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::createFromDate(1975, 5, 21)->addMinutes(2)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 1],
['id' => 33, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 1],
['id' => 34, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 2],
['id' => 35, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 3],
['id' => 36, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 4],
['id' => 37, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 5],
['id' => 38, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 6],
['id' => 33, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->addMinutes(3)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 1],
['id' => 34, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->addMinutes(4)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 2],
['id' => 35, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->addMinutes(5)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 3],
['id' => 36, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->addMinutes(6)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 4],
['id' => 37, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->addMinutes(7)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 5],
['id' => 38, 'discussion_id' => 33, 'created_at' => Carbon::createFromDate(1975, 5, 21)->addMinutes(8)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 6],
],
'discussion_user' => [
['discussion_id' => 1, 'user_id' => 1, 'last_read_post_number' => 1, 'subscription' => 'follow'],

View File

@@ -10,8 +10,11 @@
namespace Flarum\Subscriptions\Tests\integration\api\discussions;
use Carbon\Carbon;
use Flarum\Discussion\Discussion;
use Flarum\Post\Post;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
class SubscribeTest extends TestCase
{
@@ -24,18 +27,18 @@ class SubscribeTest extends TestCase
$this->extension('flarum-subscriptions');
$this->prepareDatabase([
'users' => [
User::class => [
$this->normalUser(),
['id' => 3, 'username' => 'acme', 'email' => 'acme@machine.local', 'is_email_confirmed' => 1, 'preferences' => json_encode(['flarum-subscriptions.notify_for_all_posts' => true])],
['id' => 4, 'username' => 'acme2', 'email' => 'acme2@machine.local', 'is_email_confirmed' => 1],
],
'discussions' => [
Discussion::class => [
['id' => 1, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'last_post_number' => 1, 'last_post_id' => 1],
['id' => 2, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 2, 'comment_count' => 1, 'last_post_number' => 1, 'last_post_id' => 2],
['id' => 33, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 33, 'comment_count' => 6, 'last_post_number' => 6, 'last_post_id' => 38],
],
'posts' => [
Post::class => [
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 1],
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>foo bar</p></t>', 'number' => 1],

View File

@@ -15,7 +15,7 @@ use Flarum\Search\Filter\FilterInterface;
use Flarum\Search\SearchState;
use Flarum\User\Guest;
use Flarum\User\UserRepository;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent\Builder;
/**
* @implements FilterInterface<DatabaseSearchState>

View File

@@ -16,8 +16,9 @@ use Flarum\Search\SearchState;
use Flarum\Search\ValidateFilterTrait;
use Flarum\Tags\Tag;
use Flarum\User\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;
/**
* @implements FilterInterface<DatabaseSearchState>
@@ -53,7 +54,7 @@ class TagFilter implements FilterInterface
$query->where(function (Builder $query) use ($slugs, $negate, $actor) {
foreach ($slugs as $slug) {
if ($slug === 'untagged') {
$query->whereIn('discussions.id', function (Builder $query) {
$query->whereIn('discussions.id', function (QueryBuilder $query) {
$query->select('discussion_id')
->from('discussion_tag');
}, 'or', ! $negate);
@@ -65,7 +66,7 @@ class TagFilter implements FilterInterface
$id = null;
}
$query->whereIn('discussions.id', function (Builder $query) use ($id) {
$query->whereIn('discussions.id', function (QueryBuilder $query) use ($id) {
$query->select('discussion_id')
->from('discussion_tag')
->where('tag_id', $id);

View File

@@ -31,6 +31,8 @@ class TagState extends AbstractModel
protected $casts = ['marked_as_read_at' => 'datetime'];
public $incrementing = false;
public function tag(): BelongsTo
{
return $this->belongsTo(Tag::class);