Skip to content

Commit

Permalink
Merge pull request #22 from ruslan-polutsygan/patch-1
Browse files Browse the repository at this point in the history
Optional class loader & update symfony options in runtime
  • Loading branch information
benja-M-1 committed Jan 31, 2015
2 parents 412b41f + 3279bdd commit 54b8ec7
Show file tree
Hide file tree
Showing 10 changed files with 254 additions and 20 deletions.
8 changes: 7 additions & 1 deletion DependencyInjection/Compiler/KernelConfigurationPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
* KernelConfigurationPass
Expand All @@ -23,12 +24,17 @@ public function process(ContainerBuilder $container)
{
$kernelId = $container->getParameter('theodo_evolution_legacy_wrapper.legacy_kernel.id');
$kernelOptions = $container->getParameter('theodo_evolution_legacy_wrapper.legacy_kernel.options');
$classLoaderId = $container->getParameter('theodo_evolution_legacy_wrapper.autoload.class_loader.id');
$container->setAlias('theodo_evolution_legacy_wrapper.legacy_kernel', $kernelId);

if (!empty($kernelOptions)) {
$definition = $container->findDefinition($kernelId);
$definition->addMethodCall('setOptions', array($kernelOptions));
}

if($classLoaderId) {
$definition = $container->findDefinition($kernelId);
$definition->addMethodCall('setClassLoader', array(new Reference($classLoaderId)));
}
}
}

1 change: 0 additions & 1 deletion DependencyInjection/Compiler/LoaderInjectorPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,3 @@ public function process(ContainerBuilder $container)
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ public function load(array $configs, ContainerBuilder $container)
$container->setParameter('theodo_evolution_legacy_wrapper.assets', $config['assets']);
$container->setParameter('theodo_evolution_legacy_wrapper.legacy_kernel.id', $config['kernel']['id']);
$container->setParameter('theodo_evolution_legacy_wrapper.legacy_kernel.options', isset($config['kernel']['options']) ? $config['kernel']['options'] : array());

if (isset($config['class_loader_id'])) {
$container->setAlias('theodo_evolution_legacy_wrapper.autoload.class_loader', $config['class_loader_id']);
}
$container->setParameter('theodo_evolution_legacy_wrapper.autoload.class_loader.id', isset($config['class_loader_id']) ? $config['class_loader_id'] : null);
}
}
63 changes: 63 additions & 0 deletions Kernel/Event/LegacyKernelBootEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Theodo\Evolution\Bundle\LegacyWrapperBundle\Kernel\Event;

use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;

class LegacyKernelBootEvent extends Event
{
/**
* @var Request
*/
protected $request;

/**
* @var array - legacy kernel options
*/
protected $options;

/**
* @param Request $request
* @param array $options
*/
public function __construct(Request $request, array $options = array())
{
$this->request = $request;
$this->options = $options;
}

/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}

/**
* @return array
*/
public function getOptions()
{
return $this->options;
}

/**
* @param array $options
*/
public function setOptions($options)
{
$this->options = $options;
}

/**
* @param string $name
* @param string $value
*/
public function setOption($name, $value)
{
$this->options[$name] = $value;
}

}
8 changes: 8 additions & 0 deletions Kernel/LegacyKernelEvents.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Theodo\Evolution\Bundle\LegacyWrapperBundle\Kernel;

final class LegacyKernelEvents
{
const BOOT = 'legacy_kernel.boot';
}
15 changes: 7 additions & 8 deletions Kernel/Symfony14Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Theodo\Evolution\Bundle\LegacyWrapperBundle\Autoload\LegacyClassLoaderInterface;
use Theodo\Evolution\Bundle\LegacyWrapperBundle\Kernel\Event\LegacyKernelBootEvent;

