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 'scope' => '1 = 1', 'type' => 'nested', '__parentChange' => false, 'recursive' => -1
); );
/**
* Used to preserve state between delete callbacks.
*
* @var array
*/
protected $_deletedRow = null;
/** /**
* Initiate Tree behavior * 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 Model $Model Model instance
* @param boolean $cascade * @param boolean $cascade
* @return boolean true to continue, false to abort the delete * @return boolean
*/ */
public function beforeDelete(Model $Model, $cascade = true) { public function beforeDelete(Model $Model, $cascade = true) {
extract($this->settings[$Model->alias]); extract($this->settings[$Model->alias]);
@ -121,6 +128,22 @@ class TreeBehavior extends ModelBehavior {
'conditions' => array($Model->alias . '.' . $Model->primaryKey => $Model->id), 'conditions' => array($Model->alias . '.' . $Model->primaryKey => $Model->id),
'fields' => array($Model->alias . '.' . $left, $Model->alias . '.' . $right), 'fields' => array($Model->alias . '.' . $left, $Model->alias . '.' . $right),
'recursive' => -1))); '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]) { if (!$data[$right] || !$data[$left]) {
return true; return true;