diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2613,6 +2613,7 @@ 'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php', 'PhabricatorBaseURISetupCheck' => 'applications/config/check/PhabricatorBaseURISetupCheck.php', 'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php', + 'PhabricatorBeforeDestructionEngineExtension' => 'applications/system/engine/PhabricatorBeforeDestructionEngineExtension.php', 'PhabricatorBinariesSetupCheck' => 'applications/config/check/PhabricatorBinariesSetupCheck.php', 'PhabricatorBitbucketAuthProvider' => 'applications/auth/provider/PhabricatorBitbucketAuthProvider.php', 'PhabricatorBoardColumnsSearchEngineAttachment' => 'applications/project/engineextension/PhabricatorBoardColumnsSearchEngineAttachment.php', @@ -8974,6 +8975,7 @@ 'PhabricatorBarePageView' => 'AphrontPageView', 'PhabricatorBaseURISetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher', + 'PhabricatorBeforeDestructionEngineExtension' => 'Phobject', 'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider', 'PhabricatorBoardColumnsSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment', diff --git a/src/applications/system/engine/PhabricatorBeforeDestructionEngineExtension.php b/src/applications/system/engine/PhabricatorBeforeDestructionEngineExtension.php new file mode 100644 --- /dev/null +++ b/src/applications/system/engine/PhabricatorBeforeDestructionEngineExtension.php @@ -0,0 +1,54 @@ +getPhobjectClassConstant('EXTENSIONKEY'); + } + + /** + * Get the extension human name. + * + * @return string + */ + abstract public function getExtensionName(): string; + + /** + * Check whenever your extension supports a "Berfore Destruction" hook + * on the specified object. + */ + public function canBeforeDestroyObject( + PhabricatorDestructionEngine $destruction_engine, + $object): bool { + return true; + } + + /** + * Call your "Berfore Destruction" hook on the specified object. + * The object is guaranteed to be consistent with canBeforeDestroyObject(). + */ + abstract public function beforeDestroyObject( + PhabricatorDestructionEngine $engine, + $object); + + /** + * Get all "Before Destruction Engine" extensions. + */ + final public static function getAllExtensions(): array { + $map = new PhutilClassMapQuery(); + return $map + ->setAncestorClass(__CLASS__) + ->setUniqueMethod('getExtensionKey') + ->execute(); + } + +} diff --git a/src/applications/system/engine/PhabricatorDestructionEngine.php b/src/applications/system/engine/PhabricatorDestructionEngine.php --- a/src/applications/system/engine/PhabricatorDestructionEngine.php +++ b/src/applications/system/engine/PhabricatorDestructionEngine.php @@ -73,6 +73,17 @@ } } + if ($object_phid) { + // Allow extension to do something before the destruction. + $before_extensions = + PhabricatorBeforeDestructionEngineExtension::getAllExtensions(); + foreach ($before_extensions as $key => $before_extension) { + if ($before_extension->canBeforeDestroyObject($this, $object)) { + $before_extension->beforeDestroyObject($this, $object); + } + } + } + $object->destroyObjectPermanently($this); if ($object_phid) {