@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
1<?php
2
3final class PhabricatorProjectMembersAddController
4 extends PhabricatorProjectController {
5
6 public function handleRequest(AphrontRequest $request) {
7 $viewer = $request->getViewer();
8 $id = $request->getURIData('id');
9
10 $project = id(new PhabricatorProjectQuery())
11 ->setViewer($viewer)
12 ->withIDs(array($id))
13 ->requireCapabilities(
14 array(
15 PhabricatorPolicyCapability::CAN_VIEW,
16 PhabricatorPolicyCapability::CAN_EDIT,
17 ))
18 ->executeOne();
19 if (!$project) {
20 return new Aphront404Response();
21 }
22
23 $this->setProject($project);
24 $done_uri = "/project/members/{$id}/";
25
26 if (!$project->supportsEditMembers()) {
27 $copy = pht('Parent projects and milestones do not support adding '.
28 'members. You can add members directly to any non-parent subproject.');
29
30 $subprojects_uri = "/project/subprojects/{$id}/";
31
32 return $this->newDialog()
33 ->setTitle(pht('Unsupported Project'))
34 ->appendParagraph($copy)
35 ->setSubmitURI($subprojects_uri)
36 ->addSubmitButton(pht('See Subprojects'))
37 ->setDisableWorkflowOnSubmit(true)
38 ->addCancelButton($done_uri);
39 }
40
41 if ($request->isFormPost()) {
42 $member_phids = $request->getArr('memberPHIDs');
43
44 $type_member = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST;
45
46 $xactions = array();
47
48 $xactions[] = id(new PhabricatorProjectTransaction())
49 ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
50 ->setMetadataValue('edge:type', $type_member)
51 ->setNewValue(
52 array(
53 '+' => array_fuse($member_phids),
54 ));
55
56 $editor = id(new PhabricatorProjectTransactionEditor())
57 ->setActor($viewer)
58 ->setContentSourceFromRequest($request)
59 ->setContinueOnNoEffect(true)
60 ->setContinueOnMissingFields(true)
61 ->applyTransactions($project, $xactions);
62
63 return id(new AphrontRedirectResponse())
64 ->setURI($done_uri);
65 }
66
67 $form = id(new AphrontFormView())
68 ->setUser($viewer)
69 ->appendControl(
70 id(new AphrontFormTokenizerControl())
71 ->setName('memberPHIDs')
72 ->setLabel(pht('Members'))
73 ->setDatasource(new PhabricatorPeopleDatasource()));
74
75 return $this->newDialog()
76 ->setTitle(pht('Add Members'))
77 ->appendForm($form)
78 ->addCancelButton($done_uri)
79 ->addSubmitButton(pht('Add Members'));
80 }
81
82}