diff --git a/src/applications/project/application/PhabricatorProjectApplication.php b/src/applications/project/application/PhabricatorProjectApplication.php index e1b484ffe2..c25a1b223f 100644 --- a/src/applications/project/application/PhabricatorProjectApplication.php +++ b/src/applications/project/application/PhabricatorProjectApplication.php @@ -51,7 +51,7 @@ final class PhabricatorProjectApplication extends PhabricatorApplication { => 'PhabricatorProjectMembersViewController', 'members/(?P[1-9]\d*)/add/' => 'PhabricatorProjectMembersAddController', - 'members/(?P[1-9]\d*)/remove/' + '(?Pmembers|watchers)/(?P[1-9]\d*)/remove/' => 'PhabricatorProjectMembersRemoveController', 'profile/(?P[1-9]\d*)/' => 'PhabricatorProjectProfileController', diff --git a/src/applications/project/controller/PhabricatorProjectMembersRemoveController.php b/src/applications/project/controller/PhabricatorProjectMembersRemoveController.php index cad3f35c05..ea41ea7113 100644 --- a/src/applications/project/controller/PhabricatorProjectMembersRemoveController.php +++ b/src/applications/project/controller/PhabricatorProjectMembersRemoveController.php @@ -6,11 +6,13 @@ final class PhabricatorProjectMembersRemoveController public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $id = $request->getURIData('id'); + $type = $request->getURIData('type'); $project = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->withIDs(array($id)) ->needMembers(true) + ->needWatchers(true) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, @@ -21,27 +23,31 @@ final class PhabricatorProjectMembersRemoveController return new Aphront404Response(); } - $member_phids = $project->getMemberPHIDs(); - $remove_phid = $request->getStr('phid'); + if ($type == 'watchers') { + $is_watcher = true; + $edge_type = PhabricatorObjectHasWatcherEdgeType::EDGECONST; + } else { + if (!$project->supportsEditMembers()) { + return new Aphront404Response(); + } - if (!in_array($remove_phid, $member_phids)) { - return new Aphront404Response(); + $is_watcher = false; + $edge_type = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; } $members_uri = $this->getApplicationURI('members/'.$project->getID().'/'); + $remove_phid = $request->getStr('phid'); if ($request->isFormPost()) { - $member_spec = array(); - $member_spec['-'] = array($remove_phid => $remove_phid); - - $type_member = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; - $xactions = array(); $xactions[] = id(new PhabricatorProjectTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) - ->setMetadataValue('edge:type', $type_member) - ->setNewValue($member_spec); + ->setMetadataValue('edge:type', $edge_type) + ->setNewValue( + array( + '-' => array($remove_phid => $remove_phid), + )); $editor = id(new PhabricatorProjectTransactionEditor($project)) ->setActor($viewer) @@ -59,18 +65,31 @@ final class PhabricatorProjectMembersRemoveController ->withPHIDs(array($remove_phid)) ->executeOne(); - $dialog = id(new AphrontDialogView()) - ->setUser($viewer) - ->setTitle(pht('Really Remove Member?')) - ->appendParagraph( - pht( - 'Really remove %s from the project %s?', - phutil_tag('strong', array(), $handle->getName()), - phutil_tag('strong', array(), $project->getName()))) - ->addCancelButton($members_uri) - ->addSubmitButton(pht('Remove Project Member')); + $target_name = phutil_tag('strong', array(), $handle->getName()); + $project_name = phutil_tag('strong', array(), $project->getName()); - return id(new AphrontDialogResponse())->setDialog($dialog); + if ($is_watcher) { + $title = pht('Remove Watcher'); + $body = pht( + 'Remove %s as a watcher of %s?', + $target_name, + $project_name); + $button = pht('Remove Watcher'); + } else { + $title = pht('Remove Member'); + $body = pht( + 'Remove %s as a project member of %s?', + $target_name, + $project_name); + $button = pht('Remove Member'); + } + + return $this->newDialog() + ->setTitle($title) + ->addHiddenInput('phid', $remove_phid) + ->appendParagraph($body) + ->addCancelButton($members_uri) + ->addSubmitButton($button); } } diff --git a/src/applications/project/view/PhabricatorProjectWatcherListView.php b/src/applications/project/view/PhabricatorProjectWatcherListView.php index ec993f031c..7aa9638afc 100644 --- a/src/applications/project/view/PhabricatorProjectWatcherListView.php +++ b/src/applications/project/view/PhabricatorProjectWatcherListView.php @@ -4,7 +4,13 @@ final class PhabricatorProjectWatcherListView extends PhabricatorProjectUserListView { protected function canEditList() { - return false; + $viewer = $this->getUser(); + $project = $this->getProject(); + + return PhabricatorPolicyFilter::hasCapability( + $viewer, + $project, + PhabricatorPolicyCapability::CAN_EDIT); } protected function getNoDataString() { @@ -12,7 +18,9 @@ final class PhabricatorProjectWatcherListView } protected function getRemoveURI($phid) { - return null; + $project = $this->getProject(); + $id = $project->getID(); + return "/project/watchers/{$id}/remove/?phid={$phid}"; } protected function getHeaderText() {