Hi, I’m working with doctrine and zend expressive hal, but there is a problem when I try to generate the response of an object using the method fromObject
of the class Zend\Expressive\Hal\ResourceGenerator
.
The problem here is that the object is a proxy object of doctrine and consequently the namespace is not the real one and it isn’t found in the Zend\Expressive\Hal\Metadata\MetadataMap
.
One way to solve the problem would be to implement a custom class Zend\Expressive\Hal\ResourceGenerator
overwriting the method fromObject
in this way:
<?php
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;
class ProxyDoctrineResourceGenerator
{
/** same code **/
/**
* @param object $instance An object of any type; the type will be checked
* against types registered in the metadata map.
* @param ServerRequestInterface $request
*/
public function fromObject($instance, ServerRequestInterface $request) : HalResource
{
if (! is_object($instance)) {
throw Exception\InvalidObjectException::forNonObject($instance);
}
//$class = get_class($instance);
// Use the static method of doctrine class utils to retrieve the real namespace of the class
$class=\Doctrine\Common\Util\ClassUtils::getClass($instance);
if (! $this->metadataMap->has($class)) {
throw Exception\InvalidObjectException::forUnknownType($class);
}
$metadata = $this->metadataMap->get($class);
$metadataType = get_class($metadata);
if (! isset($this->strategies[$metadataType])) {
throw Exception\UnknownMetadataTypeException::forMetadata($metadata);
}
$strategy = $this->strategies[$metadataType];
return $strategy->createResource(
$instance,
$metadata,
$this,
$request
);
}
}
We need to re-implement even the Zend\Expressive\Hal\ResourceGeneratorFactory
according with our new custom class:
<?php
class ProxyDoctrineResourceGeneratorFactory
{
public function __invoke(ContainerInterface $container) : ResourceGenerator
{
$generator = new ProxyDoctrineResourceGenerator(
$container->get(Metadata\MetadataMap::class),
$container->get(HydratorPluginManager::class),
$container->get(LinkGenerator::class)
);
$this->injectStrategies($container, $generator);
return $generator;
}
}
As you can see I don’t like very match this solution, mostly because I can’t extend the Zend\Expressive\Hal\ResourceGenerator
or Zend\Expressive\Hal\ResourceGeneratorFactory
and I would need to always look if any changes has been made to these classes… (I can extend but it would be useless because the properties are private and not protected and I would in any case rewriting al methods which depends on these private properties.).
Has someone ever had the same problem?