mirror of
https://github.com/flarum/framework.git
synced 2025-04-24 21:54:04 +08:00
Update for new tobscure/json-api relationship handling
This commit is contained in:
parent
e1315d27a4
commit
95e3ff8fa8
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Relationship;
|
||||
|
||||
use Flarum\Core\User;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
|
||||
trait BuilderTrait
|
||||
{
|
||||
/**
|
||||
* @var Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @var string|\Closure
|
||||
*/
|
||||
protected $relation;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
protected $actor;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getRelationshipData($model)
|
||||
{
|
||||
$relation = $this->relation;
|
||||
|
||||
if (is_object($model)) {
|
||||
return $model->$relation;
|
||||
} elseif (is_array($model)) {
|
||||
return $model[$relation];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function resolveSerializerClass($class)
|
||||
{
|
||||
$serializer = $this->container->make($class);
|
||||
|
||||
$serializer->setActor($this->actor);
|
||||
|
||||
return $serializer;
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Relationship;
|
||||
|
||||
use Flarum\Core\User;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Tobscure\JsonApi\Relationship\AbstractHasManyBuilder;
|
||||
|
||||
class HasManyBuilder extends AbstractHasManyBuilder
|
||||
{
|
||||
use BuilderTrait;
|
||||
|
||||
/**
|
||||
* @param string|\Closure|\Tobscure\JsonApi\SerializerInterface $serializer
|
||||
* @param string|\Closure $relation
|
||||
* @param User $actor
|
||||
* @param Container $container
|
||||
*/
|
||||
public function __construct($serializer, $relation, User $actor, Container $container)
|
||||
{
|
||||
parent::__construct($serializer);
|
||||
|
||||
$this->relation = $relation;
|
||||
$this->container = $container;
|
||||
$this->actor = $actor;
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Relationship;
|
||||
|
||||
use Flarum\Core\User;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Tobscure\JsonApi\Relationship\AbstractHasOneBuilder;
|
||||
|
||||
class HasOneBuilder extends AbstractHasOneBuilder
|
||||
{
|
||||
use BuilderTrait;
|
||||
|
||||
/**
|
||||
* @param string|\Closure|\Tobscure\JsonApi\SerializerInterface $serializer
|
||||
* @param string|\Closure $relation
|
||||
* @param User $actor
|
||||
* @param Container $container
|
||||
*/
|
||||
public function __construct($serializer, $relation, User $actor, Container $container)
|
||||
{
|
||||
parent::__construct($serializer);
|
||||
|
||||
$this->relation = $relation;
|
||||
$this->container = $container;
|
||||
$this->actor = $actor;
|
||||
}
|
||||
}
|
@ -17,11 +17,16 @@ use Flarum\Event\PrepareApiAttributes;
|
||||
use Flarum\Event\GetApiRelationship;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use Tobscure\JsonApi\AbstractSerializer as BaseAbstractSerializer;
|
||||
use Flarum\Api\Relationship\HasOneBuilder;
|
||||
use Flarum\Api\Relationship\HasManyBuilder;
|
||||
use Tobscure\JsonApi\Collection;
|
||||
use Tobscure\JsonApi\Relationship;
|
||||
use Tobscure\JsonApi\Relationship\BuilderInterface;
|
||||
use Tobscure\JsonApi\Resource;
|
||||
use Tobscure\JsonApi\SerializerInterface;
|
||||
|
||||
abstract class AbstractSerializer extends BaseAbstractSerializer
|
||||
{
|
||||
@ -96,77 +101,139 @@ abstract class AbstractSerializer extends BaseAbstractSerializer
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRelationshipBuilder($name)
|
||||
public function getRelationship($model, $name)
|
||||
{
|
||||
if ($relationship = $this->getCustomRelationship($name)) {
|
||||
if ($relationship = $this->getCustomRelationship($model, $name)) {
|
||||
return $relationship;
|
||||
}
|
||||
|
||||
return parent::getRelationshipBuilder($name);
|
||||
return parent::getRelationship($model, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a custom relationship.
|
||||
*
|
||||
* @param mixed $model
|
||||
* @param string $name
|
||||
* @return BuilderInterface|null
|
||||
* @return Relationship|null
|
||||
*/
|
||||
protected function getCustomRelationship($name)
|
||||
protected function getCustomRelationship($model, $name)
|
||||
{
|
||||
$builder = static::$dispatcher->until(
|
||||
new GetApiRelationship($this, $name)
|
||||
$relationship = static::$dispatcher->until(
|
||||
new GetApiRelationship($this, $name, $model)
|
||||
);
|
||||
|
||||
if ($builder && ! ($builder instanceof BuilderInterface)) {
|
||||
if ($relationship && ! ($relationship instanceof Relationship)) {
|
||||
throw new LogicException('GetApiRelationship handler must return an instance of '
|
||||
. BuilderInterface::class);
|
||||
. Relationship::class);
|
||||
}
|
||||
|
||||
return $builder;
|
||||
return $relationship;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a relationship builder for a has-one relationship.
|
||||
*
|
||||
* @param mixed $model
|
||||
* @param string|Closure|\Tobscure\JsonApi\SerializerInterface $serializer
|
||||
* @param string|Closure|null $relation
|
||||
* @return HasOneBuilder
|
||||
* @return Relationship
|
||||
*/
|
||||
public function hasOne($serializer, $relation = null)
|
||||
public function hasOne($model, $serializer, $relation = null)
|
||||
{
|
||||
if (is_null($relation)) {
|
||||
$relation = $this->getRelationCaller();
|
||||
}
|
||||
|
||||
return new HasOneBuilder($serializer, $relation, $this->actor, static::$container);
|
||||
return $this->buildRelationship($model, $serializer, $relation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a relationship builder for a has-many relationship.
|
||||
*
|
||||
* @param mixed $model
|
||||
* @param string|Closure|\Tobscure\JsonApi\SerializerInterface $serializer
|
||||
* @param string|Closure|null $relation
|
||||
* @return HasManyBuilder
|
||||
* @param string|null $relation
|
||||
* @return Relationship
|
||||
*/
|
||||
public function hasMany($serializer, $relation = null)
|
||||
public function hasMany($model, $serializer, $relation = null)
|
||||
{
|
||||
if (is_null($relation)) {
|
||||
$relation = $this->getRelationCaller();
|
||||
}
|
||||
|
||||
return new HasManyBuilder($serializer, $relation, $this->actor, static::$container);
|
||||
return $this->buildRelationship($model, $serializer, $relation, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess the name of a relation from the stack trace.
|
||||
*
|
||||
* @return string
|
||||
* @param mixed $model
|
||||
* @param string|Closure|\Tobscure\JsonApi\SerializerInterface $serializer
|
||||
* @param string|null $relation
|
||||
* @param bool $many
|
||||
* @return Relationship
|
||||
*/
|
||||
protected function getRelationCaller()
|
||||
protected function buildRelationship($model, $serializer, $relation = null, $many = false)
|
||||
{
|
||||
list(, , $caller) = debug_backtrace(false, 3);
|
||||
if (is_null($relation)) {
|
||||
list(, , $caller) = debug_backtrace(false, 3);
|
||||
|
||||
return $caller['function'];
|
||||
$relation = $caller['function'];
|
||||
}
|
||||
|
||||
$data = $this->getRelationshipData($model, $relation);
|
||||
|
||||
if ($data) {
|
||||
$serializer = $this->resolveSerializer($serializer, $model, $data);
|
||||
|
||||
$type = $many ? Collection::class : Resource::class;
|
||||
|
||||
$element = new $type($data, $serializer);
|
||||
|
||||
return new Relationship($element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $model
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getRelationshipData($model, $relation)
|
||||
{
|
||||
if (is_object($model)) {
|
||||
return $model->$relation;
|
||||
} elseif (is_array($model)) {
|
||||
return $model[$relation];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $serializer
|
||||
* @param mixed $model
|
||||
* @param mixed $data
|
||||
* @return SerializerInterface
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function resolveSerializer($serializer, $model, $data)
|
||||
{
|
||||
if ($serializer instanceof Closure) {
|
||||
$serializer = call_user_func($serializer, $model, $data);
|
||||
}
|
||||
|
||||
if (is_string($serializer)) {
|
||||
$serializer = $this->resolveSerializerClass($serializer);
|
||||
}
|
||||
|
||||
if (! ($serializer instanceof SerializerInterface)) {
|
||||
throw new InvalidArgumentException('Serializer must be an instance of '
|
||||
.SerializerInterface::class);
|
||||
}
|
||||
|
||||
return $serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @return object
|
||||
*/
|
||||
protected function resolveSerializerClass($class)
|
||||
{
|
||||
$serializer = static::$container->make($class);
|
||||
|
||||
$serializer->setActor($this->actor);
|
||||
|
||||
return $serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,50 +39,50 @@ class DiscussionBasicSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function startUser()
|
||||
protected function startUser($discussion)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserBasicSerializer');
|
||||
return $this->hasOne($discussion, 'Flarum\Api\Serializer\UserBasicSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function startPost()
|
||||
protected function startPost($discussion)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\PostBasicSerializer');
|
||||
return $this->hasOne($discussion, 'Flarum\Api\Serializer\PostBasicSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function lastUser()
|
||||
protected function lastUser($discussion)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserBasicSerializer');
|
||||
return $this->hasOne($discussion, 'Flarum\Api\Serializer\UserBasicSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function lastPost()
|
||||
protected function lastPost($discussion)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\PostBasicSerializer');
|
||||
return $this->hasOne($discussion, 'Flarum\Api\Serializer\PostBasicSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasManyBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function posts()
|
||||
protected function posts($discussion)
|
||||
{
|
||||
return $this->hasMany('Flarum\Api\Serializer\PostSerializer');
|
||||
return $this->hasMany($discussion, 'Flarum\Api\Serializer\PostSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasManyBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function relevantPosts()
|
||||
protected function relevantPosts($discussion)
|
||||
{
|
||||
return $this->hasMany('Flarum\Api\Serializer\PostBasicSerializer');
|
||||
return $this->hasMany($discussion, 'Flarum\Api\Serializer\PostBasicSerializer');
|
||||
}
|
||||
}
|
||||
|
@ -65,10 +65,10 @@ class DiscussionSerializer extends DiscussionBasicSerializer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function hideUser()
|
||||
protected function hideUser($discussion)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserSerializer');
|
||||
return $this->hasOne($discussion, 'Flarum\Api\Serializer\UserSerializer');
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +88,10 @@ class ForumSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasManyBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function groups()
|
||||
protected function groups($model)
|
||||
{
|
||||
return $this->hasMany('Flarum\Api\Serializer\GroupSerializer');
|
||||
return $this->hasMany($model, 'Flarum\Api\Serializer\GroupSerializer');
|
||||
}
|
||||
}
|
||||
|
@ -56,11 +56,11 @@ class GroupSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasManyBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function permissions()
|
||||
protected function permissions($group)
|
||||
{
|
||||
return $this->hasMany('Flarum\Api\Serializers\PermissionSerializer');
|
||||
return $this->hasMany($group, 'Flarum\Api\Serializers\PermissionSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,27 +51,27 @@ class NotificationSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function user()
|
||||
protected function user($notification)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserBasicSerializer');
|
||||
return $this->hasOne($notification, 'Flarum\Api\Serializer\UserBasicSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function sender()
|
||||
protected function sender($notification)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserBasicSerializer');
|
||||
return $this->hasOne($notification, 'Flarum\Api\Serializer\UserBasicSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function subject()
|
||||
protected function subject($notification)
|
||||
{
|
||||
return $this->hasOne(function ($notification) {
|
||||
return $this->hasOne($notification, function ($notification) {
|
||||
return static::$subjectSerializers[$notification->type];
|
||||
});
|
||||
}
|
||||
|
@ -51,18 +51,18 @@ class PostBasicSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function user()
|
||||
protected function user($post)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserBasicSerializer');
|
||||
return $this->hasOne($post, 'Flarum\Api\Serializer\UserBasicSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function discussion()
|
||||
protected function discussion($post)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\DiscussionBasicSerializer');
|
||||
return $this->hasOne($post, 'Flarum\Api\Serializer\DiscussionBasicSerializer');
|
||||
}
|
||||
}
|
||||
|
@ -69,34 +69,34 @@ class PostSerializer extends PostBasicSerializer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function user()
|
||||
protected function user($post)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserSerializer');
|
||||
return $this->hasOne($post, 'Flarum\Api\Serializer\UserSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function discussion()
|
||||
protected function discussion($post)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\DiscussionSerializer');
|
||||
return $this->hasOne($post, 'Flarum\Api\Serializer\DiscussionSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function editUser()
|
||||
protected function editUser($post)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserSerializer');
|
||||
return $this->hasOne($post, 'Flarum\Api\Serializer\UserSerializer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasOneBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function hideUser()
|
||||
protected function hideUser($post)
|
||||
{
|
||||
return $this->hasOne('Flarum\Api\Serializer\UserSerializer');
|
||||
return $this->hasOne($post, 'Flarum\Api\Serializer\UserSerializer');
|
||||
}
|
||||
}
|
||||
|
@ -40,10 +40,10 @@ class UserBasicSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Flarum\Api\Relationship\HasManyBuilder
|
||||
* @return \Tobscure\JsonApi\Relationship
|
||||
*/
|
||||
protected function groups()
|
||||
protected function groups($user)
|
||||
{
|
||||
return $this->hasMany('Flarum\Api\Serializer\GroupSerializer');
|
||||
return $this->hasMany($user, 'Flarum\Api\Serializer\GroupSerializer');
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ use Flarum\Api\Serializer\AbstractSerializer;
|
||||
* Get an API serializer relationship.
|
||||
*
|
||||
* This event is fired when a relationship is to be included on an API document.
|
||||
* If a handler wishes to control the given relationship, then it should return
|
||||
* an instance of `Tobscure\JsonApi\Relationship\BuilderInterface`.
|
||||
* If a handler wishes to fulfil the given relationship, then it should return
|
||||
* an instance of `Tobscure\JsonApi\Relationship`.
|
||||
*
|
||||
* @see AbstractSerializer::hasOne()
|
||||
* @see AbstractSerializer::hasMany()
|
||||
@ -35,14 +35,21 @@ class GetApiRelationship
|
||||
*/
|
||||
public $relationship;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* @param AbstractSerializer $serializer
|
||||
* @param string $relationship
|
||||
* @param mixed $model
|
||||
*/
|
||||
public function __construct(AbstractSerializer $serializer, $relationship)
|
||||
public function __construct(AbstractSerializer $serializer, $relationship, $model)
|
||||
{
|
||||
$this->serializer = $serializer;
|
||||
$this->relationship = $relationship;
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user