Skip to content

Instantly share code, notes, and snippets.

@pmjones
Last active February 11, 2017 15:28
Show Gist options
  • Save pmjones/1eca32131759ef600051 to your computer and use it in GitHub Desktop.
Save pmjones/1eca32131759ef600051 to your computer and use it in GitHub Desktop.
action extraction
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class Action
{
// specifications to be resolved
protected $input;
protected $domain;
protected $responder;
public function __construct($input, $domain, $responder)
{
$this->input = $input;
$this->domain = $domain;
$this->responder = $responder;
}
public function getInput()
{
return $this->input;
}
public function getDomain()
{
return $this->domain;
}
public function getResponder()
{
return $this->responder;
}
}
class ActionFactory
{
public function newInstance($input, $domain, $responder)
{
return new Action($input, $domain, $responder);
}
}
class ActionHandler
{
protected $resolver;
public function __construct(callable $resolver = null)
{
$this->resolver = $resolver;
}
public function handle(Request $request, Response $response, Action $action)
{
$responder = $this->resolve($action->getResponder());
$domainSpec = $action->getDomain();
if (! $domainSpec) {
return $responder($request, $response);
}
$domain = $this->resolve($domainSpec);
$params = $this->params($request, $action);
$payload = call_user_func_array($domain, $params);
return $responder($request, $response, $payload);
}
protected function params(Request $request, Action $action)
{
$inputSpec = $action->getInput();
if (! $inputSpec) {
return [];
}
$input = $this->resolve($inputSpec);
return (array) $input($request);
}
protected function resolve($spec)
{
if (! $this->resolver) {
return $spec;
}
return call_user_func($this->resolver, $spec);
}
}
// alternatively, the middleware could compose ActionHandler
class Middleware extends ActionHandler
{
public function __invoke(Request $request, Response $response, callable $next)
{
$action = $request->getAttribute('vendor/package:action');
$request = $request->withoutAttribute('vendor/package:action');
$response = $this->handle($request, $response, $action);
return $next($request, $response);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment