This commit is contained in:
Toby Zerner 2019-07-27 16:52:06 +00:00
parent a9feac5ffd
commit adc388e149
5 changed files with 61 additions and 14 deletions

View File

@ -5,6 +5,7 @@ namespace Tobscure\JsonApiServer\Adapter;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Tobscure\JsonApiServer\Schema\Attribute; use Tobscure\JsonApiServer\Schema\Attribute;
use Tobscure\JsonApiServer\Schema\HasMany; use Tobscure\JsonApiServer\Schema\HasMany;
use Tobscure\JsonApiServer\Schema\HasOne; use Tobscure\JsonApiServer\Schema\HasOne;
@ -114,7 +115,11 @@ class EloquentAdapter implements AdapterInterface
public function delete($model) public function delete($model)
{ {
$model->delete(); if (method_exists($model, 'forceDelete')) {
$model->forceDelete();
} else {
$model->delete();
}
} }
public function filterByIds($query, array $ids) public function filterByIds($query, array $ids)

View File

@ -7,13 +7,28 @@ use Tobscure\JsonApiServer\ErrorProviderInterface;
class UnprocessableEntityException extends \DomainException implements ErrorProviderInterface class UnprocessableEntityException extends \DomainException implements ErrorProviderInterface
{ {
private $failures;
public function __construct(array $failures)
{
parent::__construct();
$this->failures = $failures;
}
public function getJsonApiErrors(): array public function getJsonApiErrors(): array
{ {
return [ return array_map(function ($failure) {
new Error( return new Error(
new Error\Title('Unprocessable Entity'), new Error\Status($this->getJsonApiStatus()),
new Error\Status('422') new Error\SourcePointer('/data/'.$failure['field']->location.'/'.$failure['field']->name),
) new Error\Detail($failure['message'])
]; );
}, $this->failures);
}
public function getJsonApiStatus(): string
{
return '422';
} }
} }

View File

@ -32,7 +32,7 @@ trait SavesData
$this->applyValues($data, $model, $request); $this->applyValues($data, $model, $request);
$adapter->save($model); $this->saveModel($model, $request);
$this->saveFields($data, $model, $request); $this->saveFields($data, $model, $request);
@ -153,8 +153,8 @@ trait SavesData
continue; continue;
} }
$fail = function ($message) use (&$failures, $field, $name) { $fail = function ($message) use (&$failures, $field) {
$failures[$field->location][$name][] = $message; $failures[] = compact('field', 'message');
}; };
foreach ($field->validators as $validator) { foreach ($field->validators as $validator) {
@ -163,7 +163,7 @@ trait SavesData
} }
if (count($failures)) { 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->saver) {
if ($field->setter) { if ($field->setter) {
($field->setter)($model, $value, $request); ($field->setter)($request, $model, $value);
} }
continue; 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) private function saveFields(array $data, $model, Request $request)
{ {
$schema = $this->resource->getSchema(); $schema = $this->resource->getSchema();

View File

@ -30,7 +30,7 @@ class Create implements RequestHandlerInterface
throw new ForbiddenException('You cannot create this resource'); 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()); $data = $this->parseData($request->getParsedBody());
@ -52,7 +52,7 @@ class Create implements RequestHandlerInterface
$callback($request, $model); $callback($request, $model);
} }
$adapter->save($model); $this->saveModel($model, $request);
$this->saveFields($data, $model, $request); $this->saveFields($data, $model, $request);

View File

@ -25,10 +25,13 @@ class Builder
public $deletingCallbacks = []; public $deletingCallbacks = [];
public $deletedCallbacks = []; public $deletedCallbacks = [];
public $defaultSort; public $defaultSort;
public $createModel;
public $saver;
public function __construct() public function __construct()
{ {
$this->notCreatable(); $this->notCreatable();
$this->notUpdatable();
$this->notDeletable(); $this->notDeletable();
} }
@ -84,6 +87,11 @@ class Builder
$this->countable = false; $this->countable = false;
} }
public function createModel(Closure $callback)
{
$this->createModel = $callback;
}
public function scope(Closure $callback) public function scope(Closure $callback)
{ {
$this->scopes[] = $callback; $this->scopes[] = $callback;
@ -175,6 +183,13 @@ class Builder
$this->updatedCallbacks[] = $callback; $this->updatedCallbacks[] = $callback;
} }
public function save(Closure $callback)
{
$this->saver = $callback;
return $this;
}
public function deletableIf(Closure $condition) public function deletableIf(Closure $condition)
{ {
$this->isDeletable = $condition; $this->isDeletable = $condition;