diff --git a/README.md b/README.md
index 12130226..1c19e579 100644
--- a/README.md
+++ b/README.md
@@ -175,11 +175,11 @@ use alsvanzelf\jsonapi\ResourceDocument;
use alsvanzelf\jsonapi\interfaces\ExtensionInterface;
class ExampleExtension implements ExtensionInterface {
- public function getOfficialLink() {
+ public function getOfficialLink(): string {
return 'https://example.org/extension-documentation';
}
- public function getNamespace() {
+ public function getNamespace(): string {
return 'foo';
}
}
diff --git a/UPGRADE_2_TO_3.md b/UPGRADE_2_TO_3.md
new file mode 100644
index 00000000..8940a243
--- /dev/null
+++ b/UPGRADE_2_TO_3.md
@@ -0,0 +1,43 @@
+# Upgrade from library v2 to v3
+
+## Checking links, ...
+
+Objects more often use uninitialized properties. `has*()` helper methods have been added to support the new flow.
+
+- `$object->links` to `if ($object->hasLinks()) $object->links`
+
+## Interfaces
+
+When extending interfaces, you'll have to add method argument types and return types.
+
+Check [all interfaces](/src/interfaces) for the correct typing.
+
+## Enums
+
+Content types:
+- `Document::CONTENT_TYPE_OFFICIAL` to `ContentTypeEnum::Official`
+- `Document::CONTENT_TYPE_DEBUG` to `ContentTypeEnum::Debug`
+- `Document::CONTENT_TYPE_JSONP` to `ContentTypeEnum::Jsonp`
+
+Jsonapi versions:
+- `Document::JSONAPI_VERSION_1_0` to `JsonapiVersionEnum::V_1_0`
+- `Document::JSONAPI_VERSION_1_1` to `JsonapiVersionEnum::V_1_1`
+- `Document::JSONAPI_VERSION_LATEST` to `JsonapiVersionEnum::Latest`
+
+Document levels:
+- `Document::LEVEL_ROOT` to `DocumentLevelEnum::Root`
+- `Document::LEVEL_JSONAPI` to `DocumentLevelEnum::Jsonapi`
+- `Document::LEVEL_Resource` to `DocumentLevelEnum::Resource`
+
+Sorting orders:
+- `RequestParser->getSortFields()` returns a `SortOrderEnum` instead of `string` for the `order` field
+
+Relationship types:
+- `RelationshipObject::TO_ONE` to `RelationshipTypeEnum::ToOne`
+- `RelationshipObject::TO_MANY` to `RelationshipTypeEnum::ToMany`
+
+## Internal
+
+Enums:
+- `RequestParser::SORT_*` to `SortOrderEnum::*`
+- `Validator::OBJECT_CONTAINER_*` to `ObjectContainerEnum::*`
diff --git a/examples/atomic_operations_extension.php b/examples/atomic_operations_extension.php
index 4e97c6da..caa6aaae 100644
--- a/examples/atomic_operations_extension.php
+++ b/examples/atomic_operations_extension.php
@@ -1,5 +1,7 @@
Content-Type: '.$contentType.''.PHP_EOL;
$options = [
diff --git a/examples/meta_only.php b/examples/meta_only.php
index a41df02c..60562d7f 100644
--- a/examples/meta_only.php
+++ b/examples/meta_only.php
@@ -1,5 +1,7 @@
addRelationship('bar', null);
-$document->addRelationshipObject('baz', new RelationshipObject(RelationshipObject::TO_ONE));
-$document->addRelationshipObject('baf', new RelationshipObject(RelationshipObject::TO_MANY));
+$document->addRelationshipObject('baz', new RelationshipObject(RelationshipTypeEnum::ToOne));
+$document->addRelationshipObject('baf', new RelationshipObject(RelationshipTypeEnum::ToMany));
/**
* sending the response
diff --git a/examples/output.php b/examples/output.php
index 0844c336..f6726e8d 100644
--- a/examples/output.php
+++ b/examples/output.php
@@ -1,7 +1,9 @@
';
$document->sendResponse($options);
echo '';
-echo '
Also sends http status code ('.$document->getHttpStatusCode().') and headers: [Content-Type: '.Document::CONTENT_TYPE_OFFICIAL.']
';
+echo 'Also sends http status code ('.$document->getHttpStatusCode().') and headers: [Content-Type: '.ContentTypeEnum::Official->value.']
';
diff --git a/examples/profile.php b/examples/profile.php
index 8b070b6b..82458551 100644
--- a/examples/profile.php
+++ b/examples/profile.php
@@ -1,7 +1,9 @@
Content-Type: '.$contentType.''.PHP_EOL;
$options = [
diff --git a/examples/relationship_to_many_document.php b/examples/relationship_to_many_document.php
index 1f02263a..f2a2af2a 100644
--- a/examples/relationship_to_many_document.php
+++ b/examples/relationship_to_many_document.php
@@ -1,5 +1,7 @@
setSelfLink('/articles/1/relationship/author', $meta=[], $level=Document::LEVEL_ROOT);
+$relationshipDocument->setSelfLink('/articles/1/relationship/author', $meta=[], $level=DocumentLevelEnum::Root);
$relationshipDocument->addLink('related', '/articles/1/author');
/**
diff --git a/examples/relationships.php b/examples/relationships.php
index bc25dfe4..6755f34d 100644
--- a/examples/relationships.php
+++ b/examples/relationships.php
@@ -1,7 +1,10 @@
addResource($friend1Resource);
$relationshipObject->addResource($friend2Resource);
@@ -65,7 +68,7 @@
* to-many relationship, different types
*/
-$relationshipObject = new RelationshipObject($type=RelationshipObject::TO_MANY);
+$relationshipObject = new RelationshipObject($type=RelationshipTypeEnum::ToMany);
$relationshipObject->addResource($ship1Resource);
$relationshipObject->addResource($dockResource);
diff --git a/examples/request_superglobals.php b/examples/request_superglobals.php
index fff59921..cb93d06f 100644
--- a/examples/request_superglobals.php
+++ b/examples/request_superglobals.php
@@ -1,6 +1,8 @@
value;
/**
* parsing the request
diff --git a/examples/resource_human_api.php b/examples/resource_human_api.php
index 67ed6578..b9ae514d 100644
--- a/examples/resource_human_api.php
+++ b/examples/resource_human_api.php
@@ -1,5 +1,7 @@
id);
-$selfResourceMeta = ['level' => Document::LEVEL_RESOURCE];
-$partnerMeta = ['level' => Document::LEVEL_RESOURCE];
-$redirectMeta = ['level' => Document::LEVEL_ROOT];
+$selfResourceMeta = ['level' => DocumentLevelEnum::Resource->name];
+$partnerMeta = ['level' => DocumentLevelEnum::Resource->name];
+$redirectMeta = ['level' => DocumentLevelEnum::Root->name];
$document->setSelfLink('/user/42', $selfResourceMeta);
-$document->addLink('partner', '/user/1', $partnerMeta, $level=Document::LEVEL_RESOURCE);
-$document->addLink('redirect', '/login', $redirectMeta, $level=Document::LEVEL_ROOT);
+$document->addLink('partner', '/user/1', $partnerMeta, $level=DocumentLevelEnum::Resource);
+$document->addLink('redirect', '/login', $redirectMeta, $level=DocumentLevelEnum::Root);
/**
* sending the response
diff --git a/examples/resource_nested_relations.php b/examples/resource_nested_relations.php
index b0418f32..e182a48b 100644
--- a/examples/resource_nested_relations.php
+++ b/examples/resource_nested_relations.php
@@ -1,5 +1,7 @@
setType('user');
$resource->setAttributesObject($attributes42);
-$relationship = new RelationshipObject(RelationshipObject::TO_ONE);
+$relationship = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationship->setResource($resource);
$relationships = new RelationshipsObject();
$relationships->addRelationshipObject('friend', $relationship);
diff --git a/examples/status_only.php b/examples/status_only.php
index abcced8a..94439c01 100644
--- a/examples/status_only.php
+++ b/examples/status_only.php
@@ -1,5 +1,7 @@
'
+
treatPhpDocTypesAsCertain: false
strictRules:
diff --git a/rector.php b/rector.php
index 9556204e..de660fc6 100644
--- a/rector.php
+++ b/rector.php
@@ -3,6 +3,8 @@
declare(strict_types=1);
use Rector\Config\RectorConfig;
+use Rector\Php70\Rector\StmtsAwareInterface\IfIssetToCoalescingRector;
+use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector;
// @see https://github.com/rectorphp/rector/blob/main/docs/rector_rules_overview.md for more rules
@@ -12,16 +14,23 @@
__DIR__ . '/tests',
__DIR__ . '/examples',
])
-
+ ->withRules([
+ DeclareStrictTypesRector::class,
+ ])
+ ->withSkip([
+ // better explicit readability
+ IfIssetToCoalescingRector::class,
+ ])
+
// tab-based indenting
->withIndent(indentChar: "\t", indentSize: 1)
-
- // slowly increase php version
+
+ // lowest supported php version
->withPhpSets(php82: true)
-
+
// slowly increase levels
->withTypeCoverageLevel(1)
->withDeadCodeLevel(1)
-
+
// @todo add `->withPreparedSets()` once on a higher level with other rules
;
diff --git a/src/CollectionDocument.php b/src/CollectionDocument.php
index ba7c458b..29f3d435 100644
--- a/src/CollectionDocument.php
+++ b/src/CollectionDocument.php
@@ -1,5 +1,7 @@
addResource()} to change that behavior
- *
- * @param ResourceInterface ...$resources
- * @return CollectionDocument
*/
- public static function fromResources(ResourceInterface ...$resources) {
+ public static function fromResources(ResourceInterface ...$resources): self {
$collectionDocument = new self();
foreach ($resources as $resource) {
@@ -50,11 +49,9 @@ public static function fromResources(ResourceInterface ...$resources) {
}
/**
- * @param string $type
- * @param string|int $id
- * @param array $attributes optional, if given a ResourceObject is added, otherwise a ResourceIdentifierObject is added
+ * @param array $attributes if given a ResourceObject is added, otherwise a ResourceIdentifierObject is added
*/
- public function add($type, $id, array $attributes=[]) {
+ public function add(string $type, string|int $id, array $attributes=[]): void {
if ($attributes === []) {
$this->addResource(new ResourceIdentifierObject($type, $id));
}
@@ -63,7 +60,12 @@ public function add($type, $id, array $attributes=[]) {
}
}
- public function setPaginationLinks($previousHref=null, $nextHref=null, $firstHref=null, $lastHref=null) {
+ public function setPaginationLinks(
+ ?string $previousHref=null,
+ ?string $nextHref=null,
+ ?string $firstHref=null,
+ ?string $lastHref=null,
+ ): void {
if ($previousHref !== null) {
$this->addLink('prev', $previousHref);
}
@@ -87,12 +89,11 @@ public function setPaginationLinks($previousHref=null, $nextHref=null, $firstHre
*
* adds included resources if found inside the resource's relationships, unless $options['includeContainedResources'] is set to false
*
- * @param ResourceInterface $resource
- * @param array $options optional {@see CollectionDocument::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see CollectionDocument::$defaults}
*
* @throws InputException if the resource is empty
*/
- public function addResource(ResourceInterface $resource, array $options=[]) {
+ public function addResource(ResourceInterface $resource, array $options=[]): void {
if ($resource->getResource()->isEmpty()) {
throw new InputException('does not make sense to add empty resources to a collection');
}
@@ -112,7 +113,7 @@ public function addResource(ResourceInterface $resource, array $options=[]) {
* DocumentInterface
*/
- public function toArray() {
+ public function toArray(): array {
$array = parent::toArray();
$array['data'] = [];
@@ -127,7 +128,7 @@ public function toArray() {
* ResourceContainerInterface
*/
- public function getContainedResources() {
+ public function getContainedResources(): array {
return $this->resources;
}
}
diff --git a/src/DataDocument.php b/src/DataDocument.php
index 470fcefc..8d44270e 100644
--- a/src/DataDocument.php
+++ b/src/DataDocument.php
@@ -1,5 +1,7 @@
validator->claimUsedResourceIdentifier($resourceObject);
@@ -58,7 +58,7 @@ public function addIncludedResourceObject(ResourceObject ...$resourceObjects) {
* DocumentInterface
*/
- public function toArray() {
+ public function toArray(): array {
$array = parent::toArray();
$array['data'] = null;
diff --git a/src/Document.php b/src/Document.php
index cd26fccd..e95a4cc4 100644
--- a/src/Document.php
+++ b/src/Document.php
@@ -1,7 +1,11 @@
Document::CONTENT_TYPE_OFFICIAL,
+ 'contentType' => ContentTypeEnum::Official,
/**
* overwrite the array to encode to json
@@ -94,26 +87,18 @@ public function __construct() {
*/
/**
- * @param string $key
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
- * @param string $level one of the Document::LEVEL_* constants, optional, defaults to Document::LEVEL_ROOT
+ * if $meta is given, a LinkObject is added, otherwise a link string is added
+ *
+ * @param array $meta
*
- * @throws InputException if the $level is Document::LEVEL_JSONAPI, Document::LEVEL_RESOURCE, or unknown
+ * @throws InputException if the $level is not DocumentLevelEnum::Root
*/
- public function addLink($key, $href, array $meta=[], $level=Document::LEVEL_ROOT) {
- if ($level === Document::LEVEL_ROOT) {
- $this->linkManagerAddLink($key, $href, $meta);
- }
- elseif ($level === Document::LEVEL_JSONAPI) {
- throw new InputException('level "jsonapi" can not be used for links');
- }
- elseif ($level === Document::LEVEL_RESOURCE) {
- throw new InputException('level "resource" can only be set on a ResourceDocument');
- }
- else {
- throw new InputException('unknown level "'.$level.'"');
- }
+ public function addLink(string $key, ?string $href, array $meta=[], DocumentLevelEnum $level=DocumentLevelEnum::Root): void {
+ match ($level) {
+ DocumentLevelEnum::Root => $this->linkManagerAddLink($key, $href, $meta),
+ DocumentLevelEnum::Jsonapi => throw new InputException('level "jsonapi" can not be used for links'),
+ DocumentLevelEnum::Resource => throw new InputException('level "resource" can only be set on a ResourceDocument'),
+ };
}
/**
@@ -121,13 +106,11 @@ public function addLink($key, $href, array $meta=[], $level=Document::LEVEL_ROOT
*
* @note a LinkObject is added when extensions or profiles are applied
*
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
- * @param string $level one of the Document::LEVEL_* constants, optional, defaults to Document::LEVEL_ROOT
+ * @param array $meta if given a LinkObject is added, otherwise a link string is added
*/
- public function setSelfLink($href, array $meta=[], $level=Document::LEVEL_ROOT) {
- if ($level === Document::LEVEL_ROOT && ($this->extensions !== [] || $this->profiles !== [])) {
- $contentType = Converter::prepareContentType(Document::CONTENT_TYPE_OFFICIAL, $this->extensions, $this->profiles);
+ public function setSelfLink(string $href, array $meta=[], DocumentLevelEnum $level=DocumentLevelEnum::Root): void {
+ if ($level === DocumentLevelEnum::Root && ($this->extensions !== [] || $this->profiles !== [])) {
+ $contentType = Converter::prepareContentType(ContentTypeEnum::Official, $this->extensions, $this->profiles);
$linkObject = new LinkObject($href, $meta);
$linkObject->setMediaType($contentType);
@@ -144,43 +127,38 @@ public function setSelfLink($href, array $meta=[], $level=Document::LEVEL_ROOT)
*
* for example this could link to an OpenAPI or JSON Schema document
*
- * @note according to the spec, this can only be set to Document::LEVEL_ROOT
+ * @note according to the spec, this can only be set to DocumentLevelEnum::Root
*
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
+ * @param array $meta if given a LinkObject is added, otherwise a link string is added
*/
- public function setDescribedByLink($href, array $meta=[]) {
- $this->addLink('describedby', $href, $meta, $level=Document::LEVEL_ROOT);
+ public function setDescribedByLink(string $href, array $meta=[]): void {
+ $this->addLink('describedby', $href, $meta, $level=DocumentLevelEnum::Root);
}
/**
- * @param string $key
- * @param mixed $value
- * @param string $level one of the Document::LEVEL_* constants, optional, defaults to Document::LEVEL_ROOT
- *
* @throws InputException if the $level is unknown
- * @throws InputException if the $level is Document::LEVEL_RESOURCE
+ * @throws InputException if the $level is DocumentLevelEnum::Resource
*/
- public function addMeta($key, $value, $level=Document::LEVEL_ROOT) {
- if ($level === Document::LEVEL_ROOT) {
- if ($this->meta === null) {
+ public function addMeta(string $key, mixed $value, DocumentLevelEnum $level=DocumentLevelEnum::Root): void {
+ if ($level === DocumentLevelEnum::Root) {
+ if (isset($this->meta) === false) {
$this->setMetaObject(new MetaObject());
}
$this->meta->add($key, $value);
}
- elseif ($level === Document::LEVEL_JSONAPI) {
- if ($this->jsonapi === null) {
+ elseif ($level === DocumentLevelEnum::Jsonapi) {
+ if (isset($this->jsonapi) === false) {
$this->setJsonapiObject(new JsonapiObject());
}
$this->jsonapi->addMeta($key, $value);
}
- elseif ($level === Document::LEVEL_RESOURCE) {
+ elseif ($level === DocumentLevelEnum::Resource) {
throw new InputException('level "resource" can only be set on a ResourceDocument');
}
else {
- throw new InputException('unknown level "'.$level.'"');
+ throw new InputException('unknown level "'.$level->value.'"');
}
}
@@ -188,24 +166,18 @@ public function addMeta($key, $value, $level=Document::LEVEL_ROOT) {
* spec api
*/
- /**
- * @param MetaObject $metaObject
- */
- public function setMetaObject(MetaObject $metaObject) {
+ public function setMetaObject(MetaObject $metaObject): void {
$this->meta = $metaObject;
}
- /**
- * @param JsonapiObject $jsonapiObject
- */
- public function setJsonapiObject(JsonapiObject $jsonapiObject) {
+ public function setJsonapiObject(JsonapiObject $jsonapiObject): void {
$this->jsonapi = $jsonapiObject;
}
/**
* hide that this api supports jsonapi, or which version it is using
*/
- public function unsetJsonapiObject() {
+ public function unsetJsonapiObject(): void {
$this->jsonapi = null;
}
@@ -218,12 +190,10 @@ public function unsetJsonapiObject() {
*
* @see https://jsonapi.org/extensions/#extensions
*
- * @param ExtensionInterface $extension
- *
* @throws Exception if namespace uses illegal characters
* @throws DuplicateException if namespace conflicts with another applied extension
*/
- public function applyExtension(ExtensionInterface $extension) {
+ public function applyExtension(ExtensionInterface $extension): void {
$namespace = $extension->getNamespace();
if (strlen($namespace) < 1 || preg_match('{[^a-zA-Z0-9]}', $namespace) === 1) {
throw new Exception('invalid namespace "'.$namespace.'"');
@@ -234,7 +204,7 @@ public function applyExtension(ExtensionInterface $extension) {
$this->extensions[$namespace] = $extension;
- if ($this->jsonapi !== null) {
+ if (isset($this->jsonapi)) {
$this->jsonapi->addExtension($extension);
}
}
@@ -247,13 +217,11 @@ public function applyExtension(ExtensionInterface $extension) {
* however the $profile could have custom methods to help
*
* @see https://jsonapi.org/extensions/#profiles
- *
- * @param ProfileInterface $profile
*/
- public function applyProfile(ProfileInterface $profile) {
+ public function applyProfile(ProfileInterface $profile): void {
$this->profiles[] = $profile;
- if ($this->jsonapi !== null) {
+ if (isset($this->jsonapi)) {
$this->jsonapi->addProfile($profile);
}
}
@@ -262,7 +230,7 @@ public function applyProfile(ProfileInterface $profile) {
* DocumentInterface
*/
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
@@ -272,20 +240,20 @@ public function toArray() {
$array = array_merge($array, $this->getExtensionMembers());
}
- if ($this->jsonapi !== null && $this->jsonapi->isEmpty() === false) {
+ if (isset($this->jsonapi) && $this->jsonapi->isEmpty() === false) {
$array['jsonapi'] = $this->jsonapi->toArray();
}
- if ($this->links !== null && $this->links->isEmpty() === false) {
+ if ($this->hasLinks()) {
$array['links'] = $this->links->toArray();
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
$array['meta'] = $this->meta->toArray();
}
return $array;
}
- public function toJson(array $options=[]) {
+ public function toJson(array $options=[]): string {
$options = array_merge(self::$defaults, $options);
$array = $options['array'] ?? $this->toArray();
@@ -306,7 +274,7 @@ public function toJson(array $options=[]) {
return $json;
}
- public function sendResponse(array $options=[]) {
+ public function sendResponse(array $options=[]): void {
$options = array_merge(self::$defaults, $options);
if ($this->httpStatusCode === 204) {
@@ -329,7 +297,7 @@ public function sendResponse(array $options=[]) {
*/
#[\ReturnTypeWillChange]
- public function jsonSerialize() {
+ public function jsonSerialize(): array {
return $this->toArray();
}
}
diff --git a/src/ErrorsDocument.php b/src/ErrorsDocument.php
index 69163dbc..3e905b44 100644
--- a/src/ErrorsDocument.php
+++ b/src/ErrorsDocument.php
@@ -1,9 +1,10 @@
> */
+ protected array $httpStatusCodes;
+ /** @var PHPStanTypeAlias_InternalOptions */
+ protected static array $defaults = [
/**
* add the trace of exceptions when adding exceptions
* in some cases it might be handy to disable if traces are too big
@@ -28,9 +29,6 @@ class ErrorsDocument extends Document {
'includeExceptionPrevious' => true,
];
- /**
- * @param ?ErrorObject $errorObject optional
- */
public function __construct(?ErrorObject $errorObject=null) {
parent::__construct();
@@ -44,11 +42,9 @@ public function __construct(?ErrorObject $errorObject=null) {
*/
/**
- * @param \Throwable $exception
- * @param array $options optional {@see ErrorsDocument::$defaults}
- * @return ErrorsDocument
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ErrorsDocument::$defaults}
*/
- public static function fromException(\Throwable $exception, array $options=[]) {
+ public static function fromException(\Throwable $exception, array $options=[]): self {
$options = array_merge(self::$defaults, $options);
$errorsDocument = new self();
@@ -62,10 +58,9 @@ public static function fromException(\Throwable $exception, array $options=[]) {
*
* recursively adds multiple ErrorObjects if $exception carries a ->getPrevious()
*
- * @param \Throwable $exception
- * @param array $options optional {@see ErrorsDocument::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ErrorsDocument::$defaults}
*/
- public function addException(\Throwable $exception, array $options=[]) {
+ public function addException(\Throwable $exception, array $options=[]): void {
$options = array_merge(self::$defaults, $options);
$this->addErrorObject(ErrorObject::fromException($exception, $options));
@@ -82,11 +77,17 @@ public function addException(\Throwable $exception, array $options=[]) {
/**
* @param string|int $genericCode developer-friendly code of the generic type of error
* @param string $genericTitle human-friendly title of the generic type of error
- * @param string $specificDetails optional, human-friendly explanation of the specific error
- * @param string $specificAboutLink optional, human-friendly explanation of the specific error
- * @param string $genericTypeLink optional, human-friendly explanation of the generic type of error
+ * @param string $specificDetails human-friendly explanation of the specific error
+ * @param string $specificAboutLink human-friendly explanation of the specific error
+ * @param string $genericTypeLink human-friendly explanation of the generic type of error
*/
- public function add($genericCode, $genericTitle, $specificDetails=null, $specificAboutLink=null, $genericTypeLink=null) {
+ public function add(
+ string|int $genericCode,
+ string $genericTitle,
+ ?string $specificDetails=null,
+ ?string $specificAboutLink=null,
+ ?string $genericTypeLink=null,
+ ): void {
$errorObject = new ErrorObject($genericCode, $genericTitle, $specificDetails, $specificAboutLink, $genericTypeLink);
$this->addErrorObject($errorObject);
@@ -98,10 +99,8 @@ public function add($genericCode, $genericTitle, $specificDetails=null, $specifi
/**
* @note also defines the http status code of the document if the ErrorObject has it defined
- *
- * @param ErrorObject $errorObject
*/
- public function addErrorObject(ErrorObject $errorObject) {
+ public function addErrorObject(ErrorObject $errorObject): void {
$this->errors[] = $errorObject;
if ($errorObject->hasHttpStatusCode()) {
@@ -113,7 +112,7 @@ public function addErrorObject(ErrorObject $errorObject) {
* DocumentInterface
*/
- public function toArray() {
+ public function toArray(): array {
$array = parent::toArray();
$array['errors'] = [];
@@ -134,11 +133,8 @@ public function toArray() {
/**
* @internal
- *
- * @param string|int $httpStatusCode
- * @return int
*/
- protected function determineHttpStatusCode($httpStatusCode) {
+ protected function determineHttpStatusCode(string|int $httpStatusCode): int {
// add the new code
$category = substr((string) $httpStatusCode, 0, 1);
$this->httpStatusCodes[$category][$httpStatusCode] = true;
diff --git a/src/MetaDocument.php b/src/MetaDocument.php
index 299ad201..22a18160 100644
--- a/src/MetaDocument.php
+++ b/src/MetaDocument.php
@@ -1,8 +1,11 @@
$meta
*/
- public static function fromArray(array $meta) {
+ public static function fromArray(array $meta): self {
$metaDocument = new self();
$metaDocument->setMetaObject(MetaObject::fromArray($meta));
@@ -27,10 +29,9 @@ public static function fromArray(array $meta) {
}
/**
- * @param object $meta
- * @return MetaDocument
+ * @param object $meta
*/
- public static function fromObject($meta) {
+ public static function fromObject(object $meta): self {
$array = Converter::objectToArray($meta);
return self::fromArray($array);
@@ -38,12 +39,8 @@ public static function fromObject($meta) {
/**
* wrapper for Document::addMeta() to the primary data of this document available via `add()`
- *
- * @param string $key
- * @param mixed $value
- * @param string $level one of the Document::LEVEL_* constants, optional, defaults to Document::LEVEL_ROOT
*/
- public function add($key, $value, $level=Document::LEVEL_ROOT) {
+ public function add(string $key, mixed $value, DocumentLevelEnum $level=DocumentLevelEnum::Root): void {
parent::addMeta($key, $value, $level);
}
@@ -55,7 +52,7 @@ public function add($key, $value, $level=Document::LEVEL_ROOT) {
* DocumentInterface
*/
- public function toArray() {
+ public function toArray(): array {
$array = parent::toArray();
// force meta to be set, and be an object when converting to json
diff --git a/src/ResourceDocument.php b/src/ResourceDocument.php
index ff7ebca2..e4da6f13 100644
--- a/src/ResourceDocument.php
+++ b/src/ResourceDocument.php
@@ -1,10 +1,13 @@
setPrimaryResource() if not passing them during construction
- *
- * @param string $type optional
- * @param string|int $id optional
*/
- public function __construct($type=null, $id=null) {
+ public function __construct(?string $type=null, string|int|null $id=null) {
parent::__construct();
$this->setPrimaryResource(new ResourceObject($type, $id));
@@ -52,13 +51,14 @@ public function __construct($type=null, $id=null) {
*/
/**
- * @param array $attributes
- * @param string $type optional
- * @param string|int $id optional
- * @param array $options optional {@see ResourceDocument::$defaults} {@see ResourceObject::$defaults}
- * @return ResourceDocument
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceDocument::$defaults} {@see ResourceObject::$defaults}
*/
- public static function fromArray(array $attributes, $type=null, $id=null, array $options=[]) {
+ public static function fromArray(
+ array $attributes,
+ ?string $type=null,
+ string|int|null $id=null,
+ array $options=[],
+ ): self {
$resourceDocument = new self();
$resourceDocument->setPrimaryResource(ResourceObject::fromArray($attributes, $type, $id, $options), $options);
@@ -66,13 +66,14 @@ public static function fromArray(array $attributes, $type=null, $id=null, array
}
/**
- * @param object $attributes
- * @param string $type optional
- * @param string|int $id optional
- * @param array $options optional {@see ResourceDocument::$defaults}
- * @return ResourceDocument
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceDocument::$defaults}
*/
- public static function fromObject($attributes, $type=null, $id=null, array $options=[]) {
+ public static function fromObject(
+ object $attributes,
+ ?string $type=null,
+ string|int|null $id=null,
+ array $options=[],
+ ): self {
$array = Converter::objectToArray($attributes);
return self::fromArray($array, $type, $id, $options);
@@ -81,11 +82,10 @@ public static function fromObject($attributes, $type=null, $id=null, array $opti
/**
* add key-value pairs to the resource's attributes
*
- * @param string $key
- * @param mixed $value objects will be converted using `get_object_vars()`
- * @param array $options optional {@see ResourceDocument::$defaults}
+ * @param mixed $value objects will be converted using `get_object_vars()`
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceDocument::$defaults}
*/
- public function add($key, $value, array $options=[]) {
+ public function add(string $key, mixed $value, array $options=[]): void {
if ($this->resource instanceof ResourceObject === false) {
throw new Exception('the resource is an identifier-only object');
}
@@ -98,13 +98,18 @@ public function add($key, $value, array $options=[]) {
*
* adds included resources if found inside the relation, unless $options['includeContainedResources'] is set to false
*
- * @param string $key
- * @param mixed $relation ResourceInterface | ResourceInterface[] | CollectionDocument
- * @param array $links optional
- * @param array $meta optional
- * @param array $options optional {@see ResourceDocument::$defaults}
+ * @param CollectionDocument|ResourceInterface|ResourceInterface[]|null $relation
+ * @param array $links
+ * @param array $meta
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceDocument::$defaults}
*/
- public function addRelationship($key, $relation, array $links=[], array $meta=[], array $options=[]) {
+ public function addRelationship(
+ string $key,
+ array|CollectionDocument|ResourceInterface|null $relation,
+ array $links=[],
+ array $meta=[],
+ array $options=[],
+ ): void {
if ($this->resource instanceof ResourceObject === false) {
throw new Exception('the resource is an identifier-only object');
}
@@ -119,17 +124,16 @@ public function addRelationship($key, $relation, array $links=[], array $meta=[]
}
/**
- * @param string $key
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
- * @param string $level one of the Document::LEVEL_* constants, optional, defaults to Document::LEVEL_ROOT
+ * if $meta is given, a LinkObject is added, otherwise a link string is added
+ *
+ * @param array $meta
*/
- public function addLink($key, $href, array $meta=[], $level=Document::LEVEL_ROOT) {
+ public function addLink(string $key, ?string $href, array $meta=[], DocumentLevelEnum $level=DocumentLevelEnum::Root): void {
if ($this->resource instanceof ResourceObject === false) {
throw new Exception('the resource is an identifier-only object');
}
- if ($level === Document::LEVEL_RESOURCE) {
+ if ($level === DocumentLevelEnum::Resource) {
$this->resource->addLink($key, $href, $meta);
}
else {
@@ -140,15 +144,14 @@ public function addLink($key, $href, array $meta=[], $level=Document::LEVEL_ROOT
/**
* set the self link on the resource
*
- * @param string $href
- * @param array $meta optional
+ * @param array $meta
*/
- public function setSelfLink($href, array $meta=[], $level=Document::LEVEL_RESOURCE) {
+ public function setSelfLink(string $href, array $meta=[], DocumentLevelEnum $level=DocumentLevelEnum::Resource): void {
if ($this->resource instanceof ResourceObject === false) {
throw new Exception('the resource is an identifier-only object');
}
- if ($level === Document::LEVEL_RESOURCE) {
+ if ($level === DocumentLevelEnum::Resource) {
$this->resource->setSelfLink($href, $meta);
}
else {
@@ -156,13 +159,8 @@ public function setSelfLink($href, array $meta=[], $level=Document::LEVEL_RESOUR
}
}
- /**
- * @param string $key
- * @param mixed $value
- * @param string $level one of the Document::LEVEL_* constants, optional, defaults to Document::LEVEL_ROOT
- */
- public function addMeta($key, $value, $level=Document::LEVEL_ROOT) {
- if ($level === Document::LEVEL_RESOURCE) {
+ public function addMeta(string $key, mixed $value, DocumentLevelEnum $level=DocumentLevelEnum::Root): void {
+ if ($level === DocumentLevelEnum::Resource) {
$this->resource->addMeta($key, $value);
}
else {
@@ -174,32 +172,28 @@ public function addMeta($key, $value, $level=Document::LEVEL_ROOT) {
* wrapping ResourceObject spec api
*/
- /**
- * @param string $type
- */
- public function setType($type) {
+ public function setType(string $type): void {
$this->resource->setType($type);
}
/**
- * @param string|int $id will be casted to a string
+ * int $id will be casted to a string
*/
- public function setId($id) {
+ public function setId(string|int $id): void {
$this->resource->setId($id);
}
/**
- * @param string|int $localId will be casted to a string
+ * int $localId will be casted to a string
*/
- public function setLocalId($localId) {
+ public function setLocalId(string|int $localId): void {
$this->resource->setLocalId($localId);
}
/**
- * @param AttributesObject $attributesObject
- * @param array $options optional {@see ResourceObject::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceObject::$defaults}
*/
- public function setAttributesObject(AttributesObject $attributesObject, array $options=[]) {
+ public function setAttributesObject(AttributesObject $attributesObject, array $options=[]): void {
if ($this->resource instanceof ResourceObject === false) {
throw new Exception('the resource is an identifier-only object');
}
@@ -212,11 +206,9 @@ public function setAttributesObject(AttributesObject $attributesObject, array $o
*
* adds included resources if found inside the RelationshipObject, unless $options['includeContainedResources'] is set to false
*
- * @param string $key
- * @param RelationshipObject $relationshipObject
- * @param array $options optional {@see ResourceDocument::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceDocument::$defaults}
*/
- public function addRelationshipObject($key, RelationshipObject $relationshipObject, array $options=[]) {
+ public function addRelationshipObject(string $key, RelationshipObject $relationshipObject, array $options=[]): void {
if ($this->resource instanceof ResourceObject === false) {
throw new Exception('the resource is an identifier-only object');
}
@@ -235,10 +227,9 @@ public function addRelationshipObject($key, RelationshipObject $relationshipObje
*
* adds included resources if found inside the RelationshipObjects inside the RelationshipsObject, unless $options['includeContainedResources'] is set to false
*
- * @param RelationshipsObject $relationshipsObject
- * @param array $options optional {@see ResourceDocument::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceDocument::$defaults}
*/
- public function setRelationshipsObject(RelationshipsObject $relationshipsObject, array $options=[]) {
+ public function setRelationshipsObject(RelationshipsObject $relationshipsObject, array $options=[]): void {
if ($this->resource instanceof ResourceObject === false) {
throw new Exception('the resource is an identifier-only object');
}
@@ -261,12 +252,11 @@ public function setRelationshipsObject(RelationshipsObject $relationshipsObject,
*
* adds included resources if found inside the resource's relationships, unless $options['includeContainedResources'] is set to false
*
- * @param ResourceInterface $resource
- * @param array $options optional {@see ResourceDocument::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceDocument::$defaults}
*
* @throws InputException if the $resource is a ResourceDocument itself
*/
- public function setPrimaryResource(ResourceInterface $resource, array $options=[]) {
+ public function setPrimaryResource(ResourceInterface $resource, array $options=[]): void {
if ($resource instanceof ResourceDocument) {
throw new InputException('does not make sense to set a document inside a document, use ResourceObject or ResourceIdentifierObject instead');
}
@@ -290,11 +280,11 @@ public function setPrimaryResource(ResourceInterface $resource, array $options=[
* DocumentInterface
*/
- public function toArray() {
+ public function toArray(): array {
$array = parent::toArray();
$array['data'] = null;
- if ($this->resource !== null && $this->resource->isEmpty() === false) {
+ if ($this->resource->isEmpty() === false) {
$array['data'] = $this->resource->toArray();
}
@@ -305,15 +295,15 @@ public function toArray() {
* HasAttributesInterface
*/
- public function addAttribute($key, $value, array $options=[]) {
- return $this->add($key, $value);
+ public function addAttribute(string $key, mixed $value, array $options=[]): void {
+ $this->add($key, $value);
}
/**
* ResourceInterface
*/
- public function getResource($identifierOnly=false) {
+ public function getResource(bool $identifierOnly=false): ResourceIdentifierObject|ResourceObject {
return $this->resource->getResource($identifierOnly);
}
}
diff --git a/src/enums/ContentTypeEnum.php b/src/enums/ContentTypeEnum.php
new file mode 100644
index 00000000..a3d23d11
--- /dev/null
+++ b/src/enums/ContentTypeEnum.php
@@ -0,0 +1,11 @@
+value;
+}
diff --git a/src/enums/ObjectContainerEnum.php b/src/enums/ObjectContainerEnum.php
new file mode 100644
index 00000000..d2258c02
--- /dev/null
+++ b/src/enums/ObjectContainerEnum.php
@@ -0,0 +1,16 @@
+results = array_merge($this->results, $resources);
}
@@ -39,7 +40,7 @@ public function addResults(ResourceInterface ...$resources) {
* DocumentInterface
*/
- public function toArray() {
+ public function toArray(): array {
$results = [];
foreach ($this->results as $result) {
$results[] = [
diff --git a/src/extensions/AtomicOperationsExtension.php b/src/extensions/AtomicOperationsExtension.php
index 6b6cffd4..f5f3f86b 100644
--- a/src/extensions/AtomicOperationsExtension.php
+++ b/src/extensions/AtomicOperationsExtension.php
@@ -1,5 +1,7 @@
*/
+ protected array $atMembers = [];
/**
* human api
@@ -17,11 +19,7 @@ trait AtMemberManager {
* spec api
*/
- /**
- * @param string $key
- * @param mixed $value
- */
- public function addAtMember($key, $value) {
+ public function addAtMember(string $key, mixed $value): void {
if (str_starts_with($key, '@')) {
$key = substr($key, 1);
}
@@ -41,19 +39,17 @@ public function addAtMember($key, $value) {
/**
* @internal
- *
- * @return boolean
*/
- public function hasAtMembers() {
+ public function hasAtMembers(): bool {
return ($this->atMembers !== []);
}
/**
* @internal
*
- * @return array
+ * @return array
*/
- public function getAtMembers() {
+ public function getAtMembers(): array {
return $this->atMembers;
}
}
diff --git a/src/helpers/Converter.php b/src/helpers/Converter.php
index 336d4a80..b0c0edd3 100644
--- a/src/helpers/Converter.php
+++ b/src/helpers/Converter.php
@@ -1,7 +1,10 @@
toArray();
}
@@ -24,11 +23,8 @@ public static function objectToArray($object) {
/**
* @see https://stackoverflow.com/questions/7593969/regex-to-split-camelcase-or-titlecase-advanced/7599674#7599674
- *
- * @param string $camelCase
- * @return string
*/
- public static function camelCaseToWords($camelCase) {
+ public static function camelCaseToWords(string $camelCase): string {
$parts = preg_split('/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/', $camelCase);
return implode(' ', $parts);
@@ -37,12 +33,12 @@ public static function camelCaseToWords($camelCase) {
/**
* generates the value for a content type header, with extensions and profiles merged in if available
*
- * @param string $contentType
- * @param ExtensionInterface[] $extensions
- * @param ProfileInterface[] $profiles
- * @return string
+ * @param ExtensionInterface[] $extensions
+ * @param ProfileInterface[] $profiles
*/
- public static function prepareContentType($contentType, array $extensions, array $profiles) {
+ public static function prepareContentType(ContentTypeEnum $contentType, array $extensions, array $profiles): string {
+ $contentType = $contentType->value;
+
if ($extensions !== []) {
$extensionLinks = [];
foreach ($extensions as $extension) {
diff --git a/src/helpers/ExtensionMemberManager.php b/src/helpers/ExtensionMemberManager.php
index 1bfd257a..7d9c2c9a 100644
--- a/src/helpers/ExtensionMemberManager.php
+++ b/src/helpers/ExtensionMemberManager.php
@@ -1,5 +1,7 @@
*/
+ protected array $extensionMembers = [];
/**
* human api
@@ -18,12 +20,7 @@ trait ExtensionMemberManager {
* spec api
*/
- /**
- * @param ExtensionInterface $extension
- * @param string $key
- * @param mixed $value
- */
- public function addExtensionMember(ExtensionInterface $extension, $key, $value) {
+ public function addExtensionMember(ExtensionInterface $extension, string $key, mixed $value): void {
$namespace = $extension->getNamespace();
if (str_starts_with($key, $namespace.':')) {
@@ -45,19 +42,17 @@ public function addExtensionMember(ExtensionInterface $extension, $key, $value)
/**
* @internal
- *
- * @return boolean
*/
- public function hasExtensionMembers() {
+ public function hasExtensionMembers(): bool {
return ($this->extensionMembers !== []);
}
/**
* @internal
*
- * @return array
+ * @return array
*/
- public function getExtensionMembers() {
+ public function getExtensionMembers(): array {
return $this->extensionMembers;
}
}
diff --git a/src/helpers/HttpStatusCodeManager.php b/src/helpers/HttpStatusCodeManager.php
index 7c051b45..67af3697 100644
--- a/src/helpers/HttpStatusCodeManager.php
+++ b/src/helpers/HttpStatusCodeManager.php
@@ -1,24 +1,23 @@
httpStatusCode !== null);
+ public function hasHttpStatusCode(): bool {
+ return isset($this->httpStatusCode);
}
/**
* @internal
- *
- * @return int
*/
- public function getHttpStatusCode() {
+ public function getHttpStatusCode(): int {
return $this->httpStatusCode;
}
}
diff --git a/src/helpers/LinksManager.php b/src/helpers/LinksManager.php
index 0fa10c92..514302e5 100644
--- a/src/helpers/LinksManager.php
+++ b/src/helpers/LinksManager.php
@@ -1,13 +1,14 @@
$meta
*/
- public function addLink($key, $href, array $meta=[]) {
+ public function addLink(string $key, ?string $href, array $meta=[]): void {
$this->ensureLinksObject();
$this->links->add($key, $href, $meta);
}
@@ -31,21 +32,16 @@ public function addLink($key, $href, array $meta=[]) {
/**
* set a key containing a LinkObject
- *
- * @param string $key
- * @param LinkObject $linkObject
*/
- public function addLinkObject($key, LinkObject $linkObject) {
+ public function addLinkObject(string $key, LinkObject $linkObject): void {
$this->ensureLinksObject();
$this->links->addLinkObject($key, $linkObject);
}
/**
* set a LinksObject containing all links
- *
- * @param LinksObject $linksObject
*/
- public function setLinksObject(LinksObject $linksObject) {
+ public function setLinksObject(LinksObject $linksObject): void {
$this->links = $linksObject;
}
@@ -56,8 +52,23 @@ public function setLinksObject(LinksObject $linksObject) {
/**
* @internal
*/
- private function ensureLinksObject() {
- if ($this->links === null) {
+ protected function hasLinks(): bool {
+ if (isset($this->links) === false) {
+ return false;
+ }
+
+ if ($this->links->isEmpty()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @internal
+ */
+ private function ensureLinksObject(): void {
+ if (isset($this->links) === false) {
$this->setLinksObject(new LinksObject());
}
}
diff --git a/src/helpers/RequestParser.php b/src/helpers/RequestParser.php
index b672ff7d..3348821c 100644
--- a/src/helpers/RequestParser.php
+++ b/src/helpers/RequestParser.php
@@ -1,17 +1,17 @@
> $queryParameters all query parameters defined by the specification
+ * @param array $document the request jsonapi document
*/
public function __construct(
- private $selfLink='',
- private array $queryParameters=[],
- private array $document=[],
+ private readonly string $selfLink='',
+ private readonly array $queryParameters=[],
+ private readonly array $document=[],
) {}
- /**
- * @return self
- */
- public static function fromSuperglobals() {
+ public static function fromSuperglobals(): self {
$selfLink = '';
if (isset($_SERVER['REQUEST_SCHEME']) && isset($_SERVER['HTTP_HOST']) && isset($_SERVER['REQUEST_URI'])) {
$selfLink = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
@@ -49,8 +46,8 @@ public static function fromSuperglobals() {
$document = $_POST;
if ($document === [] && isset($_SERVER['CONTENT_TYPE'])) {
- $documentIsJsonapi = (str_contains((string) $_SERVER['CONTENT_TYPE'], Document::CONTENT_TYPE_OFFICIAL));
- $documentIsJson = (str_contains((string) $_SERVER['CONTENT_TYPE'], Document::CONTENT_TYPE_DEBUG));
+ $documentIsJsonapi = (str_contains((string) $_SERVER['CONTENT_TYPE'], ContentTypeEnum::Official->value));
+ $documentIsJson = (str_contains((string) $_SERVER['CONTENT_TYPE'], ContentTypeEnum::Debug->value));
if ($documentIsJsonapi || $documentIsJson) {
$document = json_decode(file_get_contents('php://input'), true);
@@ -64,11 +61,7 @@ public static function fromSuperglobals() {
return new self($selfLink, $queryParameters, $document);
}
- /**
- * @param ServerRequestInterface|RequestInterface $request
- * @return self
- */
- public static function fromPsrRequest(RequestInterface $request) {
+ public static function fromPsrRequest(ServerRequestInterface|RequestInterface $request): self {
$selfLink = (string) $request->getUri();
if ($request instanceof ServerRequestInterface) {
@@ -97,17 +90,12 @@ public static function fromPsrRequest(RequestInterface $request) {
* the full link used to make this request
*
* this is not a bare self link of a resource and includes query parameters if used
- *
- * @return string
*/
- public function getSelfLink() {
+ public function getSelfLink(): string {
return $this->selfLink;
}
- /**
- * @return boolean
- */
- public function hasIncludePaths() {
+ public function hasIncludePaths(): bool {
return isset($this->queryParameters['include']);
}
@@ -117,10 +105,10 @@ public function hasIncludePaths() {
* the nested format allows easier processing on each step of the chain
* the raw format allows for custom processing
*
- * @param array $options optional {@see RequestParser::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see RequestParser::$defaults}
* @return string[]|array
*/
- public function getIncludePaths(array $options=[]) {
+ public function getIncludePaths(array $options=[]): array {
if ($this->queryParameters['include'] === '') {
return [];
}
@@ -148,19 +136,14 @@ public function getIncludePaths(array $options=[]) {
return $restructured;
}
- /**
- * @param string $type
- * @return boolean
- */
- public function hasSparseFieldset($type) {
+ public function hasSparseFieldset(string $type): bool {
return isset($this->queryParameters['fields'][$type]);
}
/**
- * @param string $type
* @return string[]
*/
- public function getSparseFieldset($type) {
+ public function getSparseFieldset(string $type): array {
if ($this->queryParameters['fields'][$type] === '') {
return [];
}
@@ -168,10 +151,7 @@ public function getSparseFieldset($type) {
return explode(',', (string) $this->queryParameters['fields'][$type]);
}
- /**
- * @return boolean
- */
- public function hasSortFields() {
+ public function hasSortFields(): bool {
return isset($this->queryParameters['sort']);
}
@@ -183,13 +163,13 @@ public function hasSortFields() {
*
* @todo return some kind of SortFieldObject
*
- * @param array $options optional {@see RequestParser::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see RequestParser::$defaults}
* @return string[]|array
*/
- public function getSortFields(array $options=[]) {
+ public function getSortFields(array $options=[]): array {
if ($this->queryParameters['sort'] === '') {
return [];
}
@@ -203,11 +183,11 @@ public function getSortFields(array $options=[]) {
$sort = [];
foreach ($fields as $field) {
- $order = RequestParser::SORT_ASCENDING;
+ $order = SortOrderEnum::Ascending;
if (str_starts_with($field, '-')) {
$field = substr($field, 1);
- $order = RequestParser::SORT_DESCENDING;
+ $order = SortOrderEnum::Descending;
}
$sort[] = [
@@ -219,10 +199,7 @@ public function getSortFields(array $options=[]) {
return $sort;
}
- /**
- * @return boolean
- */
- public function hasPagination() {
+ public function hasPagination(): bool {
return isset($this->queryParameters['page']);
}
@@ -230,45 +207,32 @@ public function hasPagination() {
* @todo return some kind of PaginatorObject which recognizes the strategy of pagination used
* e.g. page-based, offset-based, cursor-based, or unknown
*
- * @return array
+ * @return array
*/
- public function getPagination() {
+ public function getPagination(): array {
return $this->queryParameters['page'];
}
- /**
- * @return boolean
- */
- public function hasFilter() {
+ public function hasFilter(): bool {
return isset($this->queryParameters['filter']);
}
/**
- * @return array
+ * @return string|array
*/
- public function getFilter() {
+ public function getFilter(): string|array {
return $this->queryParameters['filter'];
}
- /**
- * @return boolean
- */
- public function hasLocalId() {
+ public function hasLocalId(): bool {
return (isset($this->document['data']['lid']));
}
- /**
- * @return string
- */
- public function getLocalId() {
+ public function getLocalId(): string {
return $this->document['data']['lid'];
}
- /**
- * @param string $attributeName
- * @return boolean
- */
- public function hasAttribute($attributeName) {
+ public function hasAttribute(string $attributeName): bool {
if (isset($this->document['data']['attributes']) === false) {
return false;
}
@@ -279,19 +243,11 @@ public function hasAttribute($attributeName) {
return true;
}
- /**
- * @param string $attributeName
- * @return mixed
- */
- public function getAttribute($attributeName) {
+ public function getAttribute(string $attributeName): mixed {
return $this->document['data']['attributes'][$attributeName];
}
- /**
- * @param string $relationshipName
- * @return boolean
- */
- public function hasRelationship($relationshipName) {
+ public function hasRelationship(string $relationshipName): bool {
if (isset($this->document['data']['relationships']) === false) {
return false;
}
@@ -305,18 +261,13 @@ public function hasRelationship($relationshipName) {
/**
* @todo return some kind of read-only ResourceIdentifierObject
*
- * @param string $relationshipName
- * @return array
+ * @return ?array
*/
- public function getRelationship($relationshipName) {
+ public function getRelationship(string $relationshipName): ?array {
return $this->document['data']['relationships'][$relationshipName];
}
- /**
- * @param string $metaKey
- * @return boolean
- */
- public function hasMeta($metaKey) {
+ public function hasMeta(string $metaKey): bool {
if (isset($this->document['meta']) === false) {
return false;
}
@@ -327,18 +278,14 @@ public function hasMeta($metaKey) {
return true;
}
- /**
- * @param string $metaKey
- * @return mixed
- */
- public function getMeta($metaKey) {
+ public function getMeta(string $metaKey): mixed {
return $this->document['meta'][$metaKey];
}
/**
- * @return array
+ * @return array
*/
- public function getDocument() {
+ public function getDocument(): array {
return $this->document;
}
}
diff --git a/src/helpers/Validator.php b/src/helpers/Validator.php
index 2c9e5737..0639a9c3 100644
--- a/src/helpers/Validator.php
+++ b/src/helpers/Validator.php
@@ -1,7 +1,10 @@
*/
+ protected array $usedFields = [];
+ /** @var array */
+ protected array $usedResourceIdentifiers = [];
+ /** @var PHPStanTypeAlias_InternalOptions */
+ protected static array $defaults = [
/**
* blocks 'type' as a keyword inside attributes or relationships
* the specification doesn't allow this as 'type' is already set at the root of a resource
@@ -35,13 +32,12 @@ class Validator {
*
* @see https://jsonapi.org/format/1.1/#document-resource-object-fields
*
- * @param string[] $fieldNames
- * @param string $objectContainer one of the Validator::OBJECT_CONTAINER_* constants
- * @param array $options optional {@see Validator::$defaults}
+ * @param string[] $fieldNames
+ * @param PHPStanTypeAlias_InternalOptions $options {@see Validator::$defaults}
*
* @throws DuplicateException
*/
- public function claimUsedFields(array $fieldNames, $objectContainer, array $options=[]) {
+ public function claimUsedFields(array $fieldNames, ObjectContainerEnum $objectContainer, array $options=[]): void {
$options = array_merge(self::$defaults, $options);
foreach ($fieldNames as $fieldName) {
@@ -56,18 +52,15 @@ public function claimUsedFields(array $fieldNames, $objectContainer, array $opti
/**
* @note this is not allowed by the specification
*/
- if ($this->usedFields[$fieldName] === Validator::OBJECT_CONTAINER_TYPE && $options['enforceTypeFieldNamespace'] === false) {
+ if ($this->usedFields[$fieldName] === ObjectContainerEnum::Type && $options['enforceTypeFieldNamespace'] === false) {
continue;
}
- throw new DuplicateException('field name "'.$fieldName.'" already in use at "data.'.$this->usedFields[$fieldName].'"');
+ throw new DuplicateException('field name "'.$fieldName.'" already in use at "data.'.$this->usedFields[$fieldName]->value.'"');
}
}
- /**
- * @param string $objectContainerToClear one of the Validator::OBJECT_CONTAINER_* constants
- */
- public function clearUsedFields($objectContainerToClear) {
+ public function clearUsedFields(ObjectContainerEnum $objectContainerToClear): void {
foreach ($this->usedFields as $fieldName => $containerFound) {
if ($containerFound !== $objectContainerToClear) {
continue;
@@ -78,12 +71,10 @@ public function clearUsedFields($objectContainerToClear) {
}
/**
- * @param ResourceInterface $resource
- *
* @throws InputException if no type or id has been set on the resource
* @throws DuplicateException if the combination of type and id has been set before
*/
- public function claimUsedResourceIdentifier(ResourceInterface $resource) {
+ public function claimUsedResourceIdentifier(ResourceInterface $resource): void {
if ($resource->getResource()->hasIdentification() === false) {
throw new InputException('can not validate resource without identifier, set type and id/lid first');
}
@@ -102,11 +93,9 @@ public function claimUsedResourceIdentifier(ResourceInterface $resource) {
*
* @todo allow non-url safe chars
*
- * @param string $memberName
- *
* @throws InputException
*/
- public static function checkMemberName($memberName) {
+ public static function checkMemberName(string $memberName): void {
$globallyAllowedCharacters = 'a-zA-Z0-9';
$generallyAllowedCharacters = $globallyAllowedCharacters.'_-';
@@ -129,11 +118,7 @@ public static function checkMemberName($memberName) {
throw new InputException('invalid member name "'.$memberName.'"');
}
- /**
- * @param string|int $httpStatusCode
- * @return boolean
- */
- public static function checkHttpStatusCode($httpStatusCode) {
+ public static function checkHttpStatusCode(string|int $httpStatusCode): bool {
$httpStatusCode = (int) $httpStatusCode;
if ($httpStatusCode < 100) {
diff --git a/src/interfaces/DocumentInterface.php b/src/interfaces/DocumentInterface.php
index 6d3e3487..fc80a4a0 100644
--- a/src/interfaces/DocumentInterface.php
+++ b/src/interfaces/DocumentInterface.php
@@ -1,5 +1,7 @@
toJson()}
*
- * @return array
+ * @return array
*/
- public function toArray();
+ public function toArray(): array;
/**
* generate json with the contents of the document, used by {@see ->sendResponse()}
*
- * @param array $options optional
- * @return string json
+ * @param PHPStanTypeAlias_InternalOptions $options
*
* @throws Exception if generating json fails
*/
- public function toJson(array $options=[]);
+ public function toJson(array $options=[]): string;
/**
* send jsonapi response to the browser
*
* @note will set http status code and content type, and echo json
*
- * @param array $options optional
+ * @param PHPStanTypeAlias_InternalOptions $options
*/
- public function sendResponse(array $options=[]);
+ public function sendResponse(array $options=[]): void;
}
diff --git a/src/interfaces/ExtensionInterface.php b/src/interfaces/ExtensionInterface.php
index 3c074978..1c8eae67 100644
--- a/src/interfaces/ExtensionInterface.php
+++ b/src/interfaces/ExtensionInterface.php
@@ -1,5 +1,7 @@
*/
- public function getExtensionMembers();
+ public function getExtensionMembers(): array;
}
diff --git a/src/interfaces/HasLinksInterface.php b/src/interfaces/HasLinksInterface.php
index d867ada5..69ecb31c 100644
--- a/src/interfaces/HasLinksInterface.php
+++ b/src/interfaces/HasLinksInterface.php
@@ -13,20 +13,17 @@ interface HasLinksInterface {
*
* if $meta is given, a LinkObject is added, otherwise a link string is added
*
- * @param string $key
- * @param string $href
+ * @param array $meta
*/
- public function addLink($key, $href, array $meta=[]);
+ public function addLink(string $key, ?string $href, array $meta=[]): void;
/**
* set a key containing a LinkObject
- *
- * @param string $key
*/
- public function addLinkObject($key, LinkObject $linkObject);
+ public function addLinkObject(string $key, LinkObject $linkObject): void;
/**
* set a LinksObject containing all links
*/
- public function setLinksObject(LinksObject $linksObject);
+ public function setLinksObject(LinksObject $linksObject): void;
}
diff --git a/src/interfaces/HasMetaInterface.php b/src/interfaces/HasMetaInterface.php
index 52ac6b46..2c868397 100644
--- a/src/interfaces/HasMetaInterface.php
+++ b/src/interfaces/HasMetaInterface.php
@@ -5,9 +5,5 @@
namespace alsvanzelf\jsonapi\interfaces;
interface HasMetaInterface {
- /**
- * @param string $key
- * @param mixed $value
- */
- public function addMeta($key, $value);
+ public function addMeta(string $key, mixed $value): void;
}
diff --git a/src/interfaces/ObjectInterface.php b/src/interfaces/ObjectInterface.php
index 76585401..0fc9c3a5 100644
--- a/src/interfaces/ObjectInterface.php
+++ b/src/interfaces/ObjectInterface.php
@@ -1,5 +1,7 @@
*/
- public function toArray();
+ public function toArray(): array;
}
diff --git a/src/interfaces/PaginableInterface.php b/src/interfaces/PaginableInterface.php
index 2068244d..fbde5fb9 100644
--- a/src/interfaces/PaginableInterface.php
+++ b/src/interfaces/PaginableInterface.php
@@ -1,13 +1,14 @@
*/
+ protected array $attributes = [];
/**
* human api
@@ -17,11 +19,8 @@ class AttributesObject extends AbstractObject {
/**
* @note if an `id` is set inside $attributes, it is removed from there
* it is common to find it inside, and not doing so will cause an exception
- *
- * @param array $attributes
- * @return AttributesObject
*/
- public static function fromArray(array $attributes) {
+ public static function fromArray(array $attributes): self {
unset($attributes['id']);
$attributesObject = new self();
@@ -33,11 +32,7 @@ public static function fromArray(array $attributes) {
return $attributesObject;
}
- /**
- * @param object $attributes
- * @return AttributesObject
- */
- public static function fromObject($attributes) {
+ public static function fromObject(object $attributes): self {
$array = Converter::objectToArray($attributes);
return self::fromArray($array);
@@ -47,11 +42,7 @@ public static function fromObject($attributes) {
* spec api
*/
- /**
- * @param string $key
- * @param mixed $value
- */
- public function add($key, $value) {
+ public function add(string $key, mixed $value): void {
Validator::checkMemberName($key);
if (is_object($value)) {
@@ -70,7 +61,7 @@ public function add($key, $value) {
*
* @return string[]
*/
- public function getKeys() {
+ public function getKeys(): array {
return array_keys($this->attributes);
}
@@ -78,7 +69,7 @@ public function getKeys() {
* ObjectInterface
*/
- public function isEmpty() {
+ public function isEmpty(): bool {
if ($this->attributes !== []) {
return false;
}
@@ -92,7 +83,7 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
diff --git a/src/objects/ErrorObject.php b/src/objects/ErrorObject.php
index 92e3f17b..26e6ce73 100644
--- a/src/objects/ErrorObject.php
+++ b/src/objects/ErrorObject.php
@@ -1,9 +1,10 @@
setApplicationCode($genericCode);
}
@@ -63,11 +66,9 @@ public function __construct($genericCode=null, $genericTitle=null, $specificDeta
*/
/**
- * @param \Throwable $exception
- * @param array $options optional {@see ErrorObject::$defaults}
- * @return ErrorObject
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ErrorObject::$defaults}
*/
- public static function fromException(\Throwable $exception, array $options=[]) {
+ public static function fromException(\Throwable $exception, array $options=[]): self {
$options = array_merge(self::$defaults, $options);
$errorObject = new self();
@@ -117,12 +118,17 @@ public static function fromException(\Throwable $exception, array $options=[]) {
/**
* explain this particular occurence of the error in a human-friendly way
*
- * @param string $genericTitle title of the generic type of error
- * @param string $specificDetails optional, explanation of the specific error
- * @param string $specificAboutLink optional, explanation of the specific error
- * @param string $genericTypeLink optional, explanation of the generic type of error
+ * @param string $genericTitle title of the generic type of error
+ * @param ?string $specificDetails explanation of the specific error
+ * @param ?string $specificAboutLink explanation of the specific error
+ * @param ?string $genericTypeLink explanation of the generic type of error
*/
- public function setHumanExplanation($genericTitle, $specificDetails=null, $specificAboutLink=null, $genericTypeLink=null) {
+ public function setHumanExplanation(
+ string $genericTitle,
+ ?string $specificDetails=null,
+ ?string $specificAboutLink=null,
+ ?string $genericTypeLink=null,
+ ): void {
$this->setHumanTitle($genericTitle);
if ($specificDetails !== null) {
@@ -139,58 +145,47 @@ public function setHumanExplanation($genericTitle, $specificDetails=null, $speci
/**
* set the link about this specific occurence of the error, explained in a human-friendly way
*
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
+ * @param array $meta if given a LinkObject is added, otherwise a link string is added
*/
- public function setAboutLink($href, array $meta=[]) {
+ public function setAboutLink(string $href, array $meta=[]): void {
$this->addLink('about', $href, $meta);
}
/**
* set the link of the generic type of this error, explained in a human-friendly way
*
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
+ * @param array $meta if given a LinkObject is added, otherwise a link string is added
*/
- public function setTypeLink($href, array $meta=[]) {
+ public function setTypeLink(string $href, array $meta=[]): void {
$this->addLink('type', $href, $meta);
}
/**
* blame the json pointer from the request body causing this error
+ * e.g. "/data/attributes/title" or "/data"
*
* @see https://tools.ietf.org/html/rfc6901
- *
- * @param string $pointer e.g. "/data/attributes/title" or "/data"
*/
- public function blameJsonPointer($pointer) {
+ public function blameJsonPointer(string $pointer): void {
$this->addSource('pointer', $pointer);
}
/**
* blame the query parameter from the request causing this error
- *
- * @param string $parameter
*/
- public function blameQueryParameter($parameter) {
+ public function blameQueryParameter(string $parameter): void {
$this->addSource('parameter', $parameter);
}
/**
* blame the header from the request causing this error
- *
- * @param string $headerName
*/
- public function blameHeader($headerName) {
+ public function blameHeader(string $headerName): void {
$this->addSource('header', $headerName);
}
- /**
- * @param string $key
- * @param mixed $value
- */
- public function addMeta($key, $value) {
- if ($this->meta === null) {
+ public function addMeta(string $key, mixed $value): void {
+ if (isset($this->meta) === false) {
$this->setMetaObject(new MetaObject());
}
@@ -203,30 +198,27 @@ public function addMeta($key, $value) {
/**
* a unique identifier for this specific occurrence of the error
- *
- * @param string|int $id
*/
- public function setUniqueIdentifier($id) {
+ public function setUniqueIdentifier(string|int $id): void {
$this->id = $id;
}
/**
* a code expressing the generic type of this error
* it should be application-specific and aimed at developers
- *
- * @param string|int $genericCode will be casted to a string
+ * ints will be casted to a string
*/
- public function setApplicationCode($genericCode) {
+ public function setApplicationCode(string|int $genericCode): void {
$this->code = (string) $genericCode;
}
/**
* add the source of the error
*
- * @param string $key {@see ->blameJsonPointer(), ->blameQueryParameter()}
- * @param string $value
+ * @see ->blameJsonPointer()
+ * @see ->blameQueryParameter()
*/
- public function addSource($key, $value) {
+ public function addSource(string $key, string $value): void {
Validator::checkMemberName($key);
$this->source[$key] = $value;
@@ -234,26 +226,19 @@ public function addSource($key, $value) {
/**
* a short human-friendly explanation of the generic type of this error
- *
- * @param string $genericTitle
*/
- public function setHumanTitle($genericTitle) {
+ public function setHumanTitle(string $genericTitle): void {
$this->title = $genericTitle;
}
/**
* a human-friendly explanation of this specific occurrence of the error
- *
- * @param string $specificDetails
*/
- public function setHumanDetails($specificDetails) {
+ public function setHumanDetails(string $specificDetails): void {
$this->detail = $specificDetails;
}
- /**
- * @param MetaObject $metaObject
- */
- public function setMetaObject(MetaObject $metaObject) {
+ public function setMetaObject(MetaObject $metaObject): void {
$this->meta = $metaObject;
}
@@ -261,29 +246,29 @@ public function setMetaObject(MetaObject $metaObject) {
* ObjectInterface
*/
- public function isEmpty() {
- if ($this->id !== null) {
+ public function isEmpty(): bool {
+ if (isset($this->id)) {
return false;
}
if ($this->hasHttpStatusCode()) {
return false;
}
- if ($this->code !== null) {
+ if (isset($this->code)) {
return false;
}
- if ($this->title !== null) {
+ if (isset($this->title)) {
return false;
}
- if ($this->detail !== null) {
+ if (isset($this->detail)) {
return false;
}
- if ($this->links !== null && $this->links->isEmpty() === false) {
+ if ($this->hasLinks()) {
return false;
}
if ($this->source !== []) {
return false;
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
return false;
}
if ($this->hasAtMembers()) {
@@ -296,7 +281,7 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
@@ -305,28 +290,28 @@ public function toArray() {
if ($this->hasExtensionMembers()) {
$array = array_merge($array, $this->getExtensionMembers());
}
- if ($this->id !== null) {
+ if (isset($this->id)) {
$array['id'] = $this->id;
}
if ($this->hasHttpStatusCode()) {
$array['status'] = (string) $this->getHttpStatusCode();
}
- if ($this->code !== null) {
+ if (isset($this->code)) {
$array['code'] = $this->code;
}
- if ($this->title !== null) {
+ if (isset($this->title)) {
$array['title'] = $this->title;
}
- if ($this->detail !== null) {
+ if (isset($this->detail)) {
$array['detail'] = $this->detail;
}
- if ($this->links !== null && $this->links->isEmpty() === false) {
+ if ($this->hasLinks()) {
$array['links'] = $this->links->toArray();
}
if ($this->source !== []) {
$array['source'] = $this->source;
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
$array['meta'] = $this->meta->toArray();
}
diff --git a/src/objects/JsonapiObject.php b/src/objects/JsonapiObject.php
index 3d581d97..f54d1aba 100644
--- a/src/objects/JsonapiObject.php
+++ b/src/objects/JsonapiObject.php
@@ -1,8 +1,11 @@
setVersion($version);
}
@@ -32,12 +30,8 @@ public function __construct($version=Document::JSONAPI_VERSION_LATEST) {
* human api
*/
- /**
- * @param string $key
- * @param mixed $value
- */
- public function addMeta($key, $value) {
- if ($this->meta === null) {
+ public function addMeta(string $key, mixed $value): void {
+ if (isset($this->meta) === false) {
$this->setMetaObject(new MetaObject());
}
@@ -48,31 +42,19 @@ public function addMeta($key, $value) {
* spec api
*/
- /**
- * @param string $version
- */
- public function setVersion($version) {
+ public function setVersion(JsonapiVersionEnum $version): void {
$this->version = $version;
}
- /**
- * @param ExtensionInterface $extension
- */
- public function addExtension(ExtensionInterface $extension) {
+ public function addExtension(ExtensionInterface $extension): void {
$this->extensions[] = $extension;
}
- /**
- * @param ProfileInterface $profile
- */
- public function addProfile(ProfileInterface $profile) {
+ public function addProfile(ProfileInterface $profile): void {
$this->profiles[] = $profile;
}
- /**
- * @param MetaObject $metaObject
- */
- public function setMetaObject(MetaObject $metaObject) {
+ public function setMetaObject(MetaObject $metaObject): void {
$this->meta = $metaObject;
}
@@ -80,8 +62,8 @@ public function setMetaObject(MetaObject $metaObject) {
* ObjectInterface
*/
- public function isEmpty() {
- if ($this->version !== null) {
+ public function isEmpty(): bool {
+ if (isset($this->version)) {
return false;
}
if ($this->extensions !== []) {
@@ -90,7 +72,7 @@ public function isEmpty() {
if ($this->profiles !== []) {
return false;
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
return false;
}
if ($this->hasAtMembers()) {
@@ -103,7 +85,7 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
@@ -112,8 +94,8 @@ public function toArray() {
if ($this->hasExtensionMembers()) {
$array = array_merge($array, $this->getExtensionMembers());
}
- if ($this->version !== null) {
- $array['version'] = $this->version;
+ if (isset($this->version)) {
+ $array['version'] = $this->version->value;
}
if ($this->extensions !== []) {
$array['ext'] = [];
@@ -127,7 +109,7 @@ public function toArray() {
$array['profile'][] = $profile->getOfficialLink();
}
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
$array['meta'] = $this->meta->toArray();
}
diff --git a/src/objects/LinkObject.php b/src/objects/LinkObject.php
index e7a06e0b..0c483bef 100644
--- a/src/objects/LinkObject.php
+++ b/src/objects/LinkObject.php
@@ -1,5 +1,7 @@
$meta
*/
- public function __construct($href=null, array $meta=[]) {
+ public function __construct(?string $href=null, array $meta=[]) {
if ($href !== null) {
$this->setHref($href);
}
@@ -39,17 +34,11 @@ public function __construct($href=null, array $meta=[]) {
* human api
*/
- /**
- * @param string $href
- */
- public function setDescribedBy($href) {
+ public function setDescribedBy(string $href): void {
$this->setDescribedByLinkObject(new LinkObject($href));
}
- /**
- * @param string $language
- */
- public function addLanguage($language) {
+ public function addLanguage(string $language): void {
if ($this->hreflang === []) {
$this->setHreflang($language);
}
@@ -58,12 +47,8 @@ public function addLanguage($language) {
}
}
- /**
- * @param string $key
- * @param mixed $value
- */
- public function addMeta($key, $value) {
- if ($this->meta === null) {
+ public function addMeta(string $key, mixed $value): void {
+ if (isset($this->meta) === false) {
$this->setMetaObject(new MetaObject());
}
@@ -74,56 +59,37 @@ public function addMeta($key, $value) {
* spec api
*/
- /**
- * @param string $href
- */
- public function setHref($href) {
+ public function setHref(string $href): void {
$this->href = $href;
}
/**
* @todo validate according to https://tools.ietf.org/html/rfc8288#section-2.1
- *
- * @param string $relationType
*/
- public function setRelationType($relationType) {
+ public function setRelationType(string $relationType): void {
$this->rel = $relationType;
}
- /**
- * @param LinkObject $describedBy
- */
- public function setDescribedByLinkObject(LinkObject $describedBy) {
+ public function setDescribedByLinkObject(LinkObject $describedBy): void {
$this->describedby = $describedBy;
}
- /**
- * @param string $humanTitle
- */
- public function setHumanTitle($humanTitle) {
+ public function setHumanTitle(string $humanTitle): void {
$this->title = $humanTitle;
}
- /**
- * @param string $mediaType
- */
- public function setMediaType($mediaType) {
+ public function setMediaType(string $mediaType): void {
$this->type = $mediaType;
}
/**
* @todo validate according to https://tools.ietf.org/html/rfc5646
- *
- * @param string ...$hreflang
*/
- public function setHreflang(...$hreflang) {
+ public function setHreflang(string ...$hreflang): void {
$this->hreflang = $hreflang;
}
- /**
- * @param MetaObject $metaObject
- */
- public function setMetaObject(MetaObject $metaObject) {
+ public function setMetaObject(MetaObject $metaObject): void {
$this->meta = $metaObject;
}
@@ -131,26 +97,26 @@ public function setMetaObject(MetaObject $metaObject) {
* ObjectInterface
*/
- public function isEmpty() {
- if ($this->href !== null) {
+ public function isEmpty(): bool {
+ if (isset($this->href)) {
return false;
}
- if ($this->rel !== null) {
+ if (isset($this->rel)) {
return false;
}
- if ($this->title !== null) {
+ if (isset($this->title)) {
return false;
}
- if ($this->type !== null) {
+ if (isset($this->type)) {
return false;
}
if ($this->hreflang !== []) {
return false;
}
- if ($this->describedby !== null && $this->describedby->isEmpty() === false) {
+ if (isset($this->describedby) && $this->describedby->isEmpty() === false) {
return false;
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
return false;
}
if ($this->hasAtMembers()) {
@@ -163,7 +129,7 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
@@ -173,15 +139,16 @@ public function toArray() {
$array = array_merge($array, $this->getExtensionMembers());
}
- $array['href'] = $this->href;
-
- if ($this->rel !== null) {
+ if (isset($this->href)) {
+ $array['href'] = $this->href;
+ }
+ if (isset($this->rel)) {
$array['rel'] = $this->rel;
}
- if ($this->title !== null) {
+ if (isset($this->title)) {
$array['title'] = $this->title;
}
- if ($this->type !== null) {
+ if (isset($this->type)) {
$array['type'] = $this->type;
}
if ($this->hreflang !== []) {
@@ -192,10 +159,10 @@ public function toArray() {
$array['hreflang'] = $this->hreflang;
}
}
- if ($this->describedby !== null && $this->describedby->isEmpty() === false) {
+ if (isset($this->describedby) && $this->describedby->isEmpty() === false) {
$array['describedby'] = $this->describedby->toArray();
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
$array['meta'] = $this->meta->toArray();
}
diff --git a/src/objects/LinksObject.php b/src/objects/LinksObject.php
index bad61559..65385ef7 100644
--- a/src/objects/LinksObject.php
+++ b/src/objects/LinksObject.php
@@ -1,5 +1,7 @@
*/
+ protected array $links = [];
/**
* human api
*/
/**
- * @param array $links key-value with values being href strings
- * @return LinksObject
+ * @param array $links key-value with values being href strings
*/
- public static function fromArray(array $links) {
+ public static function fromArray(array $links): LinksObject {
$linksObject = new self();
foreach ($links as $key => $href) {
@@ -30,22 +31,16 @@ public static function fromArray(array $links) {
return $linksObject;
}
- /**
- * @param object $links
- * @return LinksObject
- */
- public static function fromObject($links) {
+ public static function fromObject(object $links): LinksObject {
$array = Converter::objectToArray($links);
return self::fromArray($array);
}
/**
- * @param string $key
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
+ * @param array $meta if given a LinkObject is added, otherwise a link string is added
*/
- public function add($key, $href, array $meta=[]) {
+ public function add(string $key, ?string $href, array $meta=[]): void {
if ($meta === []) {
$this->addLinkString($key, $href);
}
@@ -59,12 +54,9 @@ public function add($key, $href, array $meta=[]) {
*/
/**
- * @param string $key
- * @param string $href
- *
* @throws DuplicateException if another link is already using that $key
*/
- public function addLinkString($key, $href) {
+ public function addLinkString(string $key, ?string $href): void {
Validator::checkMemberName($key);
if (isset($this->links[$key])) {
@@ -75,12 +67,9 @@ public function addLinkString($key, $href) {
}
/**
- * @param string $key
- * @param LinkObject $linkObject
- *
* @throws DuplicateException if another link is already using that $key
*/
- public function addLinkObject($key, LinkObject $linkObject) {
+ public function addLinkObject(string $key, LinkObject $linkObject): void {
Validator::checkMemberName($key);
if (isset($this->links[$key])) {
@@ -94,7 +83,7 @@ public function addLinkObject($key, LinkObject $linkObject) {
* ObjectInterface
*/
- public function isEmpty() {
+ public function isEmpty(): bool {
if ($this->links !== []) {
return false;
}
@@ -108,7 +97,7 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
diff --git a/src/objects/MetaObject.php b/src/objects/MetaObject.php
index e98a2c96..e52c5847 100644
--- a/src/objects/MetaObject.php
+++ b/src/objects/MetaObject.php
@@ -1,5 +1,7 @@
*/
+ protected array $meta = [];
/**
* human api
*/
/**
- * @param array $meta
- * @return MetaObject
+ * @param array $meta
*/
- public static function fromArray(array $meta) {
+ public static function fromArray(array $meta): self {
$metaObject = new self();
foreach ($meta as $key => $value) {
@@ -28,11 +29,7 @@ public static function fromArray(array $meta) {
return $metaObject;
}
- /**
- * @param object $meta
- * @return MetaObject
- */
- public static function fromObject($meta) {
+ public static function fromObject(object $meta): self {
$array = Converter::objectToArray($meta);
return self::fromArray($array);
@@ -42,11 +39,7 @@ public static function fromObject($meta) {
* spec api
*/
- /**
- * @param string $key
- * @param mixed $value
- */
- public function add($key, $value) {
+ public function add(string $key, mixed $value): void {
Validator::checkMemberName($key);
if (is_object($value)) {
@@ -60,7 +53,7 @@ public function add($key, $value) {
* ObjectInterface
*/
- public function isEmpty() {
+ public function isEmpty(): bool {
if ($this->meta !== []) {
return false;
}
@@ -74,7 +67,7 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
diff --git a/src/objects/RelationshipObject.php b/src/objects/RelationshipObject.php
index 6cb0efdb..2a4af1a0 100644
--- a/src/objects/RelationshipObject.php
+++ b/src/objects/RelationshipObject.php
@@ -1,8 +1,11 @@
type = $type;
- }
+ public function __construct(
+ protected readonly RelationshipTypeEnum $type,
+ ) {}
/**
* human api
@@ -50,14 +37,17 @@ public function __construct($type) {
/**
* create a RelationshipObject from mixed input
*
- * @param mixed $relation ResourceInterface | ResourceInterface[] | CollectionDocument
- * @param array $links optional
- * @param array $meta optional
- * @return RelationshipObject
+ * @param CollectionDocument|ResourceInterface|ResourceInterface[]|null $relation
+ * @param array $links
+ * @param array $meta
*
* @throws InputException if $relation is not one of the supported formats
*/
- public static function fromAnything($relation, array $links=[], array $meta=[]) {
+ public static function fromAnything(
+ array|CollectionDocument|ResourceInterface|null $relation,
+ array $links=[],
+ array $meta=[],
+ ): self {
if (is_array($relation)) {
$relation = CollectionDocument::fromResources(...$relation);
}
@@ -69,7 +59,7 @@ public static function fromAnything($relation, array $links=[], array $meta=[])
$relationshipObject = self::fromCollectionDocument($relation, $links, $meta);
}
elseif ($relation === null) {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
}
else {
throw new InputException('unknown format of relation "'.gettype($relation).'"');
@@ -79,21 +69,21 @@ public static function fromAnything($relation, array $links=[], array $meta=[])
}
/**
- * @param ResourceInterface $resource
- * @param array $links optional
- * @param array $meta optional
- * @param string $type optional, one of the RelationshipObject::TO_* constants, defaults to RelationshipObject::TO_ONE
- * @return RelationshipObject
+ * @param array $links
+ * @param array $meta
*/
- public static function fromResource(ResourceInterface $resource, array $links=[], array $meta=[], $type=RelationshipObject::TO_ONE) {
+ public static function fromResource(
+ ResourceInterface $resource,
+ array $links=[],
+ array $meta=[],
+ RelationshipTypeEnum $type=RelationshipTypeEnum::ToOne,
+ ): self {
$relationshipObject = new self($type);
- if ($type === RelationshipObject::TO_ONE) {
- $relationshipObject->setResource($resource);
- }
- elseif ($type === RelationshipObject::TO_MANY) {
- $relationshipObject->addResource($resource);
- }
+ match ($type) {
+ RelationshipTypeEnum::ToOne => $relationshipObject->setResource($resource),
+ RelationshipTypeEnum::ToMany => $relationshipObject->addResource($resource),
+ };
if ($links !== []) {
$relationshipObject->setLinksObject(LinksObject::fromArray($links));
@@ -106,13 +96,11 @@ public static function fromResource(ResourceInterface $resource, array $links=[]
}
/**
- * @param CollectionDocument $collectionDocument
- * @param array $links optional
- * @param array $meta optional
- * @return RelationshipObject
+ * @param array $links
+ * @param array $meta
*/
- public static function fromCollectionDocument(CollectionDocument $collectionDocument, array $links=[], array $meta=[]) {
- $relationshipObject = new self(RelationshipObject::TO_MANY);
+ public static function fromCollectionDocument(CollectionDocument $collectionDocument, array $links=[], array $meta=[]): self {
+ $relationshipObject = new self(RelationshipTypeEnum::ToMany);
foreach ($collectionDocument->getContainedResources() as $resource) {
$relationshipObject->addResource($resource);
@@ -129,26 +117,29 @@ public static function fromCollectionDocument(CollectionDocument $collectionDocu
}
/**
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
+ * @param array $meta if given a LinkObject is added, otherwise a link string is added
*/
- public function setSelfLink($href, array $meta=[]) {
+ public function setSelfLink(string $href, array $meta=[]): void {
$this->addLink('self', $href, $meta);
}
/**
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
+ * @param array $meta if given a LinkObject is added, otherwise a link string is added
*/
- public function setRelatedLink($href, array $meta=[]) {
+ public function setRelatedLink(string $href, array $meta=[]): void {
$this->addLink('related', $href, $meta);
}
/**
* @throws InputException if used on a to-one relationship
*/
- public function setPaginationLinks($previousHref=null, $nextHref=null, $firstHref=null, $lastHref=null) {
- if ($this->type === RelationshipObject::TO_ONE) {
+ public function setPaginationLinks(
+ ?string $previousHref=null,
+ ?string $nextHref=null,
+ ?string $firstHref=null,
+ ?string $lastHref=null,
+ ): void {
+ if ($this->type === RelationshipTypeEnum::ToOne) {
throw new InputException('can not add pagination links to a to-one relationship');
}
@@ -166,12 +157,8 @@ public function setPaginationLinks($previousHref=null, $nextHref=null, $firstHre
}
}
- /**
- * @param string $key
- * @param mixed $value
- */
- public function addMeta($key, $value) {
- if ($this->meta === null) {
+ public function addMeta(string $key, mixed $value): void {
+ if (isset($this->meta) === false) {
$this->setMetaObject(new MetaObject());
}
@@ -185,12 +172,10 @@ public function addMeta($key, $value) {
/**
* set the resource on a to-one relationship
*
- * @param ResourceInterface $resource
- *
* @throws InputException if used on a to-many relationship, use {@see ->addResource()} instead
*/
- public function setResource(ResourceInterface $resource) {
- if ($this->type === RelationshipObject::TO_MANY) {
+ public function setResource(ResourceInterface $resource): void {
+ if ($this->type === RelationshipTypeEnum::ToMany) {
throw new InputException('can not set a resource on a to-many relationship, use ->addResource()');
}
@@ -200,22 +185,17 @@ public function setResource(ResourceInterface $resource) {
/**
* add a resource to a to-many relationship
*
- * @param ResourceInterface $resource
- *
* @throws InputException if used on a to-one relationship, use {@see ->setResource()} instead
*/
- public function addResource(ResourceInterface $resource) {
- if ($this->type === RelationshipObject::TO_ONE) {
+ public function addResource(ResourceInterface $resource): void {
+ if ($this->type === RelationshipTypeEnum::ToOne) {
throw new InputException('can not add a resource to a to-one relationship, use ->setResource()');
}
$this->resources[] = $resource;
}
- /**
- * @param MetaObject $metaObject
- */
- public function setMetaObject(MetaObject $metaObject) {
+ public function setMetaObject(MetaObject $metaObject): void {
$this->meta = $metaObject;
}
@@ -227,43 +207,42 @@ public function setMetaObject(MetaObject $metaObject) {
* whether or not the $otherResource is (one of) the resource(s) inside the relationship
*
* @internal
- *
- * @param ResourceInterface $otherResource
- * @return boolean
*/
- public function hasResource(ResourceInterface $otherResource) {
+ public function hasResource(ResourceInterface $otherResource): bool {
if ($this->isEmpty()) {
return false;
}
- if ($this->type === RelationshipObject::TO_ONE) {
- return $this->resource->getResource()->equals($otherResource->getResource());
- }
- if ($this->type === RelationshipObject::TO_MANY) {
- foreach ($this->resources as $ownResource) {
- if ($ownResource->getResource()->equals($otherResource->getResource())) {
- return true;
+
+ switch ($this->type) {
+ case RelationshipTypeEnum::ToOne:
+ return $this->resource->getResource()->equals($otherResource->getResource());
+
+ case RelationshipTypeEnum::ToMany:
+ foreach ($this->resources as $ownResource) {
+ if ($ownResource->getResource()->equals($otherResource->getResource())) {
+ return true;
+ }
}
- }
+
+ return false;
}
-
- return false;
}
/**
* ObjectInterface
*/
- public function isEmpty() {
- if ($this->type === RelationshipObject::TO_ONE && $this->resource !== null) {
+ public function isEmpty(): bool {
+ if ($this->type === RelationshipTypeEnum::ToOne && isset($this->resource)) {
return false;
}
- if ($this->type === RelationshipObject::TO_MANY && $this->resources !== []) {
+ if ($this->type === RelationshipTypeEnum::ToMany && $this->resources !== []) {
return false;
}
- if ($this->links !== null && $this->links->isEmpty() === false) {
+ if ($this->hasLinks()) {
return false;
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
return false;
}
if ($this->hasAtMembers()) {
@@ -276,7 +255,7 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
@@ -286,22 +265,22 @@ public function toArray() {
$array = array_merge($array, $this->getExtensionMembers());
}
- if ($this->links !== null && $this->links->isEmpty() === false) {
+ if ($this->hasLinks()) {
$array['links'] = $this->links->toArray();
}
- if ($this->type === RelationshipObject::TO_ONE) {
+ if ($this->type === RelationshipTypeEnum::ToOne) {
$array['data'] = null;
- if ($this->resource !== null) {
+ if (isset($this->resource)) {
$array['data'] = $this->resource->getResource($identifierOnly=true)->toArray();
}
}
- if ($this->type === RelationshipObject::TO_MANY) {
+ if ($this->type === RelationshipTypeEnum::ToMany) {
$array['data'] = [];
foreach ($this->resources as $resource) {
$array['data'][] = $resource->getResource($identifierOnly=true)->toArray();
}
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
$array['meta'] = $this->meta->toArray();
}
@@ -312,12 +291,12 @@ public function toArray() {
* RecursiveResourceContainerInterface
*/
- public function getNestedContainedResourceObjects() {
+ public function getNestedContainedResourceObjects(): array {
if ($this->isEmpty()) {
return [];
}
- $resources = ($this->type === RelationshipObject::TO_ONE) ? [$this->resource] : $this->resources;
+ $resources = ($this->type === RelationshipTypeEnum::ToOne) ? [$this->resource] : $this->resources;
$resourceObjects = [];
foreach ($resources as $resource) {
diff --git a/src/objects/RelationshipsObject.php b/src/objects/RelationshipsObject.php
index 8c8d0be7..54edd3e0 100644
--- a/src/objects/RelationshipsObject.php
+++ b/src/objects/RelationshipsObject.php
@@ -1,10 +1,14 @@
$links
+ * @param array $meta
*/
- public function add($key, $relation, array $links=[], array $meta=[]) {
+ public function add(
+ string $key,
+ $relation,
+ array $links=[],
+ array $meta=[],
+ ): RelationshipObject {
$relationshipObject = RelationshipObject::fromAnything($relation, $links, $meta);
$this->addRelationshipObject($key, $relationshipObject);
@@ -38,12 +45,9 @@ public function add($key, $relation, array $links=[], array $meta=[]) {
*/
/**
- * @param string $key
- * @param RelationshipObject $relationshipObject
- *
* @throws DuplicateException if another relationship is already using that $key
*/
- public function addRelationshipObject($key, RelationshipObject $relationshipObject) {
+ public function addRelationshipObject(string $key, RelationshipObject $relationshipObject): void {
Validator::checkMemberName($key);
if (isset($this->relationships[$key])) {
@@ -62,7 +66,7 @@ public function addRelationshipObject($key, RelationshipObject $relationshipObje
*
* @return string[]
*/
- public function getKeys() {
+ public function getKeys(): array {
return array_keys($this->relationships);
}
@@ -70,7 +74,7 @@ public function getKeys() {
* ObjectInterface
*/
- public function isEmpty() {
+ public function isEmpty(): bool {
if ($this->relationships !== []) {
return false;
}
@@ -84,7 +88,7 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
if ($this->hasAtMembers()) {
@@ -105,7 +109,7 @@ public function toArray() {
* RecursiveResourceContainerInterface
*/
- public function getNestedContainedResourceObjects() {
+ public function getNestedContainedResourceObjects(): array {
$resourceObjects = [];
foreach ($this->relationships as $relationship) {
diff --git a/src/objects/ResourceIdentifierObject.php b/src/objects/ResourceIdentifierObject.php
index 715456d4..22d35e9b 100644
--- a/src/objects/ResourceIdentifierObject.php
+++ b/src/objects/ResourceIdentifierObject.php
@@ -1,9 +1,13 @@
setType() and ->setId() if not passing them during construction
- *
- * @param string $type optional
- * @param string|int $id optional
*/
- public function __construct($type=null, $id=null) {
+ public function __construct(?string $type=null, string|int|null $id=null) {
$this->validator = new Validator();
if ($type !== null) {
@@ -41,21 +37,17 @@ public function __construct($type=null, $id=null) {
}
// always mark as used, as these keys are reserved
- $this->validator->claimUsedFields($fieldNames=['type'], Validator::OBJECT_CONTAINER_TYPE);
- $this->validator->claimUsedFields($fieldNames=['id'], Validator::OBJECT_CONTAINER_ID);
- $this->validator->claimUsedFields($fieldNames=['lid'], Validator::OBJECT_CONTAINER_LID);
+ $this->validator->claimUsedFields($fieldNames=['type'], ObjectContainerEnum::Type);
+ $this->validator->claimUsedFields($fieldNames=['id'], ObjectContainerEnum::Id);
+ $this->validator->claimUsedFields($fieldNames=['lid'], ObjectContainerEnum::Lid);
}
/**
* human api
*/
- /**
- * @param string $key
- * @param mixed $value
- */
- public function addMeta($key, $value) {
- if ($this->meta === null) {
+ public function addMeta(string $key, mixed $value): void {
+ if (isset($this->meta) === false) {
$this->setMetaObject(new MetaObject());
}
@@ -66,20 +58,17 @@ public function addMeta($key, $value) {
* spec api
*/
- /**
- * @param string $type
- */
- public function setType($type) {
+ public function setType(string $type): void {
$this->type = $type;
}
/**
- * @param string|int $id will be casted to a string
+ * int $id will be casted to a string
*
* @throws DuplicateException if localId is already set
*/
- public function setId($id) {
- if ($this->lid !== null) {
+ public function setId(string|int $id): void {
+ if (isset($this->lid)) {
throw new DuplicateException('id is not allowed when localId is already set');
}
@@ -91,22 +80,19 @@ public function setId($id) {
*
* @note this should not be used to send back from the server to the client
*
- * @param string|int $localId will be casted to a string
+ * int $localId will be casted to a string
*
* @throws DuplicateException if normal id is already set
*/
- public function setLocalId($localId) {
- if ($this->id !== null) {
+ public function setLocalId(string|int $localId): void {
+ if (isset($this->id)) {
throw new DuplicateException('localId is not allowed when id is already set');
}
$this->lid = (string) $localId;
}
- /**
- * @param MetaObject $metaObject
- */
- public function setMetaObject(MetaObject $metaObject) {
+ public function setMetaObject(MetaObject $metaObject): void {
$this->meta = $metaObject;
}
@@ -117,13 +103,16 @@ public function setMetaObject(MetaObject $metaObject) {
/**
* @internal
*
- * @param ResourceObject $resourceObject
- * @return ResourceIdentifierObject
+ * @throws InputException if the $resourceoObject's type or id is not set yet
*/
- public static function fromResourceObject(ResourceObject $resourceObject) {
+ public static function fromResourceObject(ResourceObject $resourceObject): self {
+ if ($resourceObject->hasIdentification() === false) {
+ throw new InputException('resource has no identification yet<');
+ }
+
$resourceIdentifierObject = new self($resourceObject->type, $resourceObject->primaryId());
- if ($resourceObject->meta !== null) {
+ if (isset($resourceObject->meta)) {
$resourceIdentifierObject->setMetaObject($resourceObject->meta);
}
@@ -133,12 +122,9 @@ public static function fromResourceObject(ResourceObject $resourceObject) {
/**
* @internal
*
- * @param ResourceInterface $resource
- * @return boolean
- *
* @throws Exception if one or both are missing identification
*/
- public function equals(ResourceInterface $resource) {
+ public function equals(ResourceInterface $resource): bool {
if ($this->hasIdentification() === false || $resource->getResource()->hasIdentification() === false) {
throw new Exception('can not compare resources if identification is missing');
}
@@ -148,11 +134,17 @@ public function equals(ResourceInterface $resource) {
/**
* @internal
- *
- * @return boolean
*/
- public function hasIdentification() {
- return ($this->type !== null && $this->primaryId() !== null);
+ public function hasIdentification(): bool {
+ if (isset($this->type) === false) {
+ return false;
+ }
+
+ if (isset($this->id) === false && isset($this->lid) === false) {
+ return false;
+ }
+
+ return true;
}
/**
@@ -160,11 +152,9 @@ public function hasIdentification() {
*
* @internal
*
- * @return string
- *
* @throws Exception if type or id is not set yet
*/
- public function getIdentificationKey() {
+ public function getIdentificationKey(): string {
if ($this->hasIdentification() === false) {
throw new Exception('resource has no identification yet');
}
@@ -176,11 +166,14 @@ public function getIdentificationKey() {
* ObjectInterface
*/
- public function isEmpty() {
- if ($this->type !== null || $this->primaryId() !== null) {
+ public function isEmpty(): bool {
+ if (isset($this->type)) {
return false;
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->id) || isset($this->lid)) {
+ return false;
+ }
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
return false;
}
if ($this->hasAtMembers()) {
@@ -193,15 +186,16 @@ public function isEmpty() {
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = [];
- $array['type'] = $this->type;
-
- if ($this->id !== null) {
+ if (isset($this->type)) {
+ $array['type'] = $this->type;
+ }
+ if (isset($this->id)) {
$array['id'] = $this->id;
}
- elseif ($this->lid !== null) {
+ elseif (isset($this->lid)) {
$array['lid'] = $this->lid;
}
@@ -212,7 +206,7 @@ public function toArray() {
$array = array_merge($array, $this->getExtensionMembers());
}
- if ($this->meta !== null && $this->meta->isEmpty() === false) {
+ if (isset($this->meta) && $this->meta->isEmpty() === false) {
$array['meta'] = $this->meta->toArray();
}
@@ -223,7 +217,7 @@ public function toArray() {
* ResourceInterface
*/
- public function getResource($identifierOnly=false) {
+ public function getResource(bool $identifierOnly=false): ResourceIdentifierObject {
return $this;
}
@@ -231,8 +225,12 @@ public function getResource($identifierOnly=false) {
* @internal
*/
- private function primaryId() {
- if ($this->lid !== null) {
+ private function primaryId(): string {
+ if (isset($this->id) === false && isset($this->lid) === false) {
+ throw new Exception('resource has no identification yet');
+ }
+
+ if (isset($this->lid)) {
return $this->lid;
}
diff --git a/src/objects/ResourceObject.php b/src/objects/ResourceObject.php
index e0d59d32..67a4478e 100644
--- a/src/objects/ResourceObject.php
+++ b/src/objects/ResourceObject.php
@@ -1,12 +1,14 @@
$attributes
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceObject::$defaults}
*/
- public static function fromArray(array $attributes, $type=null, $id=null, array $options=[]) {
+ public static function fromArray(array $attributes, ?string $type=null, string|int|null $id=null, array $options=[]): self {
if (isset($attributes['id'])) {
if ($id === null) {
$id = $attributes['id'];
@@ -64,13 +61,9 @@ public static function fromArray(array $attributes, $type=null, $id=null, array
}
/**
- * @param object $attributes
- * @param string $type optional
- * @param string|int $id optional
- * @param array $options optional {@see ResourceObject::$defaults}
- * @return ResourceObject
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceObject::$defaults}
*/
- public static function fromObject($attributes, $type=null, $id=null, array $options=[]) {
+ public static function fromObject(object $attributes, ?string $type=null, string|int|null $id=null, array $options=[]): self {
$array = Converter::objectToArray($attributes);
return self::fromArray($array, $type, $id, $options);
@@ -79,31 +72,33 @@ public static function fromObject($attributes, $type=null, $id=null, array $opti
/**
* add key-value pairs to attributes
*
- * @param string $key
- * @param mixed $value
- * @param array $options optional {@see ResourceObject::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceObject::$defaults}
*/
- public function add($key, $value, array $options=[]) {
+ public function add(string $key, mixed $value, array $options=[]): void {
$options = array_merge(self::$defaults, $options);
- if ($this->attributes === null) {
+ if (isset($this->attributes) === false) {
$this->attributes = new AttributesObject();
}
- $this->validator->claimUsedFields([$key], Validator::OBJECT_CONTAINER_ATTRIBUTES, $options);
+ $this->validator->claimUsedFields([$key], ObjectContainerEnum::Attributes, $options);
$this->attributes->add($key, $value);
}
/**
- * @param string $key
- * @param mixed $relation ResourceInterface | ResourceInterface[] | CollectionDocument
- * @param array $links optional
- * @param array $meta optional
- * @param array $options optional {@see ResourceObject::$defaults}
- * @return RelationshipObject
+ * @param CollectionDocument|ResourceInterface|ResourceInterface[]|null $relation
+ * @param array $links
+ * @param array $meta
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceObject::$defaults}
*/
- public function addRelationship($key, $relation, array $links=[], array $meta=[], array $options=[]) {
+ public function addRelationship(
+ string $key,
+ array|CollectionDocument|ResourceInterface|null $relation,
+ array $links=[],
+ array $meta=[],
+ array $options=[],
+ ): RelationshipObject {
$relationshipObject = RelationshipObject::fromAnything($relation, $links, $meta);
$this->addRelationshipObject($key, $relationshipObject, $options);
@@ -112,10 +107,9 @@ public function addRelationship($key, $relation, array $links=[], array $meta=[]
}
/**
- * @param string $href
- * @param array $meta optional, if given a LinkObject is added, otherwise a link string is added
+ * @param array $meta if given a LinkObject is added, otherwise a link string is added
*/
- public function setSelfLink($href, array $meta=[]) {
+ public function setSelfLink(string $href, array $meta=[]): void {
$this->addLink('self', $href, $meta);
}
@@ -124,45 +118,39 @@ public function setSelfLink($href, array $meta=[]) {
*/
/**
- * @param AttributesObject $attributesObject
- * @param array $options optional {@see ResourceObject::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceObject::$defaults}
*/
- public function setAttributesObject(AttributesObject $attributesObject, array $options=[]) {
+ public function setAttributesObject(AttributesObject $attributesObject, array $options=[]): void {
$newKeys = $attributesObject->getKeys();
- $this->validator->clearUsedFields(Validator::OBJECT_CONTAINER_ATTRIBUTES);
- $this->validator->claimUsedFields($newKeys, Validator::OBJECT_CONTAINER_ATTRIBUTES, $options);
+ $this->validator->clearUsedFields(ObjectContainerEnum::Attributes);
+ $this->validator->claimUsedFields($newKeys, ObjectContainerEnum::Attributes, $options);
$this->attributes = $attributesObject;
}
/**
- * @param string $key
- * @param RelationshipObject $relationshipObject
- * @param array $options optional {@see ResourceObject::$defaults}
+ * @param PHPStanTypeAlias_InternalOptions $options {@see ResourceObject::$defaults}
*
* @throws DuplicateException if the resource is contained as a resource in the relationship
*/
- public function addRelationshipObject($key, RelationshipObject $relationshipObject, array $options=[]) {
+ public function addRelationshipObject(string $key, RelationshipObject $relationshipObject, array $options=[]): void {
if ($relationshipObject->hasResource($this)) {
throw new DuplicateException('can not add relation to self');
}
- if ($this->relationships === null) {
+ if (isset($this->relationships) === false) {
$this->setRelationshipsObject(new RelationshipsObject());
}
- $this->validator->claimUsedFields([$key], Validator::OBJECT_CONTAINER_RELATIONSHIPS, $options);
+ $this->validator->claimUsedFields([$key], ObjectContainerEnum::Relationships, $options);
$this->relationships->addRelationshipObject($key, $relationshipObject);
}
- /**
- * @param RelationshipsObject $relationshipsObject
- */
- public function setRelationshipsObject(RelationshipsObject $relationshipsObject) {
+ public function setRelationshipsObject(RelationshipsObject $relationshipsObject): void {
$newKeys = $relationshipsObject->getKeys();
- $this->validator->clearUsedFields(Validator::OBJECT_CONTAINER_RELATIONSHIPS);
- $this->validator->claimUsedFields($newKeys, Validator::OBJECT_CONTAINER_RELATIONSHIPS);
+ $this->validator->clearUsedFields(ObjectContainerEnum::Relationships);
+ $this->validator->claimUsedFields($newKeys, ObjectContainerEnum::Relationships);
$this->relationships = $relationshipsObject;
}
@@ -177,17 +165,15 @@ public function setRelationshipsObject(RelationshipsObject $relationshipsObject)
* this can be used to determine if a Relationship's resource could be added as included resource
*
* @internal
- *
- * @return boolean
*/
- public function hasIdentifierPropertiesOnly() {
- if ($this->attributes !== null && $this->attributes->isEmpty() === false) {
+ public function hasIdentifierPropertiesOnly(): bool {
+ if (isset($this->attributes) && $this->attributes->isEmpty() === false) {
return false;
}
- if ($this->relationships !== null && $this->relationships->isEmpty() === false) {
+ if (isset($this->relationships) && $this->relationships->isEmpty() === false) {
return false;
}
- if ($this->links !== null && $this->links->isEmpty() === false) {
+ if ($this->hasLinks()) {
return false;
}
@@ -198,15 +184,15 @@ public function hasIdentifierPropertiesOnly() {
* HasAttributesInterface
*/
- public function addAttribute($key, $value, array $options=[]) {
- return $this->add($key, $value);
+ public function addAttribute(string $key, mixed $value, array $options=[]): void {
+ $this->add($key, $value);
}
/**
* ResourceInterface
*/
- public function getResource($identifierOnly=false) {
+ public function getResource(bool $identifierOnly=false): ResourceIdentifierObject|ResourceObject {
if ($identifierOnly) {
return ResourceIdentifierObject::fromResourceObject($this);
}
@@ -218,33 +204,33 @@ public function getResource($identifierOnly=false) {
* ObjectInterface
*/
- public function isEmpty() {
+ public function isEmpty(): bool {
if (parent::isEmpty() === false) {
return false;
}
- if ($this->attributes !== null && $this->attributes->isEmpty() === false) {
+ if (isset($this->attributes) && $this->attributes->isEmpty() === false) {
return false;
}
- if ($this->relationships !== null && $this->relationships->isEmpty() === false) {
+ if (isset($this->relationships) && $this->relationships->isEmpty() === false) {
return false;
}
- if ($this->links !== null && $this->links->isEmpty() === false) {
+ if ($this->hasLinks()) {
return false;
}
return true;
}
- public function toArray() {
+ public function toArray(): array {
$array = parent::toArray();
- if ($this->attributes !== null && $this->attributes->isEmpty() === false) {
+ if (isset($this->attributes) && $this->attributes->isEmpty() === false) {
$array['attributes'] = $this->attributes->toArray();
}
- if ($this->relationships !== null && $this->relationships->isEmpty() === false) {
+ if (isset($this->relationships) && $this->relationships->isEmpty() === false) {
$array['relationships'] = $this->relationships->toArray();
}
- if ($this->links !== null && $this->links->isEmpty() === false) {
+ if ($this->hasLinks()) {
$array['links'] = $this->links->toArray();
}
@@ -255,8 +241,8 @@ public function toArray() {
* RecursiveResourceContainerInterface
*/
- public function getNestedContainedResourceObjects() {
- if ($this->relationships === null) {
+ public function getNestedContainedResourceObjects(): array {
+ if (isset($this->relationships) === false) {
return [];
}
diff --git a/src/profiles/CursorPaginationProfile.php b/src/profiles/CursorPaginationProfile.php
index 8ab4a9ff..aabf16dd 100644
--- a/src/profiles/CursorPaginationProfile.php
+++ b/src/profiles/CursorPaginationProfile.php
@@ -1,9 +1,11 @@
generatePreviousLink($baseOrCurrentUrl, $firstCursor));
$nextLinkObject = new LinkObject($this->generateNextLink($baseOrCurrentUrl, $lastCursor));
@@ -67,41 +71,32 @@ public function setLinks(PaginableInterface $paginable, $baseOrCurrentUrl, $firs
}
/**
- * @param PaginableInterface $paginable a CollectionDocument or RelationshipObject
- * @param string $baseOrCurrentUrl
- * @param string $lastCursor
+ * @param PaginableInterface $paginable a CollectionDocument or RelationshipObject
*/
- public function setLinksFirstPage(PaginableInterface $paginable, $baseOrCurrentUrl, $lastCursor) {
+ public function setLinksFirstPage(PaginableInterface $paginable, string $baseOrCurrentUrl, string $lastCursor): void {
$this->setPaginationLinkObjectsWithoutPrevious($paginable, $baseOrCurrentUrl, $lastCursor);
}
/**
- * @param PaginableInterface $paginable a CollectionDocument or RelationshipObject
- * @param string $baseOrCurrentUrl
- * @param string $firstCursor
+ * @param PaginableInterface $paginable a CollectionDocument or RelationshipObject
*/
- public function setLinksLastPage(PaginableInterface $paginable, $baseOrCurrentUrl, $firstCursor) {
+ public function setLinksLastPage(PaginableInterface $paginable, string $baseOrCurrentUrl, string $firstCursor): void {
$this->setPaginationLinkObjectsWithoutNext($paginable, $baseOrCurrentUrl, $firstCursor);
}
/**
* set the cursor of a specific resource to allow pagination after or before this resource
- *
- * @param ResourceInterface $resource
- * @param string $cursor
*/
- public function setCursor(ResourceInterface $resource, $cursor) {
+ public function setCursor(ResourceInterface $resource, string $cursor): void {
$this->setItemMeta($resource, $cursor);
}
/**
* set count(s) to tell about the (estimated) total size
*
- * @param PaginableInterface $paginable a CollectionDocument or RelationshipObject
- * @param int $exactTotal optional
- * @param int $bestGuessTotal optional
+ * @param PaginableInterface $paginable a CollectionDocument or RelationshipObject
*/
- public function setCount(PaginableInterface $paginable, $exactTotal=null, $bestGuessTotal=null) {
+ public function setCount(PaginableInterface $paginable, ?int $exactTotal=null, ?int $bestGuessTotal=null) {
$this->setPaginationMeta($paginable, $exactTotal, $bestGuessTotal);
}
@@ -111,21 +106,13 @@ public function setCount(PaginableInterface $paginable, $exactTotal=null, $bestG
/**
* helper to get generate a correct page[before] link, use to apply manually
- *
- * @param string $baseOrCurrentUrl
- * @param string $beforeCursor
- * @return string
*/
- public function generatePreviousLink($baseOrCurrentUrl, $beforeCursor) {
+ public function generatePreviousLink(string $baseOrCurrentUrl, string $beforeCursor): string {
return $this->setQueryParameter($baseOrCurrentUrl, 'page[before]', $beforeCursor);
}
/**
* helper to get generate a correct page[after] link, use to apply manually
- *
- * @param string $baseOrCurrentUrl
- * @param string $afterCursor
- * @return string
*/
public function generateNextLink($baseOrCurrentUrl, $afterCursor) {
return $this->setQueryParameter($baseOrCurrentUrl, 'page[after]', $afterCursor);
@@ -140,42 +127,25 @@ public function generateNextLink($baseOrCurrentUrl, $afterCursor) {
* - /data/0/relationships/foo/links/prev & /data/0/relationships/foo/links/next
*
* @see https://jsonapi.org/profiles/ethanresnick/cursor-pagination/#terms-pagination-links
- *
- * @param PaginableInterface&HasLinksInterface $paginable
- * @param LinkObject $previousLinkObject
- * @param LinkObject $nextLinkObject
*/
- public function setPaginationLinkObjects(PaginableInterface $paginable, LinkObject $previousLinkObject, LinkObject $nextLinkObject) {
- if ($paginable instanceof HasLinksInterface === false) {
- throw new InputException('unsupported paginable to set pagination links on');
- }
-
+ public function setPaginationLinkObjects(
+ PaginableInterface & HasLinksInterface $paginable,
+ LinkObject $previousLinkObject,
+ LinkObject $nextLinkObject,
+ ): void {
$paginable->addLinkObject('prev', $previousLinkObject);
$paginable->addLinkObject('next', $nextLinkObject);
}
- /**
- * @param PaginableInterface $paginable
- * @param string $baseOrCurrentUrl
- * @param string $firstCursor
- */
- public function setPaginationLinkObjectsWithoutNext(PaginableInterface $paginable, $baseOrCurrentUrl, $firstCursor) {
+ public function setPaginationLinkObjectsWithoutNext(PaginableInterface $paginable, string $baseOrCurrentUrl, string $firstCursor): void {
$this->setPaginationLinkObjects($paginable, new LinkObject($this->generatePreviousLink($baseOrCurrentUrl, $firstCursor)), new LinkObject());
}
- /**
- * @param PaginableInterface $paginable
- * @param string $baseOrCurrentUrl
- * @param string $lastCursor
- */
- public function setPaginationLinkObjectsWithoutPrevious(PaginableInterface $paginable, $baseOrCurrentUrl, $lastCursor) {
+ public function setPaginationLinkObjectsWithoutPrevious(PaginableInterface $paginable, string $baseOrCurrentUrl, string $lastCursor): void {
$this->setPaginationLinkObjects($paginable, new LinkObject(), new LinkObject($this->generateNextLink($baseOrCurrentUrl, $lastCursor)));
}
- /**
- * @param PaginableInterface $paginable
- */
- public function setPaginationLinkObjectsExplicitlyEmpty(PaginableInterface $paginable) {
+ public function setPaginationLinkObjectsExplicitlyEmpty(PaginableInterface $paginable): void {
$this->setPaginationLinkObjects($paginable, new LinkObject(), new LinkObject());
}
@@ -188,21 +158,14 @@ public function setPaginationLinkObjectsExplicitlyEmpty(PaginableInterface $pagi
* - /data/0/relationships/foo/meta/page
*
* @see https://jsonapi.org/profiles/ethanresnick/cursor-pagination/#terms-pagination-item-metadata
- *
- * @param ResourceInterface&HasMetaInterface $resource
- * @param string $cursor
*/
- public function setItemMeta(ResourceInterface $resource, $cursor) {
- if ($resource instanceof HasMetaInterface === false) {
- throw new InputException('resource doesn\'t support meta');
- }
-
+ public function setItemMeta(ResourceInterface & HasMetaInterface $resource, string $cursor): void {
$metadata = [
'cursor' => $cursor,
];
if ($resource instanceof ResourceDocument) {
- $resource->addMeta('page', $metadata, $level=Document::LEVEL_RESOURCE);
+ $resource->addMeta('page', $metadata, $level=DocumentLevelEnum::Resource);
}
else {
$resource->addMeta('page', $metadata);
@@ -219,16 +182,14 @@ public function setItemMeta(ResourceInterface $resource, $cursor) {
*
* @see https://jsonapi.org/profiles/ethanresnick/cursor-pagination/#terms-pagination-metadata
*
- * @param PaginableInterface&HasMetaInterface $paginable
- * @param int $exactTotal optional
- * @param int $bestGuessTotal optional
- * @param boolean $rangeIsTruncated optional, if both after and before are supplied but the items exceed requested or max size
+ * @param boolean $rangeIsTruncated, if both after and before are supplied but the items exceed requested or max size
*/
- public function setPaginationMeta(PaginableInterface $paginable, $exactTotal=null, $bestGuessTotal=null, $rangeIsTruncated=null) {
- if ($paginable instanceof HasMetaInterface === false) {
- throw new InputException('paginable doesn\'t support meta');
- }
-
+ public function setPaginationMeta(
+ PaginableInterface & HasMetaInterface $paginable,
+ ?int $exactTotal=null,
+ ?int $bestGuessTotal=null,
+ ?bool $rangeIsTruncated=null,
+ ): void {
$metadata = [];
if ($exactTotal !== null) {
@@ -250,18 +211,9 @@ public function setPaginationMeta(PaginableInterface $paginable, $exactTotal=nul
* get an ErrorObject for when the requested sorting cannot efficiently be paginated
*
* ends up at:
- * - /errors/0/code
- * - /errors/0/status
- * - /errors/0/source/parameter
- * - /errors/0/links/type/0
- * - /errors/0/title optional
- * - /errors/0/detail optional
- *
- * @param string $genericTitle optional
- * @param string $specificDetails optional
- * @return ErrorObject
+ * - /errors/0/*
*/
- public function getUnsupportedSortErrorObject($genericTitle=null, $specificDetails=null) {
+ public function getUnsupportedSortErrorObject(?string $genericTitle=null, ?string $specificDetails=null): ErrorObject {
$errorObject = new ErrorObject('Unsupported sort');
$errorObject->setTypeLink('https://jsonapi.org/profiles/ethanresnick/cursor-pagination/unsupported-sort');
$errorObject->blameQueryParameter('sort');
@@ -278,20 +230,12 @@ public function getUnsupportedSortErrorObject($genericTitle=null, $specificDetai
* get an ErrorObject for when the requested page size exceeds the server-defined max page size
*
* ends up at:
- * - /errors/0/code
- * - /errors/0/status
- * - /errors/0/source/parameter
- * - /errors/0/links/type/0
- * - /errors/0/meta/page/maxSize
- * - /errors/0/title optional
- * - /errors/0/detail optional
+ * - /errors/0/*
*
- * @param int $maxSize
- * @param string $genericTitle optional, e.g. 'Page size requested is too large.'
- * @param string $specificDetails optional, e.g. 'You requested a size of 200, but 100 is the maximum.'
- * @return ErrorObject
+ * @param string $genericTitle e.g. 'Page size requested is too large.'
+ * @param string $specificDetails e.g. 'You requested a size of 200, but 100 is the maximum.'
*/
- public function getMaxPageSizeExceededErrorObject($maxSize, $genericTitle=null, $specificDetails=null) {
+ public function getMaxPageSizeExceededErrorObject(int $maxSize, ?string $genericTitle=null, ?string $specificDetails=null): ErrorObject {
$errorObject = new ErrorObject('Max page size exceeded');
$errorObject->setTypeLink('https://jsonapi.org/profiles/ethanresnick/cursor-pagination/max-size-exceeded');
$errorObject->blameQueryParameter('page[size]');
@@ -309,20 +253,18 @@ public function getMaxPageSizeExceededErrorObject($maxSize, $genericTitle=null,
* get an ErrorObject for when the requested page size is not a positive integer, or when the requested page after/before is not a valid cursor
*
* ends up at:
- * - /errors/0/code
- * - /errors/0/status
- * - /errors/0/source/parameter
- * - /errors/0/links/type/0 optional
- * - /errors/0/title optional
- * - /errors/0/detail optional
+ * - /errors/0/*
*
- * @param int $queryParameter e.g. 'sort' or 'page[size]'
- * @param string $typeLink optional
- * @param string $genericTitle optional, e.g. 'Invalid Parameter.'
- * @param string $specificDetails optional, e.g. 'page[size] must be a positive integer; got 0'
- * @return ErrorObject
+ * @param string $queryParameter e.g. 'sort' or 'page[size]'
+ * @param string $genericTitle e.g. 'Invalid Parameter.'
+ * @param string $specificDetails e.g. 'page[size] must be a positive integer; got 0'
*/
- public function getInvalidParameterValueErrorObject($queryParameter, $typeLink=null, $genericTitle=null, $specificDetails=null) {
+ public function getInvalidParameterValueErrorObject(
+ string $queryParameter,
+ ?string $typeLink=null,
+ ?string $genericTitle=null,
+ ?string $specificDetails=null,
+ ): ErrorObject {
$errorObject = new ErrorObject('Invalid parameter value');
$errorObject->blameQueryParameter($queryParameter);
$errorObject->setHttpStatusCode(400);
@@ -342,15 +284,9 @@ public function getInvalidParameterValueErrorObject($queryParameter, $typeLink=n
* get an ErrorObject for when range pagination requests (when both 'page[after]' and 'page[before]' are requested) are not supported
*
* ends up at:
- * - /errors/0/code
- * - /errors/0/status
- * - /errors/0/links/type/0
- *
- * @param string $genericTitle optional
- * @param string $specificDetails optional
- * @return ErrorObject
+ * - /errors/0/*
*/
- public function getRangePaginationNotSupportedErrorObject($genericTitle=null, $specificDetails=null) {
+ public function getRangePaginationNotSupportedErrorObject(?string $genericTitle=null, ?string $specificDetails=null): ErrorObject {
$errorObject = new ErrorObject('Range pagination not supported');
$errorObject->setTypeLink('https://jsonapi.org/profiles/ethanresnick/cursor-pagination/range-pagination-not-supported');
$errorObject->setHttpStatusCode(400);
@@ -368,12 +304,8 @@ public function getRangePaginationNotSupportedErrorObject($genericTitle=null, $s
/**
* add or adjust a key in the query string of a url
- *
- * @param string $url
- * @param string $key
- * @param string $value
*/
- private function setQueryParameter($url, $key, $value) {
+ private function setQueryParameter(string $url, string $key, string $value): string {
$originalQuery = parse_url($url, PHP_URL_QUERY);
$decodedQuery = urldecode($originalQuery);
$originalIsEncoded = ($decodedQuery !== $originalQuery);
@@ -400,7 +332,7 @@ private function setQueryParameter($url, $key, $value) {
* ProfileInterface
*/
- public function getOfficialLink() {
+ public function getOfficialLink(): string {
return 'https://jsonapi.org/profiles/ethanresnick/cursor-pagination/';
}
}
diff --git a/tests/CollectionDocumentTest.php b/tests/CollectionDocumentTest.php
index fd255f09..97ce3e86 100644
--- a/tests/CollectionDocumentTest.php
+++ b/tests/CollectionDocumentTest.php
@@ -1,5 +1,7 @@
assertSame('foo', Converter::prepareContentType('foo', [], []));
+ $this->assertSame(ContentTypeEnum::Official->value, Converter::prepareContentType(ContentTypeEnum::Official, [], []));
}
/**
@@ -78,7 +81,7 @@ public function testPrepareContentType_WithExtensionStringLink() {
$extension = new TestExtension();
$extension->setOfficialLink('bar');
- $this->assertSame('foo; ext="bar"', Converter::prepareContentType('foo', [$extension], []));
+ $this->assertSame(ContentTypeEnum::Official->value.'; ext="bar"', Converter::prepareContentType(ContentTypeEnum::Official, [$extension], []));
}
/**
@@ -88,7 +91,7 @@ public function testPrepareContentType_WithProfileStringLink() {
$profile = new TestProfile();
$profile->setOfficialLink('bar');
- $this->assertSame('foo; profile="bar"', Converter::prepareContentType('foo', [], [$profile]));
+ $this->assertSame(ContentTypeEnum::Official->value.'; profile="bar"', Converter::prepareContentType(ContentTypeEnum::Official, [], [$profile]));
}
/**
@@ -108,7 +111,7 @@ public function testPrepareContentType_WithMultipleExtensionsAndProfiles() {
$profile2 = new TestProfile();
$profile2->setOfficialLink('baz');
- $this->assertSame('foo; ext="bar baz"; profile="bar baz"', Converter::prepareContentType('foo', [$extension1, $extension2], [$profile1, $profile2]));
+ $this->assertSame(ContentTypeEnum::Official->value.'; ext="bar baz"; profile="bar baz"', Converter::prepareContentType(ContentTypeEnum::Official, [$extension1, $extension2], [$profile1, $profile2]));
}
}
diff --git a/tests/DocumentTest.php b/tests/DocumentTest.php
index 6e8e51c6..024f989d 100644
--- a/tests/DocumentTest.php
+++ b/tests/DocumentTest.php
@@ -1,7 +1,10 @@
expectException(InputException::class);
$this->expectExceptionMessage('level "jsonapi" can not be used for links');
- $document->addLink('foo', 'https://jsonapi.org', $meta=[], $level=Document::LEVEL_JSONAPI);
+ $document->addLink('foo', 'https://jsonapi.org', $meta=[], $level=DocumentLevelEnum::Jsonapi);
}
public function testAddLink_BlocksResourceLevel() {
@@ -77,16 +80,7 @@ public function testAddLink_BlocksResourceLevel() {
$this->expectException(InputException::class);
$this->expectExceptionMessage('level "resource" can only be set on a ResourceDocument');
- $document->addLink('foo', 'https://jsonapi.org', $meta=[], $level=Document::LEVEL_RESOURCE);
- }
-
- public function testAddLink_BlocksUnknownLevel() {
- $document = new Document();
-
- $this->expectException(InputException::class);
- $this->expectExceptionMessage('unknown level "foo"');
-
- $document->addLink('foo', 'https://jsonapi.org', $meta=[], $level='foo');
+ $document->addLink('foo', 'https://jsonapi.org', $meta=[], $level=DocumentLevelEnum::Resource);
}
public function testSetSelfLink_HappyPath() {
@@ -160,7 +154,7 @@ public function testAddMeta_AtJsonapiLevel() {
$this->assertArrayHasKey('jsonapi', $array);
$this->assertArrayNotHasKey('meta', $array['jsonapi']);
- $document->addMeta('foo', 'bar', $level=Document::LEVEL_JSONAPI);
+ $document->addMeta('foo', 'bar', $level=DocumentLevelEnum::Jsonapi);
$array = $document->toArray();
@@ -178,16 +172,7 @@ public function testAddMeta_BlocksResourceLevel() {
$this->expectException(InputException::class);
$this->expectExceptionMessage('level "resource" can only be set on a ResourceDocument');
- $document->addMeta('foo', 'bar', $level=Document::LEVEL_RESOURCE);
- }
-
- public function testAddMeta_BlocksUnknownLevel() {
- $document = new Document();
-
- $this->expectException(InputException::class);
- $this->expectExceptionMessage('unknown level "foo"');
-
- $document->addMeta('foo', 'bar', $level='foo');
+ $document->addMeta('foo', 'bar', $level=DocumentLevelEnum::Resource);
}
public function testAddLinkObject_HappyPath() {
diff --git a/tests/ErrorsDocumentTest.php b/tests/ErrorsDocumentTest.php
index 151f44e8..10e694f5 100644
--- a/tests/ErrorsDocumentTest.php
+++ b/tests/ErrorsDocumentTest.php
@@ -1,5 +1,7 @@
addMeta('foo', 'root', $level=Document::LEVEL_ROOT);
- $document->addMeta('bar', 'resource', $level=Document::LEVEL_RESOURCE);
- $document->addMeta('baz', 'jsonapi', $level=Document::LEVEL_JSONAPI);
+ $document->addMeta('foo', 'root', $level=DocumentLevelEnum::Root);
+ $document->addMeta('bar', 'resource', $level=DocumentLevelEnum::Resource);
+ $document->addMeta('baz', 'jsonapi', $level=DocumentLevelEnum::Jsonapi);
$array = $document->toArray();
@@ -122,7 +124,7 @@ public function testAddMeta_RecreateJsonapiObject() {
$this->assertArrayNotHasKey('jsonapi', $array);
- $document->addMeta('baz', 'jsonapi', $level=Document::LEVEL_JSONAPI);
+ $document->addMeta('baz', 'jsonapi', $level=DocumentLevelEnum::Jsonapi);
$array = $document->toArray();
diff --git a/tests/SeparateProcessTest.php b/tests/SeparateProcessTest.php
index ec00ccdf..95f8290a 100644
--- a/tests/SeparateProcessTest.php
+++ b/tests/SeparateProcessTest.php
@@ -1,8 +1,11 @@
sendResponse();
@@ -28,7 +31,7 @@ public function testSendResponse_HappyPath() {
* @runInSeparateProcess
*/
public function testSendResponse_NoContent() {
- $document = new Document();
+ $document = new TestableNonAbstractDocument();
$document->setHttpStatusCode(204);
ob_start();
@@ -47,30 +50,30 @@ public function testSendResponse_ContentTypeHeader() {
$this->markTestSkipped('can not run without xdebug');
}
- $document = new Document();
+ $document = new TestableNonAbstractDocument();
ob_start();
$document->sendResponse();
ob_end_clean();
- $this->assertSame(['Content-Type: '.Document::CONTENT_TYPE_OFFICIAL], xdebug_get_headers());
+ $this->assertSame(['Content-Type: '.ContentTypeEnum::Official->value], xdebug_get_headers());
- $options = ['contentType' => Document::CONTENT_TYPE_OFFICIAL];
+ $options = ['contentType' => ContentTypeEnum::Official];
ob_start();
$document->sendResponse($options);
ob_end_clean();
- $this->assertSame(['Content-Type: '.Document::CONTENT_TYPE_OFFICIAL], xdebug_get_headers());
+ $this->assertSame(['Content-Type: '.ContentTypeEnum::Official->value], xdebug_get_headers());
- $options = ['contentType' => Document::CONTENT_TYPE_DEBUG];
+ $options = ['contentType' => ContentTypeEnum::Debug];
ob_start();
$document->sendResponse($options);
ob_end_clean();
- $this->assertSame(['Content-Type: '.Document::CONTENT_TYPE_DEBUG], xdebug_get_headers());
+ $this->assertSame(['Content-Type: '.ContentTypeEnum::Debug->value], xdebug_get_headers());
- $options = ['contentType' => Document::CONTENT_TYPE_JSONP];
+ $options = ['contentType' => ContentTypeEnum::Jsonp];
ob_start();
$document->sendResponse($options);
ob_end_clean();
- $this->assertSame(['Content-Type: '.Document::CONTENT_TYPE_JSONP], xdebug_get_headers());
+ $this->assertSame(['Content-Type: '.ContentTypeEnum::Jsonp->value], xdebug_get_headers());
}
/**
@@ -86,13 +89,13 @@ public function testSendResponse_ContentTypeHeaderWithExtensions() {
$extension->setNamespace('one');
$extension->setOfficialLink('https://jsonapi.org');
- $document = new Document();
+ $document = new TestableNonAbstractDocument();
$document->applyExtension($extension);
ob_start();
$document->sendResponse();
ob_end_clean();
- $this->assertSame(['Content-Type: '.Document::CONTENT_TYPE_OFFICIAL.'; ext="https://jsonapi.org"'], xdebug_get_headers());
+ $this->assertSame(['Content-Type: '.ContentTypeEnum::Official->value.'; ext="https://jsonapi.org"'], xdebug_get_headers());
$extension = new TestExtension();
$extension->setNamespace('two');
@@ -102,7 +105,7 @@ public function testSendResponse_ContentTypeHeaderWithExtensions() {
ob_start();
$document->sendResponse();
ob_end_clean();
- $this->assertSame(['Content-Type: '.Document::CONTENT_TYPE_OFFICIAL.'; ext="https://jsonapi.org https://jsonapi.org/2"'], xdebug_get_headers());
+ $this->assertSame(['Content-Type: '.ContentTypeEnum::Official->value.'; ext="https://jsonapi.org https://jsonapi.org/2"'], xdebug_get_headers());
}
/**
@@ -117,13 +120,13 @@ public function testSendResponse_ContentTypeHeaderWithProfiles() {
$profile = new TestProfile();
$profile->setOfficialLink('https://jsonapi.org');
- $document = new Document();
+ $document = new TestableNonAbstractDocument();
$document->applyProfile($profile);
ob_start();
$document->sendResponse();
ob_end_clean();
- $this->assertSame(['Content-Type: '.Document::CONTENT_TYPE_OFFICIAL.'; profile="https://jsonapi.org"'], xdebug_get_headers());
+ $this->assertSame(['Content-Type: '.ContentTypeEnum::Official->value.'; profile="https://jsonapi.org"'], xdebug_get_headers());
$profile = new TestProfile();
$profile->setOfficialLink('https://jsonapi.org/2');
@@ -132,14 +135,14 @@ public function testSendResponse_ContentTypeHeaderWithProfiles() {
ob_start();
$document->sendResponse();
ob_end_clean();
- $this->assertSame(['Content-Type: '.Document::CONTENT_TYPE_OFFICIAL.'; profile="https://jsonapi.org https://jsonapi.org/2"'], xdebug_get_headers());
+ $this->assertSame(['Content-Type: '.ContentTypeEnum::Official->value.'; profile="https://jsonapi.org https://jsonapi.org/2"'], xdebug_get_headers());
}
/**
* @runInSeparateProcess
*/
public function testSendResponse_StatusCodeHeader() {
- $document = new Document();
+ $document = new TestableNonAbstractDocument();
ob_start();
$document->sendResponse();
@@ -169,7 +172,7 @@ public function testSendResponse_StatusCodeHeader() {
* @runInSeparateProcess
*/
public function testSendResponse_CustomJson() {
- $document = new Document();
+ $document = new TestableNonAbstractDocument();
$options = ['json' => '{"foo":42}'];
ob_start();
diff --git a/tests/TestableNonAbstractDocument.php b/tests/TestableNonAbstractDocument.php
index 4f1b018f..57f55161 100644
--- a/tests/TestableNonAbstractDocument.php
+++ b/tests/TestableNonAbstractDocument.php
@@ -1,5 +1,7 @@
claimUsedFields($fieldNames, $objectContainer);
$fieldNames = ['bar'];
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$validator->claimUsedFields($fieldNames, $objectContainer);
}
@@ -28,12 +31,12 @@ public function testClaimUsedFields_EnforceNamespace() {
$validator = new Validator();
$fieldNames = ['foo'];
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$validator->claimUsedFields($fieldNames, $objectContainer);
$this->expectException(DuplicateException::class);
- $objectContainer = Validator::OBJECT_CONTAINER_RELATIONSHIPS;
+ $objectContainer = ObjectContainerEnum::Relationships;
$validator->claimUsedFields($fieldNames, $objectContainer);
}
@@ -42,10 +45,10 @@ public function testClaimUsedFields_AllowSameContainer() {
$validator = new Validator();
$fieldNames = ['foo'];
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$validator->claimUsedFields($fieldNames, $objectContainer);
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$validator->claimUsedFields($fieldNames, $objectContainer);
}
@@ -54,10 +57,10 @@ public function testClaimUsedFields_OptionForReusingTypeField() {
$validator = new Validator();
$fieldNames = ['type'];
- $objectContainer = Validator::OBJECT_CONTAINER_TYPE;
+ $objectContainer = ObjectContainerEnum::Type;
$validator->claimUsedFields($fieldNames, $objectContainer);
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$options = ['enforceTypeFieldNamespace' => false];
$validator->claimUsedFields($fieldNames, $objectContainer, $options);
}
@@ -67,7 +70,7 @@ public function testClearUsedFields_HappyPath() {
$validator = new Validator();
$fieldNames = ['foo'];
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$validator->claimUsedFields($fieldNames, $objectContainer);
$validator->clearUsedFields($objectContainer);
@@ -77,13 +80,13 @@ public function testClearUsedFields_FreesForAnotherNamespace() {
$validator = new Validator();
$fieldNames = ['foo', 'bar'];
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$validator->claimUsedFields($fieldNames, $objectContainer);
$thrown = false;
try {
$fieldNames = ['bar'];
- $objectContainer = Validator::OBJECT_CONTAINER_RELATIONSHIPS;
+ $objectContainer = ObjectContainerEnum::Relationships;
$validator->claimUsedFields($fieldNames, $objectContainer);
}
catch (DuplicateException) {
@@ -91,21 +94,21 @@ public function testClearUsedFields_FreesForAnotherNamespace() {
}
$this->assertTrue($thrown);
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$validator->clearUsedFields($objectContainer);
$fieldNames = ['foo'];
- $objectContainer = Validator::OBJECT_CONTAINER_ATTRIBUTES;
+ $objectContainer = ObjectContainerEnum::Attributes;
$validator->claimUsedFields($fieldNames, $objectContainer);
$fieldNames = ['bar'];
- $objectContainer = Validator::OBJECT_CONTAINER_RELATIONSHIPS;
+ $objectContainer = ObjectContainerEnum::Relationships;
$validator->claimUsedFields($fieldNames, $objectContainer);
$this->expectException(DuplicateException::class);
$fieldNames = ['foo'];
- $objectContainer = Validator::OBJECT_CONTAINER_RELATIONSHIPS;
+ $objectContainer = ObjectContainerEnum::Relationships;
$validator->claimUsedFields($fieldNames, $objectContainer);
}
diff --git a/tests/bootstrap_tests.php b/tests/bootstrap_tests.php
index f695b44a..80a03b31 100644
--- a/tests/bootstrap_tests.php
+++ b/tests/bootstrap_tests.php
@@ -1,5 +1,7 @@
addAtMember('context', '/data/relationships/foo/meta/@context');
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationshipObject->addAtMember('context', '/data/relationships/foo/@context');
$relationshipObject->setResource($resourceObject);
$relationshipObject->setLinksObject($linksObject);
@@ -102,7 +105,7 @@ public static function createJsonapiDocument() {
$resourceIdentifierObject->addAtMember('context', '/data/relationships/bar/data/@context');
$resourceIdentifierObject->setMetaObject($metaObject);
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationshipObject->addAtMember('context', '/data/relationships/bar/@context');
$relationshipObject->setResource($resourceIdentifierObject);
diff --git a/tests/example_output/at_members_in_errors/at_members_in_errors.php b/tests/example_output/at_members_in_errors/at_members_in_errors.php
index 8d975137..e937eb88 100644
--- a/tests/example_output/at_members_in_errors/at_members_in_errors.php
+++ b/tests/example_output/at_members_in_errors/at_members_in_errors.php
@@ -1,5 +1,7 @@
addExtensionMember($extension, 'key', '/data/relationships/foo/meta/key');
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationshipObject->addExtensionMember($extension, 'key', '/data/relationships/foo/key');
$relationshipObject->setResource($resourceObject);
$relationshipObject->setLinksObject($linksObject);
@@ -107,7 +110,7 @@ public static function createJsonapiDocument() {
$resourceIdentifierObject->addExtensionMember($extension, 'key', '/data/relationships/bar/data/key');
$resourceIdentifierObject->setMetaObject($metaObject);
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationshipObject->addExtensionMember($extension, 'key', '/data/relationships/bar/key');
$relationshipObject->setResource($resourceIdentifierObject);
diff --git a/tests/example_output/meta_only/meta_only.php b/tests/example_output/meta_only/meta_only.php
index 2bf1ee62..2bf360d4 100644
--- a/tests/example_output/meta_only/meta_only.php
+++ b/tests/example_output/meta_only/meta_only.php
@@ -1,5 +1,7 @@
addLinkObject('bar', new LinkObject());
$document->addRelationship('bar', null);
- $document->addRelationshipObject('baz', new RelationshipObject(RelationshipObject::TO_ONE));
- $document->addRelationshipObject('baf', new RelationshipObject(RelationshipObject::TO_MANY));
+ $document->addRelationshipObject('baz', new RelationshipObject(RelationshipTypeEnum::ToOne));
+ $document->addRelationshipObject('baf', new RelationshipObject(RelationshipTypeEnum::ToMany));
return $document;
}
diff --git a/tests/example_output/profile/profile.php b/tests/example_output/profile/profile.php
index 16deba80..56bdde48 100644
--- a/tests/example_output/profile/profile.php
+++ b/tests/example_output/profile/profile.php
@@ -1,5 +1,7 @@
setSelfLink('/articles/1/relationship/author', $meta=[], $level=Document::LEVEL_ROOT);
+ $document->setSelfLink('/articles/1/relationship/author', $meta=[], $level=DocumentLevelEnum::Root);
$document->addLink('related', '/articles/1/author');
return $document;
diff --git a/tests/example_output/relationships/relationships.php b/tests/example_output/relationships/relationships.php
index 8426cdd2..49f833f2 100644
--- a/tests/example_output/relationships/relationships.php
+++ b/tests/example_output/relationships/relationships.php
@@ -1,9 +1,12 @@
addResource($friend1Resource);
$relationshipObject->addResource($friend2Resource);
@@ -63,7 +66,7 @@ public static function createJsonapiDocument() {
* to-many relationship, different types
*/
- $relationshipObject = new RelationshipObject($type=RelationshipObject::TO_MANY);
+ $relationshipObject = new RelationshipObject($type=RelationshipTypeEnum::ToMany);
$relationshipObject->addResource($ship1Resource);
$relationshipObject->addResource($dockResource);
diff --git a/tests/example_output/resource_document_identifier_only/resource_document_identifier_only.php b/tests/example_output/resource_document_identifier_only/resource_document_identifier_only.php
index 493f7ccf..3c960584 100644
--- a/tests/example_output/resource_document_identifier_only/resource_document_identifier_only.php
+++ b/tests/example_output/resource_document_identifier_only/resource_document_identifier_only.php
@@ -1,5 +1,7 @@
id);
- $selfResourceMeta = ['level' => Document::LEVEL_RESOURCE];
- $partnerMeta = ['level' => Document::LEVEL_RESOURCE];
- $redirectMeta = ['level' => Document::LEVEL_ROOT];
+ $selfResourceMeta = ['level' => DocumentLevelEnum::Resource->name];
+ $partnerMeta = ['level' => DocumentLevelEnum::Resource->name];
+ $redirectMeta = ['level' => DocumentLevelEnum::Root->name];
$document->setSelfLink('/user/42', $selfResourceMeta);
- $document->addLink('partner', '/user/1', $partnerMeta, $level=Document::LEVEL_RESOURCE);
- $document->addLink('redirect', '/login', $redirectMeta, $level=Document::LEVEL_ROOT);
+ $document->addLink('partner', '/user/1', $partnerMeta, $level=DocumentLevelEnum::Resource);
+ $document->addLink('redirect', '/login', $redirectMeta, $level=DocumentLevelEnum::Root);
return $document;
}
diff --git a/tests/example_output/resource_nested_relations/resource_nested_relations.php b/tests/example_output/resource_nested_relations/resource_nested_relations.php
index 4095c84a..5db1d549 100644
--- a/tests/example_output/resource_nested_relations/resource_nested_relations.php
+++ b/tests/example_output/resource_nested_relations/resource_nested_relations.php
@@ -1,5 +1,7 @@
setType('user');
$resource->setAttributesObject($attributes42);
- $relationship = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationship = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationship->setResource($resource);
$relationships = new RelationshipsObject();
$relationships->addRelationshipObject('friend', $relationship);
diff --git a/tests/example_output/status_only/status_only.php b/tests/example_output/status_only/status_only.php
index 35462051..209e9cb7 100644
--- a/tests/example_output/status_only/status_only.php
+++ b/tests/example_output/status_only/status_only.php
@@ -1,5 +1,7 @@
namespace = $namespace;
}
- public function setOfficialLink($officialLink) {
+ public function setOfficialLink(string $officialLink) {
$this->officialLink = $officialLink;
}
- public function getNamespace() {
+ public function getNamespace(): string {
return $this->namespace;
}
- public function getOfficialLink() {
+ public function getOfficialLink(): string {
return $this->officialLink;
}
}
diff --git a/tests/helpers/AtMemberManagerTest.php b/tests/helpers/AtMemberManagerTest.php
index b0244aab..ee2fc210 100644
--- a/tests/helpers/AtMemberManagerTest.php
+++ b/tests/helpers/AtMemberManagerTest.php
@@ -1,5 +1,7 @@
assertFalse($helper->hasHttpStatusCode());
- $this->assertNull($helper->getHttpStatusCode());
$helper->setHttpStatusCode(204);
diff --git a/tests/helpers/LinksManagerTest.php b/tests/helpers/LinksManagerTest.php
index b93ef1f3..97c462b0 100644
--- a/tests/helpers/LinksManagerTest.php
+++ b/tests/helpers/LinksManagerTest.php
@@ -1,5 +1,7 @@
value;
$_POST = [
'data' => [
@@ -61,7 +64,7 @@ public function testFromSuperglobals_HappyPath() {
$this->assertSame(['ship' => ['wing' => []]], $requestParser->getIncludePaths());
$this->assertSame(['name', 'location'], $requestParser->getSparseFieldset('user'));
- $this->assertSame([['field' => 'name', 'order' => RequestParser::SORT_ASCENDING], ['field' => 'location', 'order' => RequestParser::SORT_DESCENDING]], $requestParser->getSortFields());
+ $this->assertSame([['field' => 'name', 'order' => SortOrderEnum::Ascending], ['field' => 'location', 'order' => SortOrderEnum::Descending]], $requestParser->getSortFields());
$this->assertSame(['number' => '2', 'size' => '10'], $requestParser->getPagination());
$this->assertSame('42', $requestParser->getFilter());
@@ -80,7 +83,7 @@ public function testFromSuperglobals_WithPhpInputStream() {
$_SERVER['REQUEST_SCHEME'] = 'https';
$_SERVER['HTTP_HOST'] = 'example.org';
$_SERVER['REQUEST_URI'] = '/';
- $_SERVER['CONTENT_TYPE'] = Document::CONTENT_TYPE_OFFICIAL;
+ $_SERVER['CONTENT_TYPE'] = ContentTypeEnum::Official->value;
$_GET = [];
$_POST = [];
@@ -152,7 +155,7 @@ public function testFromPsrRequest_WithRequestInterface() {
$this->assertSame(['ship' => ['wing' => []]], $requestParser->getIncludePaths());
$this->assertSame(['name', 'location'], $requestParser->getSparseFieldset('user'));
- $this->assertSame([['field' => 'name', 'order' => RequestParser::SORT_ASCENDING], ['field' => 'location', 'order' => RequestParser::SORT_DESCENDING]], $requestParser->getSortFields());
+ $this->assertSame([['field' => 'name', 'order' => SortOrderEnum::Ascending], ['field' => 'location', 'order' => SortOrderEnum::Descending]], $requestParser->getSortFields());
$this->assertSame(['number' => '2', 'size' => '10'], $requestParser->getPagination());
$this->assertSame('42', $requestParser->getFilter());
@@ -190,7 +193,7 @@ public function testFromPsrRequest_WithServerRequestInterface() {
$this->assertSame('https://example.org/user/42?'.http_build_query($queryParameters), $requestParser->getSelfLink());
$this->assertTrue($requestParser->hasSortFields());
- $this->assertSame([['field' => 'name', 'order' => RequestParser::SORT_ASCENDING], ['field' => 'location', 'order' => RequestParser::SORT_DESCENDING]], $requestParser->getSortFields());
+ $this->assertSame([['field' => 'name', 'order' => SortOrderEnum::Ascending], ['field' => 'location', 'order' => SortOrderEnum::Descending]], $requestParser->getSortFields());
}
public function testGetSelfLink() {
@@ -292,15 +295,15 @@ public function testHasSortFields() {
public function testGetSortFields_Reformatted() {
$queryParameters = ['sort' => 'foo'];
$requestParser = new RequestParser($selfLink='', $queryParameters);
- $this->assertSame([['field' => 'foo', 'order' => RequestParser::SORT_ASCENDING]], $requestParser->getSortFields());
+ $this->assertSame([['field' => 'foo', 'order' => SortOrderEnum::Ascending]], $requestParser->getSortFields());
$queryParameters = ['sort' => '-bar'];
$requestParser = new RequestParser($selfLink='', $queryParameters);
- $this->assertSame([['field' => 'bar', 'order' => RequestParser::SORT_DESCENDING]], $requestParser->getSortFields());
+ $this->assertSame([['field' => 'bar', 'order' => SortOrderEnum::Descending]], $requestParser->getSortFields());
$queryParameters = ['sort' => 'foo,-bar'];
$requestParser = new RequestParser($selfLink='', $queryParameters);
- $this->assertSame([['field' => 'foo', 'order' => RequestParser::SORT_ASCENDING], ['field' => 'bar', 'order' => RequestParser::SORT_DESCENDING]], $requestParser->getSortFields());
+ $this->assertSame([['field' => 'foo', 'order' => SortOrderEnum::Ascending], ['field' => 'bar', 'order' => SortOrderEnum::Descending]], $requestParser->getSortFields());
}
public function testGetSortFields_Raw() {
diff --git a/tests/helpers/TestableNonInterfaceRequestInterface.php b/tests/helpers/TestableNonInterfaceRequestInterface.php
index e2d26da7..1918c52e 100644
--- a/tests/helpers/TestableNonInterfaceRequestInterface.php
+++ b/tests/helpers/TestableNonInterfaceRequestInterface.php
@@ -1,5 +1,7 @@
links === null) {
+ if ($this->hasLinks() === false) {
return [];
}
diff --git a/tests/objects/AttributesObjectTest.php b/tests/objects/AttributesObjectTest.php
index 047e3d1a..90e69c0f 100644
--- a/tests/objects/AttributesObjectTest.php
+++ b/tests/objects/AttributesObjectTest.php
@@ -1,5 +1,7 @@
assertSame('bar', $array['foo']);
}
+ public function testAdd_AllowsMixedValue() {
+ $attributesObject = new AttributesObject();
+ $attributesObject->add('array-list', ['foo']);
+ $attributesObject->add('array-int-key', [42 => 'foo']);
+ $attributesObject->add('array-string-key', ['foo' => 'bar']);
+ $attributesObject->add('bool', true);
+ $attributesObject->add('int', 42);
+ $attributesObject->add('float', 4.2);
+ $attributesObject->add('null', null);
+ $attributesObject->add('object', new \stdClass);
+ $attributesObject->add('string', 'foo');
+
+ $array = $attributesObject->toArray();
+
+ $this->assertCount(9, $array);
+ }
+
public function testAdd_WithObject() {
$object = new \stdClass();
$object->bar = 'baz';
diff --git a/tests/objects/ErrorObjectTest.php b/tests/objects/ErrorObjectTest.php
index a794dca8..31365208 100644
--- a/tests/objects/ErrorObjectTest.php
+++ b/tests/objects/ErrorObjectTest.php
@@ -1,5 +1,7 @@
add('array-list', ['foo']);
+ $metaObject->add('array-int-key', [42 => 'foo']);
+ $metaObject->add('array-string-key', ['foo' => 'bar']);
+ $metaObject->add('bool', true);
+ $metaObject->add('int', 42);
+ $metaObject->add('float', 4.2);
+ $metaObject->add('null', null);
+ $metaObject->add('object', new \stdClass);
+ $metaObject->add('string', 'foo');
+
+ $array = $metaObject->toArray();
+
+ $this->assertCount(9, $array);
+ }
+
public function testFromObject_HappyPath() {
$object = new \stdClass();
$object->foo = 'bar';
diff --git a/tests/objects/RelationshipObjectTest.php b/tests/objects/RelationshipObjectTest.php
index a09dec13..8ce618d6 100644
--- a/tests/objects/RelationshipObjectTest.php
+++ b/tests/objects/RelationshipObjectTest.php
@@ -1,9 +1,12 @@
setResource(new ResourceObject('user', 42));
$this->validateToOneRelationshipArray($relationshipObject->toArray());
}
public function testConstructor_ToMany() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_MANY);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToMany);
$relationshipObject->addResource(new ResourceObject('user', 42));
$this->validateToManyRelationshipArray($relationshipObject->toArray());
}
- public function testConstructor_UnknownType() {
- $this->expectException(InputException::class);
-
- $relationshipObject = new RelationshipObject('foo');
- }
-
public function testFromAnything_WithResourceObject() {
$resourceObject = new ResourceObject('user', 42);
$resourceObject->addMeta('foo', 'bar');
@@ -68,19 +65,9 @@ public function testFromAnything_WithResourceObjects() {
$this->validateToManyRelationshipArray($relationshipObject->toArray());
}
- public function testFromAnything_WithUnknownType() {
- $fakeResource = new \stdClass();
- $fakeResource->type = 'user';
- $fakeResource->id = 42;
-
- $this->expectException(InputException::class);
-
- RelationshipObject::fromAnything($fakeResource);
- }
-
public function testFromResource_ToMany() {
$resourceObject = new ResourceObject('user', 42);
- $type = RelationshipObject::TO_MANY;
+ $type = RelationshipTypeEnum::ToMany;
$relationshipObject = RelationshipObject::fromResource($resourceObject, $links=[], $meta=[], $type);
@@ -137,7 +124,7 @@ public function testFromCollectionDocument_WithMeta() {
}
public function testSetSelfLink_HappyPath() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationshipObject->setSelfLink('https://jsonapi.org');
$array = $relationshipObject->toArray();
@@ -148,7 +135,7 @@ public function testSetSelfLink_HappyPath() {
}
public function testSetRelatedLink_HappyPath() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationshipObject->setRelatedLink('https://jsonapi.org');
$array = $relationshipObject->toArray();
@@ -159,7 +146,7 @@ public function testSetRelatedLink_HappyPath() {
}
public function testSetPaginationLinks_HappyPath() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_MANY);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToMany);
$baseUrl = 'https://jsonapi.org/?page=';
$relationshipObject->setPaginationLinks($baseUrl.'prev', $baseUrl.'next', $baseUrl.'first', $baseUrl.'last');
@@ -179,7 +166,7 @@ public function testSetPaginationLinks_HappyPath() {
}
public function testSetPaginationLinks_BlockedOnToOne() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$this->expectException(InputException::class);
@@ -187,7 +174,7 @@ public function testSetPaginationLinks_BlockedOnToOne() {
}
public function testAddMeta_HappyPath() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$this->assertTrue($relationshipObject->isEmpty());
@@ -205,7 +192,7 @@ public function testAddMeta_HappyPath() {
public function testHasResource_ToMany() {
$resourceObject = new ResourceObject('user', 42);
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_MANY);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToMany);
$relationshipObject->addResource($resourceObject);
$this->assertTrue($relationshipObject->hasResource($resourceObject));
@@ -214,7 +201,7 @@ public function testHasResource_ToMany() {
}
public function testGetContainedResources_SkipsResourceIdentifierObjects() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_MANY);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToMany);
$resourceIdentifierObject = new ResourceIdentifierObject('user', 24);
$resourceObjectIdentifierOnly = new ResourceObject('user', 42);
$resourceObjectWithAttributes = new ResourceObject('user', 42);
@@ -236,14 +223,14 @@ public function testGetContainedResources_SkipsResourceIdentifierObjects() {
}
public function testSetResource_HappyPath() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationshipObject->setResource(new ResourceObject('user', 42));
$this->validateToOneRelationshipArray($relationshipObject->toArray());
}
public function testSetResource_RequiresToOneType() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_MANY);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToMany);
$this->expectException(InputException::class);
@@ -251,14 +238,14 @@ public function testSetResource_RequiresToOneType() {
}
public function testAddResource_HappyPath() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_MANY);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToMany);
$relationshipObject->addResource(new ResourceObject('user', 42));
$this->validateToManyRelationshipArray($relationshipObject->toArray());
}
public function testAddResource_RequiresToOneType() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$this->expectException(InputException::class);
@@ -266,7 +253,7 @@ public function testAddResource_RequiresToOneType() {
}
public function testAddLinkObject_HappyPath() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$this->assertTrue($relationshipObject->isEmpty());
@@ -284,7 +271,7 @@ public function testAddLinkObject_HappyPath() {
}
public function testToArray_EmptyResource() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$array = $relationshipObject->toArray();
@@ -293,7 +280,7 @@ public function testToArray_EmptyResource() {
}
public function testToArray_EmptyResources() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_MANY);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToMany);
$array = $relationshipObject->toArray();
@@ -302,7 +289,7 @@ public function testToArray_EmptyResources() {
}
public function testIsEmpty_WithAtMembers() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$this->assertTrue($relationshipObject->isEmpty());
@@ -315,7 +302,7 @@ public function testIsEmpty_WithAtMembers() {
* @group Extensions
*/
public function testIsEmpty_WithExtensionMembers() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$this->assertTrue($relationshipObject->isEmpty());
diff --git a/tests/objects/RelationshipsObjectTest.php b/tests/objects/RelationshipsObjectTest.php
index a1eb5101..9c98b613 100644
--- a/tests/objects/RelationshipsObjectTest.php
+++ b/tests/objects/RelationshipsObjectTest.php
@@ -1,7 +1,10 @@
addRelationshipObject($key='foo', $relationshipObject);
diff --git a/tests/objects/ResourceIdentifierObjectTest.php b/tests/objects/ResourceIdentifierObjectTest.php
index b7eb1eaf..6383aa20 100644
--- a/tests/objects/ResourceIdentifierObjectTest.php
+++ b/tests/objects/ResourceIdentifierObjectTest.php
@@ -1,5 +1,7 @@
toArray();
- $this->assertArrayHasKey('type', $array);
+ $this->assertArrayNotHasKey('type', $array);
$this->assertArrayNotHasKey('id', $array);
- $this->assertNull($array['type']);
+ $this->assertSame([], $array);
$this->assertFalse($resourceIdentifierObject->hasIdentification());
$this->expectException(Exception::class);
diff --git a/tests/objects/ResourceObjectTest.php b/tests/objects/ResourceObjectTest.php
index f2873d63..693c8595 100644
--- a/tests/objects/ResourceObjectTest.php
+++ b/tests/objects/ResourceObjectTest.php
@@ -1,7 +1,10 @@
setResource(new ResourceObject('user', 42));
$resourceObject = new ResourceObject('user', 24);
@@ -151,7 +154,7 @@ public function testAddRelationshipObject_HappyPath() {
}
public function testAddRelationshipObject_BlockDrosteEffect() {
- $relationshipObject = new RelationshipObject(RelationshipObject::TO_ONE);
+ $relationshipObject = new RelationshipObject(RelationshipTypeEnum::ToOne);
$relationshipObject->setResource(new ResourceObject('user', 42));
$resourceObject = new ResourceObject('user', 42);
diff --git a/tests/profiles/CursorPaginationProfileTest.php b/tests/profiles/CursorPaginationProfileTest.php
index 41fa3ef5..5b9a8c2a 100644
--- a/tests/profiles/CursorPaginationProfileTest.php
+++ b/tests/profiles/CursorPaginationProfileTest.php
@@ -1,5 +1,7 @@
officialLink = $officialLink;
}
- public function getOfficialLink() {
+ public function getOfficialLink(): string {
return $this->officialLink;
}
}