Skip to content

Commit

Permalink
Fix for serializing new doctrine ODM proxy objects
Browse files Browse the repository at this point in the history
  • Loading branch information
Hafsah Haynes committed Nov 12, 2019
1 parent 90c670f commit 92e2955
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"doctrine/orm": "~2.1",
"jackalope/jackalope-doctrine-dbal": "^1.1.5",
"doctrine/phpcr-odm": "^1.3|^2.0",
"ocramius/proxy-manager": "^2.0",
"psr/container": "^1.0",
"symfony/dependency-injection": "^3.0|^4.0",
"symfony/yaml": "^3.3|^4.0",
Expand Down
10 changes: 7 additions & 3 deletions src/EventDispatcher/Subscriber/DoctrineProxySubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
use Doctrine\ODM\MongoDB\PersistentCollection as MongoDBPersistentCollection;
use Doctrine\ODM\PHPCR\PersistentCollection as PHPCRPersistentCollection;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Proxy\Proxy as ORMProxy;
use JMS\Serializer\EventDispatcher\EventDispatcherInterface;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\PreSerializeEvent;
use ProxyManager\Proxy\LazyLoadingInterface;

final class DoctrineProxySubscriber implements EventSubscriberInterface
{
Expand Down Expand Up @@ -53,7 +53,7 @@ public function onPreSerialize(PreSerializeEvent $event): void
}

if (($this->skipVirtualTypeInit && $virtualType) ||
(!$object instanceof Proxy && !$object instanceof ORMProxy)
(!$object instanceof Proxy && !$object instanceof LazyLoadingInterface)
) {
return;
}
Expand All @@ -68,7 +68,11 @@ public function onPreSerialize(PreSerializeEvent $event): void
}
}

$object->__load();
if ($object instanceof LazyLoadingInterface) {
$object->initializeProxy();
} else {
$object->__load();
}

if (!$virtualType) {
$event->setType(get_parent_class($object), $type['params']);
Expand Down
69 changes: 69 additions & 0 deletions tests/Fixtures/SimpleObjectLazyLoading.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace JMS\Serializer\Tests\Fixtures;

use Closure;
use ProxyManager\Proxy\LazyLoadingInterface;

class SimpleObjectLazyLoading extends SimpleObject implements LazyLoadingInterface
{
public $__isInitialized__ = false;

private $initializer;

private $baz = 'baz';

public function __load()
{
if (!$this->__isInitialized__) {
$this->camelCase = 'proxy-boo';
$this->__isInitialized__ = true;
}
}

public function __isInitialized()
{
return $this->__isInitialized__;
}

/**
* {@inheritDoc}
*/
public function setProxyInitializer(?Closure $initializer = null)
{
$this->initializer = $initializer;
}

/**
* {@inheritDoc}
*/
public function getProxyInitializer(): ?Closure
{
return $this->initializer;
}

/**
* {@inheritDoc}
*/
public function initializeProxy(): bool
{
if (!$this->__isInitialized__) {
$this->camelCase = 'proxy-boo';
$this->__isInitialized__ = true;

return !$this->initializer || call_user_func($this->initializer);
}

return true;
}

/**
* {@inheritDoc}
*/
public function isProxyInitialized(): bool
{
return $this->__isInitialized__;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\Tests\Fixtures\ExclusionStrategy\AlwaysExcludeExclusionStrategy;
use JMS\Serializer\Tests\Fixtures\SimpleObject;
use JMS\Serializer\Tests\Fixtures\SimpleObjectLazyLoading;
use JMS\Serializer\Tests\Fixtures\SimpleObjectProxy;
use Metadata\MetadataFactoryInterface;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -146,6 +147,15 @@ public function testOnPreSerializeMaintainsParams()
self::assertSame(['name' => SimpleObject::class, 'params' => ['baz']], $event->getType());
}

public function testRewritesLazyLoadingClassName()
{
$event = $this->createEvent($obj = new SimpleObjectLazyLoading('a', 'b'), ['name' => get_class($obj), 'params' => []]);
$this->subscriber->onPreSerialize($event);

self::assertEquals(['name' => get_parent_class($obj), 'params' => []], $event->getType());
self::assertTrue($obj->__isInitialized());
}

protected function setUp(): void
{
$this->subscriber = new DoctrineProxySubscriber();
Expand Down

0 comments on commit 92e2955

Please sign in to comment.