1
0
mirror of https://github.com/flarum/core.git synced 2025-08-28 10:30:54 +02:00

Compare commits

...

22 Commits

Author SHA1 Message Date
StyleCI Bot
e49dd8c8b7 Apply fixes from StyleCI 2023-08-14 12:18:42 +00:00
Sami Mazouz
0db8007002 test: adapt 2023-08-14 13:16:14 +01:00
Sami Mazouz
835eba9178 chore: some fixes 2023-08-14 13:11:26 +01:00
Sami Mazouz
2a0f8ff7ed chore: use ExceptionHandler contract 2023-08-13 17:43:14 +01:00
Sami Mazouz
e1ab77f66a chore: some fixes 2023-08-13 15:50:09 +01:00
Sami Mazouz
6a812910dc fix: broken test suite 2023-08-13 15:50:04 +01:00
Sami Mazouz
f126c688d3 chore: some fixes 2023-08-13 13:43:17 +01:00
Sami Mazouz
6fb1640b3c chore: some fixes 2023-08-13 13:43:08 +01:00
Sami Mazouz
834bd732da chore: bind request to container then boot app 2023-08-13 13:41:33 +01:00
Sami Mazouz
9c3460a619 chore: adapt UrlGenerator 2023-08-11 15:48:04 +01:00
Sami Mazouz
3b3efc7cbb chore: adapt test infra 2023-08-11 15:04:30 +01:00
Sami Mazouz
cca5725fe4 chore: adapt extenders 2023-08-11 14:20:26 +01:00
Sami Mazouz
0ce33c3ec0 chore: adapt whoops formatter 2023-08-11 14:20:18 +01:00
Sami Mazouz
495b24a5aa chore: convert other middleware 2023-08-11 14:19:59 +01:00
Sami Mazouz
7d4549ea34 chore: replace request handling with illuminate http & router 2023-08-11 14:19:44 +01:00
Sami Mazouz
a60e3d174f chore: replace SeverRequestInterface with laravel Request in controllers 2023-08-11 14:17:54 +01:00
Sami Mazouz
0a89c3bd53 chore: recover container prop 2023-08-11 10:17:36 +01:00
StyleCI Bot
d056e339a4 Apply fixes from StyleCI 2023-08-11 08:34:47 +00:00
Sami Mazouz
3e49aeb32c chore: unimplement terminat(e/ing) 2023-08-11 09:34:21 +01:00
Sami Mazouz
47a0298958 chore: service provider no longer has to change app type 2023-08-11 09:28:56 +01:00
Sami Mazouz
f0eebc53ec chore: improve concern implementation readability 2023-08-11 09:28:33 +01:00
Sami Mazouz
5120e357bb chore: merge the app with the container & implement the ApplicationContract
Illuminate components always expect the app to be the container, but also expect the app to be implementing the laravel app contract. This means that very often between minor illuminate updates we get a call to a method on the app that doesn't exist in the Flarum app. This fixes the issue once and for all.
2023-08-03 14:28:18 +01:00
314 changed files with 3651 additions and 3372 deletions

View File

@@ -109,7 +109,6 @@
"ext-json": "*", "ext-json": "*",
"components/font-awesome": "^5.15.0", "components/font-awesome": "^5.15.0",
"composer/composer": "^2.0", "composer/composer": "^2.0",
"dflydev/fig-cookies": "^3.0",
"doctrine/dbal": "^3.6.2", "doctrine/dbal": "^3.6.2",
"dragonmantank/cron-expression": "^3.3", "dragonmantank/cron-expression": "^3.3",
"franzl/whoops-middleware": "2.0", "franzl/whoops-middleware": "2.0",
@@ -124,8 +123,10 @@
"illuminate/events": "^10.0", "illuminate/events": "^10.0",
"illuminate/filesystem": "^10.0", "illuminate/filesystem": "^10.0",
"illuminate/hashing": "^10.0", "illuminate/hashing": "^10.0",
"illuminate/http": "^10.0",
"illuminate/mail": "^10.0", "illuminate/mail": "^10.0",
"illuminate/queue": "^10.0", "illuminate/queue": "^10.0",
"illuminate/routing": "^10.0",
"illuminate/session": "^10.0", "illuminate/session": "^10.0",
"illuminate/support": "^10.0", "illuminate/support": "^10.0",
"illuminate/validation": "^10.0", "illuminate/validation": "^10.0",
@@ -143,7 +144,6 @@
"middlewares/request-handler": "^2.0.2", "middlewares/request-handler": "^2.0.2",
"monolog/monolog": "^3.3", "monolog/monolog": "^3.3",
"nesbot/carbon": "^2.66", "nesbot/carbon": "^2.66",
"nikic/fast-route": "^1.3",
"psr/http-message": "^1.1", "psr/http-message": "^1.1",
"psr/http-server-handler": "^1.0.2", "psr/http-server-handler": "^1.0.2",
"psr/http-server-middleware": "^1.0.2", "psr/http-server-middleware": "^1.0.2",
@@ -160,6 +160,7 @@
"symfony/mime": "^6.3", "symfony/mime": "^6.3",
"symfony/polyfill-intl-messageformatter": "^1.27", "symfony/polyfill-intl-messageformatter": "^1.27",
"symfony/postmark-mailer": "^6.3", "symfony/postmark-mailer": "^6.3",
"symfony/psr-http-message-bridge": "^2.3",
"symfony/translation": "^6.3", "symfony/translation": "^6.3",
"symfony/yaml": "^6.3", "symfony/yaml": "^6.3",
"wikimedia/less.php": "^4.1" "wikimedia/less.php": "^4.1"

View File

@@ -36,7 +36,7 @@ class AkismetProvider extends AbstractServiceProvider
return new Akismet( return new Akismet(
$settings->get('flarum-akismet.api_key'), $settings->get('flarum-akismet.api_key'),
$url->to('forum')->base(), $url->base('forum'),
$app::VERSION, $app::VERSION,
$extensions->getExtension('flarum-akismet')->getVersion() ?? 'unknown', $extensions->getExtension('flarum-akismet')->getVersion() ?? 'unknown',
$config->inDebugMode() $config->inDebugMode()

View File

@@ -38,7 +38,7 @@ class ListDiscussionsTest extends TestCase
$this->request('GET', '/api/discussions', compact('authenticatedAs')) $this->request('GET', '/api/discussions', compact('authenticatedAs'))
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEqualsCanonicalizing([1, 4, 5, 7], Arr::pluck($body['data'], 'id')); $this->assertEqualsCanonicalizing([1, 4, 5, 7], Arr::pluck($body['data'], 'id'));
@@ -54,7 +54,7 @@ class ListDiscussionsTest extends TestCase
$this->request('GET', '/api/discussions', compact('authenticatedAs')) $this->request('GET', '/api/discussions', compact('authenticatedAs'))
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEqualsCanonicalizing([1, 2, 3, 4, 5, 6, 7], Arr::pluck($body['data'], 'id')); $this->assertEqualsCanonicalizing([1, 2, 3, 4, 5, 6, 7], Arr::pluck($body['data'], 'id'));

View File

@@ -12,6 +12,7 @@ namespace Flarum\Approval\Tests\integration\api;
use Flarum\Approval\Tests\integration\InteractsWithUnapprovedContent; use Flarum\Approval\Tests\integration\InteractsWithUnapprovedContent;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ListPostsTest extends TestCase class ListPostsTest extends TestCase
@@ -35,16 +36,17 @@ class ListPostsTest extends TestCase
public function can_only_see_approved_if_not_allowed_to_approve(?int $authenticatedAs) public function can_only_see_approved_if_not_allowed_to_approve(?int $authenticatedAs)
{ {
$response = $this->send( $response = $this->send(
$this tap(
->request('GET', '/api/posts', compact('authenticatedAs')) $this->request('GET', '/api/posts', compact('authenticatedAs')),
->withQueryParams([ fn (Request $request) => $request->query->add([
'filter' => [ 'filter' => [
'discussion' => 7 'discussion' => 7
] ]
]) ])
)
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEqualsCanonicalizing([7, 8, 10], Arr::pluck($body['data'], 'id')); $this->assertEqualsCanonicalizing([7, 8, 10], Arr::pluck($body['data'], 'id'));
@@ -57,16 +59,17 @@ class ListPostsTest extends TestCase
public function can_see_unapproved_if_allowed_to_approve(int $authenticatedAs) public function can_see_unapproved_if_allowed_to_approve(int $authenticatedAs)
{ {
$response = $this->send( $response = $this->send(
$this tap(
->request('GET', '/api/posts', compact('authenticatedAs')) $this->request('GET', '/api/posts', compact('authenticatedAs')),
->withQueryParams([ fn (Request $request) => $request->query->add([
'filter' => [ 'filter' => [
'discussion' => 7 'discussion' => 7
] ]
]) ])
)
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEqualsCanonicalizing([7, 8, 9, 10, 11], Arr::pluck($body['data'], 'id')); $this->assertEqualsCanonicalizing([7, 8, 9, 10, 11], Arr::pluck($body['data'], 'id'));

View File

@@ -9,7 +9,7 @@
use Flarum\Extend; use Flarum\Extend;
use Flarum\Frontend\Document; use Flarum\Frontend\Document;
use Psr\Http\Message\ServerRequestInterface as Request; use Illuminate\Http\Request;
return [ return [
(new Extend\Frontend('forum')) (new Extend\Frontend('forum'))

View File

@@ -15,8 +15,7 @@ use Flarum\Flags\Command\CreateFlag;
use Flarum\Flags\Flag; use Flarum\Flags\Flag;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class CreateFlagController extends AbstractCreateController class CreateFlagController extends AbstractCreateController
@@ -34,10 +33,10 @@ class CreateFlagController extends AbstractCreateController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): Flag protected function data(Request $request, Document $document): Flag
{ {
return $this->bus->dispatch( return $this->bus->dispatch(
new CreateFlag(RequestUtil::getActor($request), Arr::get($request->getParsedBody(), 'data', [])) new CreateFlag(RequestUtil::getActor($request), $request->json('data', []))
); );
} }
} }

View File

@@ -13,8 +13,7 @@ use Flarum\Api\Controller\AbstractDeleteController;
use Flarum\Flags\Command\DeleteFlags; use Flarum\Flags\Command\DeleteFlags;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
class DeleteFlagsController extends AbstractDeleteController class DeleteFlagsController extends AbstractDeleteController
{ {
@@ -23,10 +22,10 @@ class DeleteFlagsController extends AbstractDeleteController
) { ) {
} }
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
$this->bus->dispatch( $this->bus->dispatch(
new DeleteFlags(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request), $request->getParsedBody()) new DeleteFlags($request->route('id'), RequestUtil::getActor($request), $request->json()->all())
); );
} }
} }

View File

@@ -14,7 +14,7 @@ use Flarum\Api\Controller\AbstractListController;
use Flarum\Flags\Api\Serializer\FlagSerializer; use Flarum\Flags\Api\Serializer\FlagSerializer;
use Flarum\Flags\Flag; use Flarum\Flags\Flag;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class ListFlagsController extends AbstractListController class ListFlagsController extends AbstractListController
@@ -28,7 +28,7 @@ class ListFlagsController extends AbstractListController
'post.discussion' 'post.discussion'
]; ];
protected function data(ServerRequestInterface $request, Document $document): iterable protected function data(Request $request, Document $document): iterable
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$include = $this->extractInclude($request); $include = $this->extractInclude($request);

View File

@@ -13,11 +13,11 @@ use Flarum\Api\Controller;
use Flarum\Flags\Api\Controller\CreateFlagController; use Flarum\Flags\Api\Controller\CreateFlagController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
class PrepareFlagsApiData class PrepareFlagsApiData
{ {
public function __invoke(Controller\AbstractSerializeController $controller, mixed $data, ServerRequestInterface $request): void public function __invoke(Controller\AbstractSerializeController $controller, mixed $data, Request $request): void
{ {
// For any API action that allows the 'flags' relationship to be // For any API action that allows the 'flags' relationship to be
// included, we need to preload this relationship onto the data (Post // included, we need to preload this relationship onto the data (Post

View File

@@ -75,7 +75,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '4', '5'], $ids); $this->assertEqualsCanonicalizing(['1', '4', '5'], $ids);
@@ -94,7 +94,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['2', '4'], $ids); $this->assertEqualsCanonicalizing(['2', '4'], $ids);
@@ -113,7 +113,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '4', '5'], $ids); $this->assertEqualsCanonicalizing(['1', '4', '5'], $ids);

View File

@@ -108,7 +108,7 @@ class ListWithTagsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '4', '5', '6', '7', '8', '9'], $ids); $this->assertEqualsCanonicalizing(['1', '4', '5', '6', '7', '8', '9'], $ids);
@@ -127,7 +127,7 @@ class ListWithTagsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['2', '4'], $ids); $this->assertEqualsCanonicalizing(['2', '4'], $ids);
@@ -146,7 +146,7 @@ class ListWithTagsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
// 7 is included, even though mods can't view discussions. // 7 is included, even though mods can't view discussions.

View File

@@ -16,13 +16,13 @@ use Flarum\Post\Post;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Query\Expression; use Illuminate\Database\Query\Expression;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
class LoadLikesRelationship class LoadLikesRelationship
{ {
public static int $maxLikes = 4; public static int $maxLikes = 4;
public static function mutateRelation(BelongsToMany $query, ServerRequestInterface $request): void public static function mutateRelation(BelongsToMany $query, Request $request): void
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);

View File

@@ -143,7 +143,7 @@ class LikePostTest extends TestCase
$this->request('GET', '/') $this->request('GET', '/')
); );
$token = $initial->getHeaderLine('X-CSRF-Token'); $token = $initial->headers->get('X-CSRF-Token');
} }
$request = $this->request('PATCH', "/api/posts/$postId", [ $request = $this->request('PATCH', "/api/posts/$postId", [
@@ -159,7 +159,7 @@ class LikePostTest extends TestCase
]); ]);
if (! isset($authenticatedAs)) { if (! isset($authenticatedAs)) {
$request = $request->withHeader('X-CSRF-Token', $token); $request->headers->set('X-CSRF-Token', $token);
} }
return $this->send($request); return $this->send($request);

View File

@@ -14,6 +14,7 @@ use Flarum\Group\Group;
use Flarum\Likes\Api\LoadLikesRelationship; use Flarum\Likes\Api\LoadLikesRelationship;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ListPostsTest extends TestCase class ListPostsTest extends TestCase
@@ -75,15 +76,17 @@ class ListPostsTest extends TestCase
public function liked_filter_works() public function liked_filter_works()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/users') tap(
->withQueryParams([ $this->request('GET', '/api/users'),
fn (Request $request) => $request->query->add([
'filter' => ['liked' => 101], 'filter' => ['liked' => 101],
]) ])
)
); );
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
// Order-independent comparison // Order-independent comparison
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
@@ -98,15 +101,17 @@ class ListPostsTest extends TestCase
public function liked_filter_works_negated() public function liked_filter_works_negated()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/users') tap(
->withQueryParams([ $this->request('GET', '/api/users'),
'filter' => ['-liked' => 101], fn (Request $request) => $request->query->add([
]) 'filter' => ['-liked' => 101],
])
)
); );
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
// Order-independent comparison // Order-independent comparison
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
@@ -118,14 +123,17 @@ class ListPostsTest extends TestCase
{ {
// List posts endpoint // List posts endpoint
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/posts/101', [ tap(
'authenticatedAs' => 2, $this->request('GET', '/api/posts/101', [
])->withQueryParams([ 'authenticatedAs' => 2,
'include' => 'likes', ]),
]) fn (Request $request) => $request->query->add([
'include' => 'likes',
])
)
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
@@ -144,15 +152,18 @@ class ListPostsTest extends TestCase
{ {
// List posts endpoint // List posts endpoint
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/posts', [ tap(
'authenticatedAs' => 2, $this->request('GET', '/api/posts', [
])->withQueryParams([ 'authenticatedAs' => 2,
'filter' => ['discussion' => 100], ]),
'include' => 'likes', fn (Request $request) => $request->query->add([
]) 'filter' => ['discussion' => 100],
'include' => 'likes',
])
)
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
@@ -174,14 +185,17 @@ class ListPostsTest extends TestCase
{ {
// Show discussion endpoint // Show discussion endpoint
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/discussions/100', [ tap(
'authenticatedAs' => 2, $this->request('GET', '/api/discussions/100', [
])->withQueryParams([ 'authenticatedAs' => 2,
'include' => $include, ]),
]) fn (Request $request) => $request->query->add([
'include' => $include,
])
)
); );
$included = json_decode($response->getBody()->getContents(), true)['included']; $included = json_decode($response->getContent(), true)['included'];
$likes = collect($included) $likes = collect($included)
->where('type', 'posts') ->where('type', 'posts')

