Skip to content

Commit

Permalink
Custom filters can now accept arguments. Improve filter docs
Browse files Browse the repository at this point in the history
  • Loading branch information
j4mie committed Sep 29, 2010
1 parent 514e7ad commit 27cfbca
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
23 changes: 20 additions & 3 deletions README.markdown
Expand Up @@ -81,11 +81,11 @@ You may also retrieve a count of the number of rows returned by your query. This

$count = Model::factory('User')->where_lt('age', 20)->count();

#### Custom filters ####
### Filters ###

It is often desirable to create reusable filters that can be used as part of queries. Paris allows this by providing a method called `filter` which can be chained in queries alongside the existing Idiorm query API. The filter method takes the name of a **public static** method on the current Model subclass as an argument. The supplied method which will be called at the point in the chain where `filter` is called, and will be passed the `ORM` object as the first parameter. It should return the ORM object after calling one or more query methods on it. The method chain can then be continued if necessary.
It is often desirable to create reusable queries that can be used to extract particular subsets of data without repeating large sections of code. Paris allows this by providing a method called `filter` which can be chained in queries alongside the existing Idiorm query API. The filter method takes the name of a **public static** method on the current Model subclass as an argument. The supplied method which will be called at the point in the chain where `filter` is called, and will be passed the `ORM` object as the first parameter. It should return the ORM object after calling one or more query methods on it. The method chain can then be continued if necessary.

It is easiest to illustrate this with an example. It may be desirable for users in your application to have a role, which controls their access to certain parts of the application. In this situation, you may often wish to retrieve a list of users with the role 'admin'. To do this, add a static method called 'admins' to your Model class:
It is easiest to illustrate this with an example. Imagine an application in which users can be assigned a role, which controls their access to certain pieces of functionality. In this situation, you may often wish to retrieve a list of users with the role 'admin'. To do this, add a static method called (for example) `admins` to your Model class:

class User extends Model {
public static function admins($orm) {
Expand All @@ -104,6 +104,23 @@ You can also chain it with other methods as normal:
->where_lt('age', 18)
->find_many();

#### Filters with arguments ####

You can also pass arguments to custom filters. Any additional arguments passed to the `filter` method (after the name of the filter to apply) will be passed through to your custom filter as additional arguments (after the ORM instance).

For example, let's say you wish to generalise your role filter (see above) to allow you to retrieve users with any role. You can pass the role name to the filter as an argument:

class User extends Model {
public static function has_role($orm, $role) {
return $orm->where('role', $role);
}
}

$admin_users = Model::factory('User')->filter('has_role', 'admin')->find_many();
$guest_users = Model::factory('User')->filter('has_role', 'guest')->find_many();

These examples may seem simple (`filter('has_role', 'admin')` could just as easily be achieved using `where('role', 'admin')`, but remember that filters can contain arbitrarily complex code - adding `raw_where` clauses or even complete `raw_query` calls to perform joins, etc. Filters provide a powerful mechanism to hide complexity in your model's query API.

### Getting data from objects, updating and inserting data ###

The model instances returned by your queries now behave exactly as if they were instances of Idiorm's raw `ORM` class.
Expand Down
14 changes: 10 additions & 4 deletions paris.php
Expand Up @@ -69,11 +69,17 @@ public function set_class_name($class_name) {
* Add a custom filter to the method chain specified on the
* model class. This allows custom queries to be added
* to models. The filter should take an instance of the
* ORM wrapper and return an instance of the ORM wrapper.
*/
public function filter($filter_function) {
* ORM wrapper as its first argument and return an instance
* of the ORM wrapper. Any arguments passed to this method
* after the name of the filter will be passed to the called
* filter function as arguments after the ORM class.
*/
public function filter() {
$args = func_get_args();
$filter_function = array_shift($args);
array_unshift($args, $this);
if (method_exists($this->_class_name, $filter_function)) {
return call_user_func_array(array($this->_class_name, $filter_function), array($this));
return call_user_func_array(array($this->_class_name, $filter_function), $args);
}
}

Expand Down

0 comments on commit 27cfbca

Please sign in to comment.