/**
* Symfony14Kernel kernel handles.
Expand All @@ -34,14 +32,15 @@ public function boot(ContainerInterface $container)
return;
}

if (empty($this->classLoader)) {
throw new \RuntimeException('You must provide a class loader to the Symfony 1.4 kernel.');
}

if (!$this->classLoader->isAutoloaded()) {
if ($this->classLoader && !$this->classLoader->isAutoloaded()) {
$this->classLoader->autoload();
}

$dispatcher = $container->get('event_dispatcher');
$event = new LegacyKernelBootEvent($container->get('request'), $this->options);
$dispatcher->dispatch(LegacyKernelEvents::BOOT, $event);
$this->options = $event->getOptions();

require_once $this->rootDir.'/config/ProjectConfiguration.class.php';

$application = $this->options['application'];
Expand Down
3 changes: 0 additions & 3 deletions Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@
<call method="setRootDir">
<argument type="string">%theodo_evolution_legacy_wrapper.root_dir%</argument>
</call>
<call method="setClassLoader">
<argument type="service" id="theodo_evolution_legacy_wrapper.autoload.class_loader" />
</call>
</service>

<service
Expand Down
54 changes: 54 additions & 0 deletions Resources/doc/symfony14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,57 @@ Here is the basic configuration for a symfony >=1.4 application:
application: frontend
environment: '%kernel.environment%'
debug: '%kernel.debug%'


Update options in runtime
-------------------------
There is an event ``LegacyKernelEvents::BOOT`` being dispatched in from ``Symfony14Kernel::boot`` before legacy project is actually started.
Handling this event allows to update ``options`` (``application``, ``environment`` and ``debug``) in runtime.
For example to launch application(in terms of symfony 1) based on request:

::

namespace My\LegacyWrapperBundle\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Theodo\Evolution\Bundle\LegacyWrapperBundle\Kernel\Event\LegacyKernelBootEvent;
use Theodo\Evolution\Bundle\LegacyWrapperBundle\Kernel\LegacyKernelEvents;
class MyListener implements EventSubscriberInterface
{
/**
* @param LegacyKernelBootEvent $event
*/
public function onLegacyKernelBoot(LegacyKernelBootEvent $event)
{
$request = $event->getRequest();
if($this->isBackendApplication()) {
$event->setOption('application', 'backend');
} else {
$event->setOption('application', 'frontend');
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
LegacyKernelEvents::BOOT => 'onLegacyKernelBoot'
];
}
/**
* @param Request $request
*
* @return bool
*/
protected function isBackendApplication(Request $request)
{
// .... some logic there
}
}


68 changes: 68 additions & 0 deletions Tests/DependencyInjection/Compiler/KernelConfigurationPassTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Theodo\Evolution\Bundle\LegacyWrapperBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

class KernelConfigurationPassTest extends \PHPUnit_Framework_TestCase
{
public function testShouldConfigureKernelBasedOnParameters()
{
$container = new ContainerBuilder();

$container->setDefinition('legacy_kernel_id', new Definition());

$container->setParameter('theodo_evolution_legacy_wrapper.legacy_kernel.id', $kernel = 'legacy_kernel_id');
$container->setParameter('theodo_evolution_legacy_wrapper.legacy_kernel.options', $options = array('key' => 'value'));
$container->setParameter('theodo_evolution_legacy_wrapper.autoload.class_loader.id', $loader = 'class_loader');

$compiler = new KernelConfigurationPass();
$compiler->process($container);

$kernelDefinition = $container->findDefinition('theodo_evolution_legacy_wrapper.legacy_kernel');

$this->assertSame($container->findDefinition('legacy_kernel_id'), $kernelDefinition, 'Legacy kernel alias has not been set correctly');
$this->assertAttributeContains(array('setOptions', array($options)), 'calls', $kernelDefinition, 'Method setOptions has not been set to call');
$this->assertAttributeContains(array('setClassLoader', array(new Reference('class_loader'))), 'calls', $kernelDefinition, 'Method setClassLoader has not been set to call');
}

public function testShouldNotCallSetOptionsIfEmpty()
{
$container = new ContainerBuilder();

$container->setDefinition('legacy_kernel_id', new Definition());

$container->setParameter('theodo_evolution_legacy_wrapper.legacy_kernel.id', $kernel = 'legacy_kernel_id');
$container->setParameter('theodo_evolution_legacy_wrapper.legacy_kernel.options', $options = array());
$container->setParameter('theodo_evolution_legacy_wrapper.autoload.class_loader.id', $loader = 'class_loader');

$compiler = new KernelConfigurationPass();
$compiler->process($container);

$kernelDefinition = $container->findDefinition('theodo_evolution_legacy_wrapper.legacy_kernel');

$this->assertSame($container->findDefinition('legacy_kernel_id'), $kernelDefinition, 'Legacy kernel alias has not been set correctly');
$this->assertAttributeNotContains(array('setOptions', array($options)), 'calls', $kernelDefinition, 'Method setOptions should not be set to call');
}

public function testShouldNotCallSetClassLoaderIfNull()
{
$container = new ContainerBuilder();

$container->setDefinition('legacy_kernel_id', new Definition());

$container->setParameter('theodo_evolution_legacy_wrapper.legacy_kernel.id', $kernel = 'legacy_kernel_id');
$container->setParameter('theodo_evolution_legacy_wrapper.legacy_kernel.options', $options = array('key' => 'value'));
$container->setParameter('theodo_evolution_legacy_wrapper.autoload.class_loader.id', $loader = null);

$compiler = new KernelConfigurationPass();
$compiler->process($container);

$kernelDefinition = $container->findDefinition('theodo_evolution_legacy_wrapper.legacy_kernel');

$this->assertSame($container->findDefinition('legacy_kernel_id'), $kernelDefinition, 'Legacy kernel alias has not been set correctly');
$this->assertAttributeNotContains(array('setClassLoader', array(new Reference('class_loader'))), 'calls', $kernelDefinition, 'Method setClassLoader should not be set to call');
}
}
49 changes: 46 additions & 3 deletions Tests/Kernel/Symfony14KernelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Theodo\Evolution\Bundle\LegacyWrapperBundle\Kernel\Event\LegacyKernelBootEvent;
use Theodo\Evolution\Bundle\LegacyWrapperBundle\Kernel\Symfony14Kernel;

