From adc388e149bfc58076c25ec9856ea4064438df6f Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Sat, 27 Jul 2019 16:52:06 +0000 Subject: [PATCH] wip --- src/Adapter/EloquentAdapter.php | 7 ++++- .../UnprocessableEntityException.php | 27 ++++++++++++++----- src/Handler/Concerns/SavesData.php | 22 +++++++++++---- src/Handler/Create.php | 4 +-- src/Schema/Builder.php | 15 +++++++++++ 5 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/Adapter/EloquentAdapter.php b/src/Adapter/EloquentAdapter.php index 63b92d4..f63042b 100644 --- a/src/Adapter/EloquentAdapter.php +++ b/src/Adapter/EloquentAdapter.php @@ -5,6 +5,7 @@ namespace Tobscure\JsonApiServer\Adapter; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\SoftDeletes; use Tobscure\JsonApiServer\Schema\Attribute; use Tobscure\JsonApiServer\Schema\HasMany; use Tobscure\JsonApiServer\Schema\HasOne; @@ -114,7 +115,11 @@ class EloquentAdapter implements AdapterInterface public function delete($model) { - $model->delete(); + if (method_exists($model, 'forceDelete')) { + $model->forceDelete(); + } else { + $model->delete(); + } } public function filterByIds($query, array $ids) diff --git a/src/Exception/UnprocessableEntityException.php b/src/Exception/UnprocessableEntityException.php index 5df10e2..debc626 100644 --- a/src/Exception/UnprocessableEntityException.php +++ b/src/Exception/UnprocessableEntityException.php @@ -7,13 +7,28 @@ use Tobscure\JsonApiServer\ErrorProviderInterface; class UnprocessableEntityException extends \DomainException implements ErrorProviderInterface { + private $failures; + + public function __construct(array $failures) + { + parent::__construct(); + + $this->failures = $failures; + } + public function getJsonApiErrors(): array { - return [ - new Error( - new Error\Title('Unprocessable Entity'), - new Error\Status('422') - ) - ]; + return array_map(function ($failure) { + return new Error( + new Error\Status($this->getJsonApiStatus()), + new Error\SourcePointer('/data/'.$failure['field']->location.'/'.$failure['field']->name), + new Error\Detail($failure['message']) + ); + }, $this->failures); + } + + public function getJsonApiStatus(): string + { + return '422'; } } diff --git a/src/Handler/Concerns/SavesData.php b/src/Handler/Concerns/SavesData.php index 60fc152..b233dcd 100644 --- a/src/Handler/Concerns/SavesData.php +++ b/src/Handler/Concerns/SavesData.php @@ -32,7 +32,7 @@ trait SavesData $this->applyValues($data, $model, $request); - $adapter->save($model); + $this->saveModel($model, $request); $this->saveFields($data, $model, $request); @@ -153,8 +153,8 @@ trait SavesData continue; } - $fail = function ($message) use (&$failures, $field, $name) { - $failures[$field->location][$name][] = $message; + $fail = function ($message) use (&$failures, $field) { + $failures[] = compact('field', 'message'); }; foreach ($field->validators as $validator) { @@ -163,7 +163,7 @@ trait SavesData } if (count($failures)) { - throw new UnprocessableEntityException(print_r($failures, true)); + throw new UnprocessableEntityException($failures); } } @@ -181,7 +181,7 @@ trait SavesData if ($field->setter || $field->saver) { if ($field->setter) { - ($field->setter)($model, $value, $request); + ($field->setter)($request, $model, $value); } continue; @@ -195,6 +195,18 @@ trait SavesData } } + private function saveModel($model, Request $request) + { + $adapter = $this->resource->getAdapter(); + $schema = $this->resource->getSchema(); + + if ($schema->saver) { + ($schema->saver)($request, $model); + } else { + $adapter->save($model); + } + } + private function saveFields(array $data, $model, Request $request) { $schema = $this->resource->getSchema(); diff --git a/src/Handler/Create.php b/src/Handler/Create.php index b66c22d..d9b4e67 100644 --- a/src/Handler/Create.php +++ b/src/Handler/Create.php @@ -30,7 +30,7 @@ class Create implements RequestHandlerInterface throw new ForbiddenException('You cannot create this resource'); } - $model = $this->resource->getAdapter()->create(); + $model = $schema->createModel ? ($schema->createModel)($request) : $this->resource->getAdapter()->create(); $data = $this->parseData($request->getParsedBody()); @@ -52,7 +52,7 @@ class Create implements RequestHandlerInterface $callback($request, $model); } - $adapter->save($model); + $this->saveModel($model, $request); $this->saveFields($data, $model, $request); diff --git a/src/Schema/Builder.php b/src/Schema/Builder.php index 6bf6b96..f7654fe 100644 --- a/src/Schema/Builder.php +++ b/src/Schema/Builder.php @@ -25,10 +25,13 @@ class Builder public $deletingCallbacks = []; public $deletedCallbacks = []; public $defaultSort; + public $createModel; + public $saver; public function __construct() { $this->notCreatable(); + $this->notUpdatable(); $this->notDeletable(); } @@ -84,6 +87,11 @@ class Builder $this->countable = false; } + public function createModel(Closure $callback) + { + $this->createModel = $callback; + } + public function scope(Closure $callback) { $this->scopes[] = $callback; @@ -175,6 +183,13 @@ class Builder $this->updatedCallbacks[] = $callback; } + public function save(Closure $callback) + { + $this->saver = $callback; + + return $this; + } + public function deletableIf(Closure $condition) { $this->isDeletable = $condition;