rudiedirkx/Rudie-on-wheels — Issue #46: Do something nice with Closure->bindTo
Author: rudiedirkx
Created: 2012-01-07 04:51:27+00:00
State: open

interface Extendable {
static function extend($name, Closure $callback);
function __call($method, $args);
}

class Model implements Extendable {
static public $methods = array();
static function extend($name, Closure $callback) {
static::$methods[strtolower(get_called_class())][strtolower($name)] = $callback;
}
function __call($name, $args) {
if ( isset($this::$methods[strtolower(get_class($this))][strtolower($name)]) ) {
$callback = $this::$methods[strtolower(get_class($this))][strtolower($name)]->bindTo($this);

$chain = array();
array_unshift($args, $chain);

return call_user_func_array($callback, $args);
}

throw new BadMethodCallException(get_class($this) . '->' . $name);
}
function doSomething($what) {
echo "I'm doing $what.\n";
}
}

class User extends Model {
public $name = '';
}

class Person extends Model {

}

User::extend('login', function($remember) {
print_r(func_get_args());
echo "I'm logging in as " . $this->name . ( $remember ? " and remembering it" : '' ) . ".\n";
echo "This is me: ";
print_r($this);
});
User::extend('doSomething', function() {
echo "FUCK YEAH HIJACKED SOME SHIT!\n";
});

$user = new User;
$user->name = 'USER oele';
$user->login(true);

$person = new Person;
$person->name = 'persoooon X';
//$person->login(true);

print_r(Model::$methods);
print_r(User::$methods);