View File

@@ -15,7 +15,7 @@ use Flarum\Http\RequestUtil;
use Flarum\Post\Post; use Flarum\Post\Post;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
/** /**
* Apply visibility permissions to API data's mentionedBy relationship. * Apply visibility permissions to API data's mentionedBy relationship.
@@ -25,7 +25,7 @@ class LoadMentionedByRelationship
{ {
public static int $maxMentionedBy = 4; public static int $maxMentionedBy = 4;
public static function mutateRelation(BelongsToMany $query, ServerRequestInterface $request): void public static function mutateRelation(BelongsToMany $query, Request $request): void
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
@@ -42,7 +42,7 @@ class LoadMentionedByRelationship
/** /**
* Called using the @see ApiController::prepareDataForSerialization extender. * Called using the @see ApiController::prepareDataForSerialization extender.
*/ */
public static function countRelation(AbstractSerializeController $controller, mixed $data, ServerRequestInterface $request): array public static function countRelation(AbstractSerializeController $controller, mixed $data, Request $request): array
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$loadable = null; $loadable = null;

View File

@@ -50,7 +50,7 @@ class ConfigureMentions
private function configureUserMentions(Configurator $config): void private function configureUserMentions(Configurator $config): void
{ {
$config->rendering->parameters['PROFILE_URL'] = $this->url->to('forum')->route('user', ['username' => '']); $config->rendering->parameters['PROFILE_URL'] = $this->url->route('forum.user', ['username' => '']);
$tagName = 'USERMENTION'; $tagName = 'USERMENTION';
@@ -108,7 +108,7 @@ class ConfigureMentions
private function configurePostMentions(Configurator $config): void private function configurePostMentions(Configurator $config): void
{ {
$config->rendering->parameters['DISCUSSION_URL'] = $this->url->to('forum')->route('discussion', ['id' => '']); $config->rendering->parameters['DISCUSSION_URL'] = $this->url->route('forum.discussion', ['id' => '']);
$tagName = 'POSTMENTION'; $tagName = 'POSTMENTION';
@@ -246,7 +246,7 @@ class ConfigureMentions
private function configureTagMentions(Configurator $config): void private function configureTagMentions(Configurator $config): void
{ {
$config->rendering->parameters['TAG_URL'] = $this->url->to('forum')->route('tag', ['slug' => '']); $config->rendering->parameters['TAG_URL'] = $this->url->route('forum.tag', ['slug' => '']);
$tagName = 'TAGMENTION'; $tagName = 'TAGMENTION';

View File

@@ -12,7 +12,7 @@ namespace Flarum\Mentions\Formatter;
use Flarum\Discussion\Discussion; use Flarum\Discussion\Discussion;
use Flarum\Http\SlugManager; use Flarum\Http\SlugManager;
use Flarum\Locale\TranslatorInterface; use Flarum\Locale\TranslatorInterface;
use Psr\Http\Message\ServerRequestInterface as Request; use Illuminate\Http\Request;
use s9e\TextFormatter\Renderer; use s9e\TextFormatter\Renderer;
use s9e\TextFormatter\Utils; use s9e\TextFormatter\Utils;

View File

@@ -11,7 +11,7 @@ namespace Flarum\Mentions\Formatter;
use Flarum\Post\Post; use Flarum\Post\Post;
use Flarum\Tags\Tag; use Flarum\Tags\Tag;
use Psr\Http\Message\ServerRequestInterface as Request; use Illuminate\Http\Request;
use s9e\TextFormatter\Renderer; use s9e\TextFormatter\Renderer;
use s9e\TextFormatter\Utils; use s9e\TextFormatter\Utils;

View File

@@ -70,7 +70,7 @@ class GroupMentionsTest extends TestCase
$this->request('GET', '/api/posts/4') $this->request('GET', '/api/posts/4')
); );
$contents = $response->getBody()->getContents(); $contents = $response->getContent();
$this->assertEquals(200, $response->getStatusCode(), $contents); $this->assertEquals(200, $response->getStatusCode(), $contents);
@@ -104,7 +104,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@"InvalidGroup"#g99', $response['data']['attributes']['content']); $this->assertStringContainsString('@"InvalidGroup"#g99', $response['data']['attributes']['content']);
$this->assertStringNotContainsString('GroupMention', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('GroupMention', $response['data']['attributes']['contentHtml']);
@@ -126,7 +126,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString("@$deleted_text", $response['data']['attributes']['contentHtml']); $this->assertStringContainsString("@$deleted_text", $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('GroupMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('GroupMention', $response['data']['attributes']['contentHtml']);
@@ -148,7 +148,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@Fresh Name', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@Fresh Name', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('GroupMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('GroupMention', $response['data']['attributes']['contentHtml']);
@@ -179,7 +179,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@Mods', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@Mods', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('fas fa-bolt', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('fas fa-bolt', $response['data']['attributes']['contentHtml']);
@@ -211,7 +211,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@Admins', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@Admins', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@Mods', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@Mods', $response['data']['attributes']['contentHtml']);
@@ -245,7 +245,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringNotContainsString('@Members', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('@Members', $response['data']['attributes']['contentHtml']);
$this->assertStringNotContainsString('@Guests', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('@Guests', $response['data']['attributes']['contentHtml']);
@@ -301,7 +301,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringNotContainsString('@Mods', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('@Mods', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"Mods"#g4', $response['data']['attributes']['content']); $this->assertStringContainsString('@"Mods"#g4', $response['data']['attributes']['content']);
@@ -332,7 +332,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@Mods', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@Mods', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"Mods"#g4', $response['data']['attributes']['content']); $this->assertStringContainsString('@"Mods"#g4', $response['data']['attributes']['content']);
@@ -363,7 +363,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringNotContainsString('@Ninjas', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('@Ninjas', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"Ninjas"#g10', $response['data']['attributes']['content']); $this->assertStringContainsString('@"Ninjas"#g10', $response['data']['attributes']['content']);
@@ -391,7 +391,7 @@ class GroupMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@Mods', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@Mods', $response['data']['attributes']['contentHtml']);
$this->assertEquals('New content with @"Mods"#g4 mention', $response['data']['attributes']['content']); $this->assertEquals('New content with @"Mods"#g4 mention', $response['data']['attributes']['content']);

View File

@@ -13,6 +13,7 @@ use Carbon\Carbon;
use Flarum\Mentions\Api\LoadMentionedByRelationship; use Flarum\Mentions\Api\LoadMentionedByRelationship;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ListPostsTest extends TestCase class ListPostsTest extends TestCase
@@ -55,13 +56,15 @@ class ListPostsTest extends TestCase
public function mentioned_filter_works() public function mentioned_filter_works()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/posts') tap(
->withQueryParams([ $this->request('GET', '/api/posts'),
fn (Request $request) => $request->query->add([
'filter' => ['mentioned' => 1], 'filter' => ['mentioned' => 1],
]) ])
)
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
// Order-independent comparison // Order-independent comparison
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
@@ -74,13 +77,15 @@ class ListPostsTest extends TestCase
public function mentioned_filter_works_negated() public function mentioned_filter_works_negated()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/posts') tap(
->withQueryParams([ $this->request('GET', '/api/posts'),
'filter' => ['-mentioned' => 1], fn (Request $request) => $request->query->add([
]) 'filter' => ['-mentioned' => 1],
])
)
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
// Order-independent comparison // Order-independent comparison
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
@@ -93,14 +98,16 @@ class ListPostsTest extends TestCase
public function mentioned_filter_works_with_sort() public function mentioned_filter_works_with_sort()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/posts') tap(
->withQueryParams([ $this->request('GET', '/api/posts'),
fn (Request $request) => $request->query->add([
'filter' => ['mentioned' => 1], 'filter' => ['mentioned' => 1],
'sort' => '-createdAt' 'sort' => '-createdAt'
]) ])
)
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
@@ -153,14 +160,17 @@ class ListPostsTest extends TestCase
// List posts endpoint // List posts endpoint
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/posts/101', [ tap(
'authenticatedAs' => 2, $this->request('GET', '/api/posts/101', [
])->withQueryParams([ 'authenticatedAs' => 2,
'include' => 'mentionedBy', ]),
]) fn (Request $request) => $request->query->add([
'include' => 'mentionedBy',
])
)
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
@@ -179,15 +189,18 @@ class ListPostsTest extends TestCase
// List posts endpoint // List posts endpoint
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/posts', [ tap(
'authenticatedAs' => 2, $this->request('GET', '/api/posts', [
])->withQueryParams([ 'authenticatedAs' => 2,
'filter' => ['discussion' => 100], ]),
'include' => 'mentionedBy', fn (Request $request) => $request->query->add([
]) 'filter' => ['discussion' => 100],
'include' => 'mentionedBy',
])
)
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
@@ -209,14 +222,17 @@ class ListPostsTest extends TestCase
// Show discussion endpoint // Show discussion endpoint
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/discussions/100', [ tap(
'authenticatedAs' => 2, $this->request('GET', '/api/discussions/100', [
])->withQueryParams([ 'authenticatedAs' => 2,
'include' => $include, ]),
]) fn (Request $request) => $request->query->add([
'include' => $include,
])
)
); );
$included = json_decode($response->getBody()->getContents(), true)['included']; $included = json_decode($response->getContent(), true)['included'];
$mentionedBy = collect($included) $mentionedBy = collect($included)
->where('type', 'posts') ->where('type', 'posts')
@@ -250,7 +266,7 @@ class ListPostsTest extends TestCase
]) ])
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());

View File

