Skip to content

Commit 7e53178

Browse files
committed
More comprehensive types
1 parent 9502158 commit 7e53178

39 files changed

+1584
-60
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ and this project adheres to
3131

3232
### Added
3333

34+
- More comprehensive type schema support
35+
- Add `nullable()` method to `Type` classes, allowing sub-types (e.g. array
36+
items or object properties) to be nullable
37+
- Add `Obj`, `Any`, `AnyOf`, `AllOf`, `OneOf`, and `Not` types
38+
- Convert type validation errors to overridable exception classes
3439
- Add `Context::createResponse()` method for building JSON:API responses with
3540
automatic `jsonapi` object inclusion
3641
- Add `JsonApi::meta()` method for including meta information in the `jsonapi`
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class AdditionalPropertyException extends UnprocessableEntityException
8+
{
9+
public function __construct(string $property)
10+
{
11+
parent::__construct("Value must not have additional property '$property'");
12+
13+
$this->error['meta'] = ['property' => $property];
14+
}
15+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class EnumViolationException extends UnprocessableEntityException
8+
{
9+
public function __construct(array $allowedValues, mixed $actual = null)
10+
{
11+
$formatted = array_map(fn($value) => '"' . $value . '"', $allowedValues);
12+
$message = sprintf('Value must be one of %s', implode(', ', $formatted));
13+
14+
parent::__construct($message);
15+
16+
$this->error['meta'] = ['allowed' => $allowedValues];
17+
18+
if ($actual !== null) {
19+
$this->error['meta']['actual'] = $actual;
20+
}
21+
}
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class InvalidSchemaException extends UnprocessableEntityException
8+
{
9+
public function __construct(string $constraint, ?int $matched = null)
10+
{
11+
parent::__construct('Value does not match schema constraint');
12+
13+
$this->error['meta'] = ['constraint' => $constraint];
14+
15+
if ($matched !== null) {
16+
$this->error['meta']['matched'] = $matched;
17+
}
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class MultipleViolationException extends UnprocessableEntityException
8+
{
9+
public function __construct(int|float $multipleOf, int|float|null $actual = null)
10+
{
11+
parent::__construct(sprintf('Value must be a multiple of %s', $multipleOf));
12+
13+
$this->error['meta'] = ['multipleOf' => $multipleOf];
14+
15+
if ($actual !== null) {
16+
$this->error['meta']['actual'] = $actual;
17+
}
18+
}
19+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class NullViolationException extends UnprocessableEntityException
8+
{
9+
public function __construct()
10+
{
11+
parent::__construct('Value must not be null');
12+
}
13+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class PatternViolationException extends UnprocessableEntityException
8+
{
9+
public function __construct(string $pattern)
10+
{
11+
parent::__construct(sprintf('Value must match the pattern %s', $pattern));
12+
13+
$this->error['meta'] = ['pattern' => $pattern];
14+
}
15+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class RangeViolationException extends UnprocessableEntityException
8+
{
9+
public function __construct(
10+
string $constraint,
11+
int|float $limit,
12+
int|float|null $actual = null,
13+
bool $exclusive = false,
14+
) {
15+
parent::__construct('Value is out of range');
16+
17+
$this->error['meta'] = [
18+
'constraint' => $constraint,
19+
'limit' => $limit,
20+
];
21+
22+
if ($actual !== null) {
23+
$this->error['meta']['actual'] = $actual;
24+
}
25+
26+
if ($exclusive) {
27+
$this->error['meta']['exclusive'] = true;
28+
}
29+
}
30+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class RequiredPropertyException extends UnprocessableEntityException
8+
{
9+
public function __construct(string $property)
10+
{
11+
parent::__construct("Value must have required property ':property'");
12+
13+
$this->error['meta'] = ['property' => $property];
14+
}
15+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Tobyz\JsonApiServer\Exception\Type;
4+
5+
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
6+
7+
class TypeMismatchException extends UnprocessableEntityException
8+
{
9+
public function __construct(string $expected, ?string $actual = null)
10+
{
11+
parent::__construct("Value must be $expected");
12+
13+
if ($actual !== null) {
14+
$this->error['meta'] = [
15+
'expected' => $expected,
16+
'actual' => $actual,
17+
];
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)