neomerx / json-api

Framework agnostic JSON API (jsonapi.org) implementation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Difficulty with traversable resource

mmelvin0 opened this issue · comments

commented

I have a resource object that is Traversable/Iterator/IteratorAggregate (specifically a subclass of ArrayObject in this case.)

I have a schema registered for my resource class but the default Parser::analayzeData() does its collection checks in such a way that it treats this single (Traversable) entity as a collection.

I "fixed" this by doing the following:

Override Container and add the following method:

public function hasSchema($resource) {
    return is_object($resource) && $this->hasProviderMapping($this->getResourceType($resource));
}

Override Parser::analyzeCurrentData():

protected function analyzeCurrentData() {
    $relationship = $this->stack->end()->getRelationship();
    $data = $relationship->isShowData() === true ? $relationship->getData() : null;
    if ($data instanceof Traversable && $this->container->hasSchema($data)) {
        return [false, false, [$data]];
    } else {
        return parent::analyzeCurrentData();
    }
}

This solution works fine for me but feels a little hacky... mainly the duplicated first two lines of analyzeCurrentData.

Just posting to see if there is a better way to go about this and also to see if this is a use case you are interested in covering in the base library.

I would not use Traversable as single resource as it's by definition something that is intended to be used in foreach. I'd rather had a method called something like getProperties() for that because it confuses otherwise. However it's up to you as a developer to chose.
I've split the method into 2 steps which should help you to override without hacky feeling. Check it out in develop branch

    protected function analyzeCurrentData()
    {
        $data   = $this->getCurrentData();
        $result = $this->analyzeData($data);

        return $result;
    }