Skip to content

Instantly share code, notes, and snippets.

@stof
Created December 10, 2011 01:37
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stof/1454212 to your computer and use it in GitHub Desktop.
Save stof/1454212 to your computer and use it in GitHub Desktop.
Idea of a drupal kernel
<?php
namespace Drupal\Core\Controller;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Extended controller resolver trying to use the node to get the controller
*/
class DrupalControllerResolver extends ControllerResolver
{
/**
* Constructor.
*
* @param LoggerInterface $logger A LoggerInterface instance
*/
public function __construct(LoggerInterface $logger = null)
{
// additional dependencies
parent::__construct($logger);
}
/**
* Returns the Controller instance associated with a Request.
*/
public function getController(Request $request)
{
if (!$node = $request->attributes->get('_node')) {
// no node is set, fallback to the Symfony implementation
return parent::getController($request);
}
// get the controller callable based on the node here
}
// getArguments could also be customized if needed.
}
<?php
namespace Drupal\Core;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Drupal\Core\EventListener\DrupalNodeListener;
use Drupal\Core\Controller\DrupalControllerResolver;
class DrupalKernel implements HttpKernelInterface
{
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
// All this bootstraping should in fact use Pimple
$routes = new RouteCollection()
$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new RouterListener($matcher));
$dispatcher->addSubscriber(new DrupalNodeListener());
$resolver = new DrupalControllerResolver();
$kernel = new HttpKernel($dispatcher, $resolver);
return $kernel->handle($request, $type, $catch);
}
}
<?php
namespace Drupal\Core\EventListener;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Retrieves the current node
*/
class DrupalNodeListener implements EventSubscriberInterface
{
private $logger;
public function __construct(LoggerInterface $logger = null)
{
// inject eventually other dependencies too if using an object to load the node
$this->logger = $logger;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if ($request->attributes->has('node_id')) {
// the route does not correspond to a node
return;
}
// the node id has been set in the request by the router
$nodeId = $request->attributes->get('node_id');
try {
$node = // some logic loading the node from the id
if (null !== $this->logger) {
$this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], $this->parametersToString($parameters)));
}
// store the node in an attribute (which should be considered as reserved for that by other drupal code)
$request->attributes->set('_node', $node);
} catch (\Exception $e) {
// the node is not found, send a 404
$message = sprintf('No node found for id "%s"', $nodeId);
throw new NotFoundHttpException($message, $e);
}
}
static public function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array(array('onKernelRequest', 25)), // lower priority than the RouterListener which has 32
);
}
}
<?php
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\DrupalKernel();
$kernel = new DrupalKernel();
$kernel->handle(Request::createFromGlobals())->send();
<?php
use Symfony\Component\HttpKernel\HttpCache\HttpCache;
use Symfony\Component\HttpKernel\HttpCache\Store;
use Symfony\Component\HttpKernel\HttpCache\Esi;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\DrupalKernel;
$kernel = new DrupalKernel();
$store = new Store(__DIR__.'/cache/http');
$esi = new Esi();
$cacheKernel = new HttpCache($kernel, $store); // eventually add $esi as the third parameter to handle ESI
$request = Request::createFromGlobals();
$cacheKernel->handle($request)->send();
@christianchristensen
Copy link

@stof
Copy link
Author

stof commented Jan 3, 2012

This is totally different. the Ekino bundle and module are about integrating Symfony2 with Drupal7 to share the same session and use the Symfony2 DIC from Drupal.
This gist is a proof of concept to build Drupal8 on top of the HttpKernel component. See http://groups.drupal.org/node/198538

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment