Move logic to afterDelete.

Because behavior callbacks are fired first, removing data in the
beforeDelete could result in data loss if the model prevents deletion.

Fixes #2699
This commit is contained in:
mark_story 2012-03-20 22:36:48 -04:00
parent d1cc29f412
commit 01e035f726

View file

@ -47,6 +47,13 @@ class TreeBehavior extends ModelBehavior {
'scope' => '1 = 1', 'type' => 'nested', '__parentChange' => false, 'recursive' => -1
);
/**
* Used to preserve state between delete callbacks.
*
* @var array
*/
protected $_deletedRow = null;
/**
* Initiate Tree behavior
*
@ -107,13 +114,13 @@ class TreeBehavior extends ModelBehavior {
}
/**
* Before delete method. Called before all deletes
* Stores the record about to be deleted.
*
* Will delete the current node and all children using the deleteAll method and sync the table
* This is used to delete child nodes in the afterDelete.
*
* @param Model $Model Model instance
* @param boolean $cascade
* @return boolean true to continue, false to abort the delete
* @return boolean
*/
public function beforeDelete(Model $Model, $cascade = true) {
extract($this->settings[$Model->alias]);
@ -121,6 +128,22 @@ class TreeBehavior extends ModelBehavior {
'conditions' => array($Model->alias . '.' . $Model->primaryKey => $Model->id),
'fields' => array($Model->alias . '.' . $left, $Model->alias . '.' . $right),
'recursive' => -1)));
$this->_deletedRow = $data;
return true;
}
/**
* After delete method.
*
* Will delete the current node and all children using the deleteAll method and sync the table
*
* @param Model $Model Model instance
* @return boolean true to continue, false to abort the delete
*/
public function afterDelete(Model $Model) {
extract($this->settings[$Model->alias]);
$data = $this->_deletedRow;
$this->_deletedRow = null;
if (!$data[$right] || !$data[$left]) {
return true;