@@ -93,7 +93,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringNotContainsString('POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@potato#4', $response['data']['attributes']['content']); $this->assertEquals('@potato#4', $response['data']['attributes']['content']);
@@ -124,7 +124,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"POTATO$"#p4', $response['data']['attributes']['content']); $this->assertEquals('@"POTATO$"#p4', $response['data']['attributes']['content']);
@@ -155,7 +155,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('potato', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('potato', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"potato"#p50', $response['data']['attributes']['content']); $this->assertEquals('@"potato"#p50', $response['data']['attributes']['content']);
@@ -186,7 +186,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"POTATO$"#p4', $response['data']['attributes']['content']); $this->assertEquals('@"POTATO$"#p4', $response['data']['attributes']['content']);
@@ -217,7 +217,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringNotContainsString('FRANZOFFLARUM$', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('FRANZOFFLARUM$', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"franzofflarum"#p215', $response['data']['attributes']['content']); $this->assertEquals('@"franzofflarum"#p215', $response['data']['attributes']['content']);
@@ -248,7 +248,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('TOBY$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('TOBY$', $response['data']['attributes']['contentHtml']);
$this->assertStringNotContainsString('FRANZOFFLARUM$', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('FRANZOFFLARUM$', $response['data']['attributes']['contentHtml']);
@@ -271,7 +271,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('TOBY$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('TOBY$', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('PostMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('PostMention', $response['data']['attributes']['contentHtml']);
@@ -291,7 +291,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@"TOBY$"#p5', $response['data']['attributes']['content']); $this->assertStringContainsString('@"TOBY$"#p5', $response['data']['attributes']['content']);
$this->assertCount(1, CommentPost::find($response['data']['id'])->mentionsPosts); $this->assertCount(1, CommentPost::find($response['data']['id'])->mentionsPosts);
@@ -312,7 +312,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString($deleted_text, $response['data']['attributes']['contentHtml']); $this->assertStringContainsString($deleted_text, $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"'.$deleted_text.'"#p7', $response['data']['attributes']['content']); $this->assertStringContainsString('@"'.$deleted_text.'"#p7', $response['data']['attributes']['content']);
@@ -337,7 +337,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString($deleted_text, $response['data']['attributes']['contentHtml']); $this->assertStringContainsString($deleted_text, $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"'.$deleted_text.'"#p2010', $response['data']['attributes']['content']); $this->assertStringContainsString('@"'.$deleted_text.'"#p2010', $response['data']['attributes']['content']);
@@ -362,7 +362,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString($deleted_text, $response['data']['attributes']['contentHtml']); $this->assertStringContainsString($deleted_text, $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"'.$deleted_text.'"#p2020', $response['data']['attributes']['content']); $this->assertStringContainsString('@"'.$deleted_text.'"#p2020', $response['data']['attributes']['content']);
@@ -395,7 +395,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"POTATO$"#p6 User"#p9', $response['data']['attributes']['content']); $this->assertEquals('@"POTATO$"#p6 User"#p9', $response['data']['attributes']['content']);
@@ -416,7 +416,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"Bad _ User"#p9', $response['data']['attributes']['content']); $this->assertStringContainsString('@"Bad _ User"#p9', $response['data']['attributes']['content']);
@@ -447,7 +447,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"Bad _ User"#p9', $response['data']['attributes']['content']); $this->assertEquals('@"Bad _ User"#p9', $response['data']['attributes']['content']);
@@ -475,7 +475,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"Bad _ User"#p9', $response['data']['attributes']['content']); $this->assertEquals('@"Bad _ User"#p9', $response['data']['attributes']['content']);
@@ -503,7 +503,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"Bad _ User"#p9', $response['data']['attributes']['content']); $this->assertEquals('@"Bad _ User"#p9', $response['data']['attributes']['content']);
@@ -531,7 +531,7 @@ class PostMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('[deleted]', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('[deleted]', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"[deleted]"#p11', $response['data']['attributes']['content']); $this->assertEquals('@"[deleted]"#p11', $response['data']['attributes']['content']);

View File

@@ -81,7 +81,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('TagMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('TagMention', $response['data']['attributes']['contentHtml']);
$this->assertStringNotContainsString('TagMention--deleted', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('TagMention--deleted', $response['data']['attributes']['contentHtml']);
@@ -109,7 +109,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Tatakai', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Tatakai', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('TagMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('TagMention', $response['data']['attributes']['contentHtml']);
@@ -138,7 +138,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertEquals('#franzofflarum', $response['data']['attributes']['content']); $this->assertEquals('#franzofflarum', $response['data']['attributes']['content']);
$this->assertStringNotContainsString('TagMention', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('TagMention', $response['data']['attributes']['contentHtml']);
@@ -168,7 +168,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertEquals('#test', $response['data']['attributes']['content']); $this->assertEquals('#test', $response['data']['attributes']['content']);
$this->assertStringNotContainsString('TagMention', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('TagMention', $response['data']['attributes']['contentHtml']);
@@ -196,7 +196,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertEquals('#dev', $response['data']['attributes']['content']); $this->assertEquals('#dev', $response['data']['attributes']['content']);
$this->assertStringNotContainsString('TagMention', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('TagMention', $response['data']['attributes']['contentHtml']);
@@ -224,7 +224,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertEquals('#dev', $response['data']['attributes']['content']); $this->assertEquals('#dev', $response['data']['attributes']['content']);
$this->assertStringContainsString('TagMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('TagMention', $response['data']['attributes']['contentHtml']);
@@ -252,7 +252,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Test', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Test', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('Flarum', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Flarum', $response['data']['attributes']['contentHtml']);
@@ -273,7 +273,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Test', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Test', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('TagMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('TagMention', $response['data']['attributes']['contentHtml']);
@@ -305,7 +305,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('#test', $response['data']['attributes']['content']); $this->assertStringContainsString('#test', $response['data']['attributes']['content']);
$this->assertCount(1, CommentPost::find($response['data']['id'])->mentionsTags); $this->assertCount(1, CommentPost::find($response['data']['id'])->mentionsTags);
@@ -325,7 +325,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString($deleted_text, $response['data']['attributes']['contentHtml']); $this->assertStringContainsString($deleted_text, $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString("#$deleted_text", $response['data']['attributes']['content']); $this->assertStringContainsString("#$deleted_text", $response['data']['attributes']['content']);
@@ -348,7 +348,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Support', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Support', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString("#$deleted_text", $response['data']['attributes']['content']); $this->assertStringContainsString("#$deleted_text", $response['data']['attributes']['content']);
@@ -375,7 +375,7 @@ class TagMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Laravel "#t6 Tag', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Laravel "#t6 Tag', $response['data']['attributes']['contentHtml']);
$this->assertEquals('#laravel', $response['data']['attributes']['content']); $this->assertEquals('#laravel', $response['data']['attributes']['content']);

View File

@@ -85,7 +85,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringNotContainsString('@POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('@POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@potato', $response['data']['attributes']['content']); $this->assertStringContainsString('@potato', $response['data']['attributes']['content']);
@@ -118,7 +118,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"POTATO$"#3', $response['data']['attributes']['content']); $this->assertEquals('@"POTATO$"#3', $response['data']['attributes']['content']);
@@ -149,7 +149,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"POTATO$"#3', $response['data']['attributes']['content']); $this->assertStringContainsString('@"POTATO$"#3', $response['data']['attributes']['content']);
@@ -180,7 +180,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"POTATO$"#3', $response['data']['attributes']['content']); $this->assertStringContainsString('@"POTATO$"#3', $response['data']['attributes']['content']);
@@ -211,7 +211,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringNotContainsString('@FRANZOFFLARUM$', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('@FRANZOFFLARUM$', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"franzofflarum"#82', $response['data']['attributes']['content']); $this->assertStringContainsString('@"franzofflarum"#82', $response['data']['attributes']['content']);
@@ -242,7 +242,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@TOBY$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@TOBY$', $response['data']['attributes']['contentHtml']);
$this->assertStringNotContainsString('@FRANZOFFLARUM$', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('@FRANZOFFLARUM$', $response['data']['attributes']['contentHtml']);
@@ -265,7 +265,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@TOBY$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@TOBY$', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('UserMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('UserMention', $response['data']['attributes']['contentHtml']);
@@ -295,7 +295,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@POTATO$', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('@POTATO$', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('UserMention', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('UserMention', $response['data']['attributes']['contentHtml']);
@@ -325,7 +325,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('@"POTATO$"#3', $response['data']['attributes']['content']); $this->assertStringContainsString('@"POTATO$"#3', $response['data']['attributes']['content']);
$this->assertNotNull(CommentPost::find($response['data']['id'])->mentionsUsers->find(3)); $this->assertNotNull(CommentPost::find($response['data']['id'])->mentionsUsers->find(3));
@@ -346,7 +346,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString("@$deleted_text", $response['data']['attributes']['contentHtml']); $this->assertStringContainsString("@$deleted_text", $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"'.$deleted_text.'"#2021', $response['data']['attributes']['content']); $this->assertStringContainsString('@"'.$deleted_text.'"#2021', $response['data']['attributes']['content']);
@@ -380,7 +380,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringNotContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringNotContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertNotEquals('@"Bad "#p6 User"#5', $response['data']['attributes']['content']); $this->assertNotEquals('@"Bad "#p6 User"#5', $response['data']['attributes']['content']);
@@ -401,7 +401,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertStringContainsString('@"Bad _ User"#5', $response['data']['attributes']['content']); $this->assertStringContainsString('@"Bad _ User"#5', $response['data']['attributes']['content']);
@@ -432,7 +432,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"Bad _ User"#5', $response['data']['attributes']['content']); $this->assertEquals('@"Bad _ User"#5', $response['data']['attributes']['content']);
@@ -460,7 +460,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"Bad _ User"#5', $response['data']['attributes']['content']); $this->assertEquals('@"Bad _ User"#5', $response['data']['attributes']['content']);
@@ -488,7 +488,7 @@ class UserMentionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$response = json_decode($response->getBody(), true); $response = json_decode($response->getContent(), true);
$this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']); $this->assertStringContainsString('Bad "#p6 User', $response['data']['attributes']['contentHtml']);
$this->assertEquals('@"Bad _ User"#5', $response['data']['attributes']['content']); $this->assertEquals('@"Bad _ User"#5', $response['data']['attributes']['content']);

View File

@@ -2,6 +2,6 @@
'{recipient_display_name}' => $user->display_name, '{recipient_display_name}' => $user->display_name,
'{mentioner_display_name}' => $blueprint->post->user->display_name, '{mentioner_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title, '{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), '{url}' => $url->route('forum.discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]),
'{content}' => $blueprint->post->content '{content}' => $blueprint->post->content
]) !!} ]) !!}

View File

@@ -3,6 +3,6 @@
'{replier_display_name}' => $blueprint->reply->user->display_name, '{replier_display_name}' => $blueprint->reply->user->display_name,
'{post_number}' => $blueprint->post->number, '{post_number}' => $blueprint->post->number,
'{title}' => $blueprint->post->discussion->title, '{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->reply->discussion_id, 'near' => $blueprint->reply->number]), '{url}' => $url->route('forum.discussion', ['id' => $blueprint->reply->discussion_id, 'near' => $blueprint->reply->number]),
'{content}' => $blueprint->reply->content '{content}' => $blueprint->reply->content
]) !!} ]) !!}

View File

@@ -2,6 +2,6 @@
'{recipient_display_name}' => $user->display_name, '{recipient_display_name}' => $user->display_name,
'{mentioner_display_name}' => $blueprint->post->user->display_name, '{mentioner_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title, '{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), '{url}' => $url->route('forum.discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]),
'{content}' => $blueprint->post->content '{content}' => $blueprint->post->content
]) !!} ]) !!}

View File

@@ -22,7 +22,7 @@ class RegisterTest extends TestCase
{ {
$this->extension('flarum-nicknames'); $this->extension('flarum-nicknames');
$this->extend( $this->extend(
(new Extend\Csrf)->exemptRoute('register') (new Extend\Csrf)->exemptRoute('forum.register')
); );
} }

View File

@@ -9,22 +9,22 @@
namespace Flarum\PackageManager\Api\Controller; namespace Flarum\PackageManager\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\PackageManager\Command\CheckForUpdates; use Flarum\PackageManager\Command\CheckForUpdates;
use Flarum\PackageManager\Job\Dispatcher; use Flarum\PackageManager\Job\Dispatcher;
use Illuminate\Http\Request;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class CheckForUpdatesController implements RequestHandlerInterface class CheckForUpdatesController extends AbstractController
{ {
public function __construct( public function __construct(
protected Dispatcher $bus protected Dispatcher $bus
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);

View File

@@ -9,23 +9,23 @@
namespace Flarum\PackageManager\Api\Controller; namespace Flarum\PackageManager\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\PackageManager\Command\GlobalUpdate; use Flarum\PackageManager\Command\GlobalUpdate;
use Flarum\PackageManager\Job\Dispatcher; use Flarum\PackageManager\Job\Dispatcher;
use Illuminate\Http\Request;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class GlobalUpdateController implements RequestHandlerInterface class GlobalUpdateController extends AbstractController
{ {
public function __construct( public function __construct(
protected Dispatcher $bus protected Dispatcher $bus
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);

View File

@@ -14,7 +14,7 @@ use Flarum\Http\RequestUtil;
use Flarum\Http\UrlGenerator; use Flarum\Http\UrlGenerator;
use Flarum\PackageManager\Api\Serializer\TaskSerializer; use Flarum\PackageManager\Api\Serializer\TaskSerializer;
use Flarum\PackageManager\Task\TaskRepository; use Flarum\PackageManager\Task\TaskRepository;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class ListTasksController extends AbstractListController class ListTasksController extends AbstractListController
@@ -27,7 +27,7 @@ class ListTasksController extends AbstractListController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): iterable protected function data(Request $request, Document $document): iterable
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
@@ -48,8 +48,8 @@ class ListTasksController extends AbstractListController
$document->addMeta('total', (string) $total); $document->addMeta('total', (string) $total);
$document->addPaginationLinks( $document->addPaginationLinks(
$this->url->to('api')->route('package-manager.tasks.index'), $this->url->route('api.package-manager.tasks.index'),
$request->getQueryParams(), $request->query(),
$offset, $offset,
$limit, $limit,
$total $total

View File

@@ -9,27 +9,26 @@
namespace Flarum\PackageManager\Api\Controller; namespace Flarum\PackageManager\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\PackageManager\Command\MajorUpdate; use Flarum\PackageManager\Command\MajorUpdate;
use Flarum\PackageManager\Job\Dispatcher; use Flarum\PackageManager\Job\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class MajorUpdateController implements RequestHandlerInterface class MajorUpdateController extends AbstractController
{ {
public function __construct( public function __construct(
protected Dispatcher $bus protected Dispatcher $bus
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$dryRun = (bool) (int) Arr::get($request->getParsedBody(), 'data.dryRun', 0); $dryRun = (bool) (int) $request->json('data.dryRun', 0);
$response = $this->bus->dispatch( $response = $this->bus->dispatch(
new MajorUpdate($actor, $dryRun) new MajorUpdate($actor, $dryRun)

View File

@@ -9,23 +9,23 @@
namespace Flarum\PackageManager\Api\Controller; namespace Flarum\PackageManager\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\PackageManager\Command\MinorUpdate; use Flarum\PackageManager\Command\MinorUpdate;
use Flarum\PackageManager\Job\Dispatcher; use Flarum\PackageManager\Job\Dispatcher;
use Illuminate\Http\Request;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class MinorUpdateController implements RequestHandlerInterface class MinorUpdateController extends AbstractController
{ {
public function __construct( public function __construct(
protected Dispatcher $bus protected Dispatcher $bus
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);

View File

@@ -9,30 +9,28 @@
namespace Flarum\PackageManager\Api\Controller; namespace Flarum\PackageManager\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\PackageManager\Command\RemoveExtension; use Flarum\PackageManager\Command\RemoveExtension;
use Flarum\PackageManager\Job\Dispatcher; use Flarum\PackageManager\Job\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class RemoveExtensionController implements RequestHandlerInterface class RemoveExtensionController extends AbstractController
{ {
public function __construct( public function __construct(
protected Dispatcher $bus protected Dispatcher $bus
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request, int $id): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$extensionId = Arr::get($request->getQueryParams(), 'id');
$response = $this->bus->dispatch( $response = $this->bus->dispatch(
new RemoveExtension($actor, $extensionId) new RemoveExtension($actor, $id)
); );
return $response->queueJobs return $response->queueJobs

View File

@@ -9,26 +9,25 @@
namespace Flarum\PackageManager\Api\Controller; namespace Flarum\PackageManager\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\PackageManager\Command\RequireExtension; use Flarum\PackageManager\Command\RequireExtension;
use Flarum\PackageManager\Job\Dispatcher; use Flarum\PackageManager\Job\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class RequireExtensionController implements RequestHandlerInterface class RequireExtensionController extends AbstractController
{ {
public function __construct( public function __construct(
protected Dispatcher $bus protected Dispatcher $bus
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$package = Arr::get($request->getParsedBody(), 'data.package'); $package = $request->json('data.package');
$response = $this->bus->dispatch( $response = $this->bus->dispatch(
new RequireExtension($actor, $package) new RequireExtension($actor, $package)

View File

@@ -9,30 +9,28 @@
namespace Flarum\PackageManager\Api\Controller; namespace Flarum\PackageManager\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\PackageManager\Command\UpdateExtension; use Flarum\PackageManager\Command\UpdateExtension;
use Flarum\PackageManager\Job\Dispatcher; use Flarum\PackageManager\Job\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class UpdateExtensionController implements RequestHandlerInterface class UpdateExtensionController extends AbstractController
{ {
public function __construct( public function __construct(
protected Dispatcher $bus protected Dispatcher $bus
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request, int $id): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$extensionId = Arr::get($request->getQueryParams(), 'id');
$response = $this->bus->dispatch( $response = $this->bus->dispatch(
new UpdateExtension($actor, $extensionId) new UpdateExtension($actor, $id)
); );
return $response->queueJobs return $response->queueJobs

View File

@@ -9,27 +9,26 @@
namespace Flarum\PackageManager\Api\Controller; namespace Flarum\PackageManager\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\PackageManager\Command\WhyNot; use Flarum\PackageManager\Command\WhyNot;
use Flarum\PackageManager\Job\Dispatcher; use Flarum\PackageManager\Job\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class WhyNotController implements RequestHandlerInterface class WhyNotController extends AbstractController
{ {
public function __construct( public function __construct(
protected Dispatcher $bus protected Dispatcher $bus
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$package = Arr::get($request->getParsedBody(), 'data.package', ''); $package = $request->json('data.package', '');
$version = Arr::get($request->getParsedBody(), 'data.version', '*'); $version = $request->json('data.version', '*');
$whyNot = $this->bus->sync()->dispatch( $whyNot = $this->bus->sync()->dispatch(
new WhyNot($actor, $package, $version) new WhyNot($actor, $package, $version)

View File

@@ -92,7 +92,7 @@ class TestCase extends \Flarum\Testing\integration\TestCase
protected function errorDetails(ResponseInterface $response): array protected function errorDetails(ResponseInterface $response): array
{ {
$json = json_decode((string) $response->getBody(), true); $json = json_decode((string) $response->getContent(), true);
return $json['errors'] ? ($json['errors'][0] ?? []) : []; return $json['errors'] ? ($json['errors'][0] ?? []) : [];
} }

View File

@@ -38,6 +38,6 @@ class CheckForUpdatesTest extends TestCase
); );
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(['flarum/tags'], Arr::pluck(json_decode((string) $response->getBody(), true)['updates']['installed'], 'name')); $this->assertEquals(['flarum/tags'], Arr::pluck(json_decode((string) $response->getContent(), true)['updates']['installed'], 'name'));
} }
} }

View File

@@ -75,7 +75,7 @@ class MajorUpdateTest extends TestCase
); );
$newMinorCoreVersion = array_filter( $newMinorCoreVersion = array_filter(
json_decode((string) $lastUpdateCheck->getBody(), true)['updates']['installed'], json_decode((string) $lastUpdateCheck->getContent(), true)['updates']['installed'],
function ($package) { function ($package) {
return $package['name'] === 'flarum/core'; return $package['name'] === 'flarum/core';
} }

View File

@@ -9,29 +9,27 @@
namespace Flarum\Pusher\Api\Controller; namespace Flarum\Pusher\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Pusher\Pusher; use Pusher\Pusher;
class AuthController implements RequestHandlerInterface class AuthController extends AbstractController
{ {
public function __construct( public function __construct(
protected SettingsRepositoryInterface $settings protected SettingsRepositoryInterface $settings
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$userChannel = 'private-user'.RequestUtil::getActor($request)->id; $userChannel = 'private-user'.RequestUtil::getActor($request)->id;
$body = $request->getParsedBody();
if (Arr::get($body, 'channel_name') === $userChannel) { if ($request->input('channel_name') === $userChannel) {
$pusher = new Pusher( $pusher = new Pusher(
$this->settings->get('flarum-pusher.app_key'), $this->settings->get('flarum-pusher.app_key'),
$this->settings->get('flarum-pusher.app_secret'), $this->settings->get('flarum-pusher.app_secret'),
@@ -39,7 +37,7 @@ class AuthController implements RequestHandlerInterface
['cluster' => $this->settings->get('flarum-pusher.app_cluster')] ['cluster' => $this->settings->get('flarum-pusher.app_cluster')]
); );
$payload = json_decode($pusher->socket_auth($userChannel, Arr::get($body, 'socket_id')), true); $payload = json_decode($pusher->socket_auth($userChannel, $request->input('socket_id')), true);
return new JsonResponse($payload); return new JsonResponse($payload);
} }

View File

@@ -12,6 +12,7 @@ namespace Flarum\Statistics\Api\Controller;
use Carbon\Carbon; use Carbon\Carbon;
use DateTime; use DateTime;
use Flarum\Discussion\Discussion; use Flarum\Discussion\Discussion;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\Post\Post; use Flarum\Post\Post;
use Flarum\Post\RegisteredTypesScope; use Flarum\Post\RegisteredTypesScope;
@@ -19,14 +20,13 @@ use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\User; use Flarum\User\User;
use Illuminate\Contracts\Cache\Repository as CacheRepository; use Illuminate\Contracts\Cache\Repository as CacheRepository;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Tobscure\JsonApi\Exception\InvalidParameterException; use Tobscure\JsonApi\Exception\InvalidParameterException;
class ShowStatisticsData implements RequestHandlerInterface class ShowStatisticsData extends AbstractController
{ {
/** /**
* The amount of time to cache lifetime statistics data for in seconds. * The amount of time to cache lifetime statistics data for in seconds.
@@ -51,7 +51,7 @@ class ShowStatisticsData implements RequestHandlerInterface
]; ];
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
@@ -59,11 +59,9 @@ class ShowStatisticsData implements RequestHandlerInterface
// control panel. // control panel.
$actor->assertAdmin(); $actor->assertAdmin();
$query = $request->getQueryParams(); $reportingPeriod = $request->query('period');
$model = $request->query('model');
$reportingPeriod = Arr::get($query, 'period'); $customDateRange = $request->query('dateRange');
$model = Arr::get($query, 'model');
$customDateRange = Arr::get($query, 'dateRange');
return new JsonResponse($this->getResponse($model, $reportingPeriod, $customDateRange)); return new JsonResponse($this->getResponse($model, $reportingPeriod, $customDateRange));
} }

View File

@@ -12,6 +12,7 @@ namespace Flarum\Statistics\tests\integration\api;
use Carbon\Carbon; use Carbon\Carbon;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
class CanRequestCustomTimedStatisticsTest extends TestCase class CanRequestCustomTimedStatisticsTest extends TestCase
{ {
@@ -87,17 +88,20 @@ class CanRequestCustomTimedStatisticsTest extends TestCase
foreach ($models as $model => $data) { foreach ($models as $model => $data) {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/statistics', ['authenticatedAs' => 1])->withQueryParams([ tap(
'model' => $model, $this->request('GET', '/api/statistics', ['authenticatedAs' => 1]),
'period' => 'custom', fn (Request $request) => $request->query->add([
'dateRange' => [ 'model' => $model,
'start' => $start, 'period' => 'custom',
'end' => $end, 'dateRange' => [
], 'start' => $start,
]) 'end' => $end,
],
])
)
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());

View File

@@ -12,6 +12,7 @@ namespace Flarum\Statistics\tests\integration\api;
use Carbon\Carbon; use Carbon\Carbon;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
class CanRequestLifetimeStatisticsTest extends TestCase class CanRequestLifetimeStatisticsTest extends TestCase
{ {
@@ -62,12 +63,15 @@ class CanRequestLifetimeStatisticsTest extends TestCase
public function can_request_lifetime_stats() public function can_request_lifetime_stats()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/statistics', ['authenticatedAs' => 1])->withQueryParams([ tap(
'period' => 'lifetime', $this->request('GET', '/api/statistics', ['authenticatedAs' => 1]),
]) fn (Request $request) => $request->query->add([
'period' => 'lifetime',
])
)
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$db = $this->getDatabaseData(); $db = $this->getDatabaseData();

View File

@@ -12,6 +12,7 @@ namespace Flarum\Statistics\tests\integration\api;
use Carbon\Carbon; use Carbon\Carbon;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
class CanRequestTimedStatisticsTest extends TestCase class CanRequestTimedStatisticsTest extends TestCase
{ {
@@ -81,12 +82,15 @@ class CanRequestTimedStatisticsTest extends TestCase
foreach ($models as $model => $data) { foreach ($models as $model => $data) {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/statistics', ['authenticatedAs' => 1])->withQueryParams([ tap(
'model' => $model, $this->request('GET', '/api/statistics', ['authenticatedAs' => 1]),
]) fn (Request $request) => $request->query->add([
'model' => $model,
])
)
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());

View File

@@ -12,6 +12,7 @@ namespace Flarum\Sticky\tests\integration\api;
use Carbon\Carbon; use Carbon\Carbon;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ListDiscussionsTest extends TestCase class ListDiscussionsTest extends TestCase
@@ -61,7 +62,7 @@ class ListDiscussionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true); $data = json_decode($response->getContent(), true);
$this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id')); $this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id'));
} }
@@ -77,7 +78,7 @@ class ListDiscussionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true); $data = json_decode($response->getContent(), true);
$this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id')); $this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id'));
} }
@@ -93,7 +94,7 @@ class ListDiscussionsTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true); $data = json_decode($response->getContent(), true);
$this->assertEquals([2, 4, 3, 1], Arr::pluck($data['data'], 'id')); $this->assertEquals([2, 4, 3, 1], Arr::pluck($data['data'], 'id'));
} }
@@ -102,18 +103,21 @@ class ListDiscussionsTest extends TestCase
public function list_discussions_shows_stick_first_on_a_tag() public function list_discussions_shows_stick_first_on_a_tag()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/discussions', [ tap(
'authenticatedAs' => 3 $this->request('GET', '/api/discussions', [
])->withQueryParams([ 'authenticatedAs' => 3
'filter' => [ ]),
'tag' => 'general' fn (Request $request) => $request->query->add([
] 'filter' => [
]) 'tag' => 'general'
]
])
)
); );
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true); $data = json_decode($response->getContent(), true);
$this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id')); $this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id'));
} }

View File

@@ -16,6 +16,7 @@ use Flarum\Post\Post;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Flarum\User\User; use Flarum\User\User;
use Illuminate\Http\Request;
class ReplyNotificationTest extends TestCase class ReplyNotificationTest extends TestCase
{ {
@@ -67,7 +68,7 @@ class ReplyNotificationTest extends TestCase
*/ */
public function replying_to_a_discussion_with_comment_post_as_last_post_sends_reply_notification(int $userId, int $discussionId, int $newNotificationCount) public function replying_to_a_discussion_with_comment_post_as_last_post_sends_reply_notification(int $userId, int $discussionId, int $newNotificationCount)
{ {
$this->app(); $this->bootstrap();
/** @var User $mainUser */ /** @var User $mainUser */
$mainUser = User::query()->find($userId); $mainUser = User::query()->find($userId);
@@ -76,7 +77,7 @@ class ReplyNotificationTest extends TestCase
for ($i = 0; $i < 5; $i++) { for ($i = 0; $i < 5; $i++) {
$this->send( $this->send(
$this->request('POST', '/api/posts', [ tap($this->request('POST', '/api/posts', [
'authenticatedAs' => 4, 'authenticatedAs' => 4,
'json' => [ 'json' => [
'data' => [ 'data' => [
@@ -88,7 +89,7 @@ class ReplyNotificationTest extends TestCase
], ],
], ],
], ],
])->withAttribute('bypassThrottling', true) ]), fn (Request $request) => $request->attributes->set('bypassThrottling', true))
); );
} }
@@ -108,7 +109,7 @@ class ReplyNotificationTest extends TestCase
/** @test */ /** @test */
public function replying_to_a_discussion_with_event_post_as_last_post_sends_reply_notification() public function replying_to_a_discussion_with_event_post_as_last_post_sends_reply_notification()
{ {
$this->app(); $this->bootstrap();
/** @var User $mainUser */ /** @var User $mainUser */
$mainUser = User::query()->find(1); $mainUser = User::query()->find(1);
@@ -231,7 +232,7 @@ class ReplyNotificationTest extends TestCase
// Flags was only specified because it is required for approval. // Flags was only specified because it is required for approval.
$this->extensions = ['flarum-flags', 'flarum-approval', 'flarum-subscriptions']; $this->extensions = ['flarum-flags', 'flarum-approval', 'flarum-subscriptions'];
$this->app(); $this->bootstrap();
$this->database() $this->database()
->table('group_permission') ->table('group_permission')
@@ -262,7 +263,7 @@ class ReplyNotificationTest extends TestCase
$this->assertEquals(0, $mainUser->getUnreadNotificationCount()); $this->assertEquals(0, $mainUser->getUnreadNotificationCount());
$json = json_decode($response->getBody()->getContents(), true); $json = json_decode($response->getContent(), true);
// Approve the previous post // Approve the previous post
$this->send( $this->send(
@@ -295,7 +296,7 @@ class ReplyNotificationTest extends TestCase
}) })
); );
$this->app(); $this->bootstrap();
/** @var User $allowedUser */ /** @var User $allowedUser */
$allowedUser = User::query()->find(1); $allowedUser = User::query()->find(1);

View File

@@ -2,6 +2,6 @@
'{recipient_display_name}' => $user->display_name, '{recipient_display_name}' => $user->display_name,
'{poster_display_name}' => $blueprint->post->user->display_name, '{poster_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title, '{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), '{url}' => $url->route('forum.discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]),
'{content}' => $blueprint->post->content '{content}' => $blueprint->post->content
]) !!} ]) !!}

View File

@@ -12,6 +12,7 @@ namespace Flarum\Suspend\Tests\integration\api\users;
use Carbon\Carbon; use Carbon\Carbon;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ListUsersTest extends TestCase class ListUsersTest extends TestCase
@@ -39,16 +40,19 @@ class ListUsersTest extends TestCase
public function can_view_default_users_list() public function can_view_default_users_list()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/users', [ tap(
'authenticatedAs' => 1, $this->request('GET', '/api/users', [
])->withQueryParams([ 'authenticatedAs' => 1,
'filter' => [ ]),
'suspended' => true, fn (Request $request) => $request->query->add([
], 'filter' => [
]) 'suspended' => true,
],
])
)
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEqualsCanonicalizing([1, 2, 3, 4, 5, 6], Arr::pluck($body['data'], 'id')); $this->assertEqualsCanonicalizing([1, 2, 3, 4, 5, 6], Arr::pluck($body['data'], 'id'));
@@ -58,16 +62,19 @@ class ListUsersTest extends TestCase
public function can_filter_users_by_suspension() public function can_filter_users_by_suspension()
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/users', [ tap(
'authenticatedAs' => 1, $this->request('GET', '/api/users', [
])->withQueryParams([ 'authenticatedAs' => 1,
'filter' => [ ]),
'suspended' => true, fn (Request $request) => $request->query->add([
], 'filter' => [
]) 'suspended' => true,
],
])
)
); );
$body = json_decode($response->getBody()->getContents(), true); $body = json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEqualsCanonicalizing([2, 3, 5], Arr::pluck($body['data'], 'id')); $this->assertEqualsCanonicalizing([2, 3, 5], Arr::pluck($body['data'], 'id'));

View File

@@ -1,4 +1,4 @@
{!! $translator->trans('flarum-suspend.email.unsuspended.body', [ {!! $translator->trans('flarum-suspend.email.unsuspended.body', [
'{recipient_display_name}' => $user->display_name, '{recipient_display_name}' => $user->display_name,
'{forum_url}' => $url->to('forum')->base(), '{forum_url}' => $url->base('forum'),
]) !!} ]) !!}

View File

@@ -37,9 +37,9 @@ use Flarum\Tags\Tag;
use Flarum\Tags\Utf8SlugDriver; use Flarum\Tags\Utf8SlugDriver;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Eloquent\Relations\Relation;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
$eagerLoadTagState = function ($query, ?ServerRequestInterface $request, array $relations) { $eagerLoadTagState = function ($query, ?Request $request, array $relations) {
if ($request && in_array('tags.state', $relations, true)) { if ($request && in_array('tags.state', $relations, true)) {
$query->withStateFor(RequestUtil::getActor($request)); $query->withStateFor(RequestUtil::getActor($request));
} }
@@ -177,7 +177,7 @@ return [
(new Extend\ApiController(FlarumController\ListPostsController::class)) (new Extend\ApiController(FlarumController\ListPostsController::class))
->addInclude('eventPostMentionsTags') ->addInclude('eventPostMentionsTags')
// Restricted tags should still appear as `deleted` to unauthorized users. // Restricted tags should still appear as `deleted` to unauthorized users.
->loadWhere('eventPostMentionsTags', function (Relation|Builder $query, ?ServerRequestInterface $request) { ->loadWhere('eventPostMentionsTags', function (Relation|Builder $query, ?Request $request) {
if ($request) { if ($request) {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$query->whereVisibleTo($actor); $query->whereVisibleTo($actor);

View File

@@ -15,8 +15,7 @@ use Flarum\Tags\Api\Serializer\TagSerializer;
use Flarum\Tags\Command\CreateTag; use Flarum\Tags\Command\CreateTag;
use Flarum\Tags\Tag; use Flarum\Tags\Tag;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class CreateTagController extends AbstractCreateController class CreateTagController extends AbstractCreateController
@@ -30,10 +29,10 @@ class CreateTagController extends AbstractCreateController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): Tag protected function data(Request $request, Document $document): Tag
{ {
return $this->bus->dispatch( return $this->bus->dispatch(
new CreateTag(RequestUtil::getActor($request), Arr::get($request->getParsedBody(), 'data', [])) new CreateTag(RequestUtil::getActor($request), $request->json('data', []))
); );
} }
} }

View File

@@ -13,8 +13,7 @@ use Flarum\Api\Controller\AbstractDeleteController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\Tags\Command\DeleteTag; use Flarum\Tags\Command\DeleteTag;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
class DeleteTagController extends AbstractDeleteController class DeleteTagController extends AbstractDeleteController
{ {
@@ -23,10 +22,10 @@ class DeleteTagController extends AbstractDeleteController
) { ) {
} }
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
$this->bus->dispatch( $this->bus->dispatch(
new DeleteTag(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request)) new DeleteTag($request->route('id'), RequestUtil::getActor($request))
); );
} }
} }

View File

@@ -16,7 +16,7 @@ use Flarum\Query\QueryCriteria;
use Flarum\Tags\Api\Serializer\TagSerializer; use Flarum\Tags\Api\Serializer\TagSerializer;
use Flarum\Tags\Search\TagSearcher; use Flarum\Tags\Search\TagSearcher;
use Flarum\Tags\TagRepository; use Flarum\Tags\TagRepository;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class ListTagsController extends AbstractListController class ListTagsController extends AbstractListController
@@ -40,7 +40,7 @@ class ListTagsController extends AbstractListController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): iterable protected function data(Request $request, Document $document): iterable
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$include = $this->extractInclude($request); $include = $this->extractInclude($request);
@@ -57,8 +57,8 @@ class ListTagsController extends AbstractListController
$tags = $results->getResults(); $tags = $results->getResults();
$document->addPaginationLinks( $document->addPaginationLinks(
$this->url->to('api')->route('tags.index'), $this->url->route('api.tags.index'),
$request->getQueryParams(), $request->query(),
$offset, $offset,
$limit, $limit,
$results->areMoreResults() ? null : 0 $results->areMoreResults() ? null : 0

View File

@@ -9,21 +9,21 @@
namespace Flarum\Tags\Api\Controller; namespace Flarum\Tags\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\Tags\Tag; use Flarum\Tags\Tag;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class OrderTagsController implements RequestHandlerInterface class OrderTagsController extends AbstractController
{ {
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
RequestUtil::getActor($request)->assertAdmin(); RequestUtil::getActor($request)->assertAdmin();
$order = Arr::get($request->getParsedBody(), 'order'); $order = $request->json('order');
if ($order === null) { if ($order === null) {
return new EmptyResponse(422); return new EmptyResponse(422);
@@ -37,7 +37,7 @@ class OrderTagsController implements RequestHandlerInterface
foreach ($order as $i => $parent) { foreach ($order as $i => $parent) {
$parentId = Arr::get($parent, 'id'); $parentId = Arr::get($parent, 'id');
Tag::where('id', $parentId)->update(['position' => $i]); Tag::query()->where('id', $parentId)->update(['position' => $i]);
if (isset($parent['children']) && is_array($parent['children'])) { if (isset($parent['children']) && is_array($parent['children'])) {
foreach ($parent['children'] as $j => $childId) { foreach ($parent['children'] as $j => $childId) {

View File

@@ -15,8 +15,7 @@ use Flarum\Http\SlugManager;
use Flarum\Tags\Api\Serializer\TagSerializer; use Flarum\Tags\Api\Serializer\TagSerializer;
use Flarum\Tags\Tag; use Flarum\Tags\Tag;
use Flarum\Tags\TagRepository; use Flarum\Tags\TagRepository;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class ShowTagController extends AbstractShowController class ShowTagController extends AbstractShowController
@@ -39,9 +38,9 @@ class ShowTagController extends AbstractShowController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): Tag protected function data(Request $request, Document $document): Tag
{ {
$slug = Arr::get($request->getQueryParams(), 'slug'); $slug = $request->route('slug');
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$include = $this->extractInclude($request); $include = $this->extractInclude($request);
$setParentOnChildren = false; $setParentOnChildren = false;

View File

@@ -15,8 +15,7 @@ use Flarum\Tags\Api\Serializer\TagSerializer;
use Flarum\Tags\Command\EditTag; use Flarum\Tags\Command\EditTag;
use Flarum\Tags\Tag; use Flarum\Tags\Tag;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class UpdateTagController extends AbstractShowController class UpdateTagController extends AbstractShowController
@@ -28,11 +27,11 @@ class UpdateTagController extends AbstractShowController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): Tag protected function data(Request $request, Document $document): Tag
{ {
$id = Arr::get($request->getQueryParams(), 'id'); $id = $request->route('id');
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$data = Arr::get($request->getParsedBody(), 'data', []); $data = $request->json('data', []);
return $this->bus->dispatch( return $this->bus->dispatch(
new EditTag($id, $actor, $data) new EditTag($id, $actor, $data)

View File

@@ -17,8 +17,7 @@ use Flarum\Locale\TranslatorInterface;
use Flarum\Tags\Tag as TagModel; use Flarum\Tags\Tag as TagModel;
use Flarum\Tags\TagRepository; use Flarum\Tags\TagRepository;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface as Request;
class Tag class Tag
{ {
@@ -33,14 +32,13 @@ class Tag
public function __invoke(Document $document, Request $request): Document public function __invoke(Document $document, Request $request): Document
{ {
$queryParams = $request->getQueryParams();
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$slug = Arr::pull($queryParams, 'slug'); $slug = $request->route('slug');
$sort = Arr::pull($queryParams, 'sort'); $sort = $request->query('sort');
$q = Arr::pull($queryParams, 'q', ''); $q = $request->query('q', '');
$page = Arr::pull($queryParams, 'page', 1); $page = $request->query('page', 1);
$filters = Arr::pull($queryParams, 'filter', []); $filters = $request->query('filter', []);
$sortMap = $this->getSortMap(); $sortMap = $this->getSortMap();
@@ -91,13 +89,13 @@ class Tag
*/ */
protected function getApiDocument(Request $request, array $params): object protected function getApiDocument(Request $request, array $params): object
{ {
return json_decode($this->api->withParentRequest($request)->withQueryParams($params)->get('/discussions')->getBody()); return json_decode($this->api->withParentRequest($request)->withQueryParams($params)->get('/discussions')->content());
} }
protected function getTagsDocument(Request $request, string $slug): object protected function getTagsDocument(Request $request, string $slug): object
{ {
return json_decode($this->api->withParentRequest($request)->withQueryParams([ return json_decode($this->api->withParentRequest($request)->withQueryParams([
'include' => 'children,children.parent,parent,parent.children.parent,state' 'include' => 'children,children.parent,parent,parent.children.parent,state'
])->get("/tags/$slug")->getBody()); ])->get("/tags/$slug")->content());
} }
} }

View File

@@ -16,8 +16,8 @@ use Flarum\Locale\TranslatorInterface;
use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\Tags\TagRepository; use Flarum\Tags\TagRepository;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Psr\Http\Message\ServerRequestInterface as Request;
class Tags class Tags
{ {
@@ -50,7 +50,7 @@ class Tags
$document->title = $this->translator->trans('flarum-tags.forum.all_tags.meta_title_text'); $document->title = $this->translator->trans('flarum-tags.forum.all_tags.meta_title_text');
$document->meta['description'] = $this->translator->trans('flarum-tags.forum.all_tags.meta_description_text'); $document->meta['description'] = $this->translator->trans('flarum-tags.forum.all_tags.meta_description_text');
$document->content = $this->view->make('tags::frontend.content.tags', compact('primaryTags', 'secondaryTags', 'children')); $document->content = $this->view->make('tags::frontend.content.tags', compact('primaryTags', 'secondaryTags', 'children'));
$document->canonicalUrl = $this->url->to('forum')->base().($defaultRoute === '/tags' ? '' : $request->getUri()->getPath()); $document->canonicalUrl = $this->url->base('forum').($defaultRoute === '/tags' ? '' : $request->getUri());
$document->payload['apiDocument'] = $apiDocument; $document->payload['apiDocument'] = $apiDocument;
return $document; return $document;
@@ -60,6 +60,6 @@ class Tags
{ {
return json_decode($this->api->withParentRequest($request)->withQueryParams([ return json_decode($this->api->withParentRequest($request)->withQueryParams([
'include' => 'children,lastPostedDiscussion,parent' 'include' => 'children,lastPostedDiscussion,parent'
])->get('/tags')->getBody(), true); ])->get('/tags')->content(), true);
} }
} }

View File

@@ -11,11 +11,11 @@ namespace Flarum\Tags;
use Flarum\Api\Controller\ShowForumController; use Flarum\Api\Controller\ShowForumController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
class LoadForumTagsRelationship class LoadForumTagsRelationship
{ {
public function __invoke(ShowForumController $controller, array &$data, ServerRequestInterface $request): void public function __invoke(ShowForumController $controller, array &$data, Request $request): void
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);

View File

@@ -12,6 +12,7 @@ namespace Flarum\Tags\Tests\integration\api\discussions;
use Flarum\Tags\Tests\integration\RetrievesRepresentativeTags; use Flarum\Tags\Tests\integration\RetrievesRepresentativeTags;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ListTest extends TestCase class ListTest extends TestCase
@@ -118,7 +119,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '2', '3', '4', '5', '6'], $ids); $this->assertEqualsCanonicalizing(['1', '2', '3', '4', '5', '6'], $ids);
@@ -137,7 +138,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '2', '3', '4'], $ids); $this->assertEqualsCanonicalizing(['1', '2', '3', '4'], $ids);
@@ -154,7 +155,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing(['1', '2'], $ids); $this->assertEqualsCanonicalizing(['1', '2'], $ids);
@@ -190,7 +191,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing($expectedDiscussions, $ids); $this->assertEqualsCanonicalizing($expectedDiscussions, $ids);
@@ -221,17 +222,19 @@ class ListTest extends TestCase
public function can_filter_by_authorized_tags(int $authenticatedAs, string $tags, array $expectedDiscussionIds) public function can_filter_by_authorized_tags(int $authenticatedAs, string $tags, array $expectedDiscussionIds)
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/discussions', compact('authenticatedAs')) tap(
->withQueryParams([ $this->request('GET', '/api/discussions', compact('authenticatedAs')),
fn (Request $request) => $request->query->add([
'filter' => [ 'filter' => [
'tag' => $tags 'tag' => $tags
] ]
]) ])
)
); );
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEqualsCanonicalizing($expectedDiscussionIds, array_map('intval', $ids)); $this->assertEqualsCanonicalizing($expectedDiscussionIds, array_map('intval', $ids));

View File

@@ -83,7 +83,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true); $data = json_decode($response->getContent(), true);
$tagIds = array_map(function ($tag) { $tagIds = array_map(function ($tag) {
return $tag['id']; return $tag['id'];
@@ -108,7 +108,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true); $data = json_decode($response->getContent(), true);
$tagIds = array_map(function ($tag) { $tagIds = array_map(function ($tag) {
return $tag['id']; return $tag['id'];

View File

@@ -89,7 +89,7 @@ class CreateTest extends TestCase
$this->assertEquals(201, $response->getStatusCode()); $this->assertEquals(201, $response->getStatusCode());
// Verify API response body // Verify API response body
$data = json_decode($response->getBody(), true); $data = json_decode($response->getContent(), true);
$this->assertEquals('Dev Blog', Arr::get($data, 'data.attributes.name')); $this->assertEquals('Dev Blog', Arr::get($data, 'data.attributes.name'));
$this->assertEquals('dev-blog', Arr::get($data, 'data.attributes.slug')); $this->assertEquals('dev-blog', Arr::get($data, 'data.attributes.slug'));
$this->assertEquals('Follow Flarum development!', Arr::get($data, 'data.attributes.description')); $this->assertEquals('Follow Flarum development!', Arr::get($data, 'data.attributes.description'));

View File

@@ -13,6 +13,7 @@ use Flarum\Group\Group;
use Flarum\Tags\Tests\integration\RetrievesRepresentativeTags; use Flarum\Tags\Tests\integration\RetrievesRepresentativeTags;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ListTest extends TestCase class ListTest extends TestCase
@@ -54,7 +55,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEquals(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14'], $ids); $this->assertEquals(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14'], $ids);
@@ -73,7 +74,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
// 5 isnt included because parent access doesnt necessarily give child access // 5 isnt included because parent access doesnt necessarily give child access
// 6, 7, 8 aren't included because child access shouldnt work unless parent // 6, 7, 8 aren't included because child access shouldnt work unless parent
@@ -89,16 +90,19 @@ class ListTest extends TestCase
public function user_sees_where_allowed_with_included_tags(string $include, array $expectedIncludes) public function user_sees_where_allowed_with_included_tags(string $include, array $expectedIncludes)
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/tags', [ tap(
'authenticatedAs' => 2, $this->request('GET', '/api/tags', [
])->withQueryParams([ 'authenticatedAs' => 2,
'include' => $include ]),
]) fn (Request $request) => $request->query->add([
'include' => $include
])
)
); );
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$responseBody = json_decode($response->getBody()->getContents(), true); $responseBody = json_decode($response->getContent(), true);
$data = $responseBody['data']; $data = $responseBody['data'];
$included = $responseBody['included']; $included = $responseBody['included'];
@@ -121,7 +125,7 @@ class ListTest extends TestCase
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$ids = Arr::pluck($data, 'id'); $ids = Arr::pluck($data, 'id');
$this->assertEquals(['1', '2', '3', '4', '9', '10'], $ids); $this->assertEquals(['1', '2', '3', '4', '9', '10'], $ids);

View File

@@ -10,6 +10,7 @@
namespace Flarum\Tags\Tests\integration\api\tags; namespace Flarum\Tags\Tests\integration\api\tags;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ListWithFulltextSearchTest extends TestCase class ListWithFulltextSearchTest extends TestCase
@@ -42,14 +43,17 @@ class ListWithFulltextSearchTest extends TestCase
public function can_search_for_tags(string $search, array $expected) public function can_search_for_tags(string $search, array $expected)
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/tags')->withQueryParams([ tap(
'filter' => [ $this->request('GET', '/api/tags'),
'q' => $search, fn (Request $request) => $request->query->add([
], 'filter' => [
]) 'q' => $search,
],
])
)
); );
$data = json_decode($response->getBody()->getContents(), true)['data']; $data = json_decode($response->getContent(), true)['data'];
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertEquals($expected, Arr::pluck($data, 'id')); $this->assertEquals($expected, Arr::pluck($data, 'id'));

View File

@@ -13,6 +13,7 @@ use Flarum\Group\Group;
use Flarum\Tags\Tests\integration\RetrievesRepresentativeTags; use Flarum\Tags\Tests\integration\RetrievesRepresentativeTags;
use Flarum\Testing\integration\RetrievesAuthorizedUsers; use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase; use Flarum\Testing\integration\TestCase;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class ShowTest extends TestCase class ShowTest extends TestCase
@@ -92,16 +93,19 @@ class ShowTest extends TestCase
public function user_sees_tag_relations_where_allowed(string $include, array $expectedIncludes) public function user_sees_tag_relations_where_allowed(string $include, array $expectedIncludes)
{ {
$response = $this->send( $response = $this->send(
$this->request('GET', '/api/tags/primary-2-child-2', [ tap(
'authenticatedAs' => 2, $this->request('GET', '/api/tags/primary-2-child-2', [
])->withQueryParams([ 'authenticatedAs' => 2,
'include' => $include ]),
]) fn (Request $request) => $request->query->add([
'include' => $include
])
)
); );
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$responseBody = json_decode($response->getBody()->getContents(), true); $responseBody = json_decode($response->getContent(), true);
$included = $responseBody['included'] ?? []; $included = $responseBody['included'] ?? [];
$this->assertEqualsCanonicalizing($expectedIncludes, Arr::pluck($included, 'id')); $this->assertEqualsCanonicalizing($expectedIncludes, Arr::pluck($included, 'id'));

View File

@@ -141,7 +141,7 @@ class GlobalPolicyTest extends TestCase
] ]
]); ]);
$this->app(); $this->bootstrap();
$this->assertTrue(User::find(2)->can('startDiscussion')); $this->assertTrue(User::find(2)->can('startDiscussion'));
} }

View File

@@ -47,7 +47,7 @@ class TagPolicyTest extends TestCase
*/ */
public function has_ability_when_allowed_in_restricted_tag() public function has_ability_when_allowed_in_restricted_tag()
{ {
$this->app(); $this->bootstrap();
$tag = Tag::find(6); $tag = Tag::find(6);
@@ -59,7 +59,7 @@ class TagPolicyTest extends TestCase
*/ */
public function has_ability_in_child_when_allowed_in_top_tag_and_child() public function has_ability_in_child_when_allowed_in_top_tag_and_child()
{ {
$this->app(); $this->bootstrap();
$tag = Tag::find(8); $tag = Tag::find(8);
@@ -71,7 +71,7 @@ class TagPolicyTest extends TestCase
*/ */
public function doesnt_have_ability_in_child_when_allowed_in_child_but_not_parent() public function doesnt_have_ability_in_child_when_allowed_in_child_but_not_parent()
{ {
$this->app(); $this->bootstrap();
$this->database()->table('group_permission')->where('permission', 'tag6.arbitraryAbility!')->delete(); $this->database()->table('group_permission')->where('permission', 'tag6.arbitraryAbility!')->delete();
@@ -91,7 +91,7 @@ class TagPolicyTest extends TestCase
] ]
]); ]);
$this->app(); $this->bootstrap();
$tag = Tag::find(1); $tag = Tag::find(1);
@@ -103,7 +103,7 @@ class TagPolicyTest extends TestCase
*/ */
public function nonrestricted_tag_falls_back_to_global_when_not_allowed() public function nonrestricted_tag_falls_back_to_global_when_not_allowed()
{ {
$this->app(); $this->bootstrap();
$tag = Tag::find(1); $tag = Tag::find(1);

View File

@@ -85,7 +85,7 @@ class DiscussionVisibilityTest extends TestCase
*/ */
public function admin_sees_all() public function admin_sees_all()
{ {
$this->app(); $this->bootstrap();
$user = User::find(1); $user = User::find(1);
$discussions = Discussion::whereVisibleTo($user, 'arbitraryAbility')->get(); $discussions = Discussion::whereVisibleTo($user, 'arbitraryAbility')->get();
@@ -99,7 +99,7 @@ class DiscussionVisibilityTest extends TestCase
*/ */
public function user_sees_where_allowed() public function user_sees_where_allowed()
{ {
$this->app(); $this->bootstrap();
$user = User::find(2); $user = User::find(2);
$discussions = Discussion::whereVisibleTo($user, 'arbitraryAbility')->get(); $discussions = Discussion::whereVisibleTo($user, 'arbitraryAbility')->get();
@@ -127,7 +127,7 @@ class DiscussionVisibilityTest extends TestCase
*/ */
public function guest_can_see_where_allowed() public function guest_can_see_where_allowed()
{ {
$this->app(); $this->bootstrap();
$user = new Guest(); $user = new Guest();
$discussions = Discussion::whereVisibleTo($user, 'arbitraryAbility')->get(); $discussions = Discussion::whereVisibleTo($user, 'arbitraryAbility')->get();

View File

@@ -7,7 +7,7 @@
<ul> <ul>
@foreach ($apiDocument->data as $discussion) @foreach ($apiDocument->data as $discussion)
<li> <li>
<a href="{{ $url->to('forum')->route('discussion', [ <a href="{{ $url->route('forum.discussion', [
'id' => $discussion->attributes->slug 'id' => $discussion->attributes->slug
]) }}"> ]) }}">
{{ $discussion->attributes->title }} {{ $discussion->attributes->title }}
@@ -17,10 +17,10 @@
</ul> </ul>
@if (isset($apiDocument->links->prev)) @if (isset($apiDocument->links->prev))
<a href="{{ $url->to('forum')->route('tag', ['slug' => $tag->slug]) }}?page={{ $page - 1 }}">&laquo; {{ $translator->trans('core.views.index.previous_page_button') }}</a> <a href="{{ $url->route('forum.tag', ['slug' => $tag->slug]) }}?page={{ $page - 1 }}">&laquo; {{ $translator->trans('core.views.index.previous_page_button') }}</a>
@endif @endif
@if (isset($apiDocument->links->next)) @if (isset($apiDocument->links->next))
<a href="{{ $url->to('forum')->route('tag', ['slug' => $tag->slug]) }}?page={{ $page + 1 }}">{{ $translator->trans('core.views.index.next_page_button') }} &raquo;</a> <a href="{{ $url->route('forum.tag', ['slug' => $tag->slug]) }}?page={{ $page + 1 }}">{{ $translator->trans('core.views.index.next_page_button') }} &raquo;</a>
@endif @endif
</div> </div>

View File

@@ -7,7 +7,7 @@
<ul> <ul>
@foreach ($category->pluck('attributes', 'id') as $id => $tag) @foreach ($category->pluck('attributes', 'id') as $id => $tag)
<li> <li>
<a href="{{ $url->to('forum')->route('tag', [ <a href="{{ $url->route('forum.tag', [
'slug' => $tag['slug'] 'slug' => $tag['slug']
]) }}"> ]) }}">
{{ $tag['name'] }} {{ $tag['name'] }}
@@ -17,7 +17,7 @@
<ul> <ul>
@foreach ($children->get($id) as $child) @foreach ($children->get($id) as $child)
<li> <li>
<a href="{{ $url->to('forum')->route('tag', [ <a href="{{ $url->route('forum.tag', [
'slug' => $child['attributes']['slug'] 'slug' => $child['attributes']['slug']
]) }}"> ]) }}">
{{ $child['attributes']['name'] }} {{ $child['attributes']['name'] }}

View File

@@ -38,7 +38,6 @@
"require": { "require": {
"php": "^8.1", "php": "^8.1",
"components/font-awesome": "^5.15.0", "components/font-awesome": "^5.15.0",
"dflydev/fig-cookies": "^3.0",
"doctrine/dbal": "^3.6", "doctrine/dbal": "^3.6",
"dragonmantank/cron-expression": "*", "dragonmantank/cron-expression": "*",
"franzl/whoops-middleware": "2.0", "franzl/whoops-middleware": "2.0",
@@ -53,8 +52,10 @@
"illuminate/events": "^10.0", "illuminate/events": "^10.0",
"illuminate/filesystem": "^10.0", "illuminate/filesystem": "^10.0",
"illuminate/hashing": "^10.0", "illuminate/hashing": "^10.0",
"illuminate/http": "^10.0",
"illuminate/mail": "^10.0", "illuminate/mail": "^10.0",
"illuminate/queue": "^10.0", "illuminate/queue": "^10.0",
"illuminate/routing": "^10.0",
"illuminate/session": "^10.0", "illuminate/session": "^10.0",
"illuminate/support": "^10.0", "illuminate/support": "^10.0",
"illuminate/validation": "^10.0", "illuminate/validation": "^10.0",
@@ -72,7 +73,6 @@
"middlewares/request-handler": "^2.0.2", "middlewares/request-handler": "^2.0.2",
"monolog/monolog": "^3.0", "monolog/monolog": "^3.0",
"nesbot/carbon": "^2.0", "nesbot/carbon": "^2.0",
"nikic/fast-route": "^1.3",
"psr/http-message": "^1.1", "psr/http-message": "^1.1",
"psr/http-server-handler": "^1.0.2", "psr/http-server-handler": "^1.0.2",
"psr/http-server-middleware": "^1.0.2", "psr/http-server-middleware": "^1.0.2",
@@ -88,6 +88,7 @@
"symfony/mime": "^6.3", "symfony/mime": "^6.3",
"symfony/polyfill-intl-messageformatter": "^1.27", "symfony/polyfill-intl-messageformatter": "^1.27",
"symfony/postmark-mailer": "^6.3", "symfony/postmark-mailer": "^6.3",
"symfony/psr-http-message-bridge": "^2.3",
"symfony/translation": "^6.3", "symfony/translation": "^6.3",
"symfony/translation-contracts": "^2.5", "symfony/translation-contracts": "^2.5",
"symfony/yaml": "^6.3", "symfony/yaml": "^6.3",

View File

@@ -12,49 +12,31 @@ namespace Flarum\Admin;
use Flarum\Extension\Event\Disabled; use Flarum\Extension\Event\Disabled;
use Flarum\Extension\Event\Enabled; use Flarum\Extension\Event\Enabled;
use Flarum\Foundation\AbstractServiceProvider; use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\ErrorHandling\Registry; use Flarum\Foundation\Config;
use Flarum\Foundation\ErrorHandling\Reporter;
use Flarum\Foundation\ErrorHandling\ViewFormatter;
use Flarum\Foundation\ErrorHandling\WhoopsFormatter;
use Flarum\Foundation\Event\ClearingCache; use Flarum\Foundation\Event\ClearingCache;
use Flarum\Frontend\AddLocaleAssets; use Flarum\Frontend\AddLocaleAssets;
use Flarum\Frontend\AddTranslations; use Flarum\Frontend\AddTranslations;
use Flarum\Frontend\Compiler\Source\SourceCollector; use Flarum\Frontend\Compiler\Source\SourceCollector;
use Flarum\Frontend\RecompileFrontendAssets; use Flarum\Frontend\RecompileFrontendAssets;
use Flarum\Http\Middleware as HttpMiddleware; use Flarum\Http\Middleware as HttpMiddleware;
use Flarum\Http\RouteCollection;
use Flarum\Http\RouteHandlerFactory; use Flarum\Http\RouteHandlerFactory;
use Flarum\Http\UrlGenerator; use Flarum\Http\Router;
use Flarum\Locale\LocaleManager; use Flarum\Locale\LocaleManager;
use Flarum\Settings\Event\Saved; use Flarum\Settings\Event\Saved;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\Container;
use Laminas\Stratigility\MiddlewarePipe; use Illuminate\Contracts\Events\Dispatcher;
class AdminServiceProvider extends AbstractServiceProvider class AdminServiceProvider extends AbstractServiceProvider
{ {
public function register(): void public function register(): void
{ {
$this->container->extend(UrlGenerator::class, function (UrlGenerator $url, Container $container) {
return $url->addCollection('admin', $container->make('flarum.admin.routes'), 'admin');
});
$this->container->singleton('flarum.admin.routes', function () {
$routes = new RouteCollection;
$this->populateRoutes($routes);
return $routes;
});
$this->container->singleton('flarum.admin.middleware', function () { $this->container->singleton('flarum.admin.middleware', function () {
return [ return [
HttpMiddleware\InjectActorReference::class, HttpMiddleware\InjectActorReference::class,
'flarum.admin.error_handler',
HttpMiddleware\ParseJsonBody::class,
HttpMiddleware\StartSession::class, HttpMiddleware\StartSession::class,
HttpMiddleware\RememberFromCookie::class, HttpMiddleware\RememberFromCookie::class,
HttpMiddleware\AuthenticateWithSession::class, HttpMiddleware\AuthenticateWithSession::class,
HttpMiddleware\SetLocale::class, HttpMiddleware\SetLocale::class,
'flarum.admin.route_resolver',
HttpMiddleware\CheckCsrfToken::class, HttpMiddleware\CheckCsrfToken::class,
Middleware\RequireAdministrateAbility::class, Middleware\RequireAdministrateAbility::class,
HttpMiddleware\ReferrerPolicyHeader::class, HttpMiddleware\ReferrerPolicyHeader::class,
@@ -63,30 +45,6 @@ class AdminServiceProvider extends AbstractServiceProvider
]; ];
}); });
$this->container->bind('flarum.admin.error_handler', function (Container $container) {
return new HttpMiddleware\HandleErrors(
$container->make(Registry::class),
$container['flarum.config']->inDebugMode() ? $container->make(WhoopsFormatter::class) : $container->make(ViewFormatter::class),
$container->tagged(Reporter::class)
);
});
$this->container->bind('flarum.admin.route_resolver', function (Container $container) {
return new HttpMiddleware\ResolveRoute($container->make('flarum.admin.routes'));
});
$this->container->singleton('flarum.admin.handler', function (Container $container) {
$pipe = new MiddlewarePipe;
foreach ($container->make('flarum.admin.middleware') as $middleware) {
$pipe->pipe($container->make($middleware));
}
$pipe->pipe(new HttpMiddleware\ExecuteRoute());
return $pipe;
});
$this->container->bind('flarum.assets.admin', function (Container $container) { $this->container->bind('flarum.assets.admin', function (Container $container) {
/** @var \Flarum\Frontend\Assets $assets */ /** @var \Flarum\Frontend\Assets $assets */
$assets = $container->make('flarum.assets.factory')('admin'); $assets = $container->make('flarum.assets.factory')('admin');
@@ -115,18 +73,17 @@ class AdminServiceProvider extends AbstractServiceProvider
}); });
} }
public function boot(): void public function boot(Container $container, Dispatcher $events): void
{ {
$this->addRoutes($container);
$this->loadViewsFrom(__DIR__.'/../../views', 'flarum.admin'); $this->loadViewsFrom(__DIR__.'/../../views', 'flarum.admin');
$events = $this->container->make('events');
$events->listen( $events->listen(
[Enabled::class, Disabled::class, ClearingCache::class], [Enabled::class, Disabled::class, ClearingCache::class],
function () { function () use ($container) {
$recompile = new RecompileFrontendAssets( $recompile = new RecompileFrontendAssets(
$this->container->make('flarum.assets.admin'), $container->make('flarum.assets.admin'),
$this->container->make(LocaleManager::class) $container->make(LocaleManager::class)
); );
$recompile->flush(); $recompile->flush();
} }
@@ -134,21 +91,30 @@ class AdminServiceProvider extends AbstractServiceProvider
$events->listen( $events->listen(
Saved::class, Saved::class,
function (Saved $event) { function (Saved $event) use ($container) {
$recompile = new RecompileFrontendAssets( $recompile = new RecompileFrontendAssets(
$this->container->make('flarum.assets.admin'), $container->make('flarum.assets.admin'),
$this->container->make(LocaleManager::class) $container->make(LocaleManager::class)
); );
$recompile->whenSettingsSaved($event); $recompile->whenSettingsSaved($event);
} }
); );
} }
protected function populateRoutes(RouteCollection $routes): void protected function addRoutes(Container $container)
{ {
$factory = $this->container->make(RouteHandlerFactory::class); /** @var Router $router */
$router = $container->make(Router::class);
/** @var Config $config */
$config = $container->make(Config::class);
$callback = include __DIR__.'/routes.php'; $router->middlewareGroup('admin', $container->make('flarum.admin.middleware'));
$callback($routes, $factory);
$factory = $container->make(RouteHandlerFactory::class);
$router->middleware('admin')
->prefix($config->path('admin'))
->name('admin.')
->group(fn (Router $router) => (include __DIR__.'/routes.php')($router, $factory));
} }
} }

View File

@@ -20,8 +20,8 @@ use Flarum\User\User;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\ConnectionInterface; use Illuminate\Database\ConnectionInterface;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Psr\Http\Message\ServerRequestInterface as Request;
class AdminPayload class AdminPayload
{ {

View File

@@ -14,7 +14,7 @@ use Flarum\Foundation\Application;
use Flarum\Frontend\Document; use Flarum\Frontend\Document;
use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Psr\Http\Message\ServerRequestInterface as Request; use Illuminate\Http\Request;
class Index class Index
{ {
@@ -29,7 +29,7 @@ class Index
{ {
$extensions = $this->extensions->getExtensions(); $extensions = $this->extensions->getExtensions();
$extensionsEnabled = json_decode($this->settings->get('extensions_enabled', '{}'), true); $extensionsEnabled = json_decode($this->settings->get('extensions_enabled', '{}'), true);
$csrfToken = $request->getAttribute('session')->token(); $csrfToken = $request->attributes->get('session')->token();
$mysqlVersion = $document->payload['mysqlVersion']; $mysqlVersion = $document->payload['mysqlVersion'];
$phpVersion = $document->payload['phpVersion']; $phpVersion = $document->payload['phpVersion'];

View File

@@ -11,15 +11,13 @@ namespace Flarum\Admin\Controller;
use Flarum\Bus\Dispatcher; use Flarum\Bus\Dispatcher;
use Flarum\Extension\Command\ToggleExtension; use Flarum\Extension\Command\ToggleExtension;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\Http\UrlGenerator; use Flarum\Http\UrlGenerator;
use Illuminate\Support\Arr; use Illuminate\Http\RedirectResponse;
use Laminas\Diactoros\Response\RedirectResponse; use Illuminate\Http\Request;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface;
class UpdateExtensionController implements RequestHandlerInterface class UpdateExtensionController extends AbstractController
{ {
public function __construct( public function __construct(
protected UrlGenerator $url, protected UrlGenerator $url,
@@ -27,16 +25,15 @@ class UpdateExtensionController implements RequestHandlerInterface
) { ) {
} }
public function handle(Request $request): ResponseInterface public function __invoke(Request $request, string $name): RedirectResponse
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$enabled = (bool) (int) Arr::get($request->getParsedBody(), 'enabled'); $enabled = (bool) (int) $request->json('enabled');
$name = Arr::get($request->getQueryParams(), 'name');
$this->bus->dispatch( $this->bus->dispatch(
new ToggleExtension($actor, $name, $enabled) new ToggleExtension($actor, $name, $enabled)
); );
return new RedirectResponse($this->url->to('admin')->base()); return new RedirectResponse($this->url->base('admin'));
} }
} }

View File

@@ -9,17 +9,22 @@
namespace Flarum\Admin\Middleware; namespace Flarum\Admin\Middleware;
use Psr\Http\Message\ResponseInterface as Response; use Closure;
use Psr\Http\Message\ServerRequestInterface as Request; use Flarum\Http\Middleware\IlluminateMiddlewareInterface;
use Psr\Http\Server\MiddlewareInterface as Middleware; use Illuminate\Http\Request;
use Psr\Http\Server\RequestHandlerInterface as Handler; use Symfony\Component\HttpFoundation\Response;
class DisableBrowserCache implements Middleware class DisableBrowserCache implements IlluminateMiddlewareInterface
{ {
public function process(Request $request, Handler $handler): Response /**
* @inheritDoc
*/
public function handle(Request $request, Closure $next): Response
{ {
$response = $handler->handle($request); $response = $next($request);
return $response->withHeader('Cache-Control', 'max-age=0, no-store'); $response->headers->set('Cache-Control', 'max-age=0, no-store');
return $response;
} }
} }

View File

@@ -9,18 +9,18 @@
namespace Flarum\Admin\Middleware; namespace Flarum\Admin\Middleware;
use Closure;
use Flarum\Http\Middleware\IlluminateMiddlewareInterface;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Psr\Http\Message\ResponseInterface as Response; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface as Request; use Symfony\Component\HttpFoundation\Response;
use Psr\Http\Server\MiddlewareInterface as Middleware;
use Psr\Http\Server\RequestHandlerInterface as Handler;
class RequireAdministrateAbility implements Middleware class RequireAdministrateAbility implements IlluminateMiddlewareInterface
{ {
public function process(Request $request, Handler $handler): Response public function handle(Request $request, Closure $next): Response
{ {
RequestUtil::getActor($request)->assertAdmin(); RequestUtil::getActor($request)->assertAdmin();
return $handler->handle($request); return $next($request);
} }
} }

View File

@@ -9,19 +9,15 @@
use Flarum\Admin\Content\Index; use Flarum\Admin\Content\Index;
use Flarum\Admin\Controller\UpdateExtensionController; use Flarum\Admin\Controller\UpdateExtensionController;
use Flarum\Http\RouteCollection;
use Flarum\Http\RouteHandlerFactory; use Flarum\Http\RouteHandlerFactory;
use Flarum\Http\Router;
return function (RouteCollection $map, RouteHandlerFactory $route) { return function (Router $router, RouteHandlerFactory $factory) {
$map->get( $router
'/', ->get('/', $factory->toAdmin(Index::class))
'index', ->name('index');
$route->toAdmin(Index::class)
);
$map->post( $router
'/extensions/{name}', ->post('/extensions/{name}', $factory->toController(UpdateExtensionController::class))
'extensions.update', ->name('extensions.update');
$route->toController(UpdateExtensionController::class)
);
}; };

View File

@@ -14,35 +14,21 @@ use Flarum\Api\Serializer\AbstractSerializer;
use Flarum\Api\Serializer\BasicDiscussionSerializer; use Flarum\Api\Serializer\BasicDiscussionSerializer;
use Flarum\Api\Serializer\NotificationSerializer; use Flarum\Api\Serializer\NotificationSerializer;
use Flarum\Foundation\AbstractServiceProvider; use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\ErrorHandling\JsonApiFormatter; use Flarum\Foundation\Config;
use Flarum\Foundation\ErrorHandling\Registry;
use Flarum\Foundation\ErrorHandling\Reporter;
use Flarum\Http\Middleware as HttpMiddleware; use Flarum\Http\Middleware as HttpMiddleware;
use Flarum\Http\RouteCollection;
use Flarum\Http\RouteHandlerFactory; use Flarum\Http\RouteHandlerFactory;
use Flarum\Http\UrlGenerator; use Flarum\Http\Router;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\Container;
use Laminas\Stratigility\MiddlewarePipe; use Illuminate\Http\Request;
class ApiServiceProvider extends AbstractServiceProvider class ApiServiceProvider extends AbstractServiceProvider
{ {
public function register(): void public function register(): void
{ {
$this->container->extend(UrlGenerator::class, function (UrlGenerator $url, Container $container) {
return $url->addCollection('api', $container->make('flarum.api.routes'), 'api');
});
$this->container->singleton('flarum.api.routes', function () {
$routes = new RouteCollection;
$this->populateRoutes($routes);
return $routes;
});
$this->container->singleton('flarum.api.throttlers', function () { $this->container->singleton('flarum.api.throttlers', function () {
return [ return [
'bypassThrottlingAttribute' => function ($request) { 'bypassThrottlingAttribute' => function (Request $request) {
if ($request->getAttribute('bypassThrottling')) { if ($request->attributes->get('bypassThrottling')) {
return false; return false;
} }
} }
@@ -56,44 +42,17 @@ class ApiServiceProvider extends AbstractServiceProvider
$this->container->singleton('flarum.api.middleware', function () { $this->container->singleton('flarum.api.middleware', function () {
return [ return [
HttpMiddleware\InjectActorReference::class, HttpMiddleware\InjectActorReference::class,
'flarum.api.error_handler',
HttpMiddleware\ParseJsonBody::class,
Middleware\FakeHttpMethods::class, Middleware\FakeHttpMethods::class,
HttpMiddleware\StartSession::class, HttpMiddleware\StartSession::class,
HttpMiddleware\RememberFromCookie::class, HttpMiddleware\RememberFromCookie::class,
HttpMiddleware\AuthenticateWithSession::class, HttpMiddleware\AuthenticateWithSession::class,
HttpMiddleware\AuthenticateWithHeader::class, HttpMiddleware\AuthenticateWithHeader::class,
HttpMiddleware\SetLocale::class, HttpMiddleware\SetLocale::class,
'flarum.api.route_resolver',
HttpMiddleware\CheckCsrfToken::class, HttpMiddleware\CheckCsrfToken::class,
Middleware\ThrottleApi::class Middleware\ThrottleApi::class
]; ];
}); });
$this->container->bind('flarum.api.error_handler', function (Container $container) {
return new HttpMiddleware\HandleErrors(
$container->make(Registry::class),
new JsonApiFormatter($container['flarum.config']->inDebugMode()),
$container->tagged(Reporter::class)
);
});
$this->container->bind('flarum.api.route_resolver', function (Container $container) {
return new HttpMiddleware\ResolveRoute($container->make('flarum.api.routes'));
});
$this->container->singleton('flarum.api.handler', function (Container $container) {
$pipe = new MiddlewarePipe;
foreach ($this->container->make('flarum.api.middleware') as $middleware) {
$pipe->pipe($container->make($middleware));
}
$pipe->pipe(new HttpMiddleware\ExecuteRoute());
return $pipe;
});
$this->container->singleton('flarum.api.notification_serializers', function () { $this->container->singleton('flarum.api.notification_serializers', function () {
return [ return [
'discussionRenamed' => BasicDiscussionSerializer::class 'discussionRenamed' => BasicDiscussionSerializer::class
@@ -103,7 +62,6 @@ class ApiServiceProvider extends AbstractServiceProvider
$this->container->singleton('flarum.api_client.exclude_middleware', function () { $this->container->singleton('flarum.api_client.exclude_middleware', function () {
return [ return [
HttpMiddleware\InjectActorReference::class, HttpMiddleware\InjectActorReference::class,
HttpMiddleware\ParseJsonBody::class,
Middleware\FakeHttpMethods::class, Middleware\FakeHttpMethods::class,
HttpMiddleware\StartSession::class, HttpMiddleware\StartSession::class,
HttpMiddleware\AuthenticateWithSession::class, HttpMiddleware\AuthenticateWithSession::class,
@@ -113,27 +71,20 @@ class ApiServiceProvider extends AbstractServiceProvider
]; ];
}); });
$this->container->singleton(Client::class, function ($container) { $this->container->singleton(Client::class, function (Container $container) {
$pipe = new MiddlewarePipe;
$exclude = $container->make('flarum.api_client.exclude_middleware'); $exclude = $container->make('flarum.api_client.exclude_middleware');
$middlewareStack = array_filter($container->make('flarum.api.middleware'), function ($middlewareClass) use ($exclude) { $middlewareStack = array_filter($container->make('flarum.api.middleware'), function ($middlewareClass) use ($exclude) {
return ! in_array($middlewareClass, $exclude); return ! in_array($middlewareClass, $exclude);
}); });
foreach ($middlewareStack as $middleware) { return new Client($middlewareStack, $container);
$pipe->pipe($container->make($middleware));
}
$pipe->pipe(new HttpMiddleware\ExecuteRoute());
return new Client($pipe);
}); });
} }
public function boot(Container $container): void public function boot(Container $container): void
{ {
$this->addRoutes($container);
$this->setNotificationSerializers(); $this->setNotificationSerializers();
AbstractSerializeController::setContainer($container); AbstractSerializeController::setContainer($container);
@@ -150,11 +101,20 @@ class ApiServiceProvider extends AbstractServiceProvider
} }
} }
protected function populateRoutes(RouteCollection $routes): void protected function addRoutes(Container $container)
{ {
$factory = $this->container->make(RouteHandlerFactory::class); /** @var Router $router */
$router = $container->make(Router::class);
/** @var Config $config */
$config = $container->make(Config::class);
$callback = include __DIR__.'/routes.php'; $router->middlewareGroup('api', $container->make('flarum.api.middleware'));
$callback($routes, $factory);
$factory = $container->make(RouteHandlerFactory::class);
$router->middleware('api')
->prefix($config->path('api'))
->name('api.')
->group(fn (Router $router) => (include __DIR__.'/routes.php')($router, $factory));
} }
} }

View File

@@ -9,23 +9,27 @@
namespace Flarum\Api; namespace Flarum\Api;
use Flarum\Foundation\Config;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\Http\Router;
use Flarum\User\User; use Flarum\User\User;
use Laminas\Diactoros\ServerRequestFactory; use Illuminate\Contracts\Container\Container;
use Laminas\Diactoros\Uri; use Illuminate\Http\JsonResponse;
use Laminas\Stratigility\MiddlewarePipeInterface; use Illuminate\Http\Request;
use Psr\Http\Message\ResponseInterface; use Illuminate\Routing\Pipeline;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
class Client class Client
{ {
protected ?User $actor = null; protected ?User $actor = null;
protected ?ServerRequestInterface $parent = null; protected ?Request $parent = null;
protected array $queryParams = []; protected array $queryParams = [];
protected array $body = []; protected array $body = [];
public function __construct( public function __construct(
protected MiddlewarePipeInterface $pipe protected array $middlewareStack,
protected Container $container
) { ) {
} }
@@ -42,9 +46,15 @@ class Client
return $new; return $new;
} }
public function withParentRequest(ServerRequestInterface $parent): Client public function withParentRequest(ServerRequestInterface|Request $parent): Client
{ {
$new = clone $this; $new = clone $this;
// Convert the PSR-7 request to an Illuminate request.
if ($parent instanceof ServerRequestInterface) {
$parent = RequestUtil::toIlluminate($parent);
}
$new->parent = $parent; $new->parent = $parent;
return $new; return $new;
@@ -66,27 +76,27 @@ class Client
return $new; return $new;
} }
public function get(string $path): ResponseInterface public function get(string $path): JsonResponse
{ {
return $this->send('GET', $path); return $this->send('GET', $path);
} }
public function post(string $path): ResponseInterface public function post(string $path): JsonResponse
{ {
return $this->send('POST', $path); return $this->send('POST', $path);
} }
public function put(string $path): ResponseInterface public function put(string $path): JsonResponse
{ {
return $this->send('PUT', $path); return $this->send('PUT', $path);
} }
public function patch(string $path): ResponseInterface public function patch(string $path): JsonResponse
{ {
return $this->send('PATCH', $path); return $this->send('PATCH', $path);
} }
public function delete(string $path): ResponseInterface public function delete(string $path): JsonResponse
{ {
return $this->send('DELETE', $path); return $this->send('DELETE', $path);
} }
@@ -96,16 +106,26 @@ class Client
* *
* @internal * @internal
*/ */
public function send(string $method, string $path): ResponseInterface public function send(string $method, string $path): JsonResponse
{ {
$request = ServerRequestFactory::fromGlobals(null, $this->queryParams, $this->body) $parent = $this->parent ?: Request::createFromGlobals();
->withMethod($method) /** @var Config $config */
->withUri(new Uri($path)); $config = $this->container->make(Config::class);
$symfonyRequest = SymfonyRequest::create(
$config->path('api').$path,
$method,
$this->queryParams,
$parent->cookies->all(),
$parent->files->all(),
$parent->server->all(),
json_encode($this->body)
);
$request = Request::createFromBase($symfonyRequest);
if ($this->parent) { if ($this->parent) {
$request = $request $request->attributes->set('session', $this->parent->attributes->get('session'));
->withAttribute('ipAddress', $this->parent->getAttribute('ipAddress'))
->withAttribute('session', $this->parent->getAttribute('session'));
$request = RequestUtil::withActor($request, RequestUtil::getActor($this->parent)); $request = RequestUtil::withActor($request, RequestUtil::getActor($this->parent));
} }
@@ -114,6 +134,27 @@ class Client
$request = RequestUtil::withActor($request, $this->actor); $request = RequestUtil::withActor($request, $this->actor);
} }
return $this->pipe->handle($request); $originalRequest = $this->container->make('request');
return (new Pipeline($this->container))
->send($request)
->then(function (Request $request) use ($originalRequest) {
$this->container->instance('request', $request);
/** @var Router $router */
$router = $this->container->make(Router::class);
$originalMiddlewareGroup = $router->getMiddlewareGroups()['api'];
$router->middlewareGroup('api', $this->middlewareStack);
$response = $router->dispatch($request);
$router->middlewareGroup('api', $originalMiddlewareGroup);
$this->container->instance('request', $originalRequest);
return $response;
});
} }
} }

View File

@@ -9,13 +9,13 @@
namespace Flarum\Api\Controller; namespace Flarum\Api\Controller;
use Psr\Http\Message\ResponseInterface; use Illuminate\Http\JsonResponse;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
abstract class AbstractCreateController extends AbstractShowController abstract class AbstractCreateController extends AbstractShowController
{ {
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): JsonResponse
{ {
return parent::handle($request)->withStatus(201); return parent::__invoke($request)->setStatusCode(201);
} }
} }

View File

@@ -9,19 +9,19 @@
namespace Flarum\Api\Controller; namespace Flarum\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Illuminate\Http\Request;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
abstract class AbstractDeleteController implements RequestHandlerInterface abstract class AbstractDeleteController extends AbstractController
{ {
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): ResponseInterface
{ {
$this->delete($request); $this->delete($request);
return new EmptyResponse(204); return new EmptyResponse(204);
} }
abstract protected function delete(ServerRequestInterface $request): void; abstract protected function delete(Request $request): void;
} }

View File

@@ -9,7 +9,7 @@
namespace Flarum\Api\Controller; namespace Flarum\Api\Controller;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
use Tobscure\JsonApi\Collection; use Tobscure\JsonApi\Collection;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
use Tobscure\JsonApi\ElementInterface; use Tobscure\JsonApi\ElementInterface;
@@ -22,5 +22,5 @@ abstract class AbstractListController extends AbstractSerializeController
return new Collection($data, $serializer); return new Collection($data, $serializer);
} }
abstract protected function data(ServerRequestInterface $request, Document $document): iterable; abstract protected function data(Request $request, Document $document): iterable;
} }

View File

@@ -11,20 +11,19 @@ namespace Flarum\Api\Controller;
use Flarum\Api\JsonApiResponse; use Flarum\Api\JsonApiResponse;
use Flarum\Api\Serializer\AbstractSerializer; use Flarum\Api\Serializer\AbstractSerializer;
use Flarum\Http\Controller\AbstractController;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\Container;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Arr; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use InvalidArgumentException; use InvalidArgumentException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
use Tobscure\JsonApi\ElementInterface; use Tobscure\JsonApi\ElementInterface;
use Tobscure\JsonApi\Parameters; use Tobscure\JsonApi\Parameters;
use Tobscure\JsonApi\SerializerInterface; use Tobscure\JsonApi\SerializerInterface;
abstract class AbstractSerializeController implements RequestHandlerInterface abstract class AbstractSerializeController extends AbstractController
{ {
/** /**
* The name of the serializer class to output results with. * The name of the serializer class to output results with.
@@ -93,7 +92,7 @@ abstract class AbstractSerializeController implements RequestHandlerInterface
*/ */
protected static array $loadRelationCallables = []; protected static array $loadRelationCallables = [];
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): JsonResponse
{ {
$document = new Document; $document = new Document;
@@ -134,7 +133,7 @@ abstract class AbstractSerializeController implements RequestHandlerInterface
/** /**
* Get the data to be serialized and assigned to the response document. * Get the data to be serialized and assigned to the response document.
*/ */
abstract protected function data(ServerRequestInterface $request, Document $document): mixed; abstract protected function data(Request $request, Document $document): mixed;
/** /**
* Create a PHP JSON-API Element for output in the document. * Create a PHP JSON-API Element for output in the document.
@@ -180,7 +179,7 @@ abstract class AbstractSerializeController implements RequestHandlerInterface
/** /**
* Eager loads the required relationships. * Eager loads the required relationships.
*/ */
protected function loadRelations(Collection $models, array $relations, ServerRequestInterface $request = null): void protected function loadRelations(Collection $models, array $relations, Request $request = null): void
{ {
$addedRelations = $this->getRelationsToLoad($models); $addedRelations = $this->getRelationsToLoad($models);
$addedRelationCallables = $this->getRelationCallablesToLoad($models); $addedRelationCallables = $this->getRelationCallablesToLoad($models);
@@ -238,14 +237,14 @@ abstract class AbstractSerializeController implements RequestHandlerInterface
/** /**
* @throws \Tobscure\JsonApi\Exception\InvalidParameterException * @throws \Tobscure\JsonApi\Exception\InvalidParameterException
*/ */
protected function extractInclude(ServerRequestInterface $request): array protected function extractInclude(Request $request): array
{ {
$available = array_merge($this->include, $this->optionalInclude); $available = array_merge($this->include, $this->optionalInclude);
return $this->buildParameters($request)->getInclude($available) ?: $this->include; return $this->buildParameters($request)->getInclude($available) ?: $this->include;
} }
protected function extractFields(ServerRequestInterface $request): array protected function extractFields(Request $request): array
{ {
return $this->buildParameters($request)->getFields(); return $this->buildParameters($request)->getFields();
} }
@@ -253,7 +252,7 @@ abstract class AbstractSerializeController implements RequestHandlerInterface
/** /**
* @throws \Tobscure\JsonApi\Exception\InvalidParameterException * @throws \Tobscure\JsonApi\Exception\InvalidParameterException
*/ */
protected function extractSort(ServerRequestInterface $request): ?array protected function extractSort(Request $request): ?array
{ {
return $this->buildParameters($request)->getSort($this->sortFields) ?: $this->sort; return $this->buildParameters($request)->getSort($this->sortFields) ?: $this->sort;
} }
@@ -261,7 +260,7 @@ abstract class AbstractSerializeController implements RequestHandlerInterface
/** /**
* @throws \Tobscure\JsonApi\Exception\InvalidParameterException * @throws \Tobscure\JsonApi\Exception\InvalidParameterException
*/ */
protected function extractOffset(ServerRequestInterface $request): int protected function extractOffset(Request $request): int
{ {
return (int) $this->buildParameters($request)->getOffset($this->extractLimit($request)) ?: 0; return (int) $this->buildParameters($request)->getOffset($this->extractLimit($request)) ?: 0;
} }
@@ -269,24 +268,24 @@ abstract class AbstractSerializeController implements RequestHandlerInterface
/** /**
* @throws \Tobscure\JsonApi\Exception\InvalidParameterException * @throws \Tobscure\JsonApi\Exception\InvalidParameterException
*/ */
protected function extractLimit(ServerRequestInterface $request): int protected function extractLimit(Request $request): int
{ {
return (int) $this->buildParameters($request)->getLimit($this->maxLimit) ?: $this->limit; return (int) $this->buildParameters($request)->getLimit($this->maxLimit) ?: $this->limit;
} }
protected function extractFilter(ServerRequestInterface $request): array protected function extractFilter(Request $request): array
{ {
return $this->buildParameters($request)->getFilter() ?: []; return $this->buildParameters($request)->getFilter() ?: [];
} }
protected function buildParameters(ServerRequestInterface $request): Parameters protected function buildParameters(Request $request): Parameters
{ {
return new Parameters($request->getQueryParams()); return new Parameters($request->query());
} }
protected function sortIsDefault(ServerRequestInterface $request): bool protected function sortIsDefault(Request $request): bool
{ {
return ! Arr::get($request->getQueryParams(), 'sort'); return ! $request->query('sort');
} }
/** /**

View File

@@ -9,12 +9,13 @@
namespace Flarum\Api\Controller; namespace Flarum\Api\Controller;
use Tobscure\JsonApi\ElementInterface;
use Tobscure\JsonApi\Resource; use Tobscure\JsonApi\Resource;
use Tobscure\JsonApi\SerializerInterface; use Tobscure\JsonApi\SerializerInterface;
abstract class AbstractShowController extends AbstractSerializeController abstract class AbstractShowController extends AbstractSerializeController
{ {
protected function createElement(mixed $data, SerializerInterface $serializer): \Tobscure\JsonApi\ElementInterface protected function createElement(mixed $data, SerializerInterface $serializer): ElementInterface
{ {
return new Resource($data, $serializer); return new Resource($data, $serializer);
} }

View File

@@ -13,7 +13,7 @@ use Flarum\Foundation\Console\AssetsPublishCommand;
use Flarum\Foundation\Console\CacheClearCommand; use Flarum\Foundation\Console\CacheClearCommand;
use Flarum\Foundation\IOException; use Flarum\Foundation\IOException;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\NullOutput;
@@ -28,7 +28,7 @@ class ClearCacheController extends AbstractDeleteController
/** /**
* @throws IOException|\Flarum\User\Exception\PermissionDeniedException|\Symfony\Component\Console\Exception\ExceptionInterface * @throws IOException|\Flarum\User\Exception\PermissionDeniedException|\Symfony\Component\Console\Exception\ExceptionInterface
*/ */
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
RequestUtil::getActor($request)->assertAdmin(); RequestUtil::getActor($request)->assertAdmin();

View File

@@ -15,8 +15,7 @@ use Flarum\Http\Event\DeveloperTokenCreated;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Validation\Factory; use Illuminate\Contracts\Validation\Factory;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
/** /**
@@ -33,14 +32,14 @@ class CreateAccessTokenController extends AbstractCreateController
) { ) {
} }
public function data(ServerRequestInterface $request, Document $document): DeveloperAccessToken public function data(Request $request, Document $document): DeveloperAccessToken
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$actor->assertRegistered(); $actor->assertRegistered();
$actor->assertCan('createAccessToken'); $actor->assertCan('createAccessToken');
$title = Arr::get($request->getParsedBody(), 'data.attributes.title'); $title = $request->json('data.attributes.title');
$this->validation->make(compact('title'), [ $this->validation->make(compact('title'), [
'title' => 'required|string|max:255', 'title' => 'required|string|max:255',

View File

@@ -16,8 +16,7 @@ use Flarum\Discussion\Discussion;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class CreateDiscussionController extends AbstractCreateController class CreateDiscussionController extends AbstractCreateController
@@ -37,13 +36,13 @@ class CreateDiscussionController extends AbstractCreateController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): Discussion protected function data(Request $request, Document $document): Discussion
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$ipAddress = $request->getAttribute('ipAddress'); $ipAddress = $request->ip();
$discussion = $this->bus->dispatch( $discussion = $this->bus->dispatch(
new StartDiscussion($actor, Arr::get($request->getParsedBody(), 'data', []), $ipAddress) new StartDiscussion($actor, $request->json('data', []), $ipAddress)
); );
// After creating the discussion, we assume that the user has seen all // After creating the discussion, we assume that the user has seen all

View File

@@ -14,8 +14,7 @@ use Flarum\Group\Command\CreateGroup;
use Flarum\Group\Group; use Flarum\Group\Group;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class CreateGroupController extends AbstractCreateController class CreateGroupController extends AbstractCreateController
@@ -27,10 +26,10 @@ class CreateGroupController extends AbstractCreateController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): Group protected function data(Request $request, Document $document): Group
{ {
return $this->bus->dispatch( return $this->bus->dispatch(
new CreateGroup(RequestUtil::getActor($request), Arr::get($request->getParsedBody(), 'data', [])) new CreateGroup(RequestUtil::getActor($request), $request->json('data', []))
); );
} }
} }

View File

@@ -15,8 +15,8 @@ use Flarum\Http\RequestUtil;
use Flarum\Post\Command\PostReply; use Flarum\Post\Command\PostReply;
use Flarum\Post\CommentPost; use Flarum\Post\CommentPost;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class CreatePostController extends AbstractCreateController class CreatePostController extends AbstractCreateController
@@ -35,12 +35,12 @@ class CreatePostController extends AbstractCreateController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): CommentPost protected function data(Request $request, Document $document): CommentPost
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$data = Arr::get($request->getParsedBody(), 'data', []); $data = $request->json('data', []);
$discussionId = (int) Arr::get($data, 'relationships.discussion.data.id'); $discussionId = (int) Arr::get($data, 'relationships.discussion.data.id');
$ipAddress = $request->getAttribute('ipAddress'); $ipAddress = $request->ip();
/** @var CommentPost $post */ /** @var CommentPost $post */
$post = $this->bus->dispatch( $post = $this->bus->dispatch(

View File

@@ -9,24 +9,22 @@
namespace Flarum\Api\Controller; namespace Flarum\Api\Controller;
use Flarum\Http\Controller\AbstractController;
use Flarum\Http\RememberAccessToken; use Flarum\Http\RememberAccessToken;
use Flarum\Http\SessionAccessToken; use Flarum\Http\SessionAccessToken;
use Flarum\User\Exception\NotAuthenticatedException; use Flarum\User\Exception\NotAuthenticatedException;
use Flarum\User\UserRepository; use Flarum\User\UserRepository;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher; use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher; use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\JsonResponse;
use Laminas\Diactoros\Response\JsonResponse; use Illuminate\Http\Request;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
/** /**
* Not to be confused with the CreateAccessTokenController, * Not to be confused with the CreateAccessTokenController,
* this controller is used to authenticate a user with credentials, * this controller is used to authenticate a user with credentials,
* and return a system generated session-type access token. * and return a system generated session-type access token.
*/ */
class CreateTokenController implements RequestHandlerInterface class CreateTokenController extends AbstractController
{ {
public function __construct( public function __construct(
protected UserRepository $users, protected UserRepository $users,
@@ -35,12 +33,10 @@ class CreateTokenController implements RequestHandlerInterface
) { ) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function __invoke(Request $request): JsonResponse
{ {
$body = $request->getParsedBody(); $identification = $request->json('identification');
$password = $request->json('password');
$identification = Arr::get($body, 'identification');
$password = Arr::get($body, 'password');
$user = $identification $user = $identification
? $this->users->findByIdentification($identification) ? $this->users->findByIdentification($identification)
@@ -50,7 +46,7 @@ class CreateTokenController implements RequestHandlerInterface
throw new NotAuthenticatedException; throw new NotAuthenticatedException;
} }
if (Arr::get($body, 'remember')) { if ($request->json('remember')) {
$token = RememberAccessToken::generate($user->id); $token = RememberAccessToken::generate($user->id);
} else { } else {
$token = SessionAccessToken::generate($user->id); $token = SessionAccessToken::generate($user->id);

View File

@@ -14,8 +14,7 @@ use Flarum\Http\RequestUtil;
use Flarum\User\Command\RegisterUser; use Flarum\User\Command\RegisterUser;
use Flarum\User\User; use Flarum\User\User;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class CreateUserController extends AbstractCreateController class CreateUserController extends AbstractCreateController
@@ -27,10 +26,10 @@ class CreateUserController extends AbstractCreateController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): User protected function data(Request $request, Document $document): User
{ {
return $this->bus->dispatch( return $this->bus->dispatch(
new RegisterUser(RequestUtil::getActor($request), Arr::get($request->getParsedBody(), 'data', [])) new RegisterUser(RequestUtil::getActor($request), $request->json('data', []))
); );
} }
} }

View File

@@ -14,22 +14,21 @@ use Flarum\Http\RequestUtil;
use Flarum\User\Exception\PermissionDeniedException; use Flarum\User\Exception\PermissionDeniedException;
use Illuminate\Contracts\Session\Session; use Illuminate\Contracts\Session\Session;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
class DeleteAccessTokenController extends AbstractDeleteController class DeleteAccessTokenController extends AbstractDeleteController
{ {
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$id = Arr::get($request->getQueryParams(), 'id'); $id = $request->route('id');
$actor->assertRegistered(); $actor->assertRegistered();
$token = AccessToken::query()->findOrFail($id); $token = AccessToken::query()->findOrFail($id);
/** @var Session|null $session */ /** @var Session|null $session */
$session = $request->getAttribute('session'); $session = $request->attributes->get('session');
// Current session should only be terminated through logout. // Current session should only be terminated through logout.
if ($session && $token->token === $session->get('access_token')) { if ($session && $token->token === $session->get('access_token')) {

View File

@@ -12,7 +12,7 @@ namespace Flarum\Api\Controller;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\Notification\Command\DeleteAllNotifications; use Flarum\Notification\Command\DeleteAllNotifications;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
class DeleteAllNotificationsController extends AbstractDeleteController class DeleteAllNotificationsController extends AbstractDeleteController
{ {
@@ -21,7 +21,7 @@ class DeleteAllNotificationsController extends AbstractDeleteController
) { ) {
} }
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
$this->bus->dispatch( $this->bus->dispatch(
new DeleteAllNotifications(RequestUtil::getActor($request)) new DeleteAllNotifications(RequestUtil::getActor($request))

View File

@@ -13,8 +13,7 @@ use Flarum\Api\Serializer\UserSerializer;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\User\Command\DeleteAvatar; use Flarum\User\Command\DeleteAvatar;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document; use Tobscure\JsonApi\Document;
class DeleteAvatarController extends AbstractShowController class DeleteAvatarController extends AbstractShowController
@@ -26,10 +25,10 @@ class DeleteAvatarController extends AbstractShowController
) { ) {
} }
protected function data(ServerRequestInterface $request, Document $document): mixed protected function data(Request $request, Document $document): mixed
{ {
return $this->bus->dispatch( return $this->bus->dispatch(
new DeleteAvatar(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request)) new DeleteAvatar($request->route('id'), RequestUtil::getActor($request))
); );
} }
} }

View File

@@ -12,8 +12,7 @@ namespace Flarum\Api\Controller;
use Flarum\Discussion\Command\DeleteDiscussion; use Flarum\Discussion\Command\DeleteDiscussion;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
class DeleteDiscussionController extends AbstractDeleteController class DeleteDiscussionController extends AbstractDeleteController
{ {
@@ -22,11 +21,11 @@ class DeleteDiscussionController extends AbstractDeleteController
) { ) {
} }
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
$id = Arr::get($request->getQueryParams(), 'id'); $id = $request->route('id');
$actor = RequestUtil::getActor($request); $actor = RequestUtil::getActor($request);
$input = $request->getParsedBody(); $input = $request->json()->all();
$this->bus->dispatch( $this->bus->dispatch(
new DeleteDiscussion($id, $actor, $input) new DeleteDiscussion($id, $actor, $input)

View File

@@ -13,7 +13,7 @@ use Flarum\Http\RequestUtil;
use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Filesystem\Factory; use Illuminate\Contracts\Filesystem\Factory;
use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Contracts\Filesystem\Filesystem;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
class DeleteFaviconController extends AbstractDeleteController class DeleteFaviconController extends AbstractDeleteController
{ {
@@ -26,7 +26,7 @@ class DeleteFaviconController extends AbstractDeleteController
$this->uploadDir = $filesystemFactory->disk('flarum-assets'); $this->uploadDir = $filesystemFactory->disk('flarum-assets');
} }
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
RequestUtil::getActor($request)->assertAdmin(); RequestUtil::getActor($request)->assertAdmin();

View File

@@ -12,8 +12,7 @@ namespace Flarum\Api\Controller;
use Flarum\Group\Command\DeleteGroup; use Flarum\Group\Command\DeleteGroup;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
class DeleteGroupController extends AbstractDeleteController class DeleteGroupController extends AbstractDeleteController
{ {
@@ -22,10 +21,10 @@ class DeleteGroupController extends AbstractDeleteController
) { ) {
} }
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
$this->bus->dispatch( $this->bus->dispatch(
new DeleteGroup(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request)) new DeleteGroup($request->route('id'), RequestUtil::getActor($request))
); );
} }
} }

View File

@@ -13,7 +13,7 @@ use Flarum\Http\RequestUtil;
use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Filesystem\Factory; use Illuminate\Contracts\Filesystem\Factory;
use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Contracts\Filesystem\Filesystem;
use Psr\Http\Message\ServerRequestInterface; use Illuminate\Http\Request;
class DeleteLogoController extends AbstractDeleteController class DeleteLogoController extends AbstractDeleteController
{ {
@@ -26,7 +26,7 @@ class DeleteLogoController extends AbstractDeleteController
$this->uploadDir = $filesystemFactory->disk('flarum-assets'); $this->uploadDir = $filesystemFactory->disk('flarum-assets');
} }
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
RequestUtil::getActor($request)->assertAdmin(); RequestUtil::getActor($request)->assertAdmin();

View File

@@ -12,8 +12,7 @@ namespace Flarum\Api\Controller;
use Flarum\Http\RequestUtil; use Flarum\Http\RequestUtil;
use Flarum\Post\Command\DeletePost; use Flarum\Post\Command\DeletePost;
use Illuminate\Contracts\Bus\Dispatcher; use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Arr; use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
class DeletePostController extends AbstractDeleteController class DeletePostController extends AbstractDeleteController
{ {
@@ -22,10 +21,10 @@ class DeletePostController extends AbstractDeleteController
) { ) {
} }
protected function delete(ServerRequestInterface $request): void protected function delete(Request $request): void
{ {
$this->bus->dispatch( $this->bus->dispatch(
new DeletePost(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request)) new DeletePost($request->route('id'), RequestUtil::getActor($request))
); );
} }
} }

Some files were not shown because too many files have changed in this diff Show More