refactor: simplify index endpoint

This commit is contained in:
Sami Mazouz 2024-03-06 09:50:09 +01:00
parent f52c6238ba
commit 7756e330b3
No known key found for this signature in database
8 changed files with 63 additions and 115 deletions

View File

@ -5,10 +5,7 @@ namespace Flarum\Api;
use Flarum\Http\RequestUtil;
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
{

View File

@ -19,7 +19,7 @@ class Create extends BaseCreate implements EndpointInterface
{
parent::setUp();
$this->after(function (Context $context, object $model) {
$this->beforeSerialization(function (Context $context, object $model) {
$this->loadRelations(Collection::make([$model]), $context, $this->getInclude($context));
return $model;

View File

@ -3,9 +3,11 @@
namespace Flarum\Api\Endpoint;
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
use Tobyz\JsonApiServer\Endpoint\Delete as BaseDelete;
class Delete extends BaseDelete implements EndpointInterface
{
use HasAuthorization;
use HasCustomHooks;
}

View File

@ -2,9 +2,16 @@
namespace Flarum\Api\Endpoint;
use Flarum\Api\Endpoint\Concerns\ExtractsListingParams;
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
use Flarum\Api\Endpoint\Concerns\HasEagerLoading;
use Tobyz\JsonApiServer\Endpoint\Endpoint as BaseEndpoint;
class Endpoint extends BaseEndpoint implements EndpointInterface
{
//
use HasAuthorization;
use HasCustomHooks;
use HasEagerLoading;
use ExtractsListingParams;
}

View File

@ -2,26 +2,18 @@
namespace Flarum\Api\Endpoint;
use Flarum\Api\Context;
use Flarum\Api\Endpoint\Concerns\ExtractsListingParams;
use Flarum\Api\Endpoint\Concerns\HasAuthorization;
use Flarum\Api\Endpoint\Concerns\HasCustomHooks;
use Flarum\Api\Endpoint\Concerns\HasCustomRoute;
use Flarum\Api\Endpoint\Concerns\HasEagerLoading;
use Flarum\Http\RequestUtil;
use Flarum\Search\SearchCriteria;
use Flarum\Search\SearchManager;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Psr\Http\Message\ResponseInterface as Response;
use RuntimeException;
use Tobyz\JsonApiServer\Context;
use Tobyz\JsonApiServer\Endpoint\Index as BaseIndex;
use Tobyz\JsonApiServer\Exception\ForbiddenException;
use Tobyz\JsonApiServer\Pagination\OffsetPagination;
use Tobyz\JsonApiServer\Resource\Countable;
use Tobyz\JsonApiServer\Resource\Listable;
use Tobyz\JsonApiServer\Serializer;
use function Tobyz\JsonApiServer\json_api_response;
use Tobyz\JsonApiServer\Pagination\Pagination;
class Index extends BaseIndex implements EndpointInterface
{
@ -30,41 +22,12 @@ class Index extends BaseIndex implements EndpointInterface
use ExtractsListingParams;
use HasCustomHooks;
public function paginate(int $defaultLimit = 20, int $maxLimit = 50): static
public function setUp(): void
{
$this->limit = $defaultLimit;
$this->maxLimit = $maxLimit;
$this->paginationResolver = fn (Context $context) => new OffsetPagination(
$context,
$this->limit,
$this->maxLimit,
);
return $this;
}
/** {@inheritDoc} */
public function handle(Context $context): ?Response
{
$collection = $context->collection;
if (!$collection instanceof Listable) {
throw new RuntimeException(
sprintf('%s must implement %s', get_class($collection), Listable::class),
);
}
if (!$this->isVisible($context)) {
throw new ForbiddenException();
}
$this->callBeforeHook($context);
$pagination = ($this->paginationResolver)($context);
$query = $collection->query($context);
parent::setUp();
$this
->query(function ($query, ?Pagination $pagination, Context $context): Context {
// This model has a searcher API, so we'll use that instead of the default.
// The searcher API allows swapping the default search engine for a custom one.
$search = $context->api->getContainer()->make(SearchManager::class);
@ -99,41 +62,24 @@ class Index extends BaseIndex implements EndpointInterface
$pagination?->apply($query);
}
$meta = $this->serializeMeta($context);
$links = [];
if (
$collection instanceof Countable &&
!is_null($total = $collection->count($query, $context))
) {
$meta['page']['total'] = $total;
return $context;
})
->beforeSerialization(function (Context $context, iterable $models) {
$this->loadRelations(Collection::make($models), $context, $this->getInclude($context));
});
}
$models = $collection->results($query, $context);
public function paginate(int $defaultLimit = 20, int $maxLimit = 50): static
{
$this->limit = $defaultLimit;
$this->maxLimit = $maxLimit;
$models = $this->callAfterHook($context, $models);
$include = $this->getInclude($context);
$this->loadRelations($models, $context, $include);
$serializer = new Serializer($context);
foreach ($models as $model) {
$serializer->addPrimary(
$context->resource($collection->resource($model, $context)),
$model,
$include,
$this->paginationResolver = fn (Context $context) => new OffsetPagination(
$context,
$this->limit,
$this->maxLimit,
);
}
[$data, $included] = $serializer->serialize();
if ($pagination) {
$meta['page'] = array_merge($meta['page'] ?? [], $pagination->meta());
$links = array_merge($links, $pagination->links(count($data), $total ?? null));
}
return json_api_response(compact('data', 'included', 'meta', 'links'));
return $this;
}
}

View File

@ -21,10 +21,8 @@ class Show extends BaseShow implements EndpointInterface
{
parent::setUp();
$this->after(function (Context $context, object $model) {
$this->beforeSerialization(function (Context $context, object $model) {
$this->loadRelations(Collection::make([$model]), $context, $this->getInclude($context));
return $model;
});
}
}

View File

@ -19,10 +19,8 @@ class Update extends BaseUpdate implements EndpointInterface
{
parent::setUp();
$this->after(function (Context $context, object $model) {
$this->beforeSerialization(function (Context $context, object $model) {
$this->loadRelations(Collection::make([$model]), $context, $this->getInclude($context));
return $model;
});
}
}

View File

@ -149,7 +149,7 @@ class ThemeTest extends TestCase
$response = $this->send($this->request('GET', '/'));
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(200, $response->getStatusCode(), $response->getBody()->getContents());
$cssFilePath = $this->app()->getContainer()->make('filesystem')->disk('flarum-assets')->path('forum.css');
$contents = file_get_contents($cssFilePath);