Created
August 25, 2010 14:48
-
-
Save hugowetterberg/549641 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class ServicesContext implements ArrayAccess { | |
protected $handlers; | |
protected $namespaces; | |
private $values = array(); | |
function __construct($handlers = array(), $namespaces = array()) { | |
$this->handlers = $handlers; | |
$this->namespaces = $namespaces; | |
} | |
public function offsetExists($key) { | |
$value = $this[$key]; | |
return $value !== NULL; | |
} | |
public function offsetGet($key) { | |
$value = NULL; | |
$namespace = NULL; | |
$local_key = $key; | |
// Detect namespace. | |
if (($pos = strrpos($key, ':')) !== FALSE) { | |
$namespace = substr($key, 0, $pos); | |
$local_key = substr($key, $pos+1); | |
} | |
// Check for a cached value. | |
if (isset($this->values[$key])) { | |
$value = $this->values[$key]; | |
} | |
else { | |
// Specific key handlers always override the generic | |
// namespace handlers. | |
if (isset($this->handlers[$key])) { | |
$value = $this->handlers[$key]->value($this, $namespace, $local_key); | |
} | |
else if ($namespace && isset($this->namespaces[$namespace])){ | |
$value = $this->namespaces[$namespace]->value($this, $namespace, $local_key); | |
} | |
$this->values[$key] = $value; | |
} | |
return $value; | |
} | |
public function offsetSet($key, $value) { | |
throw new Exception("You cannot modify your context"); | |
} | |
public function offsetUnset($key) { | |
throw new Exception("You cannot modify your context"); | |
} | |
public function mock() { | |
return new ServicesMutableContext($this->handlers, $this->namespaces); | |
} | |
} | |
class ServicesMutableContext extends ServicesContext { | |
function __construct($handlers = array(), $namespaces = array()) { | |
parent::__construct($handlers, $namespaces); | |
} | |
public function addNamespace($namespace, $handler) { | |
$this->namespaces[$namespace] = $handler; | |
} | |
public function getNamespaceHandler($namespace) { | |
$handler = NULL; | |
if (isset($this->namespaces[$namespace])) { | |
$handler = $this->namespaces[$namespace]; | |
} | |
return $handler; | |
} | |
public function offsetExists($key) { | |
return isset($handlers[$key]); | |
} | |
public function offsetGet($key) { | |
return $handlers[$key]; | |
} | |
public function offsetSet($key, $handler) { | |
$this->handlers[$key] = $handler; | |
} | |
public function offsetUnset($key) { | |
unset($this->handlers[$key]); | |
} | |
function immutableCopy() { | |
return new ServicesContext($this->handlers, $this->namespaces); | |
} | |
} | |
interface ServicesContextHandler { | |
function value($context, $namespace, $key); | |
} | |
class ServicesDumbContextHandler implements ServicesContextHandler { | |
private $value; | |
function __construct($value) { | |
$this->value = $value; | |
} | |
public function value($context, $namespace, $key) { | |
return $this->value; | |
} | |
} | |
class ServicesArrayContextHandler implements ServicesContextHandler { | |
private $array; | |
function __construct($array) { | |
$this->array = $array; | |
} | |
public function value($context, $namespace, $key) { | |
$value = NULL; | |
if (isset($this->array[$key])) { | |
$value = $this->array[$key]; | |
} | |
return $value; | |
} | |
} | |
// Example stuff | |
$getv = array( | |
'q' => '/some/path', | |
'p' => 23, | |
); | |
$cA = new ServicesMutableContext(); | |
$cA['varA'] = new ServicesDumbContextHandler('Value A'); | |
$cA['http:get:p'] = new ServicesDumbContextHandler(24); | |
$cA->addNamespace('http:get', new ServicesArrayContextHandler($getv)); | |
$c = $cA->immutableCopy(); | |
print "-- Context\n"; | |
print $c['varA'] . "\n"; | |
print $c['http:get:q'] . "\n"; | |
print $c['http:get:p'] . "\n\n"; | |
$cB = $c->mock(); | |
$cB['varB'] = new ServicesDumbContextHandler('Value B'); | |
$cB['http:get:p'] = new ServicesDumbContextHandler(25); | |
$cX = $cB->immutableCopy(); | |
print "-- Context X\n"; | |
print $cX['varA'] . "\n"; | |
print $cX['varB'] . "\n"; | |
print $cX['http:get:q'] . "\n"; | |
print $cX['http:get:p'] . "\n"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment