Skip to content

Instantly share code, notes, and snippets.

@NicolasBadey
Created January 24, 2017 10:01
Show Gist options
  • Save NicolasBadey/8d8fa125bc4b249db4217c1a3b9dd968 to your computer and use it in GitHub Desktop.
Save NicolasBadey/8d8fa125bc4b249db4217c1a3b9dd968 to your computer and use it in GitHub Desktop.
<?php
namespace Cappl;
use Symfony\Component\Console\Application as BaseApplication;
use Cappl\Console\Command\ContainerAwareCommand;
use Symfony\Component\Console\Command\Command;
use Pimple\ServiceProviderInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Application extends BaseApplication implements \ArrayAccess
{
protected $container;
protected $logger;
/**
* __construct
*
* @param Container $container
* @param string $name
* @param string $version
*
* @return void
*/
public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
{
$this->container = new Container();
parent::__construct($name, $version);
}
/**
* {@inheritDoc}
*/
public function add(Command $command)
{
if ($command instanceof ContainerAwareCommand) {
$command->setContainer($this->container);
}
return parent::add($command);
}
/**
* {@inheritDoc}
*/
public function run(InputInterface $input = null, OutputInterface $output = null)
{
$this->container->boot();
$this->setDispatcher($this->container['dispatcher']);
parent::run($input, $output);
}
/**
* register
*
* /!\ both parent and container have a "register" method
*
* @param mixed $name
*
* @return void
*/
public function register($name)
{
if ($name instanceof ServiceProviderInterface) {
return $this->container->register($name);
}
return parent::register($name);
}
// Proxy method for container
public function offsetSet($id, $value)
{
$this->container->offsetSet($id, $value);
}
public function offsetGet($id)
{
return $this->container->offsetGet($id);
}
public function offsetExists($id)
{
return $this->container->offsetExists($id);
}
public function offsetUnset($id)
{
$this->container->offsetUnset($id);
}
public function factory($callable)
{
return $this->container->factory($callable);
}
public function protect($callable)
{
return $this->container->protect($callable);
}
public function raw($id)
{
return $this->container->raw($id);
}
public function extend($id, $callable)
{
return $this->container->extend($id, $callable);
}
public function keys()
{
return $this->container->keys();
}
}
<?php
namespace Cappl\ServiceProvider;
use Pimple\Container;
interface BootableServiceProviderInterface
{
/**
* Bootstraps the application.
*
* This method is called after all services are registered
* and should be used for "dynamic" configuration (whenever
* a service must be requested).
*/
public function boot(Container $c);
}
<?php
namespace Cappl;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Pimple\ServiceProviderInterface;
use Pimple\Container as BaseContainer;
use Cappl\ServiceProvider\BootableServiceProviderInterface;
class Container extends BaseContainer
{
private $booted;
protected $bootableProviders = array();
public function __construct()
{
parent::__construct();
$this['dispatcher_class'] = 'Symfony\\Component\\EventDispatcher\\EventDispatcher';
$this['dispatcher'] = function ($c) {
return new $c['dispatcher_class']();
};
}
/**
* Registers a service provider.
*
* @param ServiceProviderInterface $provider A ServiceProviderInterface instance
* @param array $config An array of values that customizes the provider
*
* @return Application
*/
public function register(ServiceProviderInterface $provider, array $values = array())
{
if ($provider instanceof BootableServiceProviderInterface) {
$this->bootableProviders[] = $provider;
}
return parent::register($provider, $values);
}
/**
* Boots all service providers.
*
* This method is automatically called by handle(), but you can use it
* to boot all service providers when not handling a request.
*/
public function boot()
{
if ($this->booted) {
return;
}
$this->booted = true;
foreach ($this->bootableProviders as $provider) {
$provider->boot($this);
}
}
}
<?php
namespace Cappl\Console\Command;
use Cappl\Container;
use Symfony\Component\Console\Command\Command;
class ContainerAwareCommand extends Command
{
protected $container;
public function setContainer(Container $container)
{
$this->container = $container;
}
}
<?php
$app = new Application();
$app['foo'] = 'bar';
$app->register(new MonologServiceProvider());
$app->add(new MyCommand($app['foo']));
$app->run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment