wip
This commit is contained in:
parent
adc388e149
commit
0d43544adc
|
|
@ -57,11 +57,13 @@ trait IncludesData
|
|||
throw new BadRequestException("Invalid include [{$path}{$name}]", 'include');
|
||||
}
|
||||
|
||||
if (is_string($schema->fields[$name]->resource)) {
|
||||
$relatedResource = $this->api->getResource($schema->fields[$name]->resource);
|
||||
|
||||
$this->validateInclude($relatedResource, $nested, $name.'.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function buildRelationshipTrails(ResourceType $resource, array $include): array
|
||||
{
|
||||
|
|
@ -75,6 +77,7 @@ trait IncludesData
|
|||
$trails[] = [$relationship];
|
||||
}
|
||||
|
||||
if (is_string($schema->fields[$name]->resource)) {
|
||||
$relatedResource = $this->api->getResource($relationship->resource);
|
||||
|
||||
$trails = array_merge(
|
||||
|
|
@ -87,6 +90,7 @@ trait IncludesData
|
|||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $trails;
|
||||
}
|
||||
|
|
@ -101,13 +105,21 @@ trait IncludesData
|
|||
continue;
|
||||
}
|
||||
|
||||
if ($field->loader) {
|
||||
($field->loader)($models, true);
|
||||
} else {
|
||||
$adapter->loadIds($models, $field);
|
||||
}
|
||||
}
|
||||
|
||||
$trails = $this->buildRelationshipTrails($this->resource, $include);
|
||||
|
||||
foreach ($trails as $relationships) {
|
||||
if ($loader = end($relationships)->loader) {
|
||||
($loader)($models, false);
|
||||
} else {
|
||||
$adapter->load($models, $relationships);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use Psr\Http\Message\ServerRequestInterface as Request;
|
|||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Tobscure\JsonApiServer\Api;
|
||||
use Tobscure\JsonApiServer\Exception\BadRequestException;
|
||||
use Tobscure\JsonApiServer\Exception\ForbiddenException;
|
||||
use Tobscure\JsonApiServer\JsonApiResponse;
|
||||
use Tobscure\JsonApiServer\ResourceType;
|
||||
use Tobscure\JsonApiServer\Schema;
|
||||
|
|
@ -37,6 +38,10 @@ class Index implements RequestHandlerInterface
|
|||
$adapter = $this->resource->getAdapter();
|
||||
$schema = $this->resource->getSchema();
|
||||
|
||||
if (! ($schema->isVisible)($request)) {
|
||||
throw new ForbiddenException('You cannot view this resource');
|
||||
}
|
||||
|
||||
$query = $adapter->query();
|
||||
|
||||
foreach ($schema->scopes as $scope) {
|
||||
|
|
@ -219,7 +224,7 @@ class Index implements RequestHandlerInterface
|
|||
$attribute = $schema->fields[$name];
|
||||
|
||||
if ($attribute->sorter) {
|
||||
($attribute->sorter)($query, $direction, $request);
|
||||
($attribute->sorter)($request, $query, $direction);
|
||||
} else {
|
||||
$adapter->sortByAttribute($query, $attribute, $direction);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use Psr\Http\Message\ResponseInterface as Response;
|
|||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Tobscure\JsonApiServer\Api;
|
||||
use Tobscure\JsonApiServer\Exception\ForbiddenException;
|
||||
use Tobscure\JsonApiServer\JsonApiResponse;
|
||||
use Tobscure\JsonApiServer\ResourceType;
|
||||
use Tobscure\JsonApiServer\Serializer;
|
||||
|
|
@ -28,6 +29,12 @@ class Show implements RequestHandlerInterface
|
|||
|
||||
public function handle(Request $request): Response
|
||||
{
|
||||
$schema = $this->resource->getSchema();
|
||||
|
||||
if (! ($schema->isVisible)($request)) {
|
||||
throw new ForbiddenException('You cannot view this resource');
|
||||
}
|
||||
|
||||
$include = $this->getInclude($request);
|
||||
|
||||
$this->loadRelationships([$this->model], $include, $request);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class Builder
|
|||
|
||||
public function __construct()
|
||||
{
|
||||
$this->visible();
|
||||
$this->notCreatable();
|
||||
$this->notUpdatable();
|
||||
$this->notDeletable();
|
||||
|
|
@ -40,7 +41,7 @@ class Builder
|
|||
return $this->field(Attribute::class, $name, $property);
|
||||
}
|
||||
|
||||
public function hasOne(string $name, string $resource = null, string $property = null): HasOne
|
||||
public function hasOne(string $name, $resource = null, string $property = null): HasOne
|
||||
{
|
||||
$field = $this->field(HasOne::class, $name, $property);
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ class Builder
|
|||
return $field;
|
||||
}
|
||||
|
||||
public function hasMany(string $name, string $resource = null, string $property = null): HasMany
|
||||
public function hasMany(string $name, $resource = null, string $property = null): HasMany
|
||||
{
|
||||
$field = $this->field(HasMany::class, $name, $property);
|
||||
|
||||
|
|
@ -107,6 +108,34 @@ class Builder
|
|||
$this->singleScopes[] = $callback;
|
||||
}
|
||||
|
||||
public function visibleIf(Closure $condition)
|
||||
{
|
||||
$this->isVisible = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function visible()
|
||||
{
|
||||
return $this->visibleIf(function () {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public function notVisibleIf(Closure $condition)
|
||||
{
|
||||
return $this->visibleIf(function (...$args) use ($condition) {
|
||||
return ! $condition(...$args);
|
||||
});
|
||||
}
|
||||
|
||||
public function notVisible()
|
||||
{
|
||||
return $this->notVisibleIf(function () {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public function creatableIf(Closure $condition)
|
||||
{
|
||||
$this->isCreatable = $condition;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ abstract class Relationship extends Field
|
|||
public $linkage;
|
||||
public $hasLinks = true;
|
||||
public $loadable = true;
|
||||
public $loader;
|
||||
public $included = false;
|
||||
public $resource;
|
||||
|
||||
|
|
@ -70,6 +71,13 @@ abstract class Relationship extends Field
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function load(Closure $callback)
|
||||
{
|
||||
$this->loader = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function included()
|
||||
{
|
||||
$this->included = true;
|
||||
|
|
|
|||
|
|
@ -184,7 +184,17 @@ class Serializer
|
|||
|
||||
private function addRelated(Schema\Relationship $field, $model, array $include): JsonApi\ResourceIdentifier
|
||||
{
|
||||
$relatedResource = $this->api->getResource($field->resource);
|
||||
if (is_array($field->resource)) {
|
||||
foreach ($field->resource as $class => $resource) {
|
||||
if ($model instanceof $class) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$resource = $field->resource;
|
||||
}
|
||||
|
||||
$relatedResource = $this->api->getResource($resource);
|
||||
|
||||
return $this->resourceIdentifier(
|
||||
$this->addToMap($relatedResource, $model, $include)
|
||||
|
|
|
|||
Loading…
Reference in New Issue