cakephp component plugin for filtering paginated model and related model data
Pull request Compare This branch is 21 commits behind josegonzalez:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


CakePHP Filter Plugin

Paginates Filtered Records


This plugin is a fork of Jose Diaz-Gonzalez's Filter component, which is something of a fork of James Fairhurst's Filter Component, which is in turn a fork by Maciej Grajcarek, which is ITSELF a fork from Nik Chankov's code. Chad Jablonski then added RANGE support with a few bug fixes. jmroth pointed out a pretty bad redirect issue and "fixed it". Then Jose Diaz-Gonzalez 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.

This also uses a behavior adapted from work by Brenton to allow for HasAndBelongsToMany and HasMany relationships.

This works for all relationships.


  • Clone from github : in your plugin directory type

    git clone git:// filter

  • Add as a git submodule : from your app/ directory type

    git submodule add git:// plugins/filter

  • Download an archive from github and extract the contents into /plugins/filter


  • 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();
  • Finished example:
paginate = $this->Filter->paginate;
		$posts = $this->paginate();

Advanced Usage

Overriding the Filter pagination

Option 1: Controller-wide

By setting the $paginate 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();

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();

Setting up search forms

Option 1: Helper

Use the helper In between the row with all the column headers and the first row of data add:

<?php echo $this->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.

Option 2: Manually

Create your own form however you want. Below is such an example.

Form->create('Post', array('action' => 'index', 'id' => 'filters')); ?>
	<table cellpadding="0" cellspacing="0">
				<th>Paginator->sort(''); ?></th>
				<th class="actions">Actions</th>
				<th>Form->input(''); ?></th>
					<button type="submit" name="data[filter]" value="filter">Filter</button>
					<button type="submit" name="data[reset]" value="reset">Reset</button>
			// loop through and display your data
Form->end(); ?>
<div class="paging">
	Paginator->prev('<< '.__('previous', true), array(), null, array('class' => 'disabled')); ?>
	Paginator->numbers(); ?>
	Paginator->next(__('next', true).' >>', array(), null, array('class' =>' disabled')); ?>

Filtering hasMany and hasAndBelongsToMany relationships

Add Behavior to model (only necessary for HABTM and HasMany):

Initialization Tips

These different initialization options are combined in the setup array. Defaults are shown below.

		'actions' => array('index'),
		'defaults' => array(),
		'fieldFormatting' => array(
			'string'	=> "LIKE '%%%s%%'",
			'text'		=> "LIKE '%%%s%%'",
			'datetime'	=> "LIKE '%%%s%%'"
		'formOptionsDatetime' => array(),
		'paginatorParams' => array(
		'parsed' => false,
		'redirect' => false,
		'useTime' => false,
		'separator' => '/',
		'rangeSeparator' => '-',
		'url' => array(),
		'whitelist' => array()
  • actions: Array of actions upon which this component will act upon.
  • defaults: Holds pagination defaults for controller actions. (syntax is array('Model' => array('key' => 'value'))
  • fieldFormatting: 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
  • url: Url variable used in paginate helper (syntax is array('url'=>$url));
  • whitelist: Array of fields and models for which this component may filter


  1. Better code commenting - Done, left to help enforce the habit
  2. Support Datetime Done
  3. Support URL redirects and parsing Done
  4. Refactor datetime filtering for ranges Done
  5. Allow the action to be configurable Done
  6. Support jQuery Datepicker Outside scope
  7. Support Router prefixes, plugins, and named parameters in a "scope" instead of "actions" key.
  8. Expand hasMany and hasAndBelongsToMany support. Refactor behavior to conform with established practices.