@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 125 lines 3.6 kB view raw
1<?php 2 3final class PhabricatorProjectUpdateController 4 extends PhabricatorProjectController { 5 6 public function handleRequest(AphrontRequest $request) { 7 $viewer = $request->getViewer(); 8 $id = $request->getURIData('id'); 9 $action = $request->getURIData('action'); 10 11 $capabilities = array( 12 PhabricatorPolicyCapability::CAN_VIEW, 13 ); 14 15 switch ($action) { 16 case 'join': 17 $capabilities[] = PhabricatorPolicyCapability::CAN_JOIN; 18 break; 19 case 'leave': 20 break; 21 default: 22 return new Aphront404Response(); 23 } 24 25 $project = id(new PhabricatorProjectQuery()) 26 ->setViewer($viewer) 27 ->withIDs(array($id)) 28 ->needMembers(true) 29 ->requireCapabilities($capabilities) 30 ->executeOne(); 31 if (!$project) { 32 return new Aphront404Response(); 33 } 34 35 $done_uri = "/project/members/{$id}/"; 36 37 if (!$project->supportsEditMembers()) { 38 $copy = pht('Parent projects and milestones do not support adding '. 39 'members. You can add members directly to any non-parent subproject.'); 40 41 $subprojects_uri = "/project/subprojects/{$id}/"; 42 43 return $this->newDialog() 44 ->setTitle(pht('Unsupported Project')) 45 ->appendParagraph($copy) 46 ->setSubmitURI($subprojects_uri) 47 ->addSubmitButton(pht('See Subprojects')) 48 ->setDisableWorkflowOnSubmit(true) 49 ->addCancelButton($done_uri); 50 } 51 52 if ($request->isFormPost()) { 53 $edge_action = null; 54 switch ($action) { 55 case 'join': 56 $edge_action = '+'; 57 break; 58 case 'leave': 59 $edge_action = '-'; 60 break; 61 } 62 63 $type_member = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; 64 65 $member_spec = array( 66 $edge_action => array($viewer->getPHID() => $viewer->getPHID()), 67 ); 68 69 $xactions = array(); 70 $xactions[] = id(new PhabricatorProjectTransaction()) 71 ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 72 ->setMetadataValue('edge:type', $type_member) 73 ->setNewValue($member_spec); 74 75 $editor = id(new PhabricatorProjectTransactionEditor()) 76 ->setActor($viewer) 77 ->setContentSourceFromRequest($request) 78 ->setContinueOnNoEffect(true) 79 ->setContinueOnMissingFields(true) 80 ->applyTransactions($project, $xactions); 81 82 return id(new AphrontRedirectResponse())->setURI($done_uri); 83 } 84 85 $is_locked = $project->getIsMembershipLocked(); 86 $can_edit = PhabricatorPolicyFilter::hasCapability( 87 $viewer, 88 $project, 89 PhabricatorPolicyCapability::CAN_EDIT); 90 $can_leave = ($can_edit || !$is_locked); 91 92 $button = null; 93 if ($action == 'leave') { 94 if ($can_leave) { 95 $title = pht('Leave Project'); 96 $body = pht( 97 'Your tremendous contributions to this project will be sorely '. 98 'missed. Are you sure you want to leave?'); 99 $button = pht('Leave Project'); 100 } else { 101 $title = pht('Membership Locked'); 102 $body = pht( 103 'Membership for this project is locked. You can not leave.'); 104 } 105 } else { 106 $title = pht('Join Project'); 107 $body = pht( 108 'Join this project? You will become a member and enjoy whatever '. 109 'benefits membership may confer.'); 110 $button = pht('Join Project'); 111 } 112 113 $dialog = $this->newDialog() 114 ->setTitle($title) 115 ->appendParagraph($body) 116 ->addCancelButton($done_uri); 117 118 if ($button) { 119 $dialog->addSubmitButton($button); 120 } 121 122 return $dialog; 123 } 124 125}