Created
March 25, 2014 13:30
-
-
Save ringmaster/9761789 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 OC_Hook extends ArrayObject { | |
static protected $registered = array(); | |
protected $abort = false; | |
protected $callbacks = array(); | |
protected $signal = ''; | |
public static function connect($classname, $signalname, $callback) { | |
if(!isset(self::$registered[$signalname])) { | |
self::$registered[$signalname] = array(); | |
} | |
self::$registered[$signalname][$classname] = $callback; | |
} | |
public static function compact($parameters) { | |
$c = __CLASS__; | |
return new $c($parameters); | |
} | |
public static function emit($signalname, \OC_Hook $parameters = null) { | |
if(empty($parameters)) { | |
$parameters = \OC_Hook::compact(array()); | |
} | |
if(isset(self::$registered[$signalname])) { | |
$parameters->doEmit($signalname, self::$registered[$signalname]); | |
} | |
} | |
public function doEmit($signalname, $callbacks) { | |
$this->signal = $signalname; | |
$this->callbacks = $callbacks; | |
if(count($this->callbacks)) { | |
$this->next(); | |
} | |
} | |
public function next() { | |
$key = key($this->callbacks); | |
$next = array_shift($this->callbacks); | |
try { | |
call_user_func($next, $this); | |
} | |
catch (\Exception $e) { | |
// Log exception | |
echo "Caught exception while running {$this->signal} for {$key}.\n"; | |
} | |
if(!$this->abort && count($this->callbacks)) { | |
$this->next(); | |
} | |
} | |
public function abort() { | |
$this->abort = true; | |
} | |
public function has($key) { | |
$key = is_array($key) ? $key : array($key); | |
return count(array_intersect(array_keys($this->callbacks), $key)) > 0; | |
} | |
public function getSignal() { | |
return $this->signal; | |
} | |
public function until($key, $callback) { | |
while($this->has($key) && !$this->abort) { | |
$this->next(); | |
} | |
if(!$this->abort) { | |
call_user_func($callback, $this); | |
} | |
} | |
} | |
OC_Hook::connect('foo', 'sig1', function(OC_Hook $params) { | |
// wait until 'qux' fires, then abort | |
$params->until('qux', function(OC_Hook $params){ | |
$params['new'] = 'This is newer.'; | |
$params->abort(); | |
}); | |
}); | |
OC_Hook::connect('bar', 'sig1', function(OC_Hook $params) { | |
$params['new'] = 'This is new.'; | |
$params->next(); | |
}); | |
OC_Hook::connect('baz', 'sig1', function(OC_Hook $params) { | |
$params['change'] = 'This is changed.'; | |
}); | |
OC_Hook::connect('qux', 'sig1', function(OC_Hook $params) { | |
throw new \Exception('test hook exceptions'); | |
}); | |
OC_Hook::connect('quux', 'sig1', function(OC_Hook $params) { | |
$params['new'] = 'This is too new.'; | |
// This one won't execute because abort() was called from foo | |
}); | |
OC_Hook::emit('sig1', $result = OC_Hook::compact(array('change'=>'old value'))); | |
extract($result->getArrayCopy()); | |
var_dump($change, $new); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment