From 2ec46289d83af88e987fb72c426e856e1d9dd7bc Mon Sep 17 00:00:00 2001 From: Aaron Bird Date: Sat, 29 Dec 2018 13:08:30 +0000 Subject: [PATCH 1/5] handling composite key support --- src/Model/Behavior/DuplicatableBehavior.php | 39 +++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/Model/Behavior/DuplicatableBehavior.php b/src/Model/Behavior/DuplicatableBehavior.php index 21dc089..f83f07d 100644 --- a/src/Model/Behavior/DuplicatableBehavior.php +++ b/src/Model/Behavior/DuplicatableBehavior.php @@ -35,7 +35,8 @@ class DuplicatableBehavior extends Behavior 'set' => [], 'prepend' => [], 'append' => [], - 'saveOptions' => [] + 'saveOptions' => [], + 'preserveKeyFromCompositeKey' => '' ]; /** @@ -179,12 +180,14 @@ protected function _modifyEntity(EntityInterface $entity, $object) if ($object instanceof BelongsToMany) { unset($entity->_joinData); } else { + // unset primary key - unset($entity->{$object->getPrimaryKey()}); + $this->removePrimaryKey($entity, $object); // unset foreign key if ($object instanceof Association) { - unset($entity->{$object->getPrimaryKey()}); + // unset primary key + $this->removePrimaryKey($entity, $object); } } @@ -329,4 +332,34 @@ protected function _doAction($action, EntityInterface $entity, $prop, $value = n break; } } + + /** + * Removes the primary key from the entity being duplicated. If the entity has a composite key, you must + * specify which field we wish to preserve + * + * @param EntityInterface $entity + * @param $object + * @throws \Exception + */ + protected function removePrimaryKey(EntityInterface $entity, $object) + { + if (is_array($object->getPrimaryKey())) { + + $compositeKey = $object->getPrimaryKey(); + + $keyToPreserve = $this->getConfig('preserveKeyFromCompositeKey'); + + if(!in_array($keyToPreserve, $compositeKey)){ + throw new \Exception('You must specify which key to preserve when duplicating composite keys'); + } + + foreach ($compositeKey as $pkField){ + if ($pkField != $keyToPreserve) { + unset($entity->{$pkField}); + } + } + } else { + unset($entity->{$object->getPrimaryKey()}); + } + } } From 1f7f1a288230e1585204f58c0715a3866f8cb0f4 Mon Sep 17 00:00:00 2001 From: Aaron Bird Date: Sat, 29 Dec 2018 13:08:46 +0000 Subject: [PATCH 2/5] updating doc block --- src/Model/Behavior/DuplicatableBehavior.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Model/Behavior/DuplicatableBehavior.php b/src/Model/Behavior/DuplicatableBehavior.php index f83f07d..511e24a 100644 --- a/src/Model/Behavior/DuplicatableBehavior.php +++ b/src/Model/Behavior/DuplicatableBehavior.php @@ -173,6 +173,7 @@ protected function _getContain() * @param \Cake\Datasource\EntityInterface $entity Entity * @param \Cake\ORM\Table|\Cake\ORM\Association $object Table or association instance. * @return void + * @throws \Exception */ protected function _modifyEntity(EntityInterface $entity, $object) { From dff01d2bc027a8213dbc322294a017c72fe723c7 Mon Sep 17 00:00:00 2001 From: Aaron Bird Date: Sun, 30 Dec 2018 09:29:23 +0000 Subject: [PATCH 3/5] changing preserve key to an array --- src/Model/Behavior/DuplicatableBehavior.php | 34 ++++++++++++--------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/Model/Behavior/DuplicatableBehavior.php b/src/Model/Behavior/DuplicatableBehavior.php index 511e24a..ed66378 100644 --- a/src/Model/Behavior/DuplicatableBehavior.php +++ b/src/Model/Behavior/DuplicatableBehavior.php @@ -19,6 +19,7 @@ * - set: fields and their default value * - prepend: fields and text to prepend * - append: fields and text to append + * - keysToPreserve: only used in the case of composite keys. Provide any keys which the behavior should preserve and not unset */ class DuplicatableBehavior extends Behavior { @@ -36,7 +37,7 @@ class DuplicatableBehavior extends Behavior 'prepend' => [], 'append' => [], 'saveOptions' => [], - 'preserveKeyFromCompositeKey' => '' + 'keysToPreserve' => [] ]; /** @@ -55,6 +56,7 @@ public function duplicate($id) * * @param int|string $id Id of entity to duplicate. * @return \Cake\Datasource\EntityInterface + * @throws \Exception */ public function duplicateEntity($id) { @@ -210,6 +212,7 @@ protected function _modifyEntity(EntityInterface $entity, $object) * @param \Cake\ORM\Table|\Cake\ORM\Association $object Table or association instance. * @param array $parts Related properties chain. * @return void + * @throws \Exception */ protected function _drillDownAssoc(EntityInterface $entity, $object, array $parts) { @@ -336,7 +339,7 @@ protected function _doAction($action, EntityInterface $entity, $prop, $value = n /** * Removes the primary key from the entity being duplicated. If the entity has a composite key, you must - * specify which field we wish to preserve + * specify which field(s) we wish to preserve * * @param EntityInterface $entity * @param $object @@ -344,23 +347,26 @@ protected function _doAction($action, EntityInterface $entity, $prop, $value = n */ protected function removePrimaryKey(EntityInterface $entity, $object) { - if (is_array($object->getPrimaryKey())) { - $compositeKey = $object->getPrimaryKey(); + $primaryKey = $object->getPrimaryKey(); - $keyToPreserve = $this->getConfig('preserveKeyFromCompositeKey'); + if (!is_array($primaryKey)) { + unset($entity->{$primaryKey}); + return; + } - if(!in_array($keyToPreserve, $compositeKey)){ - throw new \Exception('You must specify which key to preserve when duplicating composite keys'); - } + $keysToPreserve = $this->getConfig('keysToPreserve'); - foreach ($compositeKey as $pkField){ - if ($pkField != $keyToPreserve) { - unset($entity->{$pkField}); - } + $commonKeys = array_intersect($keysToPreserve, $primaryKey); + + if (empty($keysToPreserve) || empty($commonKeys)) { + throw new \Exception('You must specify which key to preserve when duplicating composite keys'); + } + + foreach ($primaryKey as $pkField) { + if (!in_array($pkField, $keysToPreserve)) { + unset($entity->{$pkField}); } - } else { - unset($entity->{$object->getPrimaryKey()}); } } } From cc1400c6704602e711c22ac52e792ecf1e6d538b Mon Sep 17 00:00:00 2001 From: Aaron Bird Date: Sun, 30 Dec 2018 09:34:20 +0000 Subject: [PATCH 4/5] adding missing doc block throws tag --- src/Model/Behavior/DuplicatableBehavior.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Model/Behavior/DuplicatableBehavior.php b/src/Model/Behavior/DuplicatableBehavior.php index ed66378..6967c07 100644 --- a/src/Model/Behavior/DuplicatableBehavior.php +++ b/src/Model/Behavior/DuplicatableBehavior.php @@ -45,6 +45,7 @@ class DuplicatableBehavior extends Behavior * * @param int|string $id Id of entity to duplicate. * @return \Cake\Datasource\EntityInterface New entity or false on failure + * @throws \Exception */ public function duplicate($id) { From 2e691c4086a6bf344a1838cfa215e656f234ab25 Mon Sep 17 00:00:00 2001 From: Aaron Bird Date: Sun, 30 Dec 2018 09:36:06 +0000 Subject: [PATCH 5/5] removing empty line --- src/Model/Behavior/DuplicatableBehavior.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Model/Behavior/DuplicatableBehavior.php b/src/Model/Behavior/DuplicatableBehavior.php index 6967c07..84b33c6 100644 --- a/src/Model/Behavior/DuplicatableBehavior.php +++ b/src/Model/Behavior/DuplicatableBehavior.php @@ -348,7 +348,6 @@ protected function _doAction($action, EntityInterface $entity, $prop, $value = n */ protected function removePrimaryKey(EntityInterface $entity, $object) { - $primaryKey = $object->getPrimaryKey(); if (!is_array($primaryKey)) {