diff --git a/src/applications/project/controller/PhabricatorProjectMembersAddController.php b/src/applications/project/controller/PhabricatorProjectMembersAddController.php index bd1631ee92..a3b89e46fd 100644 --- a/src/applications/project/controller/PhabricatorProjectMembersAddController.php +++ b/src/applications/project/controller/PhabricatorProjectMembersAddController.php @@ -1,72 +1,77 @@ getViewer(); $id = $request->getURIData('id'); $project = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->withIDs(array($id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$project) { return new Aphront404Response(); } $this->setProject($project); + $done_uri = "/project/members/{$id}/"; if (!$project->supportsEditMembers()) { - return new Aphront404Response(); - } + $copy = pht('Parent projects and milestones do not support adding '. + 'members. You can add members directly to any non-parent subproject.'); - $done_uri = "/project/members/{$id}/"; + return $this->newDialog() + ->setTitle(pht('Unsupported Project')) + ->appendParagraph($copy) + ->addCancelButton($done_uri); + } if ($request->isFormPost()) { $member_phids = $request->getArr('memberPHIDs'); $type_member = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; $xactions = array(); $xactions[] = id(new PhabricatorProjectTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) ->setMetadataValue('edge:type', $type_member) ->setNewValue( array( '+' => array_fuse($member_phids), )); $editor = id(new PhabricatorProjectTransactionEditor($project)) ->setActor($viewer) ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true) ->applyTransactions($project, $xactions); return id(new AphrontRedirectResponse()) ->setURI($done_uri); } $form = id(new AphrontFormView()) ->setUser($viewer) ->appendControl( id(new AphrontFormTokenizerControl()) ->setName('memberPHIDs') ->setLabel(pht('Members')) ->setDatasource(new PhabricatorPeopleDatasource())); return $this->newDialog() ->setTitle(pht('Add Members')) ->appendForm($form) ->addCancelButton($done_uri) ->addSubmitButton(pht('Add Members')); } } diff --git a/src/applications/project/controller/PhabricatorProjectUpdateController.php b/src/applications/project/controller/PhabricatorProjectUpdateController.php index 762343f485..9f8c204c55 100644 --- a/src/applications/project/controller/PhabricatorProjectUpdateController.php +++ b/src/applications/project/controller/PhabricatorProjectUpdateController.php @@ -1,114 +1,120 @@ getViewer(); $id = $request->getURIData('id'); $action = $request->getURIData('action'); $capabilities = array( PhabricatorPolicyCapability::CAN_VIEW, ); switch ($action) { case 'join': $capabilities[] = PhabricatorPolicyCapability::CAN_JOIN; break; case 'leave': break; default: return new Aphront404Response(); } $project = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->withIDs(array($id)) ->needMembers(true) ->requireCapabilities($capabilities) ->executeOne(); if (!$project) { return new Aphront404Response(); } + $done_uri = "/project/members/{$id}/"; + if (!$project->supportsEditMembers()) { - return new Aphront404Response(); - } + $copy = pht('Parent projects and milestones do not support adding '. + 'members. You can add members directly to any non-parent subproject.'); - $done_uri = "/project/members/{$id}/"; + return $this->newDialog() + ->setTitle(pht('Unsupported Project')) + ->appendParagraph($copy) + ->addCancelButton($done_uri); + } if ($request->isFormPost()) { $edge_action = null; switch ($action) { case 'join': $edge_action = '+'; break; case 'leave': $edge_action = '-'; break; } $type_member = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; $member_spec = array( $edge_action => array($viewer->getPHID() => $viewer->getPHID()), ); $xactions = array(); $xactions[] = id(new PhabricatorProjectTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) ->setMetadataValue('edge:type', $type_member) ->setNewValue($member_spec); $editor = id(new PhabricatorProjectTransactionEditor($project)) ->setActor($viewer) ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true) ->applyTransactions($project, $xactions); return id(new AphrontRedirectResponse())->setURI($done_uri); } $is_locked = $project->getIsMembershipLocked(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $project, PhabricatorPolicyCapability::CAN_EDIT); $can_leave = ($can_edit || !$is_locked); $button = null; if ($action == 'leave') { if ($can_leave) { $title = pht('Leave Project'); $body = pht( 'Your tremendous contributions to this project will be sorely '. 'missed. Are you sure you want to leave?'); $button = pht('Leave Project'); } else { $title = pht('Membership Locked'); $body = pht( 'Membership for this project is locked. You can not leave.'); } } else { $title = pht('Join Project'); $body = pht( 'Join this project? You will become a member and enjoy whatever '. 'benefits membership may confer.'); $button = pht('Join Project'); } $dialog = $this->newDialog() ->setTitle($title) ->appendParagraph($body) ->addCancelButton($done_uri); if ($button) { $dialog->addSubmitButton($button); } return $dialog; } }