/**
Expand All @@ -18,14 +21,25 @@ class Symfony14KernelTest extends ProphecyTestCase
{
public function testShouldBootAndHandleRequest()
{
$kernelOptions = array(
'application' => 'frontend',
'environment' => 'prod',
'debug' => true
);

$classLoader = $this->prophesize('Theodo\Evolution\Bundle\LegacyWrapperBundle\Autoload\LegacyClassLoaderInterface');

$session = new Session(new MockArraySessionStorage());
$request = Request::create('/');
$request->setSession($session);

$eventDispatcher = $this->prophesize('Symfony\Component\EventDispatcher\EventDispatcherInterface');
$eventDispatcher->dispatch('legacy_kernel.boot', new LegacyKernelBootEvent($request, $kernelOptions))->shouldBeCalled();

$container = $this->prophesize('Symfony\Component\DependencyInjection\ContainerInterface');
$container->get('session')->willReturn($session);
$container->get('event_dispatcher')->willReturn($eventDispatcher);
$container->get('request')->willReturn($request);

$classLoader->setKernel(Argument::type('Theodo\Evolution\Bundle\LegacyWrapperBundle\Kernel\Symfony14Kernel'))->shouldBeCalled();
$classLoader->isAutoloaded()->willReturn(false);
Expand All @@ -34,19 +48,48 @@ public function testShouldBootAndHandleRequest()
$kernel = new Symfony14Kernel();
$kernel->setRootDir($_ENV['THEODO_EVOLUTION_FAKE_PROJECTS'].'/symfony14');
$kernel->setClassLoader($classLoader->reveal());
$kernel->setOptions(array(
$kernel->setOptions($kernelOptions);

$kernel->boot($container->reveal());
$this->assertTrue($kernel->isBooted());

$response = $kernel->handle($request, 1, true);

$this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
$this->assertEquals(200, $response->getStatusCode());
}

public function testShouldBootAndHandleRequestIfClassLoaderIsNotProvided()
{
$kernelOptions = array(
'application' => 'frontend',
'environment' => 'prod',
'debug' => true
));
);

$session = new Session(new MockArraySessionStorage());
$request = Request::create('/');
$request->setSession($session);

$eventDispatcher = $this->prophesize('Symfony\Component\EventDispatcher\EventDispatcherInterface');
$eventDispatcher->dispatch('legacy_kernel.boot', new LegacyKernelBootEvent($request, $kernelOptions))->shouldBeCalled();

$container = $this->prophesize('Symfony\Component\DependencyInjection\ContainerInterface');
$container->get('event_dispatcher')->willReturn($eventDispatcher);
$container->get('request')->willReturn($request);

$kernel = new Symfony14Kernel();
$kernel->setRootDir($_ENV['THEODO_EVOLUTION_FAKE_PROJECTS'].'/symfony14');
$kernel->setOptions($kernelOptions);

$kernel->boot($container->reveal());
$this->assertTrue($kernel->isBooted());
$this->assertAttributeEmpty('classLoader', $kernel);

$response = $kernel->handle($request, 1, true);

$this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
$this->assertEquals(200, $response->getStatusCode());
}
}

0 comments on commit 54b8ec7

Please sign in to comment.