1
0
mirror of https://github.com/flarum/core.git synced 2025-08-05 07:57:46 +02:00

feat: context current endpoint helpers

This commit is contained in:
Sami Mazouz
2024-03-02 12:45:58 +01:00
parent 3644d81829
commit 06364a4367
9 changed files with 63 additions and 33 deletions

View File

@@ -42,7 +42,7 @@ class FlagResource extends AbstractDatabaseResource
public function query(Context $context): object public function query(Context $context): object
{ {
if ($context->collection instanceof self && $context->endpoint instanceof Endpoint\Index) { if ($context->listing(self::class)) {
$query = Flag::query()->groupBy('post_id'); $query = Flag::query()->groupBy('post_id');
$this->scope($query, $context); $this->scope($query, $context);
@@ -60,7 +60,7 @@ class FlagResource extends AbstractDatabaseResource
public function newModel(Context $context): object public function newModel(Context $context): object
{ {
if ($context->collection instanceof self && $context->endpoint instanceof Endpoint\Create) { if ($context->creating(self::class)) {
Flag::unguard(); Flag::unguard();
return Flag::query()->firstOrNew([ return Flag::query()->firstOrNew([
@@ -118,7 +118,7 @@ class FlagResource extends AbstractDatabaseResource
Schema\Relationship\ToOne::make('post') Schema\Relationship\ToOne::make('post')
->includable() ->includable()
->writable(fn (Flag $flag, FlarumContext $context) => $context->endpoint instanceof Endpoint\Create) ->writable(fn (Flag $flag, FlarumContext $context) => $context->creating())
->set(function (Flag $flag, Post $post, FlarumContext $context) { ->set(function (Flag $flag, Post $post, FlarumContext $context) {
if (! ($post instanceof CommentPost)) { if (! ($post instanceof CommentPost)) {
throw new InvalidParameterException; throw new InvalidParameterException;

View File

@@ -13,7 +13,7 @@ class UserResourceFields
{ {
return [ return [
Schema\Str::make('subscription') Schema\Str::make('subscription')
->writable(fn (Discussion $discussion, Context $context) => $context->endpoint instanceof Endpoint\Update && ! $context->getActor()->isGuest()) ->writable(fn (Discussion $discussion, Context $context) => $context->updating() && ! $context->getActor()->isGuest())
->nullable() ->nullable()
->get(fn (Discussion $discussion) => $discussion->state?->subscription) ->get(fn (Discussion $discussion) => $discussion->state?->subscription)
->set(function (Discussion $discussion, ?string $subscription, Context $context) { ->set(function (Discussion $discussion, ?string $subscription, Context $context) {

View File

@@ -35,10 +35,7 @@ class TagResource extends AbstractDatabaseResource
{ {
$query->whereVisibleTo($context->getActor()); $query->whereVisibleTo($context->getActor());
if ($context->collection instanceof self && ( if ($context->listing(self::class) || $context->showing(self::class)) {
$context->endpoint instanceof Endpoint\Index
|| $context->endpoint instanceof Endpoint\Show
)) {
$query->withStateFor($context->getActor()); $query->withStateFor($context->getActor());
} }
} }
@@ -143,7 +140,7 @@ class TagResource extends AbstractDatabaseResource
public function saving(object $model, Context $context): ?object public function saving(object $model, Context $context): ?object
{ {
if (! $context->endpoint instanceof Endpoint\Create) { if (! $context->creating(self::class)) {
$this->events->dispatch( $this->events->dispatch(
new Saving($model, $context->getActor(), $context->body()) new Saving($model, $context->getActor(), $context->body())
); );

View File

@@ -7,13 +7,23 @@ use Flarum\Search\SearchResults;
use Flarum\User\User; use Flarum\User\User;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\Container;
use Tobyz\JsonApiServer\Context as BaseContext; use Tobyz\JsonApiServer\Context as BaseContext;
use Tobyz\JsonApiServer\Resource\Collection;
use Tobyz\JsonApiServer\Resource\Resource; use Tobyz\JsonApiServer\Resource\Resource;
class Context extends BaseContext class Context extends BaseContext
{ {
protected ?SearchResults $search = null; protected ?SearchResults $search = null;
protected int|string|null $modelId = null; protected int|string|null $modelId = null;
/**
* Data passed internally when reusing resource endpoint logic.
*/
protected array $internal = []; protected array $internal = [];
/**
* Parameters mutated on the current instance.
* Useful for passing information between different field callbacks.
*/
protected array $parameters = []; protected array $parameters = [];
public function withModelId(int|string|null $id): static public function withModelId(int|string|null $id): static
@@ -67,4 +77,29 @@ class Context extends BaseContext
{ {
return $this->parameters[$key] ?? $default; return $this->parameters[$key] ?? $default;
} }
public function creating(string|null $resource = null): bool
{
return $this->endpoint instanceof Endpoint\Create && (! $resource || is_a($this->collection, $resource));
}
public function updating(string|null $resource = null): bool
{
return $this->endpoint instanceof Endpoint\Update && (! $resource || is_a($this->collection, $resource));
}
public function deleting(string|null $resource = null): bool
{
return $this->endpoint instanceof Endpoint\Delete && (! $resource || is_a($this->collection, $resource));
}
public function showing(string|null $resource = null): bool
{
return $this->endpoint instanceof Endpoint\Show && (! $resource || is_a($this->collection, $resource));
}
public function listing(string|null $resource = null): bool
{
return $this->endpoint instanceof Endpoint\Index && (! $resource || is_a($this->collection, $resource));
}
} }

View File

@@ -41,7 +41,7 @@ class AccessTokenResource extends AbstractDatabaseResource
public function newModel(\Tobyz\JsonApiServer\Context $context): object public function newModel(\Tobyz\JsonApiServer\Context $context): object
{ {
if ($context->endpoint instanceof Endpoint\Create && $context->collection instanceof self) { if ($context->creating(self::class)) {
$token = DeveloperAccessToken::make($context->getActor()->id); $token = DeveloperAccessToken::make($context->getActor()->id);
$token->last_activity_at = null; $token->last_activity_at = null;
return $token; return $token;

View File

@@ -105,7 +105,7 @@ class DiscussionResource extends AbstractDatabaseResource
Schema\Str::make('title') Schema\Str::make('title')
->requiredOnCreate() ->requiredOnCreate()
->writable(function (Discussion $discussion, Context $context) { ->writable(function (Discussion $discussion, Context $context) {
return $context->endpoint instanceof Endpoint\Create return $context->creating()
|| $context->getActor()->can('rename', $discussion); || $context->getActor()->can('rename', $discussion);
}) })
->minLength(3) ->minLength(3)
@@ -145,7 +145,7 @@ class DiscussionResource extends AbstractDatabaseResource
Schema\Boolean::make('isHidden') Schema\Boolean::make('isHidden')
->visible(fn (Discussion $discussion) => $discussion->hidden_at !== null) ->visible(fn (Discussion $discussion) => $discussion->hidden_at !== null)
->writable(function (Discussion $discussion, Context $context) { ->writable(function (Discussion $discussion, Context $context) {
return $context->endpoint instanceof Endpoint\Update return $context->updating()
&& $context->getActor()->can('hide', $discussion); && $context->getActor()->can('hide', $discussion);
}) })
->set(function (Discussion $discussion, bool $value, Context $context) { ->set(function (Discussion $discussion, bool $value, Context $context) {
@@ -168,7 +168,7 @@ class DiscussionResource extends AbstractDatabaseResource
return $discussion->state?->last_read_post_number; return $discussion->state?->last_read_post_number;
}) })
->writable(function (Discussion $discussion, Context $context) { ->writable(function (Discussion $discussion, Context $context) {
return $context->endpoint instanceof Endpoint\Update; return $context->updating();
}) })
->set(function (Discussion $discussion, int $value, Context $context) { ->set(function (Discussion $discussion, int $value, Context $context) {
if ($readNumber = Arr::get($context->body(), 'data.attributes.lastReadPostNumber')) { if ($readNumber = Arr::get($context->body(), 'data.attributes.lastReadPostNumber')) {
@@ -194,11 +194,11 @@ class DiscussionResource extends AbstractDatabaseResource
->type('posts'), ->type('posts'),
Schema\Relationship\ToMany::make('posts') Schema\Relationship\ToMany::make('posts')
->withLinkage(function (Context $context) { ->withLinkage(function (Context $context) {
return $context->collection instanceof self && $context->endpoint instanceof Endpoint\Show; return $context->showing(self::class);
}) })
->includable() ->includable()
->get(function (Discussion $discussion, Context $context) { ->get(function (Discussion $discussion, Context $context) {
$showingDiscussion = $context->collection instanceof self && $context->endpoint instanceof Endpoint\Show; $showingDiscussion = $context->showing(self::class);
if (! $showingDiscussion) { if (! $showingDiscussion) {
return fn () => $discussion->posts->all(); return fn () => $discussion->posts->all();
@@ -235,7 +235,7 @@ class DiscussionResource extends AbstractDatabaseResource
return $allPosts; return $allPosts;
}), }),
Schema\Relationship\ToOne::make('mostRelevantPost') Schema\Relationship\ToOne::make('mostRelevantPost')
->visible(fn (Discussion $model, Context $context) => $context->endpoint instanceof Endpoint\Index) ->visible(fn (Discussion $model, Context $context) => $context->listing())
->includable() ->includable()
->type('posts'), ->type('posts'),
Schema\Relationship\ToOne::make('hideUser') Schema\Relationship\ToOne::make('hideUser')
@@ -284,7 +284,7 @@ class DiscussionResource extends AbstractDatabaseResource
/** @param Discussion $model */ /** @param Discussion $model */
protected function saveModel(Model $model, \Tobyz\JsonApiServer\Context $context): void protected function saveModel(Model $model, \Tobyz\JsonApiServer\Context $context): void
{ {
if ($context->endpoint instanceof Endpoint\Create) { if ($context->creating()) {
$model->newQuery()->getConnection()->transaction(function () use ($model, $context) { $model->newQuery()->getConnection()->transaction(function () use ($model, $context) {
$model->save(); $model->save();

View File

@@ -33,7 +33,7 @@ class NotificationResource extends AbstractDatabaseResource
public function query(\Tobyz\JsonApiServer\Context $context): object public function query(\Tobyz\JsonApiServer\Context $context): object
{ {
if ($context->collection instanceof self && $context->endpoint instanceof Endpoint\Index) { if ($context->listing(self::class)) {
/** @var Pagination $pagination */ /** @var Pagination $pagination */
$pagination = ($context->endpoint->paginationResolver)($context); $pagination = ($context->endpoint->paginationResolver)($context);

View File

@@ -50,7 +50,7 @@ class PostResource extends AbstractDatabaseResource
public function newModel(\Tobyz\JsonApiServer\Context $context): object public function newModel(\Tobyz\JsonApiServer\Context $context): object
{ {
if ($context->endpoint instanceof Endpoint\Create && $context->collection instanceof self) { if ($context->creating(self::class)) {
$post = new CommentPost(); $post = new CommentPost();
$post->user_id = $context->getActor()->id; $post->user_id = $context->getActor()->id;
@@ -149,7 +149,7 @@ class PostResource extends AbstractDatabaseResource
Schema\Integer::make('number'), Schema\Integer::make('number'),
Schema\DateTime::make('createdAt') Schema\DateTime::make('createdAt')
->writable(function (Post $post, Context $context) { ->writable(function (Post $post, Context $context) {
return $context->endpoint instanceof Endpoint\Create return $context->creating()
&& $context->getActor()->isAdmin(); && $context->getActor()->isAdmin();
}) })
->default(fn () => Carbon::now()), ->default(fn () => Carbon::now()),
@@ -159,9 +159,9 @@ class PostResource extends AbstractDatabaseResource
Schema\Str::make('content') Schema\Str::make('content')
->requiredOnCreate() ->requiredOnCreate()
->writable(function (Post $post, Context $context) { ->writable(function (Post $post, Context $context) {
return $context->endpoint instanceof Endpoint\Create || ( return $context->creating() || (
$post instanceof CommentPost $post instanceof CommentPost
&& $context->endpoint instanceof Endpoint\Update && $context->updating()
&& $context->getActor()->can('edit', $post) && $context->getActor()->can('edit', $post)
); );
}) })
@@ -172,9 +172,9 @@ class PostResource extends AbstractDatabaseResource
}) })
->set(function (Post $post, string $value, Context $context) { ->set(function (Post $post, string $value, Context $context) {
if ($post instanceof CommentPost) { if ($post instanceof CommentPost) {
if ($context->endpoint instanceof Endpoint\Create) { if ($context->creating()) {
$post->setContentAttribute($value, $context->getActor()); $post->setContentAttribute($value, $context->getActor());
} elseif ($context->endpoint instanceof Endpoint\Update) { } elseif ($context->updating()) {
$post->revise($value, $context->getActor()); $post->revise($value, $context->getActor());
} }
} }
@@ -215,7 +215,7 @@ class PostResource extends AbstractDatabaseResource
Schema\Boolean::make('isHidden') Schema\Boolean::make('isHidden')
->visible(fn (Post $post) => $post->hidden_at !== null) ->visible(fn (Post $post) => $post->hidden_at !== null)
->writable(function (Post $post, Context $context) { ->writable(function (Post $post, Context $context) {
return $context->endpoint instanceof Endpoint\Update return $context->updating()
&& $context->getActor()->can('hide', $post); && $context->getActor()->can('hide', $post);
}) })
->set(function (Post $post, bool $value, Context $context) { ->set(function (Post $post, bool $value, Context $context) {

View File

@@ -124,7 +124,7 @@ class UserResource extends AbstractDatabaseResource
->minLength(3) ->minLength(3)
->maxLength(30) ->maxLength(30)
->writable(function (User $user, Context $context) { ->writable(function (User $user, Context $context) {
return $context->endpoint instanceof Endpoint\Create return $context->creating()
|| $context->getActor()->can('editCredentials', $user); || $context->getActor()->can('editCredentials', $user);
}) })
->set(function (User $user, string $value) { ->set(function (User $user, string $value) {
@@ -146,7 +146,7 @@ class UserResource extends AbstractDatabaseResource
|| $context->getActor()->id === $user->id; || $context->getActor()->id === $user->id;
}) })
->writable(function (User $user, Context $context) { ->writable(function (User $user, Context $context) {
return $context->endpoint instanceof Endpoint\Create return $context->creating()
|| $context->getActor()->can('editCredentials', $user) || $context->getActor()->can('editCredentials', $user)
|| $context->getActor()->id === $user->id; || $context->getActor()->id === $user->id;
}) })
@@ -171,9 +171,7 @@ class UserResource extends AbstractDatabaseResource
}) })
->writable(fn (User $user, Context $context) => $context->getActor()->isAdmin()) ->writable(fn (User $user, Context $context) => $context->getActor()->isAdmin())
->set(function (User $user, $value, Context $context) { ->set(function (User $user, $value, Context $context) {
$editing = $context->endpoint instanceof Endpoint\Update; if (! empty($value) && ($context->updating() || $context->getActor()->isAdmin())) {
if (! empty($value) && ($editing || $context->getActor()->isAdmin())) {
$user->activate(); $user->activate();
} }
}), }),
@@ -185,7 +183,7 @@ class UserResource extends AbstractDatabaseResource
->minLength(8) ->minLength(8)
->visible(false) ->visible(false)
->writable(function (User $user, Context $context) { ->writable(function (User $user, Context $context) {
return $context->endpoint instanceof Endpoint\Create return $context->creating()
|| $context->getActor()->can('editCredentials', $user); || $context->getActor()->can('editCredentials', $user);
}) })
->set(function (User $user, ?string $value) { ->set(function (User $user, ?string $value) {
@@ -195,7 +193,7 @@ class UserResource extends AbstractDatabaseResource
Schema\Str::make('token') Schema\Str::make('token')
->visible(false) ->visible(false)
->writable(function (User $user, Context $context) { ->writable(function (User $user, Context $context) {
return $context->endpoint instanceof Endpoint\Create; return $context->creating();
}) })
->set(function (User $user, ?string $value, Context $context) { ->set(function (User $user, ?string $value, Context $context) {
if ($value) { if ($value) {
@@ -273,7 +271,7 @@ class UserResource extends AbstractDatabaseResource
}), }),
Schema\Relationship\ToMany::make('groups') Schema\Relationship\ToMany::make('groups')
->writable(fn (User $user, Context $context) => $context->endpoint instanceof Endpoint\Update && $context->getActor()->can('editGroups', $user)) ->writable(fn (User $user, Context $context) => $context->updating() && $context->getActor()->can('editGroups', $user))
->includable() ->includable()
->get(function (User $user, Context $context) { ->get(function (User $user, Context $context) {
if ($context->getActor()->can('viewHiddenGroups')) { if ($context->getActor()->can('viewHiddenGroups')) {