diff --git a/src/applications/maniphest/controller/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/ManiphestTaskDetailController.php --- a/src/applications/maniphest/controller/ManiphestTaskDetailController.php +++ b/src/applications/maniphest/controller/ManiphestTaskDetailController.php @@ -26,6 +26,10 @@ ->setViewer($viewer) ->readFieldsFromStorage($task); + $edit_engine = id(new ManiphestEditEngine()) + ->setViewer($viewer) + ->setTargetObject($task); + $e_commit = ManiphestTaskHasCommitEdgeType::EDGECONST; $e_dep_on = ManiphestTaskDependsOnTaskEdgeType::EDGECONST; $e_dep_by = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST; @@ -73,12 +77,11 @@ $header = $this->buildHeaderView($task); $details = $this->buildPropertyView($task, $field_list, $edges, $handles); $description = $this->buildDescriptionView($task, $engine); - $curtain = $this->buildCurtain($task); + $curtain = $this->buildCurtain($task, $edit_engine); $title = pht('%s %s', $monogram, $task->getTitle()); - $comment_view = id(new ManiphestEditEngine()) - ->setViewer($viewer) + $comment_view = $edit_engine ->buildEditEngineCommentView($task); $timeline->setQuoteRef($monogram); @@ -146,7 +149,9 @@ } - private function buildCurtain(ManiphestTask $task) { + private function buildCurtain( + ManiphestTask $task, + PhabricatorEditEngine $edit_engine) { $viewer = $this->getViewer(); $id = $task->getID(); @@ -176,11 +181,12 @@ ->setDisabled(!$can_edit) ->setWorkflow(true)); - $edit_config = id(new ManiphestEditEngine()) - ->setViewer($viewer) - ->loadDefaultEditConfiguration(); - + $edit_config = $edit_engine->loadDefaultEditConfiguration(); $can_create = (bool)$edit_config; + + $can_reassign = $edit_engine->hasEditAccessToTransaction( + ManiphestTransaction::TYPE_OWNER); + if ($can_create) { $form_key = $edit_config->getIdentifier(); $edit_uri = id(new PhutilURI("/task/edit/form/{$form_key}/")) diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -821,7 +821,7 @@ } private function buildCrumbs($object, $final = false) { - $controller = $this->getcontroller(); + $controller = $this->getController(); $crumbs = $controller->buildApplicationCrumbsForEditEngine(); if ($this->getIsCreate()) { @@ -1179,6 +1179,60 @@ return $actions; } + + /** + * Test if the viewer could apply a certain type of change by using the + * normal "Edit" form. + * + * This method returns `true` if the user has access to an edit form and + * that edit form has a field which applied the specified transaction type, + * and that field is visible and editable for the user. + * + * For example, you can use it to test if a user is able to reassign tasks + * or not, prior to rendering dedicated UI for task reassingment. + * + * Note that this method does NOT test if the user can actually edit the + * current object, just if they have access to the related field. + * + * @param const Transaction type to test for. + * @return bool True if the user could "Edit" to apply the transaction type. + */ + final public function hasEditAccessToTransaction($xaction_type) { + $viewer = $this->getViewer(); + + $config = $this->loadDefaultEditConfiguration(); + if (!$config) { + return false; + } + + $object = $this->getTargetObject(); + if (!$object) { + $object = $this->newEditableObject(); + } + + $fields = $this->buildEditFields($object); + + $field = null; + foreach ($fields as $form_field) { + $field_xaction_type = $form_field->getTransactionType(); + if ($field_xaction_type === $xaction_type) { + $field = $form_field; + break; + } + } + + if (!$field) { + return false; + } + + if (!$field->shouldReadValueFromSubmit()) { + return false; + } + + return true; + } + + final public function addActionToCrumbs(PHUICrumbsView $crumbs) { $viewer = $this->getViewer();