3.6.2 Creare Componenti personalizzati
Immagina che la tua applicazione debba risolvere un'operazione matematica complessa in diverse parti dell'applicazione. Possiamo creare un componente che esegue l'operazione e riutilizzarlo in diversi controller.
Il primo passo è creare un nuovo file e una classe per il componente. Il file deve essere creato in /app/controllers/components/math.php. La struttura di base del componente è simile a questa.
<?php
class MathComponent extends Object {
function eseguiOperazioneComplessa($parametro1, $parametro2) {
return $parametro1+ $parametro2;
}
}
?>
<?phpclass MathComponent extends Object {function eseguiOperazioneComplessa($parametro1, $parametro2) {return $parametro1+ $parametro2;}}?>
Una volta terminato il componente, lo possiamo usare nel controller semplicemente aggiungendo il suo nome nell'array $components del controller stesso
//Questo rende disponibile il componente tramite la sintassi $this->Math
var $components = array('Math', 'Session');
//Questo rende disponibile il componente tramite la sintassi $this->Mathvar $components = array('Math', 'Session');
3.6.2.1 Including Components in your Controllers
Once our component is finished, we can use it in the application’s controllers by placing the component's name (minus the "Component" part) in the controller’s $components array. The controller will automatically be given a new attribute named after the component, through which we can access an instance of it:
/* Make the new component available at $this->Math,
as well as the standard $this->Session */
var $components = array('Math', 'Session');
/* Make the new component available at $this->Math,as well as the standard $this->Session */var $components = array('Math', 'Session');
Components declared in AppController will be merged with those in your other controllers. So there is no need to redeclare the same component twice.
When including Components in a Controller you can also declare a set of parameters that will be passed onto the Components initialize() method. These parameters can then be handled by the Component.
var $components = array( 'Math' => array( 'precision' => 2, 'randomGenerator' => 'srand' ), 'Session', 'Auth' );
var $components = array('Math' => array('precision' => 2,'randomGenerator' => 'srand'),'Session', 'Auth');
The above would pass the array containing precision and randomGenerator to MathComponent's initialize() method as the second parameter.
This syntax is not implemented by any of the Core Components at this time
3.6.2.2 MVC Class Access Within Components
To get access to the controller instance from within your newly created component, you’ll need to implement the initialize() or startup() method. These special methods take a reference to the controller as their first parameter and are automatically called. The initialize method is called before the controller's beforeFilter() method, the startup() method 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, you will need to use the initialize() method of the component.
<?php
class CheckComponent extends Object {
//called before Controller::beforeFilter()
function initialize(&$controller) {
// saving the controller reference for later use
$this->controller =& $controller;
}
//called after Controller::beforeFilter()
function startup(&$controller) {
}
function redirectSomewhere($value) {
// utilizing a controller method
$this->controller->redirect($value);
}
}
?> <?phpclass CheckComponent extends Object {//called before Controller::beforeFilter()function initialize(&$controller) {// saving the controller reference for later use$this->controller =& $controller;}//called after Controller::beforeFilter()function startup(&$controller) {}function redirectSomewhere($value) {// utilizing a controller method$this->controller->redirect($value);}}?>
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);
}
}
?> <?phpclass MyComponent extends Object {// This component uses other componentsvar $components = array('Session', 'Math');function doStuff() {$result = $this->Math->doComplexOperation(1, 2);$this->Session->write('stuff', $result);}}?>
To access/use a model in a component is not generally recommended; however if after weighing the possibilities this is what you want to do, 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 doUberComplexOperation ($amount1, $amount2) {
$userInstance = ClassRegistry::init('User');
$totalUsers = $userInstance->find('count');
return ($amount1 + $amount2) / $totalUsers;
}
}
?> <?phpclass MathComponent extends Object {function doComplexOperation($amount1, $amount2) {return $amount1 + $amount2;}function doUberComplexOperation ($amount1, $amount2) {$userInstance = ClassRegistry::init('User');$totalUsers = $userInstance->find('count');return ($amount1 + $amount2) / $totalUsers;}}?>
