Components
Introduction
Components are packages of logic that are shared between controllers. If you find yourself wanting to copy and paste things between controllers, you might consider wrapping some functionality in a component.
CakePHP also comes with a fantastic set of core components you can use to aid in:
- Security
- Sessions
- Access control lists
- Emails
- Cookies
- Authentication
- Request handling
Each of these core components are detailed in their own chapters. For now, we’ll show you how to create your own components. Creating components keeps controller code clean and allows you to reuse code between projects.
Creating Custom Components
Suppose our online application needs to perform a complex mathematical operation in many different parts of the application. We could create a component to house this shared logic for use in many different controllers.
The first step is to create a new component file and class. Create the file in /app/controllers/components/math.php. The basic structure for the component would look something like this.
<?php
class MathComponent extends Object {
function doComplexOperation($amount1, $amount2) {
return $amount1 + $amount2;
}
}
?>
<?phpclass MathComponent extends Object {function doComplexOperation($amount1, $amount2) {return $amount1 + $amount2;}}?>
Once our component is finished, we can use it in the application’s controllers by placing the components name in the controller’s $components arrays.
//Make the new component available at $this->Math
var $components = array('Math', 'Session');
//Make the new component available at $this->Mathvar $components = array('Math', 'Session');
MVC Class Access Within Components
To get access to the controller instance from within your newly created component, you’ll need to implement the startup() method. This special method takes a reference to the controller as its first parameter, and is automatically called after the controller’s beforeFilter() method. If for some reason you do not want the startup() method called when the controller is setting things up, set the class variable $disableStartup to true.
If you want to insert some logic before a controller’s beforeFilter() has been called, use the initialize() method of the component.
<?php
class MathComponent extends Object {
//called before Controller:beforeFilter()
function initialize() {
}
//called after Controller::beforeFilter()
function startup(&$controller) {
}
function doComplexOperation($amount1, $amount2) {
return $amount1 + $amount2;
}
}
?> <?phpclass MathComponent extends Object {//called before Controller:beforeFilter()function initialize() {}//called after Controller::beforeFilter()function startup(&$controller) {}function doComplexOperation($amount1, $amount2) {return $amount1 + $amount2;}}?>
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.
To access/use a model in a component is not generally recommended; however if weighing the possibilities this is what you want to do you'll need to instanciate your model class and use it manually. Here's an example:
<?php
class MathComponent extends Object {
//called before Controller:beforeFilter()
function initialize() {
}
//called after Controller::beforeFilter()
function startup(&$controller) {
// Saving a reference to the controller on the component instance
$this->controller =& $controller;
}
function doComplexOperation($amount1, $amount2) {
return $amount1 + $amount2;
}
function doUberComplexOperation ($amount1, $amount2) {
$userInstance = ClassRegistry::init('User');
$totalUsers = $userInstance->find('count');
return ($amount1 + $amount2) / $totalUsers;
}
}
?> <?phpclass MathComponent extends Object {//called before Controller:beforeFilter()function initialize() {}//called after Controller::beforeFilter()function startup(&$controller) {// Saving a reference to the controller on the component instance$this->controller =& $controller;}function doComplexOperation($amount1, $amount2) {return $amount1 + $amount2;}function doUberComplexOperation ($amount1, $amount2) {$userInstance = ClassRegistry::init('User');$totalUsers = $userInstance->find('count');return ($amount1 + $amount2) / $totalUsers;}}?>

By thewoodman on 22/2/08
1 - Reorder in TOC?
Surely Components should come under Controllers, rather than come on the same level as the M, V and C chapters?
Alternatives would be to move components into a section under Controllers, like "Extending controllers - Components,"
And Models could have "Extending Models - Behaviours"
Or to put all the extensions afterwards, i.e
Extending Controllers with Components, Extending Models with Behaviours, etc
login to add a comment