Skip to content

Commit

Permalink
Merge a3e0609 into fdea2a5
Browse files Browse the repository at this point in the history
  • Loading branch information
marc-jan committed Jan 17, 2021
2 parents fdea2a5 + a3e0609 commit f91b39b
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 1 deletion.
34 changes: 34 additions & 0 deletions docs/book/plugin-manager.md
@@ -0,0 +1,34 @@
# Plugin Manager

The `AdapterPluginManager` extends the laminas-servicemanager
`AbstractPluginManager`, and has the following behaviors:

- It will only return `Laminas\Serializer\Adapter\AdapterInterface` instances.
- It defines short-name aliases for all shipped serializers (the class name minus
the namespace), in a variety of casing combinations.
- All services are shared by default; a new instance will only be created once and shared each time you call `get()`.

## Factory

`Laminas\Serializer\AdapterPluginManager` is mapped to the factory
`Laminas\Serializer\AdapterPluginManagerFactory` when wired to the dependency
injection container.

The factory will be automatically registered when loading/installing the `Laminas\Serializer` module in `laminas-mvc` and/or loading/installing the `ConfigProvider` into a Mezzio application.

The factory will look for the `config` service, and use the `serializers`
configuration key to seed it with additional services. This configuration key
should map to an array that follows [standard laminas-servicemanager configuration](https://docs.laminas.dev/laminas-servicemanager/configuring-the-service-manager/).

To add your own serializer you can add the following configuration:

```php
// config/autoload/serializers.global.php
return [
'serializers' => [
'factories' => [
\App\MyCustomSerializer::class => \App\Container\MyCustomSerializerFactory::class,
],
],
];
```
1 change: 1 addition & 0 deletions mkdocs.yml
Expand Up @@ -4,6 +4,7 @@ nav:
- Home: index.md
- Introduction: intro.md
- Adapters: adapter.md
- Plugin Manager: plugin-manager.md
site_name: laminas-serializer
site_description: "Serialize and deserialize PHP structures to a variety of representations"
repo_url: 'https://github.com/laminas/laminas-serializer'
Expand Down
26 changes: 25 additions & 1 deletion src/AdapterPluginManagerFactory.php
Expand Up @@ -9,6 +9,7 @@
namespace Laminas\Serializer;

use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Config;
use Laminas\ServiceManager\FactoryInterface;
use Laminas\ServiceManager\ServiceLocatorInterface;

Expand All @@ -28,7 +29,30 @@ class AdapterPluginManagerFactory implements FactoryInterface
*/
public function __invoke(ContainerInterface $container, $name, array $options = null)
{
return new AdapterPluginManager($container, $options ?: []);
$pluginManager = new AdapterPluginManager($container, $options ?: []);

// If this is in a laminas-mvc application, the ServiceListener will inject
// merged configuration during bootstrap.
if ($container->has('ServiceListener')) {
return $pluginManager;
}

// If we do not have a config service, nothing more to do
if (! $container->has('config')) {
return $pluginManager;
}

$config = $container->get('config');

// If we do not have serializers configuration, nothing more to do
if (! isset($config['serializers']) || ! is_array($config['serializers'])) {
return $pluginManager;
}

// Wire service configuration for serializers
(new Config($config['serializers']))->configureServiceManager($pluginManager);

return $pluginManager;
}

/**
Expand Down
95 changes: 95 additions & 0 deletions test/AdapterPluginManagerFactoryTest.php
Expand Up @@ -71,4 +71,99 @@ public function testFactoryConfiguresPluginManagerUnderServiceManagerV2()
$serializers = $factory->createService($container->reveal());
$this->assertSame($serializer, $serializers->get('test'));
}

public function testConfiguresSerializerServicesWhenFound()
{
$serializer = $this->prophesize(AdapterInterface::class)->reveal();
$config = [
'serializers' => [
'aliases' => [
'test' => 'test-too',
],
'factories' => [
'test-too' => function ($container) use ($serializer) {
return $serializer;
},
],
],
];

$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);

$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(true);
$container->get('config')->willReturn($config);

$factory = new AdapterPluginManagerFactory();
$serializers = $factory($container->reveal(), 'SerializerAdapterManager');

$this->assertInstanceOf(AdapterPluginManager::class, $serializers);
$this->assertTrue($serializers->has('test'));
$this->assertSame($serializer, $serializers->get('test'));
$this->assertTrue($serializers->has('test-too'));
$this->assertSame($serializer, $serializers->get('test-too'));
}

public function testDoesNotConfigureSerializerServicesWhenServiceListenerPresent()
{
$serializer = $this->prophesize(AdapterInterface::class)->reveal();
$config = [
'serializers' => [
'aliases' => [
'test' => 'test-too',
],
'factories' => [
'test-too' => function ($container) use ($serializer) {
return $serializer;
},
],
],
];

$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);

$container->has('ServiceListener')->willReturn(true);
$container->has('config')->shouldNotBeCalled();
$container->get('config')->shouldNotBeCalled();

$factory = new AdapterPluginManagerFactory();
$serializers = $factory($container->reveal(), 'SerializerAdapterManager');

$this->assertInstanceOf(AdapterPluginManager::class, $serializers);
$this->assertFalse($serializers->has('test'));
$this->assertFalse($serializers->has('test-too'));
}

public function testDoesNotConfigureSerializerServicesWhenConfigServiceNotPresent()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);

$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(false);
$container->get('config')->shouldNotBeCalled();

$factory = new AdapterPluginManagerFactory();
$serializers = $factory($container->reveal(), 'SerializerAdapterManager');

$this->assertInstanceOf(AdapterPluginManager::class, $serializers);
}

public function testDoesNotConfigureSerializerServicesWhenConfigServiceDoesNotContainSerializersConfig()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);

$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(true);
$container->get('config')->willReturn(['foo' => 'bar']);

$factory = new AdapterPluginManagerFactory();
$serializers = $factory($container->reveal(), 'SerializerAdapterManager');

$this->assertInstanceOf(AdapterPluginManager::class, $serializers);
$this->assertFalse($serializers->has('foo'));
}
}

0 comments on commit f91b39b

Please sign in to comment.