mirror of
https://github.com/flarum/framework.git
synced 2024-12-11 21:43:38 +08:00
feat: eager loading
This commit is contained in:
parent
7756e330b3
commit
d2bbd83492
|
@ -72,18 +72,24 @@ return [
|
||||||
|
|
||||||
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
||||||
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint): Endpoint\Index {
|
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint): Endpoint\Index {
|
||||||
return $endpoint->eagerLoad([
|
return $endpoint->eagerLoadWhenIncluded([
|
||||||
|
'firstPost' => [
|
||||||
'firstPost.mentionsUsers', 'firstPost.mentionsPosts',
|
'firstPost.mentionsUsers', 'firstPost.mentionsPosts',
|
||||||
'firstPost.mentionsPosts.user', 'firstPost.mentionsPosts.discussion', 'firstPost.mentionsGroups',
|
'firstPost.mentionsPosts.user', 'firstPost.mentionsPosts.discussion', 'firstPost.mentionsGroups',
|
||||||
|
],
|
||||||
|
'lastPost' => [
|
||||||
'lastPost.mentionsUsers', 'lastPost.mentionsPosts',
|
'lastPost.mentionsUsers', 'lastPost.mentionsPosts',
|
||||||
'lastPost.mentionsPosts.user', 'lastPost.mentionsPosts.discussion', 'lastPost.mentionsGroups',
|
'lastPost.mentionsPosts.user', 'lastPost.mentionsPosts.discussion', 'lastPost.mentionsGroups',
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
->endpoint(Endpoint\Show::class, function (Endpoint\Show $endpoint): Endpoint\Show {
|
->endpoint(Endpoint\Show::class, function (Endpoint\Show $endpoint): Endpoint\Show {
|
||||||
return $endpoint->addDefaultInclude(['posts.mentionedBy', 'posts.mentionedBy.user', 'posts.mentionedBy.discussion'])
|
return $endpoint->addDefaultInclude(['posts.mentionedBy', 'posts.mentionedBy.user', 'posts.mentionedBy.discussion'])
|
||||||
->eagerLoad([
|
->eagerLoadWhenIncluded([
|
||||||
|
'posts' => [
|
||||||
'posts.mentionsUsers', 'posts.mentionsPosts', 'posts.mentionsPosts.user',
|
'posts.mentionsUsers', 'posts.mentionsPosts', 'posts.mentionsPosts.user',
|
||||||
'posts.mentionsPosts.discussion', 'posts.mentionsGroups'
|
'posts.mentionsPosts.discussion', 'posts.mentionsGroups'
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -124,10 +130,10 @@ return [
|
||||||
|
|
||||||
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
||||||
->endpoint(Endpoint\Show::class, function (Endpoint\Show $endpoint): Endpoint\Show {
|
->endpoint(Endpoint\Show::class, function (Endpoint\Show $endpoint): Endpoint\Show {
|
||||||
return $endpoint->eagerLoad(['posts.mentionsTags']);
|
return $endpoint->eagerLoadWhenIncluded(['posts' => ['posts.mentionsTags']]);
|
||||||
})
|
})
|
||||||
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint): Endpoint\Index {
|
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint): Endpoint\Index {
|
||||||
return $endpoint->eagerLoad(['firstPost.mentionsTags', 'lastPost.mentionsTags']);
|
return $endpoint->eagerLoadWhenIncluded(['firstPost' => ['firstPost.mentionsTags'], 'lastPost' => ['lastPost.mentionsTags']]);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
(new Extend\ApiResource(Resource\PostResource::class))
|
(new Extend\ApiResource(Resource\PostResource::class))
|
||||||
|
|
|
@ -36,10 +36,6 @@ use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
$eagerLoadTagState = function ($query, ServerRequestInterface $request, array $relations) {
|
|
||||||
$query->withStateFor(RequestUtil::getActor($request));
|
|
||||||
};
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(new Extend\Frontend('forum'))
|
(new Extend\Frontend('forum'))
|
||||||
->js(__DIR__.'/js/dist/forum.js')
|
->js(__DIR__.'/js/dist/forum.js')
|
||||||
|
@ -95,29 +91,29 @@ return [
|
||||||
return $endpoint->addDefaultInclude(['tags', 'tags.parent']);
|
return $endpoint->addDefaultInclude(['tags', 'tags.parent']);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
|
||||||
->fields(Api\DiscussionResourceFields::class),
|
|
||||||
|
|
||||||
(new Extend\ApiResource(Resource\PostResource::class))
|
(new Extend\ApiResource(Resource\PostResource::class))
|
||||||
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint) {
|
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint) {
|
||||||
return $endpoint->eagerLoad('discussion.tags');
|
return $endpoint->eagerLoadWhenIncluded(['discussion' => ['discussion.tags']]);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
(new Extend\Conditional())
|
(new Extend\Conditional())
|
||||||
->whenExtensionEnabled('flarum-flags', fn () => [
|
->whenExtensionEnabled('flarum-flags', fn () => [
|
||||||
(new Extend\ApiResource(FlagResource::class))
|
(new Extend\ApiResource(FlagResource::class))
|
||||||
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint) {
|
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint) {
|
||||||
return $endpoint->eagerLoad(['post.discussion.tags']);
|
return $endpoint->eagerLoadWhenIncluded(['post.discussion' => ['post.discussion.tags']]);
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
||||||
|
->fields(Api\DiscussionResourceFields::class)
|
||||||
->endpoint(
|
->endpoint(
|
||||||
[Endpoint\Index::class, Endpoint\Show::class, Endpoint\Create::class],
|
[Endpoint\Index::class, Endpoint\Show::class, Endpoint\Create::class],
|
||||||
function (Endpoint\Index|Endpoint\Show|Endpoint\Create $endpoint) use ($eagerLoadTagState) {
|
function (Endpoint\Index|Endpoint\Show|Endpoint\Create $endpoint) {
|
||||||
return $endpoint
|
return $endpoint
|
||||||
->addDefaultInclude(['tags', 'tags.parent'])
|
->addDefaultInclude(['tags', 'tags.parent'])
|
||||||
->eagerLoadWhere('tags', $eagerLoadTagState);
|
->eagerLoadWhere('tags', function ($query, Context $context) {
|
||||||
|
$query->withStateFor($context->getActor());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -181,18 +177,12 @@ return [
|
||||||
])
|
])
|
||||||
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint) {
|
->endpoint(Endpoint\Index::class, function (Endpoint\Index $endpoint) {
|
||||||
return $endpoint
|
return $endpoint
|
||||||
->addDefaultInclude(['eventPostMentionsTags'])
|
->addDefaultInclude(['eventPostMentionsTags']);
|
||||||
->eagerLoadWhere('eventPostMentionsTags', function (Relation|Builder $query, ServerRequestInterface $request) {
|
|
||||||
$query->whereVisibleTo(RequestUtil::getActor($request));
|
|
||||||
});
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
(new Extend\ApiResource(Resource\DiscussionResource::class))
|
||||||
->endpoint(Endpoint\Show::class, function (Endpoint\Show $endpoint) {
|
->endpoint(Endpoint\Show::class, function (Endpoint\Show $endpoint) {
|
||||||
return $endpoint
|
return $endpoint
|
||||||
->addDefaultInclude(['posts.eventPostMentionsTags'])
|
->addDefaultInclude(['posts.eventPostMentionsTags']);
|
||||||
->eagerLoadWhere('posts.eventPostMentionsTags', function (Relation|Builder $query, ServerRequestInterface $request) {
|
|
||||||
$query->whereVisibleTo(RequestUtil::getActor($request));
|
|
||||||
});
|
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Flarum\Api\Endpoint\Concerns;
|
|
||||||
|
|
||||||
use Flarum\Api\Context;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Tobyz\JsonApiServer\Laravel\EloquentResource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is directed at eager loading relationships apart from the request includes.
|
|
||||||
*/
|
|
||||||
trait HasEagerLoading
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var string[]
|
|
||||||
*/
|
|
||||||
protected array $loadRelations = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<string, callable>
|
|
||||||
*/
|
|
||||||
protected array $loadRelationCallables = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Eager loads relationships needed for serializer logic.
|
|
||||||
*
|
|
||||||
* First level relationships will be loaded regardless of whether they are included in the response.
|
|
||||||
* Sub-level relationships will only be loaded if the upper level was included or manually loaded.
|
|
||||||
*
|
|
||||||
* @example If a relationship such as: 'relation.subRelation' is specified,
|
|
||||||
* it will only be loaded if 'relation' is or has been loaded.
|
|
||||||
* To force load the relationship, both levels have to be specified,
|
|
||||||
* example: ['relation', 'relation.subRelation'].
|
|
||||||
*
|
|
||||||
* @param string|string[] $relations
|
|
||||||
*/
|
|
||||||
public function eagerLoad(array|string $relations): self
|
|
||||||
{
|
|
||||||
$this->loadRelations = array_merge($this->loadRelations, array_map('strval', (array) $relations));
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows loading a relationship with additional query modification.
|
|
||||||
*
|
|
||||||
* @param string $relation: Relationship name, see load method description.
|
|
||||||
* @template R of Relation
|
|
||||||
* @param (callable(Builder|R, \Psr\Http\Message\ServerRequestInterface|null, array): void) $callback
|
|
||||||
*
|
|
||||||
* The callback to modify the query, should accept:
|
|
||||||
* - \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query: A query object.
|
|
||||||
* - \Psr\Http\Message\ServerRequestInterface|null $request: An instance of the request.
|
|
||||||
* - array $relations: An array of relations that are to be loaded.
|
|
||||||
*/
|
|
||||||
public function eagerLoadWhere(string $relation, callable $callback): self
|
|
||||||
{
|
|
||||||
$this->loadRelationCallables = array_merge($this->loadRelationCallables, [$relation => $callback]);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Eager loads the required relationships.
|
|
||||||
*/
|
|
||||||
protected function loadRelations(Collection $models, Context $context, array $included = []): void
|
|
||||||
{
|
|
||||||
if (! $context->collection instanceof EloquentResource) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$request = $context->request;
|
|
||||||
|
|
||||||
$included = $this->stringInclude($included);
|
|
||||||
$models = $models->filter(fn ($model) => $model instanceof Model);
|
|
||||||
|
|
||||||
$addedRelations = $this->loadRelations;
|
|
||||||
$addedRelationCallables = $this->loadRelationCallables;
|
|
||||||
|
|
||||||
$relations = $included;
|
|
||||||
|
|
||||||
foreach ($addedRelationCallables as $name => $relation) {
|
|
||||||
$addedRelations[] = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! empty($addedRelations)) {
|
|
||||||
usort($addedRelations, function ($a, $b) {
|
|
||||||
return substr_count($a, '.') - substr_count($b, '.');
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach ($addedRelations as $relation) {
|
|
||||||
if (str_contains($relation, '.')) {
|
|
||||||
$parentRelation = Str::beforeLast($relation, '.');
|
|
||||||
|
|
||||||
if (! in_array($parentRelation, $relations, true)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$relations[] = $relation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! empty($relations)) {
|
|
||||||
$relations = array_unique($relations);
|
|
||||||
}
|
|
||||||
|
|
||||||
$callableRelations = [];
|
|
||||||
$nonCallableRelations = [];
|
|
||||||
|
|
||||||
foreach ($relations as $relation) {
|
|
||||||
if (isset($addedRelationCallables[$relation])) {
|
|
||||||
$load = $addedRelationCallables[$relation];
|
|
||||||
|
|
||||||
$callableRelations[$relation] = function ($query) use ($load, $request, $relations) {
|
|
||||||
$load($query, $request, $relations);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
$nonCallableRelations[] = $relation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! empty($callableRelations)) {
|
|
||||||
$models->loadMissing($callableRelations);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! empty($nonCallableRelations)) {
|
|
||||||
$models->loadMissing($nonCallableRelations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From format of: 'relation' => [ ...nested ] to ['relation', 'relation.nested']
|
|
||||||
*/
|
|
||||||
private function stringInclude(array $include): array
|
|
||||||
{
|
|
||||||
$relations = [];
|
|
||||||
|
|
||||||
foreach ($include as $relation => $nested) {
|
|
||||||
$relations[] = $relation;
|
|
||||||
|
|
||||||
if (is_array($nested)) {
|
|
||||||
foreach ($this->stringInclude($nested) as $nestedRelation) {
|
|
||||||
$relations[] = $relation.'.'.$nestedRelation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $relations;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,27 +2,17 @@
|
||||||
|
|
||||||
namespace Flarum\Api\Endpoint;
|
namespace Flarum\Api\Endpoint;
|
||||||
|
|
||||||
use Flarum\Api\Context;
|
|
||||||
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasEagerLoading;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Tobyz\JsonApiServer\Endpoint\Create as BaseCreate;
|
use Tobyz\JsonApiServer\Endpoint\Create as BaseCreate;
|
||||||
|
|
||||||
class Create extends BaseCreate implements EndpointInterface
|
class Create extends BaseCreate implements EndpointInterface
|
||||||
{
|
{
|
||||||
use HasAuthorization;
|
use HasAuthorization;
|
||||||
use HasEagerLoading;
|
|
||||||
use HasCustomHooks;
|
use HasCustomHooks;
|
||||||
|
|
||||||
public function setUp(): void
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->beforeSerialization(function (Context $context, object $model) {
|
|
||||||
$this->loadRelations(Collection::make([$model]), $context, $this->getInclude($context));
|
|
||||||
|
|
||||||
return $model;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,11 @@ namespace Flarum\Api\Endpoint;
|
||||||
use Flarum\Api\Endpoint\Concerns\ExtractsListingParams;
|
use Flarum\Api\Endpoint\Concerns\ExtractsListingParams;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasEagerLoading;
|
|
||||||
use Tobyz\JsonApiServer\Endpoint\Endpoint as BaseEndpoint;
|
use Tobyz\JsonApiServer\Endpoint\Endpoint as BaseEndpoint;
|
||||||
|
|
||||||
class Endpoint extends BaseEndpoint implements EndpointInterface
|
class Endpoint extends BaseEndpoint implements EndpointInterface
|
||||||
{
|
{
|
||||||
use HasAuthorization;
|
use HasAuthorization;
|
||||||
use HasCustomHooks;
|
use HasCustomHooks;
|
||||||
use HasEagerLoading;
|
|
||||||
use ExtractsListingParams;
|
use ExtractsListingParams;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,9 @@ use Flarum\Api\Context;
|
||||||
use Flarum\Api\Endpoint\Concerns\ExtractsListingParams;
|
use Flarum\Api\Endpoint\Concerns\ExtractsListingParams;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasEagerLoading;
|
|
||||||
use Flarum\Search\SearchCriteria;
|
use Flarum\Search\SearchCriteria;
|
||||||
use Flarum\Search\SearchManager;
|
use Flarum\Search\SearchManager;
|
||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Tobyz\JsonApiServer\Endpoint\Index as BaseIndex;
|
use Tobyz\JsonApiServer\Endpoint\Index as BaseIndex;
|
||||||
use Tobyz\JsonApiServer\Pagination\OffsetPagination;
|
use Tobyz\JsonApiServer\Pagination\OffsetPagination;
|
||||||
use Tobyz\JsonApiServer\Pagination\Pagination;
|
use Tobyz\JsonApiServer\Pagination\Pagination;
|
||||||
|
@ -18,7 +16,6 @@ use Tobyz\JsonApiServer\Pagination\Pagination;
|
||||||
class Index extends BaseIndex implements EndpointInterface
|
class Index extends BaseIndex implements EndpointInterface
|
||||||
{
|
{
|
||||||
use HasAuthorization;
|
use HasAuthorization;
|
||||||
use HasEagerLoading;
|
|
||||||
use ExtractsListingParams;
|
use ExtractsListingParams;
|
||||||
use HasCustomHooks;
|
use HasCustomHooks;
|
||||||
|
|
||||||
|
@ -63,9 +60,6 @@ class Index extends BaseIndex implements EndpointInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
return $context;
|
return $context;
|
||||||
})
|
|
||||||
->beforeSerialization(function (Context $context, iterable $models) {
|
|
||||||
$this->loadRelations(Collection::make($models), $context, $this->getInclude($context));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,27 +2,19 @@
|
||||||
|
|
||||||
namespace Flarum\Api\Endpoint;
|
namespace Flarum\Api\Endpoint;
|
||||||
|
|
||||||
use Flarum\Api\Context;
|
|
||||||
use Flarum\Api\Endpoint\Concerns\ExtractsListingParams;
|
use Flarum\Api\Endpoint\Concerns\ExtractsListingParams;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasEagerLoading;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Tobyz\JsonApiServer\Endpoint\Show as BaseShow;
|
use Tobyz\JsonApiServer\Endpoint\Show as BaseShow;
|
||||||
|
|
||||||
class Show extends BaseShow implements EndpointInterface
|
class Show extends BaseShow implements EndpointInterface
|
||||||
{
|
{
|
||||||
use HasAuthorization;
|
use HasAuthorization;
|
||||||
use HasEagerLoading;
|
|
||||||
use ExtractsListingParams;
|
use ExtractsListingParams;
|
||||||
use HasCustomHooks;
|
use HasCustomHooks;
|
||||||
|
|
||||||
public function setUp(): void
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();;
|
||||||
|
|
||||||
$this->beforeSerialization(function (Context $context, object $model) {
|
|
||||||
$this->loadRelations(Collection::make([$model]), $context, $this->getInclude($context));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,17 @@
|
||||||
|
|
||||||
namespace Flarum\Api\Endpoint;
|
namespace Flarum\Api\Endpoint;
|
||||||
|
|
||||||
use Flarum\Api\Context;
|
|
||||||
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
|
||||||
use Flarum\Api\Endpoint\Concerns\HasEagerLoading;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Tobyz\JsonApiServer\Endpoint\Update as BaseUpdate;
|
use Tobyz\JsonApiServer\Endpoint\Update as BaseUpdate;
|
||||||
|
|
||||||
class Update extends BaseUpdate implements EndpointInterface
|
class Update extends BaseUpdate implements EndpointInterface
|
||||||
{
|
{
|
||||||
use HasAuthorization;
|
use HasAuthorization;
|
||||||
use HasEagerLoading;
|
|
||||||
use HasCustomHooks;
|
use HasCustomHooks;
|
||||||
|
|
||||||
public function setUp(): void
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->beforeSerialization(function (Context $context, object $model) {
|
|
||||||
$this->loadRelations(Collection::make([$model]), $context, $this->getInclude($context));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||||
'mostRelevantPost.user'
|
'mostRelevantPost.user'
|
||||||
])
|
])
|
||||||
->defaultSort('-lastPostedAt')
|
->defaultSort('-lastPostedAt')
|
||||||
|
->eagerLoad('state')
|
||||||
->paginate(),
|
->paginate(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -184,12 +185,14 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||||
->includable(),
|
->includable(),
|
||||||
Schema\Relationship\ToOne::make('firstPost')
|
Schema\Relationship\ToOne::make('firstPost')
|
||||||
->includable()
|
->includable()
|
||||||
|
->inverse('discussion')
|
||||||
->type('posts'),
|
->type('posts'),
|
||||||
Schema\Relationship\ToOne::make('lastPostedUser')
|
Schema\Relationship\ToOne::make('lastPostedUser')
|
||||||
->includable()
|
->includable()
|
||||||
->type('users'),
|
->type('users'),
|
||||||
Schema\Relationship\ToOne::make('lastPost')
|
Schema\Relationship\ToOne::make('lastPost')
|
||||||
->includable()
|
->includable()
|
||||||
|
->inverse('discussion')
|
||||||
->type('posts'),
|
->type('posts'),
|
||||||
Schema\Relationship\ToMany::make('posts')
|
Schema\Relationship\ToMany::make('posts')
|
||||||
->withLinkage(function (Context $context) {
|
->withLinkage(function (Context $context) {
|
||||||
|
@ -216,6 +219,8 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||||
|
|
||||||
$posts = $discussion->posts()
|
$posts = $discussion->posts()
|
||||||
->whereVisibleTo($actor)
|
->whereVisibleTo($actor)
|
||||||
|
->with($context->endpoint->getEagerLoadsFor('posts', $context))
|
||||||
|
->with($context->endpoint->getWhereEagerLoadsFor('posts', $context))
|
||||||
->orderBy('number')
|
->orderBy('number')
|
||||||
->skip($offset)
|
->skip($offset)
|
||||||
->take($limit)
|
->take($limit)
|
||||||
|
@ -236,6 +241,7 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||||
Schema\Relationship\ToOne::make('mostRelevantPost')
|
Schema\Relationship\ToOne::make('mostRelevantPost')
|
||||||
->visible(fn (Discussion $model, Context $context) => $context->listing())
|
->visible(fn (Discussion $model, Context $context) => $context->listing())
|
||||||
->includable()
|
->includable()
|
||||||
|
->inverse('discussion')
|
||||||
->type('posts'),
|
->type('posts'),
|
||||||
Schema\Relationship\ToOne::make('hideUser')
|
Schema\Relationship\ToOne::make('hideUser')
|
||||||
->type('users'),
|
->type('users'),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user