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:
@@ -42,7 +42,7 @@ class FlagResource extends AbstractDatabaseResource
|
||||
|
||||
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');
|
||||
|
||||
$this->scope($query, $context);
|
||||
@@ -60,7 +60,7 @@ class FlagResource extends AbstractDatabaseResource
|
||||
|
||||
public function newModel(Context $context): object
|
||||
{
|
||||
if ($context->collection instanceof self && $context->endpoint instanceof Endpoint\Create) {
|
||||
if ($context->creating(self::class)) {
|
||||
Flag::unguard();
|
||||
|
||||
return Flag::query()->firstOrNew([
|
||||
@@ -118,7 +118,7 @@ class FlagResource extends AbstractDatabaseResource
|
||||
|
||||
Schema\Relationship\ToOne::make('post')
|
||||
->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) {
|
||||
if (! ($post instanceof CommentPost)) {
|
||||
throw new InvalidParameterException;
|
||||
|
@@ -13,7 +13,7 @@ class UserResourceFields
|
||||
{
|
||||
return [
|
||||
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()
|
||||
->get(fn (Discussion $discussion) => $discussion->state?->subscription)
|
||||
->set(function (Discussion $discussion, ?string $subscription, Context $context) {
|
||||
|
@@ -35,10 +35,7 @@ class TagResource extends AbstractDatabaseResource
|
||||
{
|
||||
$query->whereVisibleTo($context->getActor());
|
||||
|
||||
if ($context->collection instanceof self && (
|
||||
$context->endpoint instanceof Endpoint\Index
|
||||
|| $context->endpoint instanceof Endpoint\Show
|
||||
)) {
|
||||
if ($context->listing(self::class) || $context->showing(self::class)) {
|
||||
$query->withStateFor($context->getActor());
|
||||
}
|
||||
}
|
||||
@@ -143,7 +140,7 @@ class TagResource extends AbstractDatabaseResource
|
||||
|
||||
public function saving(object $model, Context $context): ?object
|
||||
{
|
||||
if (! $context->endpoint instanceof Endpoint\Create) {
|
||||
if (! $context->creating(self::class)) {
|
||||
$this->events->dispatch(
|
||||
new Saving($model, $context->getActor(), $context->body())
|
||||
);
|
||||
|
@@ -7,13 +7,23 @@ use Flarum\Search\SearchResults;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Tobyz\JsonApiServer\Context as BaseContext;
|
||||
use Tobyz\JsonApiServer\Resource\Collection;
|
||||
use Tobyz\JsonApiServer\Resource\Resource;
|
||||
|
||||
class Context extends BaseContext
|
||||
{
|
||||
protected ?SearchResults $search = null;
|
||||
protected int|string|null $modelId = null;
|
||||
|
||||
/**
|
||||
* Data passed internally when reusing resource endpoint logic.
|
||||
*/
|
||||
protected array $internal = [];
|
||||
|
||||
/**
|
||||
* Parameters mutated on the current instance.
|
||||
* Useful for passing information between different field callbacks.
|
||||
*/
|
||||
protected array $parameters = [];
|
||||
|
||||
public function withModelId(int|string|null $id): static
|
||||
@@ -67,4 +77,29 @@ class Context extends BaseContext
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ class AccessTokenResource extends AbstractDatabaseResource
|
||||
|
||||
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->last_activity_at = null;
|
||||
return $token;
|
||||
|
@@ -105,7 +105,7 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
Schema\Str::make('title')
|
||||
->requiredOnCreate()
|
||||
->writable(function (Discussion $discussion, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Create
|
||||
return $context->creating()
|
||||
|| $context->getActor()->can('rename', $discussion);
|
||||
})
|
||||
->minLength(3)
|
||||
@@ -145,7 +145,7 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
Schema\Boolean::make('isHidden')
|
||||
->visible(fn (Discussion $discussion) => $discussion->hidden_at !== null)
|
||||
->writable(function (Discussion $discussion, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Update
|
||||
return $context->updating()
|
||||
&& $context->getActor()->can('hide', $discussion);
|
||||
})
|
||||
->set(function (Discussion $discussion, bool $value, Context $context) {
|
||||
@@ -168,7 +168,7 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
return $discussion->state?->last_read_post_number;
|
||||
})
|
||||
->writable(function (Discussion $discussion, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Update;
|
||||
return $context->updating();
|
||||
})
|
||||
->set(function (Discussion $discussion, int $value, Context $context) {
|
||||
if ($readNumber = Arr::get($context->body(), 'data.attributes.lastReadPostNumber')) {
|
||||
@@ -194,11 +194,11 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
->type('posts'),
|
||||
Schema\Relationship\ToMany::make('posts')
|
||||
->withLinkage(function (Context $context) {
|
||||
return $context->collection instanceof self && $context->endpoint instanceof Endpoint\Show;
|
||||
return $context->showing(self::class);
|
||||
})
|
||||
->includable()
|
||||
->get(function (Discussion $discussion, Context $context) {
|
||||
$showingDiscussion = $context->collection instanceof self && $context->endpoint instanceof Endpoint\Show;
|
||||
$showingDiscussion = $context->showing(self::class);
|
||||
|
||||
if (! $showingDiscussion) {
|
||||
return fn () => $discussion->posts->all();
|
||||
@@ -235,7 +235,7 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
return $allPosts;
|
||||
}),
|
||||
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()
|
||||
->type('posts'),
|
||||
Schema\Relationship\ToOne::make('hideUser')
|
||||
@@ -284,7 +284,7 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
/** @param Discussion $model */
|
||||
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->save();
|
||||
|
||||
|
@@ -33,7 +33,7 @@ class NotificationResource extends AbstractDatabaseResource
|
||||
|
||||
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 */
|
||||
$pagination = ($context->endpoint->paginationResolver)($context);
|
||||
|
||||
|
@@ -50,7 +50,7 @@ class PostResource extends AbstractDatabaseResource
|
||||
|
||||
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->user_id = $context->getActor()->id;
|
||||
@@ -149,7 +149,7 @@ class PostResource extends AbstractDatabaseResource
|
||||
Schema\Integer::make('number'),
|
||||
Schema\DateTime::make('createdAt')
|
||||
->writable(function (Post $post, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Create
|
||||
return $context->creating()
|
||||
&& $context->getActor()->isAdmin();
|
||||
})
|
||||
->default(fn () => Carbon::now()),
|
||||
@@ -159,9 +159,9 @@ class PostResource extends AbstractDatabaseResource
|
||||
Schema\Str::make('content')
|
||||
->requiredOnCreate()
|
||||
->writable(function (Post $post, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Create || (
|
||||
return $context->creating() || (
|
||||
$post instanceof CommentPost
|
||||
&& $context->endpoint instanceof Endpoint\Update
|
||||
&& $context->updating()
|
||||
&& $context->getActor()->can('edit', $post)
|
||||
);
|
||||
})
|
||||
@@ -172,9 +172,9 @@ class PostResource extends AbstractDatabaseResource
|
||||
})
|
||||
->set(function (Post $post, string $value, Context $context) {
|
||||
if ($post instanceof CommentPost) {
|
||||
if ($context->endpoint instanceof Endpoint\Create) {
|
||||
if ($context->creating()) {
|
||||
$post->setContentAttribute($value, $context->getActor());
|
||||
} elseif ($context->endpoint instanceof Endpoint\Update) {
|
||||
} elseif ($context->updating()) {
|
||||
$post->revise($value, $context->getActor());
|
||||
}
|
||||
}
|
||||
@@ -215,7 +215,7 @@ class PostResource extends AbstractDatabaseResource
|
||||
Schema\Boolean::make('isHidden')
|
||||
->visible(fn (Post $post) => $post->hidden_at !== null)
|
||||
->writable(function (Post $post, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Update
|
||||
return $context->updating()
|
||||
&& $context->getActor()->can('hide', $post);
|
||||
})
|
||||
->set(function (Post $post, bool $value, Context $context) {
|
||||
|
@@ -124,7 +124,7 @@ class UserResource extends AbstractDatabaseResource
|
||||
->minLength(3)
|
||||
->maxLength(30)
|
||||
->writable(function (User $user, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Create
|
||||
return $context->creating()
|
||||
|| $context->getActor()->can('editCredentials', $user);
|
||||
})
|
||||
->set(function (User $user, string $value) {
|
||||
@@ -146,7 +146,7 @@ class UserResource extends AbstractDatabaseResource
|
||||
|| $context->getActor()->id === $user->id;
|
||||
})
|
||||
->writable(function (User $user, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Create
|
||||
return $context->creating()
|
||||
|| $context->getActor()->can('editCredentials', $user)
|
||||
|| $context->getActor()->id === $user->id;
|
||||
})
|
||||
@@ -171,9 +171,7 @@ class UserResource extends AbstractDatabaseResource
|
||||
})
|
||||
->writable(fn (User $user, Context $context) => $context->getActor()->isAdmin())
|
||||
->set(function (User $user, $value, Context $context) {
|
||||
$editing = $context->endpoint instanceof Endpoint\Update;
|
||||
|
||||
if (! empty($value) && ($editing || $context->getActor()->isAdmin())) {
|
||||
if (! empty($value) && ($context->updating() || $context->getActor()->isAdmin())) {
|
||||
$user->activate();
|
||||
}
|
||||
}),
|
||||
@@ -185,7 +183,7 @@ class UserResource extends AbstractDatabaseResource
|
||||
->minLength(8)
|
||||
->visible(false)
|
||||
->writable(function (User $user, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Create
|
||||
return $context->creating()
|
||||
|| $context->getActor()->can('editCredentials', $user);
|
||||
})
|
||||
->set(function (User $user, ?string $value) {
|
||||
@@ -195,7 +193,7 @@ class UserResource extends AbstractDatabaseResource
|
||||
Schema\Str::make('token')
|
||||
->visible(false)
|
||||
->writable(function (User $user, Context $context) {
|
||||
return $context->endpoint instanceof Endpoint\Create;
|
||||
return $context->creating();
|
||||
})
|
||||
->set(function (User $user, ?string $value, Context $context) {
|
||||
if ($value) {
|
||||
@@ -273,7 +271,7 @@ class UserResource extends AbstractDatabaseResource
|
||||
}),
|
||||
|
||||
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()
|
||||
->get(function (User $user, Context $context) {
|
||||
if ($context->getActor()->can('viewHiddenGroups')) {
|
||||
|
Reference in New Issue
Block a user