Silverstripe Version: 3.7.3
Question:
I’m a bit confused about how the onBeforeDuplicate / onAfterDuplicate functions are intended to work. If I define these functions on a page object, when the page is duplicated the functions are being called twice:
-
SiteTree.duplicate()
callsparent::duplicate(false)
-
DataObject.duplicate()
creates the new object and then invokesonBeforeDuplicate()
andonAfterDuplicate()
on the clone, with the original record as the argument -
SiteTree.duplicate()
then invokesonBeforeDuplicate()
on the original record, with the clone as the argument, then writes the record to the database, then callsonAfterDuplicate()
in the same way.
For example, say I have these functions in my page class:
public function onBeforeDuplicate($arg) {
SS_Log::log('onBeforeDuplicate called: ' . $this->ID . ', ' . $arg->ID, SS_Log::DEBUG);
}
public function onAfterDuplicate($arg) {
SS_Log::log('onAfterDuplicate called: ' . $this->ID . ', ' . $arg->ID, SS_Log::DEBUG);
}
When I duplicate the page I see this in my logs:
DEBUG at framework/core/Object.php line 1031: onBeforeDuplicate called: 0, 500
DEBUG at framework/core/Object.php line 1031: onAfterDuplicate called: 0, 500
DEBUG at framework/core/Object.php line 1031: onBeforeDuplicate called: 500, 0
DEBUG at framework/core/Object.php line 1031: onAfterDuplicate called: 500, 501
Is it meant to work this way? I want to add some code that runs when a page is duplicated, but I don’t want it to run twice - and I need to know whether $this
is the original record of the clone. The only way I can think to make this work at the moment is to check if $this->ID === 0
. Is there a better way?
Thanks.