This commit is contained in:
Toby Zerner 2019-07-04 15:40:45 +09:30
parent 9ee46b3ee0
commit bb415b0486
13 changed files with 69 additions and 21 deletions

View File

@ -6,8 +6,7 @@
"json-api-php/json-api": "^2.0",
"psr/http-message": "^1.0",
"psr/http-server-handler": "^1.0",
"spatie/macroable": "^1.0",
"zendframework/zend-diactoros": "^2.0"
"zendframework/zend-diactoros": "^2.1"
},
"license": "MIT",
"authors": [

View File

@ -119,7 +119,28 @@ class EloquentAdapter implements AdapterInterface
public function filterByAttribute($query, Attribute $field, $value)
{
$query->where($this->getAttributeProperty($field), $value);
$property = $this->getAttributeProperty($field);
if (preg_match('/(.+)\.\.(.+)/', $value, $matches)) {
if ($matches[1] !== '*') {
$query->where($property, '>=', $matches[1]);
}
if ($matches[2] !== '*') {
$query->where($property, '<=', $matches[2]);
}
return;
}
foreach (['>=', '>', '<=', '<'] as $operator) {
if (strpos($value, $operator) === 0) {
$query->where($property, $operator, substr($value, strlen($operator)));
return;
}
}
$query->where($property, $value);
}
public function filterByHasOne($query, HasOne $field, array $ids)

View File

@ -123,12 +123,13 @@ class Api implements RequestHandlerInterface
}
$errors = $e->getJsonApiErrors();
$status = $e->getJsonApiStatus();
$data = new JsonApi\ErrorDocument(
...$errors
);
return new JsonApiResponse($data);
return new JsonApiResponse($data, $status);
}
public function getBaseUrl(): string

View File

@ -5,4 +5,6 @@ namespace Tobscure\JsonApiServer;
interface ErrorProviderInterface
{
public function getJsonApiErrors(): array;
public function getJsonApiStatus(): string;
}

View File

@ -34,9 +34,14 @@ class BadRequestException extends \DomainException implements ErrorProviderInter
return [
new Error(
new Error\Title('Bad Request'),
new Error\Status('400'),
new Error\Status($this->getJsonApiStatus()),
...$members
)
];
}
public function getJsonApiStatus(): string
{
return '400';
}
}

View File

@ -5,15 +5,20 @@ namespace Tobscure\JsonApiServer\Exception;
use JsonApiPhp\JsonApi\Error;
use Tobscure\JsonApiServer\ErrorProviderInterface;
class BadRequestException extends \DomainException implements ErrorProviderInterface
class ForbiddenException extends \DomainException implements ErrorProviderInterface
{
public function getJsonApiErrors(): array
{
return [
new Error(
new Error\Title('Forbidden'),
new Error\Status('403')
new Error\Status($this->getJsonApiStatus())
)
];
}
public function getJsonApiStatus(): string
{
return '403';
}
}

View File

@ -16,4 +16,9 @@ class InternalServerErrorException extends \RuntimeException implements ErrorPro
)
];
}
public function getJsonApiStatus(): string
{
return '500';
}
}

View File

@ -5,7 +5,7 @@ namespace Tobscure\JsonApiServer\Exception;
use JsonApiPhp\JsonApi\Error;
use Tobscure\JsonApiServer\ErrorProviderInterface;
class BadRequestException extends \DomainException implements ErrorProviderInterface
class MethodNotAllowedException extends \DomainException implements ErrorProviderInterface
{
public function getJsonApiErrors(): array
{

View File

@ -48,15 +48,15 @@ trait SavesData
$body = (array) $body;
if (! isset($body['data'])) {
throw new BadRequestException;
throw new BadRequestException('Root data attribute missing');
}
if (isset($body['data']['attributes']) && ! is_array($body['data']['attributes'])) {
throw new BadRequestException;
throw new BadRequestException('data.attributes must be an object');
}
if (isset($body['data']['relationships']) && ! is_array($body['data']['relationships'])) {
throw new BadRequestException;
throw new BadRequestException('data.relationships must be an object');
}
return array_merge(

View File

@ -127,6 +127,14 @@ class Index implements RequestHandlerInterface
unset($queryParams['page']['offset']);
}
if (isset($queryParams['filter'])) {
foreach ($queryParams['filter'] as $k => &$v) {
if ($v === null) {
$v = '';
}
}
}
$queryString = http_build_query($queryParams);
return $selfUrl.($queryString ? '?'.$queryString : '');

View File

@ -3,12 +3,9 @@
namespace Tobscure\JsonApiServer\Schema;
use Closure;
use Spatie\Macroable\Macroable;
class Attribute extends Field
{
use Macroable;
public $location = 'attributes';
public $sortable = false;
public $sorter;

View File

@ -3,13 +3,10 @@
namespace Tobscure\JsonApiServer\Schema;
use Closure;
use Spatie\Macroable\Macroable;
use Tobscure\JsonApiServer\Handler\Show;
abstract class Relationship extends Field
{
use Macroable;
public $location = 'relationships';
public $linkage;
public $hasLinks = true;

View File

@ -34,7 +34,7 @@ class Serializer
$schema = $resource->getSchema();
$data = [
'type' => $resource->getType(),
'type' => $type = $resource->getType(),
'id' => $adapter->getId($model),
'fields' => [],
'links' => [],
@ -43,9 +43,17 @@ class Serializer
$resourceUrl = $this->api->getBaseUrl().'/'.$data['type'].'/'.$data['id'];
ksort($schema->fields);
$fields = $schema->fields;
foreach ($schema->fields as $name => $field) {
$queryParams = $this->request->getQueryParams();
if (isset($queryParams['fields'][$type])) {
$fields = array_intersect_key($fields, array_flip(explode(',', $queryParams['fields'][$type])));
}
ksort($fields);
foreach ($fields as $name => $field) {
if (! ($field->isVisible)($this->request, $model)) {
continue;
}
@ -132,7 +140,7 @@ class Serializer
if ($field->getter) {
$value = ($field->getter)($this->request, $model);
} else {
$value = $isLinkage ? $adapter->getHasMany($model, $field) : null;
$value = ($isLinkage || $isIncluded) ? $adapter->getHasMany($model, $field) : null;
}
$identifiers = [];