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 @@ -3061,6 +3061,8 @@ 'PhabricatorEditPage' => 'applications/transactions/editengine/PhabricatorEditPage.php', 'PhabricatorEditType' => 'applications/transactions/edittype/PhabricatorEditType.php', 'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php', + 'PhabricatorEditorExtension' => 'applications/transactions/engineextension/PhabricatorEditorExtension.php', + 'PhabricatorEditorExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditorExtensionModule.php', 'PhabricatorEditorMailEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditorMailEngineExtension.php', 'PhabricatorEditorMultipleSetting' => 'applications/settings/setting/PhabricatorEditorMultipleSetting.php', 'PhabricatorEditorSetting' => 'applications/settings/setting/PhabricatorEditorSetting.php', @@ -8927,6 +8929,8 @@ 'PhabricatorEditPage' => 'Phobject', 'PhabricatorEditType' => 'Phobject', 'PhabricatorEditor' => 'Phobject', + 'PhabricatorEditorExtension' => 'Phobject', + 'PhabricatorEditorExtensionModule' => 'PhabricatorConfigModule', 'PhabricatorEditorMailEngineExtension' => 'PhabricatorMailEngineExtension', 'PhabricatorEditorMultipleSetting' => 'PhabricatorSelectSetting', 'PhabricatorEditorSetting' => 'PhabricatorStringSetting', diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -88,6 +88,7 @@ private $hasRequiredMFA = false; private $request; private $cancelURI; + private $extensions; const STORAGE_ENCODING_BINARY = 'binary'; @@ -1013,6 +1014,7 @@ } $errors[] = $this->validateAllTransactions($object, $xactions); + $errors[] = $this->validateTransactionsWithExtensions($object, $xactions); $errors = array_mergev($errors); $continue_on_missing = $this->getContinueOnMissingFields(); @@ -4975,4 +4977,60 @@ return $xactions; } + +/* -( Extensions )--------------------------------------------------------- */ + + + private function validateTransactionsWithExtensions( + PhabricatorLiskDAO $object, + array $xactions) { + $errors = array(); + + $extensions = $this->getEditorExtensions(); + foreach ($extensions as $extension) { + $extension_errors = $extension + ->setObject($object) + ->validateTransactions($object, $xactions); + + assert_instances_of( + $extension_errors, + 'PhabricatorApplicationTransactionValidationError'); + + $errors[] = $extension_errors; + } + + return array_mergev($errors); + } + + private function getEditorExtensions() { + if ($this->extensions === null) { + $this->extensions = $this->newEditorExtensions(); + } + return $this->extensions; + } + + private function newEditorExtensions() { + $extensions = PhabricatorEditorExtension::getAllExtensions(); + + $actor = $this->getActor(); + $object = $this->object; + foreach ($extensions as $key => $extension) { + + $extension = id(clone $extension) + ->setViewer($actor) + ->setEditor($this) + ->setObject($object); + + if (!$extension->supportsObject($this, $object)) { + unset($extensions[$key]); + continue; + } + + $extensions[$key] = $extension; + } + + return $extensions; + } + + } diff --git a/src/applications/transactions/engineextension/PhabricatorEditorExtension.php b/src/applications/transactions/engineextension/PhabricatorEditorExtension.php new file mode 100644 --- /dev/null +++ b/src/applications/transactions/engineextension/PhabricatorEditorExtension.php @@ -0,0 +1,83 @@ +getPhobjectClassConstant('EXTENSIONKEY'); + } + + final public function setEditor( + PhabricatorApplicationTransactionEditor $editor) { + $this->editor = $editor; + return $this; + } + + final public function getEditor() { + return $this->editor; + } + + final public function setViewer(PhabricatorUser $viewer) { + $this->viewer = $viewer; + return $this; + } + + final public function getViewer() { + return $this->viewer; + } + + final public function setObject( + PhabricatorApplicationTransactionInterface $object) { + $this->object = $object; + return $this; + } + + final public static function getAllExtensions() { + return id(new PhutilClassMapQuery()) + ->setAncestorClass(__CLASS__) + ->setUniqueMethod('getExtensionKey') + ->execute(); + } + + abstract public function getExtensionName(); + + public function supportsObject( + PhabricatorApplicationTransactionEditor $editor, + PhabricatorApplicationTransactionInterface $object) { + return true; + } + + public function validateTransactions($object, array $xactions) { + return array(); + } + + final protected function newTransactionError( + PhabricatorApplicationTransaction $xaction, + $title, + $message) { + return new PhabricatorApplicationTransactionValidationError( + $xaction->getTransactionType(), + $title, + $message, + $xaction); + } + + final protected function newRequiredTransasctionError( + PhabricatorApplicationTransaction $xaction, + $message) { + return $this->newError($xaction, pht('Required'), $message) + ->setIsMissingFieldError(true); + } + + final protected function newInvalidTransactionError( + PhabricatorApplicationTransaction $xaction, + $message) { + return $this->newTransactionError($xaction, pht('Invalid'), $message); + } + + +} diff --git a/src/applications/transactions/engineextension/PhabricatorEditorExtensionModule.php b/src/applications/transactions/engineextension/PhabricatorEditorExtensionModule.php new file mode 100644 --- /dev/null +++ b/src/applications/transactions/engineextension/PhabricatorEditorExtensionModule.php @@ -0,0 +1,40 @@ +getViewer(); + + $extensions = PhabricatorEditorExtension::getAllExtensions(); + + $rows = array(); + foreach ($extensions as $extension) { + $rows[] = array( + get_class($extension), + $extension->getExtensionName(), + ); + } + + return id(new AphrontTableView($rows)) + ->setHeaders( + array( + pht('Class'), + pht('Name'), + )) + ->setColumnClasses( + array( + null, + 'wide pri', + )); + } + +}