Skip to content

Commit

Permalink
Add event support
Browse files Browse the repository at this point in the history
  • Loading branch information
GeLoLabs committed Feb 11, 2017
1 parent d49b5b7 commit 4e70748
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 87 deletions.
29 changes: 29 additions & 0 deletions DependencyInjection/Compiler/RegisterListenerPass.php
@@ -0,0 +1,29 @@
<?php

/*
* This file is part of the Ivory Serializer bundle package.
*
* (c) Eric GELOEN <geloen.eric@gmail.com>
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code.
*/

namespace Ivory\SerializerBundle\DependencyInjection\Compiler;

use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass as AbstractRegisterListenerPass;

/**
* @author GeLo <geloen.eric@gmail.com>
*/
class RegisterListenerPass extends AbstractRegisterListenerPass
{
public function __construct()
{
parent::__construct(
'ivory.serializer.event.dispatcher',
'ivory.serializer.listener',
'ivory.serializer.subscriber'
);
}
}
14 changes: 14 additions & 0 deletions DependencyInjection/Configuration.php
Expand Up @@ -15,6 +15,7 @@
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;

/**
* @author GeLo <geloen.eric@gmail.com>
Expand All @@ -29,6 +30,7 @@ public function getConfigTreeBuilder()
$treeBuilder = $this->createTreeBuilder();
$treeBuilder->root('ivory_serializer')
->children()
->append($this->createEventNode())
->append($this->createMappingNode())
->append($this->createTypesNode())
->append($this->createVisitorsNode());
Expand Down Expand Up @@ -74,6 +76,18 @@ private function createMappingNode()
->end();
}

/**
* @return ArrayNodeDefinition
*/
private function createEventNode()
{
return $this->createNode('event')
->addDefaultsIfNotSet()
->children()
->booleanNode('enabled')->defaultValue(class_exists(EventDispatcher::class))->end()
->end();
}

/**
* @return ArrayNodeDefinition
*/
Expand Down
25 changes: 25 additions & 0 deletions DependencyInjection/IvorySerializerExtension.php
Expand Up @@ -40,6 +40,7 @@ protected function loadInternal(array $config, ContainerBuilder $container)
$resources = [
'cache',
'common',
'event',
'fos',
'mapping',
'navigator',
Expand All @@ -54,6 +55,7 @@ protected function loadInternal(array $config, ContainerBuilder $container)
}

$this->loadCache($config, $container);
$this->loadEvent($config['event'], $container);
$this->loadMapping($config['mapping'], $container);
$this->loadTypes($config['types'], $container);
$this->loadVisitors($config['visitors'], $container);
Expand All @@ -75,6 +77,29 @@ private function loadCache(array $config, ContainerBuilder $container)
->addArgument($cache);
}

/**
* @param mixed[] $config
* @param ContainerBuilder $container
*/
private function loadEvent(array $config, ContainerBuilder $container)
{
if ($config['enabled']) {
$container
->getDefinition('ivory.serializer.mapping.factory')
->replaceArgument(0, new Reference('ivory.serializer.mapping.factory.event'));

$container->setAlias('ivory.serializer.navigator', 'ivory.serializer.navigator.event');

return;
}

$container->removeDefinition('ivory.serializer.event.dispatcher');
$container->removeDefinition('ivory.serializer.mapping.factory.event');
$container->removeDefinition('ivory.serializer.navigator.event');

$container->setAlias('ivory.serializer.navigator', 'ivory.serializer.navigator.default');
}

