mirror of
https://github.com/flarum/core.git
synced 2025-08-03 15:07:53 +02:00
test: phpstan
This commit is contained in:
@@ -28,6 +28,9 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Tobyz\JsonApiServer\Context;
|
||||
|
||||
/**
|
||||
* @extends AbstractDatabaseResource<Flag>
|
||||
*/
|
||||
class FlagResource extends AbstractDatabaseResource
|
||||
{
|
||||
public function __construct(
|
||||
|
@@ -18,7 +18,7 @@ use Flarum\Sticky\Event\DiscussionWasUnstickied;
|
||||
|
||||
class DiscussionResourceFields
|
||||
{
|
||||
public function __invoke()
|
||||
public function __invoke(): array
|
||||
{
|
||||
return [
|
||||
Schema\Boolean::make('isSticky')
|
||||
|
@@ -17,7 +17,6 @@ class PinStickiedDiscussionsToTop
|
||||
{
|
||||
public function __invoke(DatabaseSearchState $state, SearchCriteria $criteria): void
|
||||
{
|
||||
return;
|
||||
if ($criteria->sortIsDefault && ! $state->isFulltextSearch()) {
|
||||
$query = $state->getQuery();
|
||||
|
||||
|
@@ -31,6 +31,7 @@ use Flarum\Tags\Search\HideHiddenTagsFromAllDiscussionsPage;
|
||||
use Flarum\Tags\Search\TagSearcher;
|
||||
use Flarum\Tags\Tag;
|
||||
use Flarum\Tags\Utf8SlugDriver;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
return [
|
||||
(new Extend\Frontend('forum'))
|
||||
@@ -107,7 +108,8 @@ return [
|
||||
function (Endpoint\Index|Endpoint\Show|Endpoint\Create $endpoint) {
|
||||
return $endpoint
|
||||
->addDefaultInclude(['tags', 'tags.parent'])
|
||||
->eagerLoadWhere('tags', function ($query, Context $context) {
|
||||
->eagerLoadWhere('tags', function (Builder $query, Context $context, array $relations) {
|
||||
/** @var Builder<Tag> $query */
|
||||
$query->withStateFor($context->getActor());
|
||||
});
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Flarum\Tags\Api\Resource;
|
||||
|
||||
use Flarum\Api\Context as FlarumContext;
|
||||
use Flarum\Api\Endpoint;
|
||||
use Flarum\Api\Resource\AbstractDatabaseResource;
|
||||
use Flarum\Api\Schema;
|
||||
@@ -21,6 +22,9 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Tobyz\JsonApiServer\Context;
|
||||
|
||||
/**
|
||||
* @extends AbstractDatabaseResource<Tag>
|
||||
*/
|
||||
class TagResource extends AbstractDatabaseResource
|
||||
{
|
||||
public function __construct(
|
||||
@@ -107,7 +111,7 @@ class TagResource extends AbstractDatabaseResource
|
||||
->writable(),
|
||||
Schema\Boolean::make('isRestricted')
|
||||
->writableOnUpdate()
|
||||
->visible(fn (Tag $tag, Context $context) => $context->getActor()->isAdmin()),
|
||||
->visible(fn (Tag $tag, FlarumContext $context) => $context->getActor()->isAdmin()),
|
||||
Schema\Str::make('backgroundUrl')
|
||||
->get(fn (Tag $tag) => $tag->background_path),
|
||||
Schema\Str::make('backgroundMode'),
|
||||
@@ -119,14 +123,14 @@ class TagResource extends AbstractDatabaseResource
|
||||
->get(fn (Tag $tag) => (bool) $tag->parent_id),
|
||||
Schema\DateTime::make('lastPostedAt'),
|
||||
Schema\Boolean::make('canStartDiscussion')
|
||||
->get(fn (Tag $tag, Context $context) => $context->getActor()->can('startDiscussion', $tag)),
|
||||
->get(fn (Tag $tag, FlarumContext $context) => $context->getActor()->can('startDiscussion', $tag)),
|
||||
Schema\Boolean::make('canAddToDiscussion')
|
||||
->get(fn (Tag $tag, Context $context) => $context->getActor()->can('addToDiscussion', $tag)),
|
||||
->get(fn (Tag $tag, FlarumContext $context) => $context->getActor()->can('addToDiscussion', $tag)),
|
||||
|
||||
Schema\Relationship\ToOne::make('parent')
|
||||
->type('tags')
|
||||
->includable()
|
||||
->writable(fn (Tag $tag, Context $context) => (bool) Arr::get($context->body(), 'attributes.isPrimary')),
|
||||
->writable(fn (Tag $tag, FlarumContext $context) => (bool) Arr::get($context->body(), 'attributes.isPrimary')),
|
||||
Schema\Relationship\ToMany::make('children')
|
||||
->type('tags')
|
||||
->includable(),
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\JsonApi;
|
||||
use Flarum\Foundation\ValidationException;
|
||||
use Flarum\Locale\TranslatorInterface;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
@@ -23,12 +24,13 @@ class UploadFaviconController extends UploadImageController
|
||||
protected string $filenamePrefix = 'favicon';
|
||||
|
||||
public function __construct(
|
||||
JsonApi $api,
|
||||
SettingsRepositoryInterface $settings,
|
||||
Factory $filesystemFactory,
|
||||
protected TranslatorInterface $translator,
|
||||
protected ImageManager $imageManager
|
||||
) {
|
||||
parent::__construct($settings, $filesystemFactory);
|
||||
parent::__construct($api, $settings, $filesystemFactory);
|
||||
}
|
||||
|
||||
protected function makeImage(UploadedFileInterface $file): EncodedImageInterface
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\JsonApi;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Illuminate\Contracts\Filesystem\Factory;
|
||||
use Intervention\Image\ImageManager;
|
||||
@@ -21,11 +22,12 @@ class UploadLogoController extends UploadImageController
|
||||
protected string $filenamePrefix = 'logo';
|
||||
|
||||
public function __construct(
|
||||
JsonApi $api,
|
||||
SettingsRepositoryInterface $settings,
|
||||
Factory $filesystemFactory,
|
||||
protected ImageManager $imageManager
|
||||
) {
|
||||
parent::__construct($settings, $filesystemFactory);
|
||||
parent::__construct($api, $settings, $filesystemFactory);
|
||||
}
|
||||
|
||||
protected function makeImage(UploadedFileInterface $file): EncodedImageInterface
|
||||
|
@@ -12,6 +12,7 @@ namespace Flarum\Api\Endpoint\Concerns;
|
||||
use Closure;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Tobyz\JsonApiServer\Context;
|
||||
use Tobyz\JsonApiServer\Resource\AbstractResource;
|
||||
use Tobyz\JsonApiServer\Schema\Sort;
|
||||
|
||||
trait ExtractsListingParams
|
||||
@@ -109,6 +110,10 @@ trait ExtractsListingParams
|
||||
|
||||
public function getAvailableSorts(Context $context): array
|
||||
{
|
||||
if (! $context->collection instanceof AbstractResource) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$asc = collect($context->collection->resolveSorts())
|
||||
->filter(fn (Sort $field) => $field->isVisible($context))
|
||||
->pluck('name')
|
||||
|
@@ -17,14 +17,8 @@ use Tobyz\JsonApiServer\Context;
|
||||
|
||||
trait HasAuthorization
|
||||
{
|
||||
/**
|
||||
* @var bool|(Closure(mixed, Context): bool)
|
||||
*/
|
||||
protected bool|Closure $authenticated = false;
|
||||
|
||||
/**
|
||||
* @var null|string|Closure(mixed, Context): string
|
||||
*/
|
||||
protected null|string|Closure $ability = null;
|
||||
|
||||
protected bool $admin = false;
|
||||
@@ -67,9 +61,9 @@ trait HasAuthorization
|
||||
return $this->ability;
|
||||
}
|
||||
|
||||
return (bool) (isset($context->model)
|
||||
return isset($context->model)
|
||||
? ($this->ability)($context->model, $context)
|
||||
: ($this->ability)($context));
|
||||
: ($this->ability)($context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -9,6 +9,9 @@
|
||||
|
||||
namespace Flarum\Api\Endpoint;
|
||||
|
||||
/**
|
||||
* @mixin \Tobyz\JsonApiServer\Endpoint\Endpoint
|
||||
*/
|
||||
interface EndpointInterface
|
||||
{
|
||||
//
|
||||
|
@@ -9,35 +9,22 @@
|
||||
|
||||
namespace Flarum\Api\Resource;
|
||||
|
||||
use Flarum\Api\Context as FlarumContext;
|
||||
use Flarum\Api\Resource\Concerns\Bootable;
|
||||
use Flarum\Api\Resource\Concerns\Extendable;
|
||||
use Flarum\Api\Resource\Concerns\HasSortMap;
|
||||
use Flarum\Api\Resource\Contracts\{
|
||||
Countable,
|
||||
Creatable,
|
||||
Deletable,
|
||||
Findable,
|
||||
Listable,
|
||||
Paginatable,
|
||||
Resource,
|
||||
Updatable
|
||||
};
|
||||
use Flarum\Foundation\DispatchEventsTrait;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use RuntimeException;
|
||||
use Tobyz\JsonApiServer\Context;
|
||||
use Tobyz\JsonApiServer\Laravel\EloquentResource as BaseResource;
|
||||
|
||||
abstract class AbstractDatabaseResource extends BaseResource implements
|
||||
Resource,
|
||||
Findable,
|
||||
Listable,
|
||||
Countable,
|
||||
Paginatable,
|
||||
Creatable,
|
||||
Updatable,
|
||||
Deletable
|
||||
{
|
||||
/**
|
||||
* @template M of Model
|
||||
* @extends BaseResource<M, FlarumContext>
|
||||
*/
|
||||
abstract class AbstractDatabaseResource extends BaseResource {
|
||||
use Bootable;
|
||||
use Extendable;
|
||||
use HasSortMap;
|
||||
@@ -47,6 +34,7 @@ abstract class AbstractDatabaseResource extends BaseResource implements
|
||||
|
||||
abstract public function model(): string;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function newModel(Context $context): object
|
||||
{
|
||||
return new ($this->model());
|
||||
@@ -97,41 +85,79 @@ abstract class AbstractDatabaseResource extends BaseResource implements
|
||||
$this->dispatchEventsFor($model, $context->getActor());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param M $model
|
||||
* @param FlarumContext $context
|
||||
* @return M|null
|
||||
*/
|
||||
public function creating(object $model, Context $context): ?object
|
||||
{
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param M $model
|
||||
* @param FlarumContext $context
|
||||
* @return M|null
|
||||
*/
|
||||
public function updating(object $model, Context $context): ?object
|
||||
{
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param M $model
|
||||
* @param FlarumContext $context
|
||||
* @return M|null
|
||||
*/
|
||||
public function saving(object $model, Context $context): ?object
|
||||
{
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param M $model
|
||||
* @param FlarumContext $context
|
||||
* @return M|null
|
||||
*/
|
||||
public function saved(object $model, Context $context): ?object
|
||||
{
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param M $model
|
||||
* @param FlarumContext $context
|
||||
* @return M|null
|
||||
*/
|
||||
public function created(object $model, Context $context): ?object
|
||||
{
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param M $model
|
||||
* @param FlarumContext $context
|
||||
* @return M|null
|
||||
*/
|
||||
public function updated(object $model, Context $context): ?object
|
||||
{
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param M $model
|
||||
* @param FlarumContext $context
|
||||
*/
|
||||
public function deleting(object $model, Context $context): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* @param M $model
|
||||
* @param FlarumContext $context
|
||||
*/
|
||||
public function deleted(object $model, Context $context): void
|
||||
{
|
||||
//
|
||||
@@ -144,11 +170,17 @@ abstract class AbstractDatabaseResource extends BaseResource implements
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlarumContext $context
|
||||
*/
|
||||
public function mutateDataBeforeValidation(Context $context, array $data): array
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlarumContext $context
|
||||
*/
|
||||
public function results(object $query, Context $context): iterable
|
||||
{
|
||||
if ($results = $context->getSearchResults()) {
|
||||
@@ -158,6 +190,9 @@ abstract class AbstractDatabaseResource extends BaseResource implements
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlarumContext $context
|
||||
*/
|
||||
public function count(object $query, Context $context): ?int
|
||||
{
|
||||
if ($results = $context->getSearchResults()) {
|
||||
|
@@ -9,14 +9,17 @@
|
||||
|
||||
namespace Flarum\Api\Resource;
|
||||
|
||||
use Flarum\Api\Context;
|
||||
use Flarum\Api\Resource\Concerns\Bootable;
|
||||
use Flarum\Api\Resource\Concerns\Extendable;
|
||||
use Flarum\Api\Resource\Concerns\HasSortMap;
|
||||
use Flarum\Api\Resource\Contracts\Collection;
|
||||
use Flarum\Api\Resource\Contracts\Resource;
|
||||
use Tobyz\JsonApiServer\Resource\AbstractResource as BaseResource;
|
||||
|
||||
abstract class AbstractResource extends BaseResource implements Resource, Collection
|
||||
/**
|
||||
* @template M of object
|
||||
* @extends BaseResource<M, Context>
|
||||
*/
|
||||
abstract class AbstractResource extends BaseResource
|
||||
{
|
||||
use Bootable;
|
||||
use Extendable;
|
||||
|
@@ -24,6 +24,9 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Jenssegers\Agent\Agent;
|
||||
|
||||
/**
|
||||
* @extends AbstractDatabaseResource<AccessToken>
|
||||
*/
|
||||
class AccessTokenResource extends AbstractDatabaseResource
|
||||
{
|
||||
public function __construct(
|
||||
|
@@ -15,9 +15,9 @@ use Illuminate\Contracts\Validation\Factory;
|
||||
|
||||
trait Bootable
|
||||
{
|
||||
protected readonly JsonApi $api;
|
||||
protected readonly Dispatcher $events;
|
||||
protected readonly Factory $validation;
|
||||
protected JsonApi $api;
|
||||
protected Dispatcher $events;
|
||||
protected Factory $validation;
|
||||
|
||||
/**
|
||||
* Avoids polluting the constructor of the resource with dependencies.
|
||||
|
@@ -11,13 +11,13 @@ namespace Flarum\Api\Resource\Concerns;
|
||||
|
||||
trait Extendable
|
||||
{
|
||||
private static array $endpointModifiers = [];
|
||||
private static array $fieldModifiers = [];
|
||||
private static array $sortModifiers = [];
|
||||
protected static array $endpointModifiers = [];
|
||||
protected static array $fieldModifiers = [];
|
||||
protected static array $sortModifiers = [];
|
||||
|
||||
private ?array $cachedEndpoints = null;
|
||||
private ?array $cachedFields = null;
|
||||
private ?array $cachedSorts = null;
|
||||
protected ?array $cachedEndpoints = null;
|
||||
protected ?array $cachedFields = null;
|
||||
protected ?array $cachedSorts = null;
|
||||
|
||||
public static function mutateEndpoints(callable $modifier): void
|
||||
{
|
||||
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Attachable as BaseAttachable;
|
||||
|
||||
interface Attachable extends BaseAttachable
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Collection as BaseCollection;
|
||||
|
||||
interface Collection extends BaseCollection
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Countable as BaseCountable;
|
||||
|
||||
interface Countable extends BaseCountable
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Creatable as BaseCreatable;
|
||||
|
||||
interface Creatable extends BaseCreatable
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Deletable as BaseDeletable;
|
||||
|
||||
interface Deletable extends BaseDeletable
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Findable as BaseFindable;
|
||||
|
||||
interface Findable extends BaseFindable
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Listable as BaseListable;
|
||||
|
||||
interface Listable extends BaseListable
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Paginatable as BasePaginatable;
|
||||
|
||||
interface Paginatable extends BasePaginatable
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Resource as BaseResource;
|
||||
|
||||
interface Resource extends BaseResource
|
||||
{
|
||||
//
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Resource\Contracts;
|
||||
|
||||
use Tobyz\JsonApiServer\Resource\Updatable as BaseUpdatable;
|
||||
|
||||
interface Updatable extends BaseUpdatable
|
||||
{
|
||||
//
|
||||
}
|
@@ -28,6 +28,9 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
/**
|
||||
* @extends AbstractDatabaseResource<Discussion>
|
||||
*/
|
||||
class DiscussionResource extends AbstractDatabaseResource
|
||||
{
|
||||
public function __construct(
|
||||
@@ -213,6 +216,9 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
return fn () => $discussion->posts->all();
|
||||
}
|
||||
|
||||
/** @var Endpoint\Show $endpoint */
|
||||
$endpoint = $context->endpoint;
|
||||
|
||||
$actor = $context->getActor();
|
||||
|
||||
$limit = PostResource::$defaultLimit;
|
||||
@@ -221,7 +227,7 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
$offset = $this->posts->getIndexForNumber($discussion->id, $near, $actor);
|
||||
$offset = max(0, $offset - $limit / 2);
|
||||
} else {
|
||||
$offset = $context->endpoint->extractOffsetValue($context, $context->endpoint->defaultExtracts($context));
|
||||
$offset = $endpoint->extractOffsetValue($context, $endpoint->defaultExtracts($context));
|
||||
}
|
||||
|
||||
$posts = $discussion->posts()
|
||||
@@ -304,14 +310,12 @@ class DiscussionResource extends AbstractDatabaseResource
|
||||
$model->newQuery()->getConnection()->transaction(function () use ($model, $context) {
|
||||
$model->save();
|
||||
|
||||
/**
|
||||
* @var JsonApi $api
|
||||
* @var Post $post
|
||||
*/
|
||||
/** @var JsonApi $api */
|
||||
$api = $context->api;
|
||||
|
||||
// Now that the discussion has been created, we can add the first post.
|
||||
// We will do this by running the PostReply command.
|
||||
/** @var Post $post */
|
||||
$post = $api->forResource(PostResource::class)
|
||||
->forEndpoint('create')
|
||||
->withRequest($context->request)
|
||||
|
@@ -10,14 +10,16 @@
|
||||
namespace Flarum\Api\Resource;
|
||||
|
||||
use Flarum\Api\Endpoint;
|
||||
use Flarum\Api\Resource\Contracts\Findable;
|
||||
use Flarum\Api\Schema;
|
||||
use Flarum\Extension\Extension;
|
||||
use Flarum\Extension\ExtensionManager;
|
||||
use Tobyz\JsonApiServer\Context;
|
||||
use Tobyz\JsonApiServer\Resource\Findable;
|
||||
|
||||
/**
|
||||
* @todo: change to a simple ExtensionResource with readme field.
|
||||
*
|
||||
* @extends AbstractResource<Extension>
|
||||
*/
|
||||
class ExtensionReadmeResource extends AbstractResource implements Findable
|
||||
{
|
||||
|
@@ -11,19 +11,26 @@ namespace Flarum\Api\Resource;
|
||||
|
||||
use Flarum\Api\Context;
|
||||
use Flarum\Api\Endpoint;
|
||||
use Flarum\Api\Resource\Contracts\Findable;
|
||||
use Flarum\Api\Schema;
|
||||
use Flarum\Foundation\Application;
|
||||
use Flarum\Foundation\Config;
|
||||
use Flarum\Group\Group;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Illuminate\Contracts\Filesystem\Cloud;
|
||||
use Illuminate\Contracts\Filesystem\Factory;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use stdClass;
|
||||
use Tobyz\JsonApiServer\Resource\Findable;
|
||||
|
||||
/**
|
||||
* @extends AbstractResource<stdClass>
|
||||
*/
|
||||
class ForumResource extends AbstractResource implements Findable
|
||||
{
|
||||
/**
|
||||
* @var Filesystem&Cloud
|
||||
*/
|
||||
protected Filesystem $assetsFilesystem;
|
||||
|
||||
public function __construct(
|
||||
|
@@ -20,6 +20,9 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Tobyz\JsonApiServer\Context;
|
||||
|
||||
/**
|
||||
* @extends AbstractDatabaseResource<Group>
|
||||
*/
|
||||
class GroupResource extends AbstractDatabaseResource
|
||||
{
|
||||
public function __construct(
|
||||
|
@@ -10,7 +10,6 @@
|
||||
namespace Flarum\Api\Resource;
|
||||
|
||||
use Flarum\Api\Endpoint;
|
||||
use Flarum\Api\Resource\Contracts\Findable;
|
||||
use Flarum\Api\Schema;
|
||||
use Flarum\Mail\DriverInterface;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
@@ -18,7 +17,11 @@ use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Validation\Factory;
|
||||
use stdClass;
|
||||
use Tobyz\JsonApiServer\Context;
|
||||
use Tobyz\JsonApiServer\Resource\Findable;
|
||||
|
||||
/**
|
||||
* @extends AbstractResource<object>
|
||||
*/
|
||||
class MailSettingResource extends AbstractResource implements Findable
|
||||
{
|
||||
public function __construct(
|
||||
|
@@ -16,8 +16,11 @@ use Flarum\Bus\Dispatcher;
|
||||
use Flarum\Notification\Command\ReadNotification;
|
||||
use Flarum\Notification\Notification;
|
||||
use Flarum\Notification\NotificationRepository;
|
||||
use Tobyz\JsonApiServer\Pagination\Pagination;
|
||||
use Tobyz\JsonApiServer\Pagination\OffsetPagination;
|
||||
|
||||
/**
|
||||
* @extends AbstractDatabaseResource<Notification>
|
||||
*/
|
||||
class NotificationResource extends AbstractDatabaseResource
|
||||
{
|
||||
public function __construct(
|
||||
@@ -39,8 +42,10 @@ class NotificationResource extends AbstractDatabaseResource
|
||||
public function query(\Tobyz\JsonApiServer\Context $context): object
|
||||
{
|
||||
if ($context->listing(self::class)) {
|
||||
/** @var Pagination $pagination */
|
||||
$pagination = ($context->endpoint->paginationResolver)($context);
|
||||
/** @var Endpoint\Index $endpoint */
|
||||
$endpoint = $context->endpoint;
|
||||
/** @var OffsetPagination $pagination */
|
||||
$pagination = ($endpoint->paginationResolver)($context);
|
||||
|
||||
return $this->notifications->query($context->getActor(), $pagination->limit, $pagination->offset);
|
||||
}
|
||||
|
@@ -28,6 +28,9 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Tobyz\JsonApiServer\Exception\BadRequestException;
|
||||
|
||||
/**
|
||||
* @extends AbstractDatabaseResource<Post>
|
||||
*/
|
||||
class PostResource extends AbstractDatabaseResource
|
||||
{
|
||||
public static int $defaultLimit = 20;
|
||||
@@ -187,8 +190,12 @@ class PostResource extends AbstractDatabaseResource
|
||||
}
|
||||
})
|
||||
->serialize(function (null|string|array $value, Context $context) {
|
||||
// Prevent the string type from trying to convert array content (for event posts) to a string.
|
||||
$context->field->type = null;
|
||||
/**
|
||||
* Prevent the string type from trying to convert array content (for event posts) to a string.
|
||||
* @var Schema\Str $field
|
||||
*/
|
||||
$field = $context->field;
|
||||
$field->type = null;
|
||||
|
||||
return $value;
|
||||
}),
|
||||
@@ -196,7 +203,7 @@ class PostResource extends AbstractDatabaseResource
|
||||
->visible(function (Post $post) {
|
||||
return $post instanceof CommentPost;
|
||||
})
|
||||
->get(function (Post $post, Context $context) {
|
||||
->get(function (CommentPost $post, Context $context) {
|
||||
try {
|
||||
$rendered = $post->formatContent($context->request);
|
||||
$post->setAttribute('renderFailed', false);
|
||||
|
@@ -35,6 +35,9 @@ use Illuminate\Support\Str;
|
||||
use Intervention\Image\ImageManager;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @extends AbstractDatabaseResource<User>
|
||||
*/
|
||||
class UserResource extends AbstractDatabaseResource
|
||||
{
|
||||
public function __construct(
|
||||
@@ -224,6 +227,7 @@ class UserResource extends AbstractDatabaseResource
|
||||
})
|
||||
->set(function (User $user, ?string $value, Context $context) {
|
||||
if ($value) {
|
||||
/** @var RegistrationToken $token */
|
||||
$token = RegistrationToken::validOrFail($value);
|
||||
|
||||
$context->setParam('token', $token);
|
||||
|
@@ -44,11 +44,6 @@ class UserState extends AbstractModel
|
||||
'last_read_at' => 'datetime'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = ['last_read_post_number'];
|
||||
|
||||
/**
|
||||
|
@@ -10,11 +10,13 @@
|
||||
namespace Flarum\Extend;
|
||||
|
||||
use Flarum\Api\Endpoint\EndpointInterface;
|
||||
use Flarum\Api\Resource\Contracts\Resource;
|
||||
use Flarum\Extension\Extension;
|
||||
use Flarum\Foundation\ContainerUtil;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use ReflectionClass;
|
||||
use RuntimeException;
|
||||
use Tobyz\JsonApiServer\Endpoint\Endpoint;
|
||||
use Tobyz\JsonApiServer\Resource\Resource;
|
||||
use Tobyz\JsonApiServer\Schema\Field\Field;
|
||||
use Tobyz\JsonApiServer\Schema\Sort;
|
||||
|
||||
@@ -55,7 +57,7 @@ class ApiResource implements ExtenderInterface
|
||||
/**
|
||||
* Remove endpoints from the resource.
|
||||
*
|
||||
* @param array $endpoints must be an array of class names of the endpoints.
|
||||
* @param array $endpoints must be an array of names of the endpoints.
|
||||
* @param callable|class-string|null $condition a callable that returns a boolean or a string that represents whether this should be applied.
|
||||
*/
|
||||
public function removeEndpoints(array $endpoints, callable|string $condition = null): self
|
||||
@@ -68,14 +70,13 @@ class ApiResource implements ExtenderInterface
|
||||
/**
|
||||
* Modify an endpoint.
|
||||
*
|
||||
* @param class-string<\Flarum\Api\Endpoint\EndpointInterface>|array<\Flarum\Api\Endpoint\EndpointInterface> $endpointClass the class name of the endpoint.
|
||||
* or an array of class names of the endpoints.
|
||||
* @param string|string[] $endpointNameOrClass the name or class name of the endpoint or an array of so.
|
||||
* @param callable|class-string $mutator a callable that accepts an endpoint and returns the modified endpoint.
|
||||
*/
|
||||
public function endpoint(string|array $endpointClass, callable|string $mutator): self
|
||||
public function endpoint(string|array $endpointNameOrClass, callable|string $mutator): self
|
||||
{
|
||||
foreach ((array) $endpointClass as $endpointClassItem) {
|
||||
$this->endpoint[$endpointClassItem][] = $mutator;
|
||||
foreach ((array) $endpointNameOrClass as $item) {
|
||||
$this->endpoint[$item][] = $mutator;
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -176,39 +177,45 @@ class ApiResource implements ExtenderInterface
|
||||
/** @var class-string<\Flarum\Api\Resource\AbstractResource|\Flarum\Api\Resource\AbstractDatabaseResource> $resourceClass */
|
||||
$resourceClass = $this->resourceClass;
|
||||
|
||||
$resourceClass::mutateEndpoints(function (array $endpoints, Resource $resource) use ($container): array {
|
||||
foreach ($this->endpoints as $newEndpointsCallback) {
|
||||
$newEndpointsCallback = ContainerUtil::wrapCallback($newEndpointsCallback, $container);
|
||||
$endpoints = array_merge($endpoints, $newEndpointsCallback());
|
||||
}
|
||||
|
||||
foreach ($this->removeEndpoints as $removeEndpointClass) {
|
||||
[$endpointsToRemove, $condition] = $removeEndpointClass;
|
||||
|
||||
if ($this->isApplicable($condition, $resource, $container)) {
|
||||
$endpoints = array_filter($endpoints, fn (EndpointInterface $endpoint) => ! in_array($endpoint::class, $endpointsToRemove));
|
||||
$resourceClass::mutateEndpoints(
|
||||
/**
|
||||
* @var EndpointInterface[] $endpoints
|
||||
*/
|
||||
function (array $endpoints, Resource $resource) use ($container): array {
|
||||
foreach ($this->endpoints as $newEndpointsCallback) {
|
||||
$newEndpointsCallback = ContainerUtil::wrapCallback($newEndpointsCallback, $container);
|
||||
$endpoints = array_merge($endpoints, $newEndpointsCallback());
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($endpoints as $key => $endpoint) {
|
||||
$endpointClass = $endpoint::class;
|
||||
foreach ($this->removeEndpoints as $removeEndpointClass) {
|
||||
[$endpointsToRemove, $condition] = $removeEndpointClass;
|
||||
|
||||
if (! empty($this->endpoint[$endpointClass])) {
|
||||
foreach ($this->endpoint[$endpointClass] as $mutator) {
|
||||
$mutateEndpoint = ContainerUtil::wrapCallback($mutator, $container);
|
||||
$endpoint = $mutateEndpoint($endpoint, $resource);
|
||||
|
||||
if (! $endpoint instanceof EndpointInterface) {
|
||||
throw new \RuntimeException('The endpoint mutator must return an instance of '.EndpointInterface::class);
|
||||
}
|
||||
if ($this->isApplicable($condition, $resource, $container)) {
|
||||
$endpoints = array_filter($endpoints, fn (Endpoint $endpoint) => ! in_array($endpoint->name, $endpointsToRemove));
|
||||
}
|
||||
}
|
||||
|
||||
$endpoints[$key] = $endpoint;
|
||||
}
|
||||
foreach ($endpoints as $key => $endpoint) {
|
||||
$endpointClass = $endpoint::class;
|
||||
|
||||
return $endpoints;
|
||||
});
|
||||
if (! empty($this->endpoint[$endpoint->name]) || ! empty($this->endpoint[$endpointClass])) {
|
||||
foreach (array_merge($this->endpoint[$endpoint->name] ?? [], $this->endpoint[$endpointClass] ?? []) as $mutator) {
|
||||
$mutateEndpoint = ContainerUtil::wrapCallback($mutator, $container);
|
||||
$endpoint = $mutateEndpoint($endpoint, $resource);
|
||||
|
||||
if (! $endpoint instanceof EndpointInterface) {
|
||||
throw new RuntimeException('The endpoint mutator must return an instance of '.EndpointInterface::class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$endpoints[$key] = $endpoint;
|
||||
}
|
||||
|
||||
return $endpoints;
|
||||
}
|
||||
);
|
||||
|
||||
$resourceClass::mutateFields(function (array $fields, Resource $resource) use ($container): array {
|
||||
foreach ($this->fields as $newFieldsCallback) {
|
||||
@@ -231,7 +238,7 @@ class ApiResource implements ExtenderInterface
|
||||
$field = $mutateField($field);
|
||||
|
||||
if (! $field instanceof Field) {
|
||||
throw new \RuntimeException('The field mutator must return an instance of '.Field::class);
|
||||
throw new RuntimeException('The field mutator must return an instance of '.Field::class);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -263,7 +270,7 @@ class ApiResource implements ExtenderInterface
|
||||
$sort = $mutateSort($sort);
|
||||
|
||||
if (! $sort instanceof Sort) {
|
||||
throw new \RuntimeException('The sort mutator must return an instance of '.Sort::class);
|
||||
throw new RuntimeException('The sort mutator must return an instance of '.Sort::class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -40,7 +40,6 @@ class Routes implements ExtenderInterface
|
||||
*
|
||||
* The handler should accept:
|
||||
* - \Psr\Http\Message\ServerRequestInterface $request
|
||||
* - \Tobscure\JsonApi\Document $document: If it extends one of the Flarum Api controllers.
|
||||
*
|
||||
* The handler should return:
|
||||
* - \Psr\Http\Message\ResponseInterface $response
|
||||
@@ -64,7 +63,6 @@ class Routes implements ExtenderInterface
|
||||
*
|
||||
* The handler should accept:
|
||||
* - \Psr\Http\Message\ServerRequestInterface $request
|
||||
* - \Tobscure\JsonApi\Document $document: If it extends one of the Flarum Api controllers.
|
||||
*
|
||||
* The handler should return:
|
||||
* - \Psr\Http\Message\ResponseInterface $response
|
||||
@@ -88,7 +86,6 @@ class Routes implements ExtenderInterface
|
||||
*
|
||||
* The handler should accept:
|
||||
* - \Psr\Http\Message\ServerRequestInterface $request
|
||||
* - \Tobscure\JsonApi\Document $document: If it extends one of the Flarum Api controllers.
|
||||
*
|
||||
* The handler should return:
|
||||
* - \Psr\Http\Message\ResponseInterface $response
|
||||
@@ -112,7 +109,6 @@ class Routes implements ExtenderInterface
|
||||
*
|
||||
* The handler should accept:
|
||||
* - \Psr\Http\Message\ServerRequestInterface $request
|
||||
* - \Tobscure\JsonApi\Document $document: If it extends one of the Flarum Api controllers.
|
||||
*
|
||||
* The handler should return:
|
||||
* - \Psr\Http\Message\ResponseInterface $response
|
||||
@@ -136,7 +132,6 @@ class Routes implements ExtenderInterface
|
||||
*
|
||||
* The handler should accept:
|
||||
* - \Psr\Http\Message\ServerRequestInterface $request
|
||||
* - \Tobscure\JsonApi\Document $document: If it extends one of the Flarum Api controllers.
|
||||
*
|
||||
* The handler should return:
|
||||
* - \Psr\Http\Message\ResponseInterface $response
|
||||
|
@@ -20,7 +20,7 @@ class JsonApiExceptionHandler
|
||||
return (new HandledError(
|
||||
$e,
|
||||
'validation_error',
|
||||
$e->getJsonApiStatus()
|
||||
intval($e->getJsonApiStatus())
|
||||
))->withDetails($e->getJsonApiErrors());
|
||||
}
|
||||
}
|
||||
|
@@ -78,7 +78,7 @@ class RequestUtil
|
||||
{
|
||||
$limit = $request->getQueryParams()['page']['limit'] ?? '';
|
||||
|
||||
if (is_null($limit) || ! filled($limit)) {
|
||||
if (! filled($limit)) {
|
||||
$limit = $defaultLimit;
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,9 @@ class NotificationRepository
|
||||
return $this->query($user, $limit, $offset)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Builder<Notification>
|
||||
*/
|
||||
public function query(User $user, ?int $limit = null, int $offset = 0): Builder
|
||||
{
|
||||
$primaries = Notification::query()
|
||||
|
@@ -16,6 +16,9 @@ parameters:
|
||||
- stubs/Illuminate/Contracts/Filesystem/Cloud.stub
|
||||
- stubs/Illuminate/Contracts/Filesystem/Filesystem.stub
|
||||
|
||||
# We know for a fact the JsonApi object used internally is always the Flarum one.
|
||||
- stubs/Tobyz/JsonApiServer/JsonApi.stub
|
||||
|
||||
services:
|
||||
-
|
||||
class: Flarum\PHPStan\Relations\ModelRelationsExtension
|
||||
|
@@ -30,3 +30,13 @@ parameters:
|
||||
# ignore this error, so we have to ignore it globally.
|
||||
- message: '#^Parameter \#[0-9]+ \$[A-z0-9_]+ of method Flarum\Extend\[A-z0-9_:\\()]+ expects \(?callable\([A-z0-9_,|\\: ()-]+\)\)?, (callable|Closure)\([A-z0-9_,|\\: ()-]+\) given\.$#'
|
||||
reportUnmatched: false
|
||||
|
||||
# PHPStan suddenly doesn't recognize callables can be function names?
|
||||
- message: '#^Parameter \#[0-9]+ \$[A-z0-9_]+ of function [A-z0-9_:\\()]+ expects \(?callable\([A-z0-9_,|\\: ()-]+, ''[A-z0-9_:\\()]+'' given\.$#'
|
||||
reportUnmatched: false
|
||||
|
||||
# Not if we're using our own static make method.
|
||||
- message: '#^Called ''Model\:\:make\(\)'' which performs unnecessary work, use ''new Model\(\)''\.$#'
|
||||
|
||||
# This assumes that the phpdoc telling it it's not nullable is correct, that's not the case for internal Laravel typings.
|
||||
- message: '#^Property [A-z0-9-_:$,\\]+ \([A-z]+\) on left side of \?\? is not nullable\.$#'
|
||||
|
11
php-packages/phpstan/stubs/Tobyz/JsonApiServer/JsonApi.stub
Normal file
11
php-packages/phpstan/stubs/Tobyz/JsonApiServer/JsonApi.stub
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Tobyz\JsonApiServer;
|
||||
|
||||
/**
|
||||
* @mixin \Flarum\Api\JsonApi
|
||||
*/
|
||||
class JsonApi
|
||||
{
|
||||
|
||||
}
|
Reference in New Issue
Block a user