Skip to content

Commit

Permalink
Merge pull request #4 from PHP-DI/refactoring
Browse files Browse the repository at this point in the history
Big simplification, less overhead
  • Loading branch information
mnapoli committed Sep 1, 2015
2 parents b9eccdb + 0007f6d commit b527077
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 107 deletions.
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"php": ">=5.4",
"php-di/php-di": "~5.0",
"silex/silex" : "~1.3",
"pimple/pimple" : "~1.1",
"mouf/pimple-interop": "~1.0"
"pimple/pimple" : "~1.1"
},
"require-dev": {
"phpunit/phpunit": "~4.5",
"twig/twig": "~1.8"
"twig/twig": "~1.8",
"swiftmailer/swiftmailer": "^5.4"
}
}
63 changes: 13 additions & 50 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

namespace DI\Bridge\Silex;

use DI\Bridge\Silex\Container\CompositeContainer;
use DI\Bridge\Silex\Container\ContainerInteropProxy;
use DI\Bridge\Silex\Controller\ControllerResolver;
use DI\Container;
use DI\ContainerBuilder;
use Interop\Container\ContainerInterface;
use Interop\Container\Pimple\PimpleInterop;
use Pimple;

/**
* Replacement for the Silex Application class to use PHP-DI instead of Pimple.
Expand All @@ -18,90 +16,55 @@
class Application extends \Silex\Application
{
/**
* @var CompositeContainer
* @var ContainerInteropProxy
*/
private $rootContainer;
private $containerInteropProxy;

/**
* @var Container
*/
private $phpdi;

/**
* @var Pimple
*/
private $pimple;

/**
* @param ContainerBuilder|null $containerBuilder You can optionally provide your preconfigured container builder.
* @param array $values
*/
public function __construct(ContainerBuilder $containerBuilder = null, array $values = [])
{
// The composite container "merges" PHP-DI and Pimple into one container
$this->rootContainer = new CompositeContainer();

$this->pimple = new PimpleInterop();
$this->rootContainer->setPimple($this->pimple);
$this->containerInteropProxy = new ContainerInteropProxy($this);

$containerBuilder = $containerBuilder ?: new ContainerBuilder();
$containerBuilder->addDefinitions([
'Interop\Container\ContainerInterface' => $this->rootContainer,
'Interop\Container\ContainerInterface' => $this->containerInteropProxy,
]);
$containerBuilder->wrapContainer($this->rootContainer);
$containerBuilder->wrapContainer($this->containerInteropProxy);
$this->phpdi = $containerBuilder->build();

$this->rootContainer->setPhpdi($this->phpdi);

parent::__construct($values);

// Override the controller resolver with ours
$this->pimple['resolver'] = function () {
return new ControllerResolver($this->phpdi);
};
$this['resolver'] = new ControllerResolver($this->phpdi);
}

public function offsetGet($id)
{
return $this->rootContainer->get($id);
if (parent::offsetExists($id)) {
return parent::offsetGet($id);
}
return $this->phpdi->get($id);
}

public function offsetExists($id)
{
return $this->rootContainer->has($id);
}

public function offsetSet($id, $value)
{
$this->pimple[$id] = $value;
}

public function offsetUnset($id)
{
unset($this->pimple[$id]);
}

public function raw($id)
{
return $this->pimple->raw($id);
}

public function extend($id, $callable)
{
return $this->pimple->extend($id, $callable);
}

public function keys()
{
throw new \LogicException('Unsupported operation');
return parent::offsetExists($id) || $this->phpdi->has($id);
}

/**
* @return ContainerInterface
*/
public function getContainer()
{
return $this->rootContainer;
return $this->containerInteropProxy;
}

/**
Expand Down
54 changes: 0 additions & 54 deletions src/Container/CompositeContainer.php

This file was deleted.

38 changes: 38 additions & 0 deletions src/Container/ContainerInteropProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace DI\Bridge\Silex\Container;

use DI\Bridge\Silex\Application;
use Interop\Container\ContainerInterface;

/**
* Proxies container-interop methods to the application.
*
* ContainerInterface cannot be implemented directly by Application because it defines
* a `get()` method already (to add a controller for a GET HTTP method). So we use this
* proxy to have a ContainerInterop container but still use the application.
*
* @author Matthieu Napoli <matthieu@mnapoli.fr>
*/
class ContainerInteropProxy implements ContainerInterface
{
/**
* @var Application
*/
private $application;

public function __construct(Application $application)
{
$this->application = $application;
}

public function get($id)
{
return $this->application->offsetGet($id);
}

public function has($id)
{
return $this->application->offsetExists($id);
}
}
58 changes: 58 additions & 0 deletions tests/ProvidersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
namespace DI\Bridge\Silex\Test;

use DI\ContainerBuilder;
use Silex\Provider\SwiftmailerServiceProvider;
use Silex\Provider\TwigServiceProvider;
use Silex\Provider\UrlGeneratorServiceProvider;
use Swift_Events_SimpleEventDispatcher;
use Swift_Mailer;
use Swift_Transport_NullTransport;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGenerator;

class ProvidersTest extends BaseTestCase
{
Expand All @@ -31,4 +37,56 @@ public function test_twig()
$response = $app->handle(Request::create('/'));
$this->assertEquals('Hello', $response->getContent());
}

/**
* @see https://github.com/PHP-DI/Silex-Bridge/issues/3
* @test
*/
public function test_url_generator()
{
$builder = new ContainerBuilder;
$builder->addDefinitions([
// Create an alias so that we can inject with the type-hint
'Symfony\Component\Routing\Generator\UrlGenerator' => \DI\get('url_generator'),
]);
$app = $this->createApplication($builder);

$app->register(new UrlGeneratorServiceProvider());

$app->get('/', function (UrlGenerator $urlGenerator) {
return $urlGenerator->generate('home');
})->bind('home');

$response = $app->handle(Request::create('/'));
$this->assertEquals('/', $response->getContent());
}

/**
* @see https://github.com/PHP-DI/Silex-Bridge/issues/3
* @test
*/
public function test_mailer()
{
$builder = new ContainerBuilder;
$builder->addDefinitions([
// Create an alias so that we can inject with the type-hint
'Swift_Mailer' => \DI\get('mailer'),
]);
$app = $this->createApplication($builder);

$app->register(new SwiftmailerServiceProvider, [
'swiftmailer.transport' => new Swift_Transport_NullTransport(
new Swift_Events_SimpleEventDispatcher
),
]);

$app->get('/', function (Swift_Mailer $mailer) {
$message = \Swift_Message::newInstance();
$mailer->send($message);
return 'OK';
});

$response = $app->handle(Request::create('/'));
$this->assertEquals('OK', $response->getContent());
}
}

0 comments on commit b527077

Please sign in to comment.