/**
* @param mixed[] $config
* @param ContainerBuilder $container
Expand Down
2 changes: 2 additions & 0 deletions IvorySerializerBundle.php
Expand Up @@ -13,6 +13,7 @@

use Ivory\SerializerBundle\DependencyInjection\Compiler\RegisterClassMetadataLoaderPass;
use Ivory\SerializerBundle\DependencyInjection\Compiler\RegisterFOSServicePass;
use Ivory\SerializerBundle\DependencyInjection\Compiler\RegisterListenerPass;
use Ivory\SerializerBundle\DependencyInjection\Compiler\RegisterTypePass;
use Ivory\SerializerBundle\DependencyInjection\Compiler\RegisterVisitorPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -30,6 +31,7 @@ public function build(ContainerBuilder $container)
{
$container
->addCompilerPass(new RegisterClassMetadataLoaderPass())
->addCompilerPass(new RegisterListenerPass())
->addCompilerPass(new RegisterFOSServicePass())
->addCompilerPass(new RegisterTypePass())
->addCompilerPass(new RegisterVisitorPass());
Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -36,6 +36,7 @@ $deserialize = $serializer->deserialize($json, \stdClass::class, Format::JSON);
- [Configuration](/Resources/doc/configuration/index.md)
- [Mapping](/Resources/doc/configuration/mapping.md)
- [Type](/Resources/doc/configuration/type.md)
- [Event](/Resources/doc/configuration/event.md)
- [Visitor](/Resources/doc/configuration/visitor.md)
- [Cache](/Resources/doc/configuration/cache.md)
- [FOSRestBundle Integration](/Resources/doc/configuration/fos_rest.md)
Expand Down
28 changes: 28 additions & 0 deletions Resources/config/event.xml
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>

<container
xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd"
>
<services>
<service
id="ivory.serializer.event.dispatcher"
class="Symfony\Component\EventDispatcher\EventDispatcher"
/>

<service
id="ivory.serializer.mapping.factory.event"
class="Ivory\Serializer\Mapping\Factory\EventClassMetadataFactory"
>
<argument type="service" id="ivory.serializer.mapping.factory.default" />
<argument type="service" id="ivory.serializer.event.dispatcher" />
</service>

<service id="ivory.serializer.navigator.event" class="Ivory\Serializer\Navigator\EventNavigator">
<argument type="service" id="ivory.serializer.navigator.default" />
<argument type="service" id="ivory.serializer.event.dispatcher" />
</service>
</services>
</container>
2 changes: 1 addition & 1 deletion Resources/config/navigator.xml
Expand Up @@ -7,7 +7,7 @@
http://symfony.com/schema/dic/services/services-1.0.xsd"
>
<services>
<service id="ivory.serializer.navigator" class="Ivory\Serializer\Navigator\Navigator">
<service id="ivory.serializer.navigator.default" class="Ivory\Serializer\Navigator\Navigator">
<argument type="service" id="ivory.serializer.registry.type" />
<argument type="service" id="ivory.serializer.type.guesser" />
</service>
Expand Down
67 changes: 67 additions & 0 deletions Resources/doc/configuration/event.md
@@ -0,0 +1,67 @@
# Event

The bundle supports events and allows you to hook into the (de)-serialization process. If you want to learn more about
the supported events, you can read this [documentation](https://github.com/egeloen/ivory-serializer/blob/master/doc/event.md).

## Register a listener

In order to register a listener on the event dispatcher, you need to use the `ivory.serializer.listener` tag as well
as the `event` and `method` attributes:

``` xml
<?xml version="1.0" encoding="UTF-8" ?>

<container
xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd"
>
<services>
<service
id="acme.serializer.event.listener"
class="Acme\Serializer\Event\CustomListener"
>
<tag
name="ivory.serializer.listsner"
event="serializer.pre_serialize"
method="onPreSerialize"
/>
</service>
</services>
</container>
```

## Register a subscriber

To register a subscriber on the event dispatcher, you need to use the `ivory.serializer.subscriber` tag:

``` xml
<?xml version="1.0" encoding="UTF-8" ?>

<container
xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd"
>
<services>
<service
id="acme.serializer.event.listener"
class="Acme\Serializer\Event\CustomSubscriber"
>
<tag name="ivory.serializer.subscriber" />
</service>
</services>
</container>
```

## Disable Events

If you don't use events, we recommend you to disable it since it adds some overhead:

``` yaml
ivory_serializer:
event:
enabled: false
```
1 change: 1 addition & 0 deletions Resources/doc/configuration/index.md
Expand Up @@ -4,6 +4,7 @@ The configuration allows you to set up the serializer the way you want instead o

- [Mapping](/Resources/doc/configuration/mapping.md)
- [Types](/Resources/doc/configuration/types.md)

- [Visitors](/Resources/doc/configuration/visitors.md)
- [Cache](/Resources/doc/configuration/cache.md)
- [FOSRestBundle Integration](/Resources/doc/configuration/fos_rest.md)
23 changes: 21 additions & 2 deletions Tests/DependencyInjection/AbstractIvorySerializerExtensionTest.php
Expand Up @@ -204,7 +204,7 @@ public function testMappingCache()
$classMetadataFactoryDefinition = $this->container->getDefinition($classMetadataFactoryService);

$this->assertSame(
'ivory.serializer.mapping.factory.default',
'ivory.serializer.mapping.factory.event',
(string) $classMetadataFactoryDefinition->getArgument(0)
);

Expand All @@ -227,7 +227,7 @@ public function testCustomMappingCache()
$classMetadataFactoryDefinition = $this->container->getDefinition($classMetadataFactoryService);

$this->assertSame(
'ivory.serializer.mapping.factory.default',
'ivory.serializer.mapping.factory.event',
(string) $classMetadataFactoryDefinition->getArgument(0)
);

Expand Down Expand Up @@ -257,6 +257,25 @@ public function testCacheWarmer()
);
}

public function testEventEnabled()
{
$this->container->compile();

$this->assertTrue($this->container->has('ivory.serializer.event.dispatcher'));
$this->assertTrue($this->container->has('ivory.serializer.mapping.factory.event'));
$this->assertTrue($this->container->has('ivory.serializer.navigator.event'));
}

public function testEventDisabled()
{
$this->loadConfiguration($this->container, 'event_disabled');
$this->container->compile();

$this->assertFalse($this->container->has('ivory.serializer.event.dispatcher'));
$this->assertFalse($this->container->has('ivory.serializer.mapping.factory.event'));
$this->assertFalse($this->container->has('ivory.serializer.navigator.event'));
}

public function testDateTimeType()
{
$this->loadConfiguration($this->container, 'type_date_time');
Expand Down
3 changes: 3 additions & 0 deletions Tests/Fixtures/Config/Yaml/event_disabled.yml
@@ -0,0 +1,3 @@
ivory_serializer:
event:
enabled: false
84 changes: 0 additions & 84 deletions Tests/IvorySerializerBundleTest.php

This file was deleted.

0 comments on commit 4e70748

Please sign in to comment.