diff --git a/src/Model/Behavior/SequenceBehavior.php b/src/Model/Behavior/SequenceBehavior.php index f0d6d48..da4d601 100644 --- a/src/Model/Behavior/SequenceBehavior.php +++ b/src/Model/Behavior/SequenceBehavior.php @@ -73,6 +73,13 @@ class SequenceBehavior extends Behavior 'start' => 1, ]; + /** + * Old values for the entity being deleted + * + * @var array|null + */ + protected $_oldValues; + /** * Normalize config options. * @@ -235,14 +242,33 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) */ public function beforeDelete(Event $event, Entity $entity) { + $this->_oldValues = $this->_getOldValues($entity); + } + + /** + * When you delete a record from a set, you need to decrement the order of all + * records that were after it in the set. + * + * @param \Cake\Event\Event $event The afterDelete event that was fired. + * @param \Cake\ORM\Entity $entity The entity that has been deleted. + * + * @return void + */ + public function afterDelete(Event $event, Entity $entity) + { + if (!$this->_oldValues) { + return; + } + $orderField = $this->_config['order']; - list($order, $scope) = $this->_getOldValues($entity); + list($order, $scope) = $this->_oldValues; $this->_sync( [$orderField => $this->_getUpdateExpression('-')], [$orderField . ' >' => $order], $scope ); + $this->_oldValues = null; } /** diff --git a/tests/Fixture/UniqueItemsFixture.php b/tests/Fixture/UniqueItemsFixture.php new file mode 100644 index 0000000..4f25ba8 --- /dev/null +++ b/tests/Fixture/UniqueItemsFixture.php @@ -0,0 +1,35 @@ + ['type' => 'integer'], + 'name' => ['type' => 'string', 'null' => true], + 'position' => ['type' => 'integer', 'null' => true], + '_constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id']], + 'position' => ['type' => 'unique', 'columns' => ['position']], + ], + ]; + + /** + * records property. + * + * @var array + */ + public $records = [ + ['name' => 'Item A', 'position' => 0], + ['name' => 'Item B', 'position' => 1], + ['name' => 'Item C', 'position' => 2], + ['name' => 'Item D', 'position' => 3], + ['name' => 'Item E', 'position' => 4], + ]; +} diff --git a/tests/TestCase/Model/Behavior/SequenceBehaviorTest.php b/tests/TestCase/Model/Behavior/SequenceBehaviorTest.php index f2e2386..180af97 100644 --- a/tests/TestCase/Model/Behavior/SequenceBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/SequenceBehaviorTest.php @@ -44,12 +44,21 @@ public function initialize(array $config) } } +class UniqueItems extends Table +{ + public function initialize(array $config) + { + $this->addBehavior('ADmad/Sequence.Sequence', ['start' => 0]); + } +} + class SequenceTest extends TestCase { public $fixtures = [ 'plugin.ADmad/Sequence.Items', 'plugin.ADmad/Sequence.GroupedItems', 'plugin.ADmad/Sequence.KeywordItems', + 'plugin.ADmad/Sequence.UniqueItems' ]; /** @@ -241,6 +250,16 @@ public function testDelete() $this->assertOrder([1, 2, 4, 5], $GroupedItems, ['group_field' => 1]); $this->assertOrder([6, 7, 8, 9, 10], $GroupedItems, ['group_field' => 2]); $this->assertOrder([11, 12, 13, 14, 15], $GroupedItems, ['group_field' => 3]); + + $UniqueItems = TableRegistry::get('UniqueItems', [ + 'table' => 'unique_items', + 'alias' => 'UniqueItems', + 'className' => 'ADmad\Sequence\Test\TestCase\Model\Behavior\UniqueItems', + ]); + + $entity = $UniqueItems->get(3); + $UniqueItems->delete($entity); + $this->assertOrder([1, 2, 4, 5], $UniqueItems); } /**