Skip to content

Instantly share code, notes, and snippets.

@lsmith77
Created October 27, 2010 09:04
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save lsmith77/648702 to your computer and use it in GitHub Desktop.
multiplexer to json-ify any controller as well as call multiple separate controllers via one request
<?php
namespace Application\FooBundle\Controller;
class MultiplexController
{
/**
* Request
* @var Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* Response
* @var Symfony\Component\HttpFoundation\Response
*/
protected $response;
/**
* Kernel
* @var Symfony\Component\HttpKernel\Kernel
*/
protected $kernel;
/**
* Router
* @var Symfony\Component\Routing\RouterInterface
*/
protected $router;
/**
* assoc array with config parameters
* @var array
*/
protected $params;
/**
* Constructor
*
* @param array $params assoc array with config parameters
* @param Symfony\Component\HttpFoundation\Request $request
* @param Symfony\Component\HttpFoundation\Response $response
* @param Symfony\Component\HttpKernel\Kernel $kernel
* @param Symfony\Component\Routing\RouterInterface $router
*/
public function __construct(array $params, $request, $response, $kernel, $router)
{
$this->params = $params;
$this->request = $request;
$this->response = $response;
$this->kernel = $kernel;
$this->router = $router;
}
/**
* Handle a single request
*
* @param array $request array contains 'uri', 'method' and 'query'
* @param string $id id value
* @return array contains 'id', 'status' and 'html'
*/
protected function handleRequest($request, $i)
{
if (empty($request['uri'])) {
throw new \InvalidArgumentException('no uri given for index: '.$i);
}
$request['uri'] = preg_replace('/^('.preg_quote($this->request->getScriptName(), '/').')?\//', '', $request['uri']);
if (empty($request['method'])) {
$request['method'] = 'get';
}
if (empty($request['parameters'])) {
$request['parameters'] = array();
}
$subRequest = $this->request->create($request['uri'], $request['method'], $request['parameters']);
if (false === ($parameters = $this->router->match($subRequest->getPathInfo()))) {
throw new \InvalidArgumentException('uri did not match a route for index: '.$i);
}
$subRequest->attributes->add($parameters);
$subResponse = $this->kernel->handle($subRequest, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST);
if (substr($subResponse->getStatusCode(), 0, 1) === '3') {
$request = array(
'uri' => $subResponse->headers->get('location'),
'method' => 'get',
'parameters' => array(),
);
return $this->handleRequest($request, $i);
}
return array(
'id' => $i,
'status' => $subResponse->getStatusCode(),
'html' => $subResponse->getContent(),
);
}
/**
* Handle the index request
*
* @param string $_format the format to use in the response (json, html ..)
* @return Symfony\Component\HttpFoundation\Response
*/
public function indexAction($_format)
{
$requests = (array)$this->request->get('requests');
$content = array('response' => array());
foreach ($requests as $i => $request) {
if ($_format === 'html') {
$content['response'][] = $this->handleRequest($request, $i);
} else {
try {
$content['response'][] = $this->handleRequest($request, $i);
} catch (\Exception $e) {
// TODO: are our error messages safe to be returned?
$content['response'][] = array('id' => $i, 'status' => '500', 'html' => $e->getMessage());
}
}
}
$this->response->setStatusCode(200);
$content['status'] = 'success';
// TODO add xml?
switch ($_format) {
case 'json':
$content = json_encode($content);
break;
case 'html':
default:
$content = '<pre>'.var_export($content, true).'</pre>';
break;
}
$this->response->setContent($content);
return $this->response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment