Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions PhpUnit/ContainerBuilderHasFactoryConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PHPUnit\Framework\Constraint\IsEqual;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;

class ContainerBuilderHasFactoryConstraint extends Constraint
{
Expand Down Expand Up @@ -93,7 +94,7 @@ private function evaluateFactory(ContainerBuilder $containerBuilder, $returnResu
/** @var Definition */
$definition = $containerBuilder->getDefinition($this->serviceId);

$factory = $definition->getFactory();
$factory = $this->getFactoryData($definition);

if( !is_array( $factory ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could check if the Definition::getFactoryClass() method exists to implement a pre Symfony 2.7 compatible solution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!is_array($factory)) {

if ($returnResult) {
Expand All @@ -117,7 +118,7 @@ private function evaluateFactoryClass(ContainerBuilder $containerBuilder, $retur
/** @var Definition */
$definition = $containerBuilder->getDefinition($this->serviceId);

$factory = $definition->getFactory();
$factory = $this->getFactoryData( $definition );

list( $factoryDefinition, $factoryMethod ) = $factory;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove all spaces in function calls. Same for those in if/else etc.


Expand Down Expand Up @@ -175,4 +176,30 @@ private function evaluateFactoryClass(ContainerBuilder $containerBuilder, $retur
return true;
}

private function getFactoryData( Definition $definition )
{
if( self::isLegacySymfonyDI() ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a dirty, but working solution ... I checked with DI 2.3, 3.0 and 3.3 and they working ... a better approach may be an abstract class with "getFactoryData" as abstract method, but this commit resolves <= 2.6 versions and variated factory syntax in yml.

A test case not cover is a service with "setFactoryClass" definition ... This is pending.

$factoryService = $definition->getFactoryService();
$factoryMethod = $definition->getFactoryMethod();
$factoryClass = $definition->getFactoryClass();
if( !$factoryService && !$factoryClass )
return null;

return array( $factoryClass ? $factoryClass : $factoryService, $factoryMethod );
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No point for else as you do return in if.

$factory = $definition->getFactory();
if( is_array( $factory ) ) return $factory;

if( is_string( $factory ) && false !== strpos( $factory, ':' ) )
return preg_split( '/:/', $factory, 2 );

return $factory;
}
}


static public function isLegacySymfonyDI()
{
return method_exists( new Definition(), 'getFactoryService' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to create an instance here, just using the class name works too

}
}
32 changes: 26 additions & 6 deletions Tests/Fixtures/MatthiasDependencyInjectionTestExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\Config\FileLocator;
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\ContainerBuilderHasFactoryConstraint;

class MatthiasDependencyInjectionTestExtension implements ExtensionInterface
{
Expand All @@ -17,6 +19,17 @@ public function load(array $config, ContainerBuilder $container)
$loader = new XmlFileLoader($container, new FileLocator(__DIR__));
$loader->load('services.xml');

// load factory services definitions
if( ContainerBuilderHasFactoryConstraint::isLegacySymfonyDI() ) {
$loader->load('services-factory-legacy.xml');
} else {
$loader->load('services-factory.xml');

// Load old syntax for services in YML files
$ymlLoader = new YamlFileLoader($container, new FileLocator(__DIR__));
$ymlLoader->load('services-factory-old-syntax.yml');
}

// set a parameter manually
$container->setParameter('manual_parameter', 'parameter value');

Expand All @@ -34,13 +47,20 @@ public function load(array $config, ContainerBuilder $container)
$container->setAlias('manual_alias', 'service_id');

// add an factory service
$container
->register( 'manual_factory_service', new Definition() );
$container->register( 'manual_factory_service', new Definition() );

$container
->register( 'manual_created_by_factory_service', new Definition() )
->setFactory( [new Reference('manual_factory_service'), 'factoryMethod'] )
;
if( ContainerBuilderHasFactoryConstraint::isLegacySymfonyDI() ) {
$container
->register( 'manual_created_by_factory_service', new Definition() )
->setFactoryService(new Reference('manual_factory_service'))
->setFactoryMethod('factoryMethod');
;
} else {
$container
->register( 'manual_created_by_factory_service', new Definition() )
->setFactory( 'manual_factory_service:factoryMethod' )
;
}
}

public function getAlias()
Expand Down
12 changes: 12 additions & 0 deletions Tests/Fixtures/services-factory-legacy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" ?>
<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="factory_service">
</service>

<service id="created_by_factory_service" factory-service="factory_service" factory-method="factoryMethod">
</service>
</services>
</container>
3 changes: 3 additions & 0 deletions Tests/Fixtures/services-factory-old-syntax.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
services:
created_with_factory_with_old_syntax:
factory: ['@factory_service', 'factoryMethod']
13 changes: 13 additions & 0 deletions Tests/Fixtures/services-factory.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" ?>
<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="factory_service">
</service>

<service id="created_by_factory_service">
<factory service="factory_service" method="factoryMethod" />
</service>
</services>
</container>
6 changes: 0 additions & 6 deletions Tests/Fixtures/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,5 @@
<service id="synthetic_service" synthetic="true">
</service>

<service id="factory_service">
</service>

<service id="created_by_factory_service">
<factory class="@factory_service" method="factoryMethod" />
</service>
</services>
</container>
13 changes: 11 additions & 2 deletions Tests/PhpUnit/AbstractExtensionTestCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Matthias\DependencyInjectionTests\Test\DependencyInjection;

use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase;
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\ContainerBuilderHasFactoryConstraint;
use Matthias\SymfonyDependencyInjectionTest\Tests\Fixtures\MatthiasDependencyInjectionTestExtension;
use PHPUnit\Framework\ExpectationFailedException;

Expand All @@ -28,8 +29,8 @@ public function if_load_is_successful_it_does_not_fail()
// defined in services.xml
$this->assertContainerBuilderHasSyntheticService('synthetic_service');

// defined in services.xml
$this->assertContainerBuilderHasCreatedByFactoryService('created_by_factory_service', '@factory_service', 'factoryMethod');
// defined in services-factory.xml
$this->assertContainerBuilderHasCreatedByFactoryService('created_by_factory_service', 'factory_service', 'factoryMethod');

// manually defined parameter
$this->assertContainerBuilderHasParameter('manual_parameter', 'parameter value');
Expand Down Expand Up @@ -58,8 +59,16 @@ public function if_load_is_successful_it_does_not_fail()
'manual_created_by_factory_service',
'manual_factory_service',
'factoryMethod' );

if( !ContainerBuilderHasFactoryConstraint::isLegacySymfonyDI() ) {
$this->assertContainerBuilderHasCreatedByFactoryService(
'created_with_factory_with_old_syntax',
'factory_service',
'factoryMethod' );
}
}


/**
* @test
*/
Expand Down
15 changes: 10 additions & 5 deletions Tests/PhpUnit/ContainerBuilderHasFactoryConstraintTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@ public function containerBuilderProvider()

$builderWithFactory = new ContainerBuilder();
$factoryReference = new Reference($factoryClass);
$builderWithFactory->register( $rightServiceId)
->setFactory([$factoryReference,$factoryMethod]);
$builderWithFactory->register( $wrongServiceId );

return [
array($builderWithFactory, $rightServiceId, $factoryClass, $factoryMethod, true ), ];
if( ContainerBuilderHasFactoryConstraint::isLegacySymfonyDI() ) {
$builderWithFactory->register( $rightServiceId)
->setFactoryService($factoryReference)
->setFactoryMethod($factoryMethod);
} else {
$builderWithFactory->register( $rightServiceId)
->setFactory([$factoryReference,$factoryMethod]);
}

$builderWithFactory->register( $wrongServiceId );

return array(
// the container does not have the service
Expand Down