Skip to content

Commit

Permalink
Add Kernel class for building modular applications using Puli and PHP-DI
Browse files Browse the repository at this point in the history
  • Loading branch information
mnapoli committed Jan 1, 2016
1 parent f76dfdb commit 370c3c2
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 1 deletion.
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
"mnapoli/phpunit-easymock": "~0.2.0",
"doctrine/cache": "~1.4",
"doctrine/annotations": "~1.2",
"ocramius/proxy-manager": "~1.0"
"ocramius/proxy-manager": "~1.0",
"puli/repository": "^1.0@beta",
"puli/discovery": "^1.0@beta"
},
"replace": {
"mnapoli/php-di": "*"
Expand Down
97 changes: 97 additions & 0 deletions src/DI/Application/Kernel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace DI\Application;

use DI\Container;
use DI\ContainerBuilder;
use Doctrine\Common\Cache\Cache;
use Puli\Discovery\Api\Binding\Binding;
use Puli\Discovery\Api\Discovery;
use Puli\Discovery\Binding\ResourceBinding;
use Puli\Repository\Api\ResourceRepository;
use Puli\Repository\Resource\FileResource;

/**
* Application kernel.
*
* @author Matthieu Napoli <matthieu@mnapoli.fr>
*/
class Kernel
{
/**
* Name of the binding for PHP-DI configuration files in Puli.
*
* @see http://docs.puli.io/en/latest/discovery/introduction.html
*/
const PULI_BINDING_NAME = 'php-di/configuration';

/**
* Configure and create a container using all configuration files registered under
* the `php-di/configuration` binding type in Puli.
*
* @return Container
*/
public function createContainer()
{
if (!defined('PULI_FACTORY_CLASS')) {
throw new \RuntimeException('Puli is not installed');
}

// Create Puli objects
$factoryClass = PULI_FACTORY_CLASS;
$factory = new $factoryClass();
/** @var ResourceRepository $repository */
$repository = $factory->createRepository();
/** @var Discovery $discovery */
$discovery = $factory->createDiscovery($repository);

$containerBuilder = new ContainerBuilder();

$cache = $this->getContainerCache();
if ($cache) {
$containerBuilder->setDefinitionCache($cache);
}

// Discover and load all configuration files registered under `php-di/configuration` in Puli
$bindings = $discovery->findBindings(self::PULI_BINDING_NAME);
$bindings = array_filter($bindings, function (Binding $binding) {
return $binding instanceof ResourceBinding;
});
/** @var ResourceBinding[] $bindings */
foreach ($bindings as $binding) {
foreach ($binding->getResources() as $resource) {
if (!$resource instanceof FileResource) {
throw new \RuntimeException(sprintf('Cannot load "%s": only file resources are supported', $resource->getName()));
}
$containerBuilder->addDefinitions($resource->getFilesystemPath());
}
}

// Puli objects
$containerBuilder->addDefinitions([
'Puli\Repository\Api\ResourceRepository' => $repository,
'Puli\Discovery\Api\Discovery' => $discovery,
]);

$this->configureContainerBuilder($containerBuilder);

return $containerBuilder->build();
}

/**
* Override this method to configure the cache to use for container definitions.
*
* @return Cache|null
*/
protected function getContainerCache()
{
return null;
}

/**
* Override this method to customize the container builder before it is used.
*/
protected function configureContainerBuilder(ContainerBuilder $containerBuilder)
{
}
}
29 changes: 29 additions & 0 deletions tests/IntegrationTest/Application/Fixture/PuliFactoryClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace DI\Test\IntegrationTest\Application\Fixture;

use Puli\Discovery\InMemoryDiscovery;
use Puli\Repository\InMemoryRepository;

class PuliFactoryClass
{
/**
* @var InMemoryRepository
*/
public static $repository;

/**
* @var InMemoryDiscovery
*/
public static $discovery;

public function createRepository()
{
return self::$repository;
}

public function createDiscovery()
{
return self::$discovery;
}
}
5 changes: 5 additions & 0 deletions tests/IntegrationTest/Application/Fixture/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
'foo' => 'bar',
];
79 changes: 79 additions & 0 deletions tests/IntegrationTest/Application/KernelTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace DI\Test\IntegrationTest\Application;

use DI\Application\Kernel;
use DI\Test\IntegrationTest\Application\Fixture\PuliFactoryClass;
use Puli\Discovery\Api\Type\BindingType;
use Puli\Discovery\Binding\ResourceBinding;
use Puli\Discovery\InMemoryDiscovery;
use Puli\Repository\InMemoryRepository;
use Puli\Repository\Resource\FileResource;

/**
* @covers \DI\Application\Kernel
*/
class KernelTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
if (!defined('PULI_FACTORY_CLASS')) {
define('PULI_FACTORY_CLASS', 'DI\Test\IntegrationTest\Application\Fixture\PuliFactoryClass');
}

PuliFactoryClass::$repository = new InMemoryRepository();
PuliFactoryClass::$discovery = new InMemoryDiscovery();
}

/**
* @test
*/
public function creates_a_container()
{
$this->assertInstanceOf('DI\Container', (new Kernel)->createContainer());
}

/**
* @test
*/
public function registers_puli_repository()
{
$container = (new Kernel)->createContainer();
$this->assertInstanceOf('Puli\Repository\Api\ResourceRepository', $container->get('Puli\Repository\Api\ResourceRepository'));
}

/**
* @test
*/
public function registers_puli_discovery()
{
$container = (new Kernel)->createContainer();
$this->assertInstanceOf('Puli\Discovery\Api\Discovery', $container->get('Puli\Discovery\Api\Discovery'));
}

/**
* @test
*/
public function registers_module_configuration_files()
{
$this->createPuliResource('/blog/config.php', __DIR__ . '/Fixture/config.php');
$this->bindPuliResource('/blog/config.php', Kernel::PULI_BINDING_NAME);

$container = (new Kernel)->createContainer();
$this->assertEquals('bar', $container->get('foo'));
}

private function createPuliResource($path, $file)
{
PuliFactoryClass::$repository->add($path, new FileResource($file));
}

private function bindPuliResource($path, $bindingName)
{
PuliFactoryClass::$discovery->addBindingType(new BindingType($bindingName));

$binding = new ResourceBinding($path, $bindingName);
$binding->setRepository(PuliFactoryClass::$repository);
PuliFactoryClass::$discovery->addBinding($binding);
}
}

0 comments on commit 370c3c2

Please sign in to comment.