3.7.7 Méthodes de Callbacks du Modèle
Si vous voulez glisser un bout de logique applicative juste avant ou après une opération d’un modèle CakePHP, utilisez les callbacks de modèle. Ces fonctions peuvent être définies dans les classes de modèle (cela comprend également votre classe AppModel). Notez bien les valeurs de retour attendues pour chacune de ces méthodes spéciales.
Appelée avant toute opération de recherche (find()). La variable $queryData passée à ce callback contient des informations concernant la requête courante : conditions, champs etc.
Si vous souhaitez que l’opération de recherche n’ait pas lieu (sur la base possible d’une décision liée aux options de $queryData), retournez false.
Vous pourriez utiliser ce callback afin de restreindre les opérations de recherche d’après un rôle de l’utilisateur, ou décider de la mise en cache d’après la charge actuelle.
Utilisez ce callback pour modifier les résultats qui ont été renvoyés lors d’une opération de recherche, ou pour effectuer toute autre logique post-recherche. Le paramètre $resultats passé à ce callback contient les résultats renvoyés par l’opération de recherche du modèle (find()).
La valeur de retour de ce callback doit être (possibilité de le modifier) le résultat de l’opération de recherche qui à déclenché ce callback.
Ce callback pourrait être utilisé pour mettre en forme des formats de date ou de monnaie.
Utilisez ce callback pour modifier les données du modèle avant qu’elles ne soient validées. Il peut également être utilisé pour ajouter des règles de validation additionnelles plus complexes, en utilisant Model::invalidate(). Dans ce contexte, les données du modèle sont accessibles via $this->data. Cette fonction doit également retourner true, sans quoi l’exécution actuelle de save() sera avortée.
Placez toute la logique pré-sauvegarde dans cette fonction. Cette fonction s’exécute immédiatement après que les données du modèle aient été validées avec succès, et juste avant qu’elles soient sauvegardées. Cette fonction devrait retourner true si vous voulez que l’opération de sauvegarde continue.
Ce callback est particulièrement utile pour toute la logique de mise en forme des données qui doit avoir lieu avant que vos données soient stockées. Si votre application de stockage a besoin de dates dans un format spécifique, accédez y par $this->data et modifiez les.
Si vous avez de la logique qui doit être exécutée juste après chaque opération de sauvegarde, placez la dans cette méthode de callback.
La valeur de $cree sera true si un nouvel objet a été créé (plutôt que mis à jour)
Placez toute logique pré-suppression dans cette fonction. Cette fonction doit renvoyer true si vous souhaitez que la suppression continue, et false si vous voulez l’annuler.
Placez toute logique que vous voulez voir exécutée après chaque suppression dans cette méthode de callback.
Appelée si un problème quelconque survient.
3.7.7.1 beforeFind
beforeFind(mixed $queryData)
Called before any find-related operation. The $queryData passed to this callback contains information about the current query: conditions, fields, etc.
If you do not wish the find operation to begin (possibly based on a decision relating to the $queryData options), return false. Otherwise, return the possibly modified $queryData, or anything you want to get passed to find and its counterparts.
You might use this callback to restrict find operations based on a user’s role, or make caching decisions based on the current load.
3.7.7.2 afterFind
afterFind(array $results, bool $primary)
Use this callback to modify results that have been returned from a find operation, or to perform any other post-find logic. The $results parameter passed to this callback contains the returned results from the model's find operation, i.e. something like:
$results = array(
0 => array(
'ModelName' => array(
'field1' => 'value1',
'field2' => 'value2',
),
),
);
$results = array(0 => array('ModelName' => array('field1' => 'value1','field2' => 'value2',),),);
The return value for this callback should be the (possibly modified) results for the find operation that triggered this callback.
If $primary is false, the format of $results will be a little different than one might expect; instead of the result you would normally get from a find operation, you will get this:
$results = array( 'field_1' => 'value', 'field_2' => 'value2' );
$results = array('field_1' => 'value','field_2' => 'value2');
Code expecting $primary to be true will probably get a "Cannot use string offset as
an array" fatal error from PHP if a recursive find is used.
Below is an example of how afterfind can be used for date formating.
function afterFind($results) {
foreach ($results as $key => $val) {
if (isset($val['Event']['begindate'])) {
$results[$key]['Event']['begindate'] = $this->dateFormatAfterFind($val['Event']['begindate']);
}
}
return $results;
}
function dateFormatAfterFind($dateString) {
return date('d-m-Y', strtotime($dateString));
}
function afterFind($results) {foreach ($results as $key => $val) {if (isset($val['Event']['begindate'])) {$results[$key]['Event']['begindate'] = $this->dateFormatAfterFind($val['Event']['begindate']);}}return $results;}function dateFormatAfterFind($dateString) {return date('d-m-Y', strtotime($dateString));}
3.7.7.3 beforeValidate
beforeValidate()
Use this callback to modify model data before it is validated. It can also be used to add additional, more complex validation rules using Model::invalidate(). In this context, model data is accessible via $this->data. This function must also return true, otherwise the current save() execution will abort.
3.7.7.4 beforeSave
beforeSave()
Place any pre-save logic in this function. This function executes immediately after model data has been successfully validated, but just before the data is saved. This function should also return true if you want the save operation to continue.
This callback is especially handy for any data-massaging logic that needs to happen before your data is stored. If your storage engine needs dates in a specific format, access it at $this->data and modify it.
Below is an example of how beforeSave can be used for date conversion. The code in the example is used for an application with a begindate formatted like YYYY-MM-DD in the database and is displayed like DD-MM-YYYY in the application. Of course this can be changed very easily. Use the code below in the appropriate model.
function beforeSave() {
if(!empty($this->data['Event']['begindate']) && !empty($this->data['Event']['enddate'])) {
$this->data['Event']['begindate'] = $this->dateFormatBeforeSave($this->data['Event']['begindate']);
$this->data['Event']['enddate'] = $this->dateFormat($this->data['Event']['enddate']);
}
return true;
}
function dateFormatBeforeSave($dateString) {
return date('Y-m-d', strtotime($dateString)); // Direction is from
}
function beforeSave() {if(!empty($this->data['Event']['begindate']) && !empty($this->data['Event']['enddate'])) {$this->data['Event']['begindate'] = $this->dateFormatBeforeSave($this->data['Event']['begindate']);$this->data['Event']['enddate'] = $this->dateFormat($this->data['Event']['enddate']);}return true;}function dateFormatBeforeSave($dateString) {return date('Y-m-d', strtotime($dateString)); // Direction is from}
Be sure that beforeSave() returns true, or your save is going to fail.
3.7.7.5 afterSave
afterSave(boolean $created)
If you have logic you need to be executed just after every save operation, place it in this callback method.
The value of $created will be true if a new object was created (rather than an update).
3.7.7.6 beforeDelete
beforeDelete()
Place any pre-deletion logic in this function. This function should return true if you want the deletion to continue, and false if you want to abort.
3.7.7.7 afterDelete
afterDelete()
Place any logic that you want to be executed after every deletion in this callback method.
3.7.7.8 onError
onError()
Called if any problems occur.
