3.7.7 Callbacks

Se você quer colocar alguma lógica antes ou depois de uma operação do model, use as funções de callback do model. Estas funções podem ser definidas na classe do model (incluindo seu AppModel). Certifique-se de notar o valor retornado para cada uma dessas funções especiais.

beforeFind(mixed $queryData)

Chamada antes de qualquer operação de busca. A variável $queryData contém informações sobre a busca atual, como: condições (conditions), campos (fields), etc.

Se você não quer que a busca inicie (possivelmente relacionada a alguma decisão tomada em cima da $queryData), retorne false.

Você pode usar este callback para restringir funções de busca baseada em regras de usuários ou guardar informações da busca atual.

afterFind(array $results)

Use este callback para modificar os resultados de uma busca realizada ou tomar decisões baseada nos resultados. O parâmetro $results contém as informações retornadas da busca.

O valor do retorno dessa função (possivelmente modificado) deve ser o retorno que você deseja para a busca.

Esta função pode ser usada para melhorar a apresentação dos dados, como formatação de moedas.

beforeValidate()

Use esta função de callback para alterar os dados antes de serem validados. Esta função também pode ser usada para adicionar algo, para validações mais complexas, usando o Model::invalidate(). Neste contexto, os dados são acessados via $this->data. Esta função deve retornar true, senão o método save() será abortado.

beforeSave()

Local para colocar a lógica que vai antes de salvar. Esta função executa imediatamente depois dos dados serem validados como verdadeiros, mas antes de serem salvos. Você deve retornar true se deseja continuar o processo.

Essa função de callback é especialmente para você manipular seus dados antes de serem armazenados. Se o seu banco de dados necessita de alguma formatação especial de data, por exemplo, você deve fazê-la antes de salvar.

afterSave(boolean $created)

Se você tem alguma lógica a ser colocada depois que os dados são salvos, o lugar é nesta função de callback.

O valor de $created será true se você estiver inserindo um novo registro, caso contrário é um update.

beforeDelete()

Local para colocar a lógica que vai antes de excluir. Você deve retornar true se deseja continuar o processo.

afterDelete()

Coloque nesta função de callback toda a lógica que você quer que execute após as operações de exclusão.

onError()

Chamada caso ocorra qualquer problema.

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',
    ),
  ),
);
  1. $results = array(
  2. 0 => array(
  3. 'ModelName' => array(
  4. 'field1' => 'value1',
  5. 'field2' => 'value2',
  6. ),
  7. ),
  8. );

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'
);
  1. $results = array(
  2. 'field_1' => 'value',
  3. 'field_2' => 'value2'
  4. );

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));
}
  1. function afterFind($results) {
  2. foreach ($results as $key => $val) {
  3. if (isset($val['Event']['begindate'])) {
  4. $results[$key]['Event']['begindate'] = $this->dateFormatAfterFind($val['Event']['begindate']);
  5. }
  6. }
  7. return $results;
  8. }
  9. function dateFormatAfterFind($dateString) {
  10. return date('d-m-Y', strtotime($dateString));
  11. }

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 
}
  1. function beforeSave() {
  2. if(!empty($this->data['Event']['begindate']) && !empty($this->data['Event']['enddate'])) {
  3. $this->data['Event']['begindate'] = $this->dateFormatBeforeSave($this->data['Event']['begindate']);
  4. $this->data['Event']['enddate'] = $this->dateFormat($this->data['Event']['enddate']);
  5. }
  6. return true;
  7. }
  8. function dateFormatBeforeSave($dateString) {
  9. return date('Y-m-d', strtotime($dateString)); // Direction is from
  10. }

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.