Description
Hi,
There are some use cases where the resource type that is defined with Encoder::instance()
will not match the one that another schema is returning, but instead is a subclass. One of them is when you return a proxy object in the getRelationships
method of a schema.
I will give a code example. Let's say we have a PostSchema
that has the following relationships:
public function getRelationships($post)
{
return [
'author' => [
self::DATA => $post->getAuthor() // will not return an Author object, but an AuthorProxy which extends Author
]
];
}
Now when you want to encode a Post
, it will give you an error, saying that there is no provider for AuthorProxy
. You see the problem? AuthorProxy
IS an Author
, but the encoder cannot handle this.
This is caused by Container::getSchema($resource)
:
public function getSchema($resource)
{
$resourceType = get_class($resource);
// ...
}
I can propose two solutions. One is that we check with instanceof
if it can provide a schema for $resource
. The second solution is that it supports Doctrine
natively, we can do this by extending the Container
with:
public function getSchema($resource)
{
$resourceType = get_class($resource);
// support for Doctrine Proxies
if (class_exists('Doctrine\Common\Util\ClassUtils')) {
$resourceType = ClassUtils::getRealClass($resourceType);
}
// ...
}
Also, it could have it's own ClassUtils
class that will get the correct class name if there is __CG__
(common marker name for proxy classes) in the name. Then it will support Doctrine
too and probably more libraries that implement the Proxy
pattern.