diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 23512ff..c1fed25 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: true matrix: - php: [8.2, 8.3] + php: [8.2, 8.3, 8.4] laravel: [11] steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index f82979e..444db4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. This projec ## Unreleased +## [4.3.0] - 2024-11-26 + +### Added + +- [#19](https://github.com/laravel-json-api/core/pull/19) The `Authorizer` contract now allows all methods to return a + `bool` or an authorizer response. + +### Fixed + +- Removed deprecation notices in PHP 8.4. + ## [4.2.0] - 2024-08-21 ### Added diff --git a/composer.json b/composer.json index 16e6df1..0098432 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "require": { "php": "^8.2", "ext-json": "*", + "illuminate/auth": "^11.33", "illuminate/contracts": "^11.0", "illuminate/http": "^11.0", "illuminate/support": "^11.0" diff --git a/phpunit.xml b/phpunit.xml index b54b694..d2cb9ed 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -13,6 +13,7 @@ failOnWarning="true" failOnDeprecation="true" failOnNotice="true" + displayDetailsOnTestsThatTriggerDeprecations="true" > diff --git a/src/Contracts/Auth/Authorizer.php b/src/Contracts/Auth/Authorizer.php index 8c83b4d..2378e30 100644 --- a/src/Contracts/Auth/Authorizer.php +++ b/src/Contracts/Auth/Authorizer.php @@ -11,6 +11,7 @@ namespace LaravelJsonApi\Contracts\Auth; +use Illuminate\Auth\Access\Response; use Illuminate\Http\Request; interface Authorizer @@ -20,45 +21,45 @@ interface Authorizer * * @param Request $request * @param string $modelClass - * @return bool + * @return bool|Response */ - public function index(Request $request, string $modelClass): bool; + public function index(Request $request, string $modelClass): bool|Response; /** * Authorize the store controller action. * * @param Request $request * @param string $modelClass - * @return bool + * @return bool|Response */ - public function store(Request $request, string $modelClass): bool; + public function store(Request $request, string $modelClass): bool|Response; /** * Authorize the show controller action. * * @param Request $request * @param object $model - * @return bool + * @return bool|Response */ - public function show(Request $request, object $model): bool; + public function show(Request $request, object $model): bool|Response; /** * Authorize the update controller action. * * @param object $model * @param Request $request - * @return bool + * @return bool|Response */ - public function update(Request $request, object $model): bool; + public function update(Request $request, object $model): bool|Response; /** * Authorize the destroy controller action. * * @param Request $request * @param object $model - * @return bool + * @return bool|Response */ - public function destroy(Request $request, object $model): bool; + public function destroy(Request $request, object $model): bool|Response; /** * Authorize the show-related controller action. @@ -66,9 +67,9 @@ public function destroy(Request $request, object $model): bool; * @param Request $request * @param object $model * @param string $fieldName - * @return bool + * @return bool|Response */ - public function showRelated(Request $request, object $model, string $fieldName): bool; + public function showRelated(Request $request, object $model, string $fieldName): bool|Response; /** * Authorize the show-relationship controller action. @@ -76,9 +77,9 @@ public function showRelated(Request $request, object $model, string $fieldName): * @param Request $request * @param object $model * @param string $fieldName - * @return bool + * @return bool|Response */ - public function showRelationship(Request $request, object $model, string $fieldName): bool; + public function showRelationship(Request $request, object $model, string $fieldName): bool|Response; /** * Authorize the update-relationship controller action. @@ -86,9 +87,9 @@ public function showRelationship(Request $request, object $model, string $fieldN * @param Request $request * @param object $model * @param string $fieldName - * @return bool + * @return bool|Response */ - public function updateRelationship(Request $request, object $model, string $fieldName): bool; + public function updateRelationship(Request $request, object $model, string $fieldName): bool|Response; /** * Authorize the attach-relationship controller action. @@ -96,9 +97,9 @@ public function updateRelationship(Request $request, object $model, string $fiel * @param Request $request * @param object $model * @param string $fieldName - * @return bool + * @return bool|Response */ - public function attachRelationship(Request $request, object $model, string $fieldName): bool; + public function attachRelationship(Request $request, object $model, string $fieldName): bool|Response; /** * Authorize the detach-relationship controller action. @@ -106,7 +107,7 @@ public function attachRelationship(Request $request, object $model, string $fiel * @param Request $request * @param object $model * @param string $fieldName - * @return bool + * @return bool|Response */ - public function detachRelationship(Request $request, object $model, string $fieldName): bool; + public function detachRelationship(Request $request, object $model, string $fieldName): bool|Response; } diff --git a/src/Contracts/Schema/Schema.php b/src/Contracts/Schema/Schema.php index eb769cb..f5d488c 100644 --- a/src/Contracts/Schema/Schema.php +++ b/src/Contracts/Schema/Schema.php @@ -72,7 +72,7 @@ public function uriType(): string; * @param bool|null $secure * @return string */ - public function url($extra = [], bool $secure = null): string; + public function url($extra = [], ?bool $secure = null): string; /** * Do resources of this type have a `self` link? diff --git a/src/Contracts/Server/Server.php b/src/Contracts/Server/Server.php index 94add03..1384f00 100644 --- a/src/Contracts/Server/Server.php +++ b/src/Contracts/Server/Server.php @@ -74,5 +74,5 @@ public function authorizable(): bool; * @param bool|null $secure * @return string */ - public function url($extra = [], bool $secure = null): string; + public function url($extra = [], ?bool $secure = null): string; } diff --git a/src/Core/Auth/Authorizer.php b/src/Core/Auth/Authorizer.php index 31b4a8d..2347752 100644 --- a/src/Core/Auth/Authorizer.php +++ b/src/Core/Auth/Authorizer.php @@ -12,6 +12,7 @@ namespace LaravelJsonApi\Core\Auth; use Illuminate\Contracts\Auth\Access\Gate; +use Illuminate\Auth\Access\Response; use Illuminate\Http\Request; use LaravelJsonApi\Contracts\Auth\Authorizer as AuthorizerContract; use LaravelJsonApi\Contracts\Schema\Schema; @@ -47,10 +48,10 @@ public function __construct(Gate $gate, JsonApiService $service) /** * @inheritDoc */ - public function index(Request $request, string $modelClass): bool + public function index(Request $request, string $modelClass): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'viewAny', $modelClass ); @@ -62,10 +63,10 @@ public function index(Request $request, string $modelClass): bool /** * @inheritDoc */ - public function store(Request $request, string $modelClass): bool + public function store(Request $request, string $modelClass): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'create', $modelClass ); @@ -77,10 +78,10 @@ public function store(Request $request, string $modelClass): bool /** * @inheritDoc */ - public function show(Request $request, object $model): bool + public function show(Request $request, object $model): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'view', $model ); @@ -92,10 +93,10 @@ public function show(Request $request, object $model): bool /** * @inheritDoc */ - public function update(Request $request, object $model): bool + public function update(Request $request, object $model): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'update', $model ); @@ -107,10 +108,10 @@ public function update(Request $request, object $model): bool /** * @inheritDoc */ - public function destroy(Request $request, object $model): bool + public function destroy(Request $request, object $model): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'delete', $model ); @@ -122,10 +123,10 @@ public function destroy(Request $request, object $model): bool /** * @inheritDoc */ - public function showRelated(Request $request, object $model, string $fieldName): bool + public function showRelated(Request $request, object $model, string $fieldName): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'view' . Str::classify($fieldName), $model ); @@ -137,7 +138,7 @@ public function showRelated(Request $request, object $model, string $fieldName): /** * @inheritDoc */ - public function showRelationship(Request $request, object $model, string $fieldName): bool + public function showRelationship(Request $request, object $model, string $fieldName): bool|Response { return $this->showRelated($request, $model, $fieldName); } @@ -145,10 +146,10 @@ public function showRelationship(Request $request, object $model, string $fieldN /** * @inheritDoc */ - public function updateRelationship(Request $request, object $model, string $fieldName): bool + public function updateRelationship(Request $request, object $model, string $fieldName): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'update' . Str::classify($fieldName), [$model, $this->createRelation($request, $fieldName)] ); @@ -160,10 +161,10 @@ public function updateRelationship(Request $request, object $model, string $fiel /** * @inheritDoc */ - public function attachRelationship(Request $request, object $model, string $fieldName): bool + public function attachRelationship(Request $request, object $model, string $fieldName): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'attach' . Str::classify($fieldName), [$model, $this->createRelation($request, $fieldName)] ); @@ -175,10 +176,10 @@ public function attachRelationship(Request $request, object $model, string $fiel /** * @inheritDoc */ - public function detachRelationship(Request $request, object $model, string $fieldName): bool + public function detachRelationship(Request $request, object $model, string $fieldName): bool|Response { if ($this->mustAuthorize()) { - return $this->gate->check( + return $this->gate->inspect( 'detach' . Str::classify($fieldName), [$model, $this->createRelation($request, $fieldName)] ); diff --git a/src/Core/Document/JsonApi.php b/src/Core/Document/JsonApi.php index d389268..e2442be 100644 --- a/src/Core/Document/JsonApi.php +++ b/src/Core/Document/JsonApi.php @@ -34,7 +34,7 @@ class JsonApi implements Serializable * @param string|null $version * @return JsonApi */ - public static function make(string $version = null): self + public static function make(?string $version = null): self { return new self($version); } @@ -113,7 +113,7 @@ public static function nullable($value): ?self * * @param string|null $version */ - public function __construct(string $version = null) + public function __construct(?string $version = null) { $this->version = $version ?: null; } diff --git a/src/Core/Document/LinkHref.php b/src/Core/Document/LinkHref.php index b6fd870..5ef0edf 100644 --- a/src/Core/Document/LinkHref.php +++ b/src/Core/Document/LinkHref.php @@ -56,7 +56,7 @@ public static function cast($value): self * @param string $uri * @param iterable|null $query */ - public function __construct(string $uri, iterable $query = null) + public function __construct(string $uri, ?iterable $query = null) { if (empty($uri)) { throw new UnexpectedValueException('Expecting a non-empty string URI.'); diff --git a/src/Core/Exceptions/JsonApiException.php b/src/Core/Exceptions/JsonApiException.php index dd20fe2..cdd9146 100644 --- a/src/Core/Exceptions/JsonApiException.php +++ b/src/Core/Exceptions/JsonApiException.php @@ -38,7 +38,7 @@ class JsonApiException extends Exception implements HttpExceptionInterface, Resp * @param Throwable|null $previous * @return static */ - public static function make($errors, Throwable $previous = null): self + public static function make($errors, ?Throwable $previous = null): self { return new self($errors, $previous); } @@ -50,7 +50,7 @@ public static function make($errors, Throwable $previous = null): self * @param Throwable|null $previous * @return static */ - public static function error($error, Throwable $previous = null): self + public static function error($error, ?Throwable $previous = null): self { return new self(Error::cast($error), $previous); } @@ -62,7 +62,7 @@ public static function error($error, Throwable $previous = null): self * @param Throwable|null $previous * @param array $headers */ - public function __construct($errors, Throwable $previous = null, array $headers = []) + public function __construct($errors, ?Throwable $previous = null, array $headers = []) { parent::__construct('JSON:API error', 0, $previous); $this->errors = ErrorList::cast($errors); diff --git a/src/Core/Json/Hash.php b/src/Core/Json/Hash.php index 927a1d3..0e4a0d0 100644 --- a/src/Core/Json/Hash.php +++ b/src/Core/Json/Hash.php @@ -55,7 +55,7 @@ public static function cast($value): self * * @param array|null $value */ - public function __construct(array $value = null) + public function __construct(?array $value = null) { $this->value = $value ?: []; } diff --git a/src/Core/Query/Custom/ExtendedQueryParameters.php b/src/Core/Query/Custom/ExtendedQueryParameters.php index caf34f0..4cc4292 100644 --- a/src/Core/Query/Custom/ExtendedQueryParameters.php +++ b/src/Core/Query/Custom/ExtendedQueryParameters.php @@ -34,7 +34,7 @@ class ExtendedQueryParameters extends QueryParameters * @param string|null $name * @return string */ - public static function withCount(string $name = null): string + public static function withCount(?string $name = null): string { if (empty($name)) { return self::$withCount; @@ -59,12 +59,12 @@ public static function withCount(string $name = null): string * @param array|null $unrecognised */ public function __construct( - IncludePaths $includePaths = null, - FieldSets $fieldSets = null, - SortFields $sortFields = null, - array $page = null, - FilterParameters $filters = null, - array $unrecognised = null + ?IncludePaths $includePaths = null, + ?FieldSets $fieldSets = null, + ?SortFields $sortFields = null, + ?array $page = null, + ?FilterParameters $filters = null, + ?array $unrecognised = null ) { parent::__construct( $includePaths, diff --git a/src/Core/Query/QueryParameters.php b/src/Core/Query/QueryParameters.php index 2674940..dfcc113 100644 --- a/src/Core/Query/QueryParameters.php +++ b/src/Core/Query/QueryParameters.php @@ -158,12 +158,12 @@ public static function nullable($value): ?self * @param array|null $unrecognised */ public function __construct( - IncludePaths $includePaths = null, - FieldSets $fieldSets = null, - SortFields $sortFields = null, - array $page = null, - FilterParameters $filters = null, - array $unrecognised = null + ?IncludePaths $includePaths = null, + ?FieldSets $fieldSets = null, + ?SortFields $sortFields = null, + ?array $page = null, + ?FilterParameters $filters = null, + ?array $unrecognised = null ) { $this->includePaths = $includePaths; $this->fieldSets = $fieldSets; diff --git a/src/Core/Resources/JsonApiResource.php b/src/Core/Resources/JsonApiResource.php index 1b93167..9987872 100644 --- a/src/Core/Resources/JsonApiResource.php +++ b/src/Core/Resources/JsonApiResource.php @@ -309,7 +309,7 @@ protected function identifierMeta(): array * @param string|null $keyName * @return Relation */ - protected function relation(string $fieldName, string $keyName = null): Relation + protected function relation(string $fieldName, ?string $keyName = null): Relation { $field = $this->schema->isRelationship($fieldName) ? $this->schema->relationship($fieldName) : null; diff --git a/src/Core/Resources/Relation.php b/src/Core/Resources/Relation.php index 28d2d1c..a085cde 100644 --- a/src/Core/Resources/Relation.php +++ b/src/Core/Resources/Relation.php @@ -91,8 +91,8 @@ public function __construct( object $resource, ?string $baseUri, string $fieldName, - string $keyName = null, - string $uriName = null + ?string $keyName = null, + ?string $uriName = null ) { $this->resource = $resource; $this->baseUri = $baseUri; diff --git a/src/Core/Responses/Concerns/IsResponsable.php b/src/Core/Responses/Concerns/IsResponsable.php index ac43757..02c8a1d 100644 --- a/src/Core/Responses/Concerns/IsResponsable.php +++ b/src/Core/Responses/Concerns/IsResponsable.php @@ -143,7 +143,7 @@ public function withEncodeOptions(int $options): self * @param string|null $value * @return $this */ - public function withHeader(string $name, string $value = null): self + public function withHeader(string $name, ?string $value = null): self { $this->headers[$name] = $value; diff --git a/src/Core/Schema/IdParser.php b/src/Core/Schema/IdParser.php index 78acdb9..a3e7f41 100644 --- a/src/Core/Schema/IdParser.php +++ b/src/Core/Schema/IdParser.php @@ -44,7 +44,7 @@ public static function encoder($value): IdEncoderContract * @param ID|null $field * @return static */ - public static function make(ID $field = null): self + public static function make(?ID $field = null): self { return new self($field); } diff --git a/src/Core/Server/Server.php b/src/Core/Server/Server.php index 167760b..fe90c1a 100644 --- a/src/Core/Server/Server.php +++ b/src/Core/Server/Server.php @@ -159,7 +159,7 @@ public function authorizable(): bool /** * @inheritDoc */ - public function url($extra = [], bool $secure = null): string + public function url($extra = [], ?bool $secure = null): string { $tail = Collection::make(Arr::wrap($extra)) ->map(fn($value) => ($value instanceof UrlRoutable) ? $value->getRouteKey() : $value)