I'm attending CakeFest 2010!

3.6.4.2 MVC Class Access Within Components

Components feature a number of callbacks used by the parent controller class. Judicious use of these callbacks can make creating and using components much easier.

initialize(&$controller, $settings=array())

The initialize method is called before the controller's beforeFilter method.

startup(&$controller)

The startup method is called after the controller's beforeFilter method but before the controller executes the current action handler.

beforeRender(&$controller)

The beforeRender method is called after the controller executes the requested action's logic but before the controller's renders views and layout.

shutdown(&$controller)

The shutdown method is called before output is sent to browser.

beforeRedirect(&$controller, $url, $status=null, $exit=true)

The beforeRedirect method is invoked when the controller's redirect method is called but before any further action. If this method returns false the controller will not continue on to redirect the request. The $url, $status and $exit variables have same meaning as for the controller's method.

Here is a skeleton component you can use as a template for your own custom components.

<?php
class SkeletonComponent extends Object {
	//called before Controller::beforeFilter()
	function initialize(&$controller, $settings = array()) {
		// saving the controller reference for later use
		$this->controller =& $controller;
	}

	//called after Controller::beforeFilter()
	function startup(&$controller) {
	}

	//called after Controller::beforeRender()
	function beforeRender(&$controller) {
	}

	//called after Controller::render()
	function shutdown(&$controller) {
	}

	//called before Controller::redirect()
	function beforeRedirect(&$controller, $url, $status=null, $exit=true) {
	}

	function redirectSomewhere($value) {
		// utilizing a controller method
		$this->controller->redirect($value);
	}
}
?>
  1. <?php
  2. class SkeletonComponent extends Object {
  3. //called before Controller::beforeFilter()
  4. function initialize(&$controller, $settings = array()) {
  5. // saving the controller reference for later use
  6. $this->controller =& $controller;
  7. }
  8. //called after Controller::beforeFilter()
  9. function startup(&$controller) {
  10. }
  11. //called after Controller::beforeRender()
  12. function beforeRender(&$controller) {
  13. }
  14. //called after Controller::render()
  15. function shutdown(&$controller) {
  16. }
  17. //called before Controller::redirect()
  18. function beforeRedirect(&$controller, $url, $status=null, $exit=true) {
  19. }
  20. function redirectSomewhere($value) {
  21. // utilizing a controller method
  22. $this->controller->redirect($value);
  23. }
  24. }
  25. ?>

You might also want to utilize other components inside a custom component. To do so, just create a $components class variable (just like you would in a controller) as an array that holds the names of components you wish to utilize.

<?php
class MyComponent extends Object {

	// This component uses other components
	var $components = array('Session', 'Math');

	function doStuff() {
		$result = $this->Math->doComplexOperation(1, 2);
		$this->Session->write('stuff', $result);
	}

}
?>
  1. <?php
  2. class MyComponent extends Object {
  3. // This component uses other components
  4. var $components = array('Session', 'Math');
  5. function doStuff() {
  6. $result = $this->Math->doComplexOperation(1, 2);
  7. $this->Session->write('stuff', $result);
  8. }
  9. }
  10. ?>

To access/use a model in a component is not generally recommended; If you end up needing one, you'll need to instantiate your model class and use it manually. Here's an example:

<?php
class MathComponent extends Object {
	function doComplexOperation($amount1, $amount2) {
		return $amount1 + $amount2;
	}

	function doReallyComplexOperation ($amount1, $amount2) {
		$userInstance = ClassRegistry::init('User');
		$totalUsers = $userInstance->find('count');
		return ($amount1 + $amount2) / $totalUsers;
	}
}
?>
  1. <?php
  2. class MathComponent extends Object {
  3. function doComplexOperation($amount1, $amount2) {
  4. return $amount1 + $amount2;
  5. }
  6. function doReallyComplexOperation ($amount1, $amount2) {
  7. $userInstance = ClassRegistry::init('User');
  8. $totalUsers = $userInstance->find('count');
  9. return ($amount1 + $amount2) / $totalUsers;
  10. }
  11. }
  12. ?>