@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 DiffusionDoorkeeperCommitFeedStoryPublisher
4 extends DoorkeeperFeedStoryPublisher {
5
6 private $auditRequests;
7 private $activePHIDs;
8 private $passivePHIDs;
9
10 public function canPublishStory(PhabricatorFeedStory $story, $object) {
11 return
12 ($story instanceof PhabricatorApplicationTransactionFeedStory) &&
13 ($object instanceof PhabricatorRepositoryCommit);
14 }
15
16 public function isStoryAboutObjectCreation($object) {
17 // TODO: Although creation stories exist, they currently don't have a
18 // primary object PHID set, so they'll never make it here because they
19 // won't pass `canPublishStory()`.
20 return false;
21 }
22
23 public function isStoryAboutObjectClosure($object) {
24 // TODO: This isn't quite accurate, but pretty close: check if this story
25 // is a close (which clearly is about object closure) or is an "Accept" and
26 // the commit is fully audited (which is almost certainly a closure).
27 // After ApplicationTransactions, we could annotate feed stories more
28 // explicitly.
29
30 $story = $this->getFeedStory();
31 $xaction = $story->getPrimaryTransaction();
32 switch ($xaction->getTransactionType()) {
33 case PhabricatorAuditActionConstants::ACTION:
34 switch ($xaction->getNewValue()) {
35 case PhabricatorAuditActionConstants::CLOSE:
36 return true;
37 case PhabricatorAuditActionConstants::ACCEPT:
38 if ($object->isAuditStatusAudited()) {
39 return true;
40 }
41 break;
42 }
43 }
44
45 return false;
46 }
47
48 public function willPublishStory($commit) {
49 $requests = id(new DiffusionCommitQuery())
50 ->setViewer($this->getViewer())
51 ->withPHIDs(array($commit->getPHID()))
52 ->needAuditRequests(true)
53 ->executeOne()
54 ->getAudits();
55
56 // TODO: This is messy and should be generalized, but we don't have a good
57 // query for it yet. Since we run in the daemons, just do the easiest thing
58 // we can for the moment. Figure out who all of the "active" (need to
59 // audit) and "passive" (no action necessary) users are.
60
61 $auditor_phids = mpull($requests, 'getAuditorPHID');
62 $objects = id(new PhabricatorObjectQuery())
63 ->setViewer($this->getViewer())
64 ->withPHIDs($auditor_phids)
65 ->execute();
66
67 $active = array();
68 $passive = array();
69
70 foreach ($requests as $request) {
71 $status = $request->getAuditStatus();
72
73 $object = idx($objects, $request->getAuditorPHID());
74 if (!$object) {
75 continue;
76 }
77
78 $request_phids = array();
79 if ($object instanceof PhabricatorUser) {
80 $request_phids = array($object->getPHID());
81 } else if ($object instanceof PhabricatorOwnersPackage) {
82 $request_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(
83 array($object->getID()));
84 } else if ($object instanceof PhabricatorProject) {
85 $project = id(new PhabricatorProjectQuery())
86 ->setViewer($this->getViewer())
87 ->withIDs(array($object->getID()))
88 ->needMembers(true)
89 ->executeOne();
90 $request_phids = $project->getMemberPHIDs();
91 } else {
92 // Dunno what this is.
93 $request_phids = array();
94 }
95
96 switch ($status) {
97 case PhabricatorAuditRequestStatus::AUDIT_REQUIRED:
98 case PhabricatorAuditRequestStatus::AUDIT_REQUESTED:
99 case PhabricatorAuditRequestStatus::CONCERNED:
100 $active += array_fuse($request_phids);
101 break;
102 default:
103 $passive += array_fuse($request_phids);
104 break;
105 }
106 }
107
108
109 // Remove "Active" users from the "Passive" list.
110 $passive = array_diff_key($passive, $active);
111
112 $this->activePHIDs = $active;
113 $this->passivePHIDs = $passive;
114 $this->auditRequests = $requests;
115
116 return $commit;
117 }
118
119 public function getOwnerPHID($object) {
120 return $object->getAuthorPHID();
121 }
122
123 public function getActiveUserPHIDs($object) {
124 return $this->activePHIDs;
125 }
126
127 public function getPassiveUserPHIDs($object) {
128 return $this->passivePHIDs;
129 }
130
131 public function getCCUserPHIDs($object) {
132 return PhabricatorSubscribersQuery::loadSubscribersForPHID(
133 $object->getPHID());
134 }
135
136 public function getObjectTitle($object) {
137 $prefix = $this->getTitlePrefix($object);
138
139 $repository = $object->getRepository();
140 $name = $repository->formatCommitName($object->getCommitIdentifier());
141
142 $title = $object->getSummary();
143
144 return ltrim("{$prefix} {$name}: {$title}");
145 }
146
147 public function getObjectURI($object) {
148 $repository = $object->getRepository();
149 $name = $repository->formatCommitName($object->getCommitIdentifier());
150 return PhabricatorEnv::getProductionURI('/'.$name);
151 }
152
153 public function getObjectDescription($object) {
154 $data = $object->loadCommitData();
155 if ($data) {
156 return $data->getCommitMessage();
157 }
158 return null;
159 }
160
161 public function isObjectClosed($object) {
162 return $object->getAuditStatusObject()->getIsClosed();
163 }
164
165 public function getResponsibilityTitle($object) {
166 $prefix = $this->getTitlePrefix($object);
167 return pht('%s Audit', $prefix);
168 }
169
170 private function getTitlePrefix(PhabricatorRepositoryCommit $commit) {
171 return pht('[Diffusion]');
172 }
173
174}