Fork me on GitHub
Heads up!
These docs are for Crud v3 - that only works with CakePHP 2.x. For CRUD v4 docs please go to the new documentation site
The CRUD v4 documentation has been completely rewritten, and since CRUD v3 and CRUD v4 API is ~95% identical, it may be worth a look for CRUD v3 users as well until v4 docs are backported for v3.
...toc....

Crud actions and their events

All Crud events always return NULL, any modifications should be done to the CrudEventSubject object ($event->subject)

All Crud events take exactly one parameter, CakeEvent $event

For a list of emitted events, please see the configuration documentation

Global accessible subject properties

The $subject object can be accessed through $event->subject in all event callbacks

Property name Type Description
crud CrudComponent A reference to the CRUD component
controller AppController A reference to the controller handling the current request
collection ComponentCollection The original ComponentCollection that was injected into CrudComponent
model AppModel A reference to the model Crud is working on
modelClass string The modelClass property from the controller - usually the same as the model alias
action string The request action name. This doesn't always match the request objects action property
request CakeRequest A reference to the CakeRequest for the current request
response CakeResponse The current CakeResponse object

Callbacks in the controller

In all these examples there is a call to parent:: in beforeFilter at the end of the method - it is highly recommended to remember to include this.

The Crud->on() method accepts anything that is_callable evaluate to true.

Lambda / Closure in beforeFilter()

This is convenient for for very simple callbacks, or for callbacks shared between multiple actions

It’s recommended to add your callbacks to controller action they need to be used in, as it makes the controller code much more coherent and easier to debug

Don’t put too many lines of logic in a closure callback as it quickly gets messy, and it’s very hard to unit test the isolated behavior of the callback.

<?php
class DemoController extends AppController {

	public function beforeFilter() {
		$this->Crud->on('beforePaginate', function(CakeEvent $event) {
			$event->subject->paginator->settings['conditions'] = array('is_active' => true);
			debug($event->subject->paginator->settings);
		});

		parent::beforeFilter();
	}

}
?>

Method inside the controller

Very much like the Closure example above, except the callback code is in a method of its own, that can be unit tested easier.

The method must be public, since it’s called from outside the scope of the controller.

Pro tip: Prefix your callbacks with _ and CakePHP will prevent the method to be called through the web.

<?php
class DemoController extends AppController {

	public function beforeFilter() {
		$this->Crud->on('beforePaginate', array($this, '_demoCallback'));

		parent::beforeFilter();
	}

	public function _demoCallback(CakeEvent $event) {
		$event->subject->paginator->settings['conditions']['is_active'] = true;
		debug($event->subject->paginator->settings);
	}

}
?>

Overriding implementedEvents() in the controller

You can override the implementedEvents method inside the controller and provide a list of event => callback for Crud.

The key is the Crud event name (Remember all events need the Crud. prefix) and the value is the name of the method in your controller that should be executed.

The method must be public, since it’s called from outside the scope of the controller.

Pro tip: Prefix your callbacks with _ and CakePHP will prevent the method to be called through the web.

<?php
public function implementedEvents() {
	return parent::implementedEvents() + array(
		'Crud.beforeFind' => '_beforeFind',
		'Crud.beforeSave' => '_beforeSave',
	);
}

public function _beforeFind(CakeEvent $event) {

}

public function _beforeSave(CakeEvent $event) {

}
?>

Lambda / Closure inside a specific controller action

Very much like the other Closure examples above.

When implementing callbacks inside the controller action, it’s very important to call the execute in Crud.

This will allow Crud to continue to do it’s magic just as if the method didn’t exist at all in the controller in the first place.

<?php
class DemoController extends AppController {

	public function view($id = null) {
		$this->Crud->on('beforeFind', function(CakeEvent $event) use ($id) {
			$event->subject->query['conditions']['is_active'] = true;
		}

		// Important for the ViewCrudAction to be executed
		return $this->Crud->execute();
	}

}
?>

CrudListener classes

You can attach custom listener classes by simply passing them to the normal controller EventManager

Creating custom listener classes is documented in the custom listeners section

<?php
App::uses('DemoListener', 'Controller/Crud/Listener');

class DemoController extends AppController {

	public function beforeFilter() {
		$this->getEventManager()->attach(new DemoListener());
		parent::beforeFilter();
	}

}
?>



comments powered by Disqus