Skip to content

Instantly share code, notes, and snippets.

@designermonkey
Last active August 29, 2015 14:06
Show Gist options
  • Save designermonkey/d8ed86868e2fe7ebc4ae to your computer and use it in GitHub Desktop.
Save designermonkey/d8ed86868e2fe7ebc4ae to your computer and use it in GitHub Desktop.
<?php
/**
* Beagle Bones
*/
namespace Beagle\Bones;
/**
* Middleware Decorator
*/
class MiddlewareDecorator
{
/**
* Application instance
* @var Beagle\Bones\Application
*/
protected $application;
/**
* Middleware instance
* @var callable
*/
protected $middleware;
/**
* Invoke instance
* @var callable
*/
protected $invoke;
/**
* Call instance
* @var callable
*/
protected $call;
/**
* Get instance
* @var callable
*/
protected $get;
/**
* Set instance
* @var callable
*/
protected $set;
protected $unset;
protected $isset;
/**
* Constructor
* @param Beagle\Bones\Application $application
* @param callable $middleware
*/
public function __construct(Application $application, callable $middleware)
{
$this->application = $application;
$this->middlware = $middlware;
}
/**
* Invoke the middleware
* @return mixed
*/
public function __invoke()
{
if (null === $this->invoke) {
// Rebind the middleware invoke to $this:
$object = new ReflectionObject($this->middleware);
$method = $object->getMethod('__invoke');
$this->invoke = $method->getClosure($this->middleware)->bindTo($this);
}
$invoke = $this->invoke;
return $invoke();
}
/**
* Call a function of the middleware
* @param string $name
* @param array $args
* @return mixed
*/
public function __call($name, $args)
{
if (null === $this->call) {
// Define our __call closure:
$call = function ($name, $args) {
return $this->{$name}($args);
};
$this->call = $call->bindTo($this->middleware, $this->middleware);
}
$closure = $this->call;
return $closure($name, $args);
}
/**
* Get a property from the middleware
* @param string $name
* @return mixed
*/
public function __get($name)
{
if (null === $this->get) {
// Define our __get closure:
$get = function($name) {
return $this->{$name};
};
$this->get = $get->bindTo($this->middleware, $this->middleware);
}
$closure = $this->get;
return $closure($name);
}
/**
* Set a property on the middleware
* @param string $name
* @param mixed $value
*/
public function __set($name, $value)
{
if (null === $this->set) {
// Define our __set closure:
$set = function($name, $value) {
return $this->{$name} = $value;
};
$this->set = $set->bindTo($this->middleware, $this->middleware);
}
$closure = $this->set;
return $closure($name, $value);
}
/**
* Check a property is set in the middleware
* @param string $name
* @return boolean
*/
public function __isset($name)
{
if (null === $this->isset) {
// Define our __isset closure:
$isset = function ($name) {
return isset($this->{$name});
}
$this->isset = $isset->bindTo($this->middleware, $this->middleware);
}
$closure = $this->isset;
return $closure($name);
}
/**
* Unset a property on the middleware
* @param string $name
*/
public function __unset($name)
{
if (null === $this->isset) {
// Define our __isset closure:
$isset = function ($name) {
return $this->{$name} = null;
}
$this->isset = $isset->bindTo($this->middleware, $this->middleware);
}
$closure = $this->isset;
return $closure($name);
}
/**
* Unwrap the middleware
* @return callable
*/
public function unwrap()
{
return $this->middleware;
}
/**
* Call the next middleware in the application
* @return function
*/
public function next()
{
$this->application->next();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment