Skip to content

Support resource types that can behave as a proxy (e.x. Doctrine Proxies etc.) #40

Closed
@koemeet

Description

@koemeet

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.

Metadata

Metadata

Assignees

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions