From 5caeb5c4db9982324f831bbb4b0c53acef57708e Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 23 Aug 2015 07:39:04 -0700 Subject: [PATCH] Allow Nuance source definitions to add actions to source views Summary: Ref T8783. If you have a source (like a "report bug" form), let it put a link (like "View Form") on the source detail page. This also straightens out getting definitions from sources, which had a bug with the modern way we do `PhutilClassMapQuery`. Specifically, if you called the old mechanism on two different sources, they'd return the same definition object, but they need to return different definitions. Test Plan: {F747093} {F747092} Reviewers: chad Reviewed By: chad Maniphest Tasks: T8783 Differential Revision: https://secure.phabricator.com/D13966 --- .../NuanceSourceActionController.php | 2 +- .../controller/NuanceSourceEditController.php | 2 +- .../controller/NuanceSourceViewController.php | 9 ++++++- .../NuancePhabricatorFormSourceDefinition.php | 11 ++++++++ .../nuance/source/NuanceSourceDefinition.php | 19 +++++-------- .../nuance/storage/NuanceSource.php | 27 +++++++++++++++++++ 6 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/applications/nuance/controller/NuanceSourceActionController.php b/src/applications/nuance/controller/NuanceSourceActionController.php index 6e9fabe455..06739cea1e 100644 --- a/src/applications/nuance/controller/NuanceSourceActionController.php +++ b/src/applications/nuance/controller/NuanceSourceActionController.php @@ -13,7 +13,7 @@ final class NuanceSourceActionController extends NuanceController { return new Aphront404Response(); } - $def = NuanceSourceDefinition::getDefinitionForSource($source); + $def = $source->requireDefinition(); $def->setActor($viewer); $response = $def->handleActionRequest($request); diff --git a/src/applications/nuance/controller/NuanceSourceEditController.php b/src/applications/nuance/controller/NuanceSourceEditController.php index 79bc8c94dc..18234bc778 100644 --- a/src/applications/nuance/controller/NuanceSourceEditController.php +++ b/src/applications/nuance/controller/NuanceSourceEditController.php @@ -41,7 +41,7 @@ final class NuanceSourceEditController extends NuanceController { $cancel_uri = $source->getURI(); } - $definition = NuanceSourceDefinition::getDefinitionForSource($source); + $definition = $source->requireDefinition(); $definition->setActor($viewer); $response = $definition->buildEditLayout($request); diff --git a/src/applications/nuance/controller/NuanceSourceViewController.php b/src/applications/nuance/controller/NuanceSourceViewController.php index edff9fb0a1..e902029b11 100644 --- a/src/applications/nuance/controller/NuanceSourceViewController.php +++ b/src/applications/nuance/controller/NuanceSourceViewController.php @@ -77,6 +77,13 @@ final class NuanceSourceViewController extends NuanceController { ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); + $request = $this->getRequest(); + $definition = $source->requireDefinition(); + $source_actions = $definition->getSourceViewActions($request); + foreach ($source_actions as $source_action) { + $actions->addAction($source_action); + } + return $actions; } @@ -90,7 +97,7 @@ final class NuanceSourceViewController extends NuanceController { ->setObject($source) ->setActionList($actions); - $definition = NuanceSourceDefinition::getDefinitionForSource($source); + $definition = $source->requireDefinition(); $properties->addProperty( pht('Source Type'), $definition->getName()); diff --git a/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php b/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php index 2b596cc198..4cc3d7c610 100644 --- a/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php +++ b/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php @@ -15,6 +15,17 @@ final class NuancePhabricatorFormSourceDefinition return 'phabricator-form'; } + public function getSourceViewActions(AphrontRequest $request) { + $actions = array(); + + $actions[] = id(new PhabricatorActionView()) + ->setName(pht('View Form')) + ->setIcon('fa-align-justify') + ->setHref($this->getActionURI()); + + return $actions; + } + public function updateItems() { return null; } diff --git a/src/applications/nuance/source/NuanceSourceDefinition.php b/src/applications/nuance/source/NuanceSourceDefinition.php index 621fa615f9..2c030badfa 100644 --- a/src/applications/nuance/source/NuanceSourceDefinition.php +++ b/src/applications/nuance/source/NuanceSourceDefinition.php @@ -43,18 +43,8 @@ abstract class NuanceSourceDefinition extends Phobject { return $source; } - /** - * Gives a @{class:NuanceSourceDefinition} object for a given - * @{class:NuanceSource}. Note you still need to @{method:setActor} - * before the @{class:NuanceSourceDefinition} object will be useful. - */ - public static function getDefinitionForSource(NuanceSource $source) { - $definitions = self::getAllDefinitions(); - $map = mpull($definitions, null, 'getSourceTypeConstant'); - $definition = $map[$source->getType()]; - $definition->setSourceObject($source); - - return $definition; + public function getSourceViewActions(AphrontRequest $request) { + return array(); } public static function getAllDefinitions() { @@ -286,4 +276,9 @@ abstract class NuanceSourceDefinition extends Phobject { return new Aphront404Response(); } + public function getActionURI($path = null) { + $source_id = $this->getSourceObject()->getID(); + return '/action/'.$source_id.'/'.ltrim($path, '/'); + } + } diff --git a/src/applications/nuance/storage/NuanceSource.php b/src/applications/nuance/storage/NuanceSource.php index 01f0d6e620..6ac04ba33a 100644 --- a/src/applications/nuance/storage/NuanceSource.php +++ b/src/applications/nuance/storage/NuanceSource.php @@ -12,6 +12,8 @@ final class NuanceSource extends NuanceDAO protected $viewPolicy; protected $editPolicy; + private $definition; + protected function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, @@ -62,6 +64,31 @@ final class NuanceSource extends NuanceDAO ->setEditPolicy($edit_policy); } + public function getDefinition() { + if ($this->definition === null) { + $definitions = NuanceSourceDefinition::getAllDefinitions(); + if (isset($definitions[$this->getType()])) { + $definition = clone $definitions[$this->getType()]; + $definition->setSourceObject($this); + $this->definition = $definition; + } + } + + return $this->definition; + } + + public function requireDefinition() { + $definition = $this->getDefinition(); + if (!$definition) { + throw new Exception( + pht( + 'Unable to load source definition implementation for source '. + 'type "%s".', + $this->getType())); + } + return $definition; + } + /* -( PhabricatorApplicationTransactionInterface )------------------------- */