Skip to content

Commit

Permalink
Merge pull request #232 from adrienbrault/circular-references
Browse files Browse the repository at this point in the history
Avoid serializing the same object twice
  • Loading branch information
willdurand committed May 19, 2016
2 parents 835d6af + 9778fb2 commit f13adc8
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 3 deletions.
Expand Up @@ -80,6 +80,8 @@ public function onPostSerialize(ObjectEvent $event)
$object = $event->getObject();
$context = $event->getContext();

$context->startVisiting($object);

$embeddeds = $this->embeddedsFactory->create($object, $context);
$links = $this->linksFactory->create($object, $context);

Expand All @@ -93,5 +95,7 @@ public function onPostSerialize(ObjectEvent $event)
if (count($embeddeds) > 0) {
$this->jsonSerializer->serializeEmbeddeds($embeddeds, $event->getVisitor(), $context);
}

$context->stopVisiting($object);
}
}
12 changes: 9 additions & 3 deletions src/Hateoas/Serializer/EventSubscriber/XmlEventSubscriber.php
Expand Up @@ -57,9 +57,13 @@ public function __construct(XmlSerializerInterface $xmlSerializer, LinksFactory

public function onPostSerialize(ObjectEvent $event)
{
$context = $event->getContext();
$embeddeds = $this->embeddedsFactory->create($event->getObject(), $event->getContext());
$links = $this->linksFactory->create($event->getObject(), $event->getContext());
$object = $event->getObject();
$context = $event->getContext();

$context->startVisiting($object);

$embeddeds = $this->embeddedsFactory->create($object, $context);
$links = $this->linksFactory->create($object, $context);

if (count($links) > 0) {
$this->xmlSerializer->serializeLinks($links, $event->getVisitor(), $context);
Expand All @@ -68,5 +72,7 @@ public function onPostSerialize(ObjectEvent $event)
if (count($embeddeds) > 0) {
$this->xmlSerializer->serializeEmbeddeds($embeddeds, $event->getVisitor(), $context);
}

$context->stopVisiting($object);
}
}
31 changes: 31 additions & 0 deletions tests/Hateoas/Tests/Fixtures/CircularReference1.php
@@ -0,0 +1,31 @@
<?php

namespace Hateoas\Tests\Fixtures;

use Hateoas\Configuration\Annotation as Hateoas;
use JMS\Serializer\Annotation as Serializer;

/**
* @Serializer\ExclusionPolicy("all")
*
* @Hateoas\Relation("reference2", embedded="expr(object.getReference2())")
*/
class CircularReference1
{
/**
* @Serializer\Expose
*/
private $name = 'reference1';

private $reference2;

public function setReference2($reference2)
{
$this->reference2 = $reference2;
}

public function getReference2()
{
return $this->reference2;
}
}
31 changes: 31 additions & 0 deletions tests/Hateoas/Tests/Fixtures/CircularReference2.php
@@ -0,0 +1,31 @@
<?php

namespace Hateoas\Tests\Fixtures;

use Hateoas\Configuration\Annotation as Hateoas;
use JMS\Serializer\Annotation as Serializer;

/**
* @Serializer\ExclusionPolicy("all")
*
* @Hateoas\Relation("reference1", embedded="expr(object.getReference1())")
*/
class CircularReference2
{
/**
* @Serializer\Expose
*/
private $name = 'reference2';

private $reference1;

public function setReference1($reference1)
{
$this->reference1 = $reference1;
}

public function getReference1()
{
return $this->reference1;
}
}
43 changes: 43 additions & 0 deletions tests/Hateoas/Tests/HateoasBuilderTest.php
Expand Up @@ -3,6 +3,8 @@
namespace Hateoas\Tests;

use Hateoas\HateoasBuilder;
use Hateoas\Tests\Fixtures\CircularReference1;
use Hateoas\Tests\Fixtures\CircularReference2;
use Hateoas\UrlGenerator\CallableUrlGenerator;
use JMS\Serializer\SerializationContext;
use Hateoas\Tests\Fixtures\AdrienBrault;
Expand Down Expand Up @@ -85,4 +87,45 @@ public function testAlternativeUrlGenerator()
$hateoas->serialize(new WithAlternativeRouter(), 'xml')
);
}

public function testCyclicalReferences()
{
$hateoas = HateoasBuilder::create()->build();

$reference1 = new CircularReference1();
$reference2 = new CircularReference2();
$reference1->setReference2($reference2);
$reference2->setReference1($reference1);

$this->assertSame(
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<result>
<name><![CDATA[reference1]]></name>
<entry rel="reference2">
<name><![CDATA[reference2]]></name>
<entry rel="reference1"/>
</entry>
</result>
XML
,
$hateoas->serialize($reference1, 'xml')
);

$this->assertSame(
'{'
.'"name":"reference1",'
.'"_embedded":{'
.'"reference2":{'
.'"name":"reference2",'
.'"_embedded":{'
.'"reference1":null'
.'}'
.'}'
.'}'
.'}',
$hateoas->serialize($reference1, 'json')
);
}
}

0 comments on commit f13adc8

Please sign in to comment.