josegonzalez / Cakephp Filter
h1. CakePHP Filter Plugin Paginates Filtered Records
h2. Background
This plugin is a fork of "Jose Diaz-Gonzalez's Filter component":http://github.com/josegonzalez/cakephp-filter-component, which is something of a fork of "James Fairhurst's Filter Component":http://www.jamesfairhurst.co.uk/posts/view/cakephp_filter_component/, which is in turn a fork by "Maciej Grajcarek":http://blog.uplevel.pl/index.php/2008/06/cakephp-12-filter-component/, which is ITSELF a fork from "Nik Chankov's code":http://nik.chankov.net/2008/03/01/filtering-component-for-your-tables/. "Chad Jablonski":http://github.com/cjab/cakephp-filter-plugin then added RANGE support with a few bug fixes. "jmroth":http://github.com/jmroth/cakephp-filter-plugin pointed out a pretty bad redirect issue and "fixed it". Then "Jose Diaz-Gonzalez":http://josediazgonzalez.com/ took everyone's changes, merged them together, and updated the Component to be a bit more 1.3 compliant.
That's a lot of forks...
This also contains a view helper made by "Matt Curry":http://github.com/mcurry/cakephp-filter-component.
This also uses a behavior adapted from work by "Brenton":http://bakery.cakephp.org/articles/view/habtm-searching to allow for HasAndBelongsToMany and HasMany relationships.
This works for all relationships.
h2. Installation
Clone from github : in your plugin directory type
@git clone git://github.com/josegonzalez/cakephp-filter-plugin.git [email protected]
Add as a git submodule : from your app/ directory type
@git submodule add git://github.com/josegonzalez/cakephp-filter-plugin.git plugins/[email protected]
[email protected]
Download an archive from github and extract the contents into @/plugins/h2. Usage
Include the component in your controller (AppController or otherwise)
@var $components = array('Filter.Filter');@
Use something like the following in your index
function index() {
$this->paginate = $this->Filter->paginate;
$posts = $this->paginate();
$this->set(compact('posts'));
}
Finished example:
paginate = $this->Filter->paginate;
$posts = $this->paginate();
$this->set(compact('posts'));
}
}
?>
h3. Note on 1.2 usage
In order for this to work in 1.2, you need to have the following in your controller:
paginate = $this->Filter->paginate;
$filterOptions = $this->Filter->filterOptions;
$posts = $this->paginate();
$this->set(compact('filterOptions', 'posts'));
}
}
?>
And then merge the $filterOptions variable on anything pagination uses. It can be set globally using PaginatorHelper::options() as follows (in the view):
@options($filterOptions); ?>@
h2. Advanced Usage
h3. Overriding the Filter pagination
h4. Option 1: Controller-wide
By setting the @[email protected] variable for your controller, the Filter component merges those into it's own rules before processing incoming information.
array('Comment'), 'limit' => 5);
function index() {
$this->paginate = $this->Filter->paginate;
$posts = $this->paginate();
$this->set(compact('posts'));
}
}
?>
h4. Option 2: Action-specific
You can merge in things to the paginate array before any pagination happens if necessary.
paginate = array_merge($this->Filter->paginate,
array('contain' => array('Comment'), 'limit' => 5)
);
$posts = $this->paginate();
$this->set(compact('posts'));
}
}
?>
h3. Setting up search forms
h4. Option 1: Helper
Use the helper In between the row with all the column headers and the first row of data add:
@Filter->form('Post', array('name')) ?>@
The first parameter is the model name. The second parameter is an array of fields. If you don't want to filter a particular field pass null in that spot.
h4. Option 2: Manually
Create your own form however you want. Below is such an example.
Form->create('Post', array('action' => 'index', 'id' => 'filters')); ?>
// loop through and display your data
Paginator->sort('Post.name'); ?>
Actions
Form->input('Post.name'); ?>
Filter
Reset
Form->end(); ?>
Paginator->prev('<< '.__('previous', true), array(), null, array('class' => 'disabled')); ?>
Paginator->numbers(); ?>
Paginator->next(__('next', true).' >>', array(), null, array('class' =>' disabled')); ?>
h3. Filtering hasMany and hasAndBelongsToMany relationships
Add Behavior to model (only necessary for HABTM and HasMany):
h3. Initialization Tips
These different initialization options are combined in the setup array. Defaults are shown below.
array(
'actions' => array('index'),
'defaults' => array(),
'fieldFormatting' => array(
'string' => "LIKE '%%%s%%'",
'text' => "LIKE '%%%s%%'",
'datetime' => "LIKE '%%%s%%'"
),
'formOptionsDatetime' => array(),
'paginatorParams' => array(
'page',
'sort',
'direction',
'limit'
),
'parsed' => false,
'redirect' => false,
'useTime' => false,
'separator' => '/',
'rangeSeparator' => '-',
'url' => array(),
'whitelist' => array()
));
}
?>
actions: Array of actions upon which this component will act upon.
@array('Model' => array('key' => 'value')@)
defaults: Holds pagination defaults for controller actions. (syntax isfieldFormatting: Fields which will replace the regular syntax in where i.e. field = 'value'
formOptionsDatetime: Formatting for datetime fields (unused)
paginatorParams: Paginator params sent in the URL
parsed: Used to tell whether the data options have been parsed
redirect: Used to tell whether to redirect so the url includes filter data
useTime: Used to tell whether time should be used in the filtering
separator: Separator to use between fields in a date input
rangeSeparator: Separator to use between dates in a date range
@array('url' => $url)@);
url: Url variable used in paginate helper (syntax iswhitelist: Array of fields and models for which this component may filter
h2. Todo