Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Read more about it at [jsonapi.org](https://jsonapi.org/).
composer require alsvanzelf/jsonapi
```

The library supports, and is is tested on, php versions 5.6, 7 and 8.
The library requires php 8.2. For lower versions see [v2](/releases/tag/v2.5.0).

#### Upgrading from v1

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
}
],
"require": {
"php": ">=5.6",
"php": ">=8.2",
"ext-json": "*"
},
"autoload": {
Expand Down
4 changes: 2 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions examples/bootstrap_examples.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,13 @@ public static function findEntities($type) {
}

class ExampleUser {
public $id;
public $name;
public $heads;
public $unknown;

public function __construct($id) {
$this->id = $id;
}
public function __construct(
public $id,
) {}

function getCurrentLocation() {
return 'Earth';
Expand Down
2 changes: 1 addition & 1 deletion rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
->withIndent(indentChar: "\t", indentSize: 1)

// slowly increase php version
->withPhpSets(php56: true)
->withPhpSets(php82: true)

// slowly increase levels
->withTypeCoverageLevel(1)
Expand Down
2 changes: 1 addition & 1 deletion src/DataDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function addIncludedResourceObject(ResourceObject ...$resourceObjects) {
try {
$this->validator->claimUsedResourceIdentifier($resourceObject);
}
catch (DuplicateException $e) {
catch (DuplicateException) {
// silently skip duplicates
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ public function toArray() {
public function toJson(array $options=[]) {
$options = array_merge(self::$defaults, $options);

$array = ($options['array'] !== null) ? $options['array'] : $this->toArray();
$array = $options['array'] ?? $this->toArray();

if ($options['prettyPrint']) {
$options['encodeOptions'] |= JSON_PRETTY_PRINT;
Expand All @@ -314,7 +314,7 @@ public function sendResponse(array $options=[]) {
return;
}

$json = ($options['json'] !== null) ? $options['json'] : $this->toJson($options);
$json = $options['json'] ?? $this->toJson($options);

http_response_code($this->httpStatusCode);

Expand Down
22 changes: 5 additions & 17 deletions src/ErrorsDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,11 @@ public function __construct(?ErrorObject $errorObject=null) {
*/

/**
* @param \Exception|\Throwable $exception
* @param \Throwable $exception
* @param array $options optional {@see ErrorsDocument::$defaults}
* @return ErrorsDocument
*
* @throws InputException if $exception is not \Exception or \Throwable
*/
public static function fromException($exception, array $options=[]) {
if ($exception instanceof \Exception === false && $exception instanceof \Throwable === false) {
throw new InputException('input is not a real exception in php5 or php7');
}

public static function fromException(\Throwable $exception, array $options=[]) {
$options = array_merge(self::$defaults, $options);

$errorsDocument = new self();
Expand All @@ -68,16 +62,10 @@ public static function fromException($exception, array $options=[]) {
*
* recursively adds multiple ErrorObjects if $exception carries a ->getPrevious()
*
* @param \Exception|\Throwable $exception
* @param \Throwable $exception
* @param array $options optional {@see ErrorsDocument::$defaults}
*
* @throws InputException if $exception is not \Exception or \Throwable
*/
public function addException($exception, array $options=[]) {
if ($exception instanceof \Exception === false && $exception instanceof \Throwable === false) {
throw new InputException('input is not a real exception in php5 or php7');
}

public function addException(\Throwable $exception, array $options=[]) {
$options = array_merge(self::$defaults, $options);

$this->addErrorObject(ErrorObject::fromException($exception, $options));
Expand Down Expand Up @@ -152,7 +140,7 @@ public function toArray() {
*/
protected function determineHttpStatusCode($httpStatusCode) {
// add the new code
$category = substr($httpStatusCode, 0, 1);
$category = substr((string) $httpStatusCode, 0, 1);
$this->httpStatusCodes[$category][$httpStatusCode] = true;

$advisedStatusCode = $httpStatusCode;
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/AtMemberManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ trait AtMemberManager {
* @param mixed $value
*/
public function addAtMember($key, $value) {
if (strpos($key, '@') === 0) {
if (str_starts_with($key, '@')) {
$key = substr($key, 1);
}

Expand Down
2 changes: 1 addition & 1 deletion src/helpers/ExtensionMemberManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ trait ExtensionMemberManager {
public function addExtensionMember(ExtensionInterface $extension, $key, $value) {
$namespace = $extension->getNamespace();

if (strpos($key, $namespace.':') === 0) {
if (str_starts_with($key, $namespace.':')) {
$key = substr($key, strlen($namespace.':'));
}

Expand Down
28 changes: 11 additions & 17 deletions src/helpers/RequestParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,17 @@ class RequestParser {
*/
'useAnnotatedSortFields' => true,
];
/** @var string */
private $selfLink = '';
/** @var array */
private $queryParameters = [];
/** @var array */
private $document = [];

/**
* @param string $selfLink the uri used to make this request {@see getSelfLink()}
* @param array $queryParameters all query parameters defined by the specification
* @param array $document the request jsonapi document
*/
public function __construct($selfLink='', array $queryParameters=[], array $document=[]) {
$this->selfLink = $selfLink;
$this->queryParameters = $queryParameters;
$this->document = $document;
}
public function __construct(
private $selfLink='',
private array $queryParameters=[],
private array $document=[],
) {}

/**
* @return self
Expand All @@ -55,8 +49,8 @@ public static function fromSuperglobals() {

$document = $_POST;
if ($document === [] && isset($_SERVER['CONTENT_TYPE'])) {
$documentIsJsonapi = (strpos($_SERVER['CONTENT_TYPE'], Document::CONTENT_TYPE_OFFICIAL) !== false);
$documentIsJson = (strpos($_SERVER['CONTENT_TYPE'], Document::CONTENT_TYPE_DEBUG) !== false);
$documentIsJsonapi = (str_contains((string) $_SERVER['CONTENT_TYPE'], Document::CONTENT_TYPE_OFFICIAL));
$documentIsJson = (str_contains((string) $_SERVER['CONTENT_TYPE'], Document::CONTENT_TYPE_DEBUG));

if ($documentIsJsonapi || $documentIsJson) {
$document = json_decode(file_get_contents('php://input'), true);
Expand Down Expand Up @@ -131,7 +125,7 @@ public function getIncludePaths(array $options=[]) {
return [];
}

$includePaths = explode(',', $this->queryParameters['include']);
$includePaths = explode(',', (string) $this->queryParameters['include']);

$options = array_merge(self::$defaults, $options);
if ($options['useNestedIncludePaths'] === false) {
Expand Down Expand Up @@ -171,7 +165,7 @@ public function getSparseFieldset($type) {
return [];
}

return explode(',', $this->queryParameters['fields'][$type]);
return explode(',', (string) $this->queryParameters['fields'][$type]);
}

/**
Expand Down Expand Up @@ -200,7 +194,7 @@ public function getSortFields(array $options=[]) {
return [];
}

$fields = explode(',', $this->queryParameters['sort']);
$fields = explode(',', (string) $this->queryParameters['sort']);

$options = array_merge(self::$defaults, $options);
if ($options['useAnnotatedSortFields'] === false) {
Expand All @@ -211,7 +205,7 @@ public function getSortFields(array $options=[]) {
foreach ($fields as $field) {
$order = RequestParser::SORT_ASCENDING;

if (strpos($field, '-') === 0) {
if (str_starts_with($field, '-')) {
$field = substr($field, 1);
$order = RequestParser::SORT_DESCENDING;
}
Expand Down
16 changes: 5 additions & 11 deletions src/objects/ErrorObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,16 @@ public function __construct($genericCode=null, $genericTitle=null, $specificDeta
*/

/**
* @param \Exception|\Throwable $exception
* @param array $options optional {@see ErrorObject::$defaults}
* @param \Throwable $exception
* @param array $options optional {@see ErrorObject::$defaults}
* @return ErrorObject
*
* @throws InputException if $exception is not \Exception or \Throwable
*/
public static function fromException($exception, array $options=[]) {
if ($exception instanceof \Exception === false && $exception instanceof \Throwable === false) {
throw new InputException('input is not a real exception in php5 or php7');
}

public static function fromException(\Throwable $exception, array $options=[]) {
$options = array_merge(self::$defaults, $options);

$errorObject = new self();

$className = get_class($exception);
$className = $exception::class;
if (strpos($className, '\\')) {
$exploded = explode('\\', $className);
$className = end($exploded);
Expand All @@ -91,7 +85,7 @@ public static function fromException($exception, array $options=[]) {
}

$metaObject = MetaObject::fromArray([
'type' => get_class($exception),
'type' => $exception::class,
'message' => $exception->getMessage(),
'code' => $exception->getCode(),
'file' => $filePath,
Expand Down
19 changes: 0 additions & 19 deletions tests/ErrorsDocumentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use alsvanzelf\jsonapi\ErrorsDocument;
use alsvanzelf\jsonapi\exceptions\InputException;
use alsvanzelf\jsonapi\objects\ErrorObject;

class ErrorsDocumentTest extends TestCase {
Expand All @@ -32,9 +31,6 @@ public function testFromException_HappyPath() {
$this->assertSame(self::class, $array['errors'][0]['meta']['trace'][0]['class']);
}

/**
* @group non-php5
*/
public function testFromException_AllowsThrowable() {
$document = ErrorsDocument::fromException(new \Error('foo', 42));

Expand All @@ -58,12 +54,6 @@ public function testFromException_AllowsThrowable() {
$this->assertSame(self::class, $array['errors'][0]['meta']['trace'][0]['class']);
}

public function testFromException_BlocksNonException() {
$this->expectException(InputException::class);

ErrorsDocument::fromException(new \stdClass());
}

public function testAddException_WithPrevious() {
$exception = new \Exception('foo', 1, new \Exception('bar', 2));

Expand Down Expand Up @@ -98,14 +88,6 @@ public function testAddException_SkipPrevious() {
$this->assertSame('foo', $array['errors'][0]['meta']['message']);
}

public function testAddException_BlocksNonException() {
$document = new ErrorsDocument();

$this->expectException(InputException::class);

$document->addException(new \stdClass());
}

public function testToArray_EmptyErrorObject() {
$document = new ErrorsDocument();
$document->addErrorObject(new ErrorObject('foo'));
Expand All @@ -127,7 +109,6 @@ public function testDetermineHttpStatusCode_HappyPath(int $expectedAdvisedErrorC
$document = new ErrorsDocument();

$method = new \ReflectionMethod($document, 'determineHttpStatusCode');
$method->setAccessible(true);

$advisedErrorCode = null;
foreach ($allErrorCodes as $errorCode) {
Expand Down
2 changes: 1 addition & 1 deletion tests/ValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function testClearUsedFields_FreesForAnotherNamespace() {
$objectContainer = Validator::OBJECT_CONTAINER_RELATIONSHIPS;
$validator->claimUsedFields($fieldNames, $objectContainer);
}
catch (DuplicateException $e) {
catch (DuplicateException) {
$thrown = true;
}
$this->assertTrue($thrown);
Expand Down
7 changes: 3 additions & 4 deletions tests/example_output/ExampleUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
namespace alsvanzelf\jsonapiTests\example_output;

class ExampleUser {
public $id;
public $name;
public $heads;
public $unknown;

public function __construct($id) {
$this->id = $id;
}
public function __construct(
public $id,
) {}

function getCurrentLocation() {
return 'Earth';
Expand Down
14 changes: 5 additions & 9 deletions tests/helpers/TestableNonInterfaceRequestInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,11 @@
use Psr\Http\Message\UriInterface;

class TestableNonInterfaceRequestInterface implements RequestInterface {
protected $selfLink;
protected $queryParameters;
protected $document;

public function __construct($selfLink, $queryParameters, $document) {
$this->selfLink = $selfLink;
$this->queryParameters = $queryParameters;
$this->document = $document;
}
public function __construct(
protected $selfLink,
protected $queryParameters,
protected $document,
) {}

/**
* RequestInterface
Expand Down
10 changes: 4 additions & 6 deletions tests/helpers/TestableNonInterfaceStreamInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
use Psr\Http\Message\StreamInterface;

class TestableNonInterfaceStreamInterface implements StreamInterface {
protected $document;

public function __construct($document) {
$this->document = $document;
}
public function __construct(
protected $document,
) {}

/**
* StreamInterface
Expand All @@ -24,7 +22,7 @@ public function getContents() {
}

// not used in current implementation
public function __toString() {
public function __toString(): string {
return '';
}

Expand Down
Loading