Skip to content

Instantly share code, notes, and snippets.

@westonruter
Created March 11, 2011 22:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westonruter/866716 to your computer and use it in GitHub Desktop.
Save westonruter/866716 to your computer and use it in GitHub Desktop.
Adding filtering to any class simply by having it extend the Filterable class.
<?php
// Builds off of Aspect-Oriented Design demo by Garrett Woodworth:
// <http://phpadvent.org/2010/aspect-oriented-design-by-garrett-woodworth>
class Filters {
protected static $_filters = array();
/**
* Register a new filter; note there could be an array index also provided
* to indicate where in the list order that a callback filter should be applied
*/
public static function add($member, $callback) {
static::$_filters[$member][] = $callback;
}
/**
* Run the method's return value by all of the filters in order of addition
*/
public static function apply($value, $member, $object, $params){
if(isset(self::$_filters[$member])){
foreach(self::$_filters[$member] as $callback){
$value = $callback($value, $member, $object, $params);
}
}
return $value;
}
/**
* Remove a filter
*/
public static function remove($member, $callback){
$i = array_search($callback, self::$_filters[$member]);
if($i !== false){
list($removed) = array_splice(self::$_filters, $i, 1);
return $removed;
}
return null;
}
}
/**
* This is a wrapper class that gets inherited from to add filtering to any class method.
* Function argument filtering could be added here as well, as well as instance
* variable filtering.
*/
class Filterable {
function __call($name, $args){
$_name = '_'.$name;
$return = call_user_func_array( array($this, $_name), $args );
$key = get_class($this)."::$name";
return Filters::apply($return, $key, $this, $args);
}
}
/**
* Sample class that is filterable. Note that all filterable methods merely need
* to be prefixed by a single underscore, but then they are invoked without it.
*/
class HelloWorld extends Filterable {
public function _greet($name){
return "Hello, $name!\n";
}
}
/**
* Demo
*/
$hello_world = new HelloWorld();
print $hello_world->greet("John");
//> Hello, John!
Filters::add('HelloWorld::greet', function($value){
return str_replace('Hello', 'Hola', $value);
});
print $hello_world->greet("John");
//> Hola, John!
Filters::add('HelloWorld::greet', function($value){
return str_replace('John', 'Johnny', $value);
});
print $hello_world->greet("John");
//> Hola, Johnny!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment