@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 HeraldTranscript extends HeraldDAO
4 implements
5 PhabricatorPolicyInterface,
6 PhabricatorDestructibleInterface {
7
8 protected $objectTranscript;
9 protected $ruleTranscripts = array();
10 protected $conditionTranscripts = array();
11 protected $applyTranscripts = array();
12
13 protected $time;
14 protected $host;
15 protected $duration;
16
17 protected $objectPHID;
18 protected $dryRun;
19 protected $garbageCollected = 0;
20
21 private $object = self::ATTACHABLE;
22
23 const TABLE_SAVED_HEADER = 'herald_savedheader';
24
25 public function getXHeraldRulesHeader() {
26 $ids = array();
27 foreach ($this->applyTranscripts as $xscript) {
28 if ($xscript->getApplied()) {
29 if ($xscript->getRuleID()) {
30 $ids[] = $xscript->getRuleID();
31 }
32 }
33 }
34 if (!$ids) {
35 return 'none';
36 }
37
38 // A rule may have multiple effects, which will cause it to be listed
39 // multiple times.
40 $ids = array_unique($ids);
41
42 foreach ($ids as $k => $id) {
43 $ids[$k] = '<'.$id.'>';
44 }
45
46 return implode(', ', $ids);
47 }
48
49 public static function saveXHeraldRulesHeader($phid, $header) {
50
51 // Combine any existing header with the new header, listing all rules
52 // which have ever triggered for this object.
53 $header = self::combineXHeraldRulesHeaders(
54 self::loadXHeraldRulesHeader($phid),
55 $header);
56
57 queryfx(
58 id(new HeraldTranscript())->establishConnection('w'),
59 'INSERT INTO %T (phid, header) VALUES (%s, %s)
60 ON DUPLICATE KEY UPDATE header = VALUES(header)',
61 self::TABLE_SAVED_HEADER,
62 $phid,
63 $header);
64
65 return $header;
66 }
67
68 private static function combineXHeraldRulesHeaders($u, $v) {
69 if ($u === null) {
70 return $v;
71 }
72
73 $u = preg_split('/[, ]+/', $u);
74 $v = preg_split('/[, ]+/', $v);
75
76 $combined = array_unique(array_filter(array_merge($u, $v)));
77 return implode(', ', $combined);
78 }
79
80 public static function loadXHeraldRulesHeader($phid) {
81 $header = queryfx_one(
82 id(new HeraldTranscript())->establishConnection('r'),
83 'SELECT * FROM %T WHERE phid = %s',
84 self::TABLE_SAVED_HEADER,
85 $phid);
86 if ($header) {
87 return idx($header, 'header');
88 }
89 return null;
90 }
91
92
93 protected function getConfiguration() {
94 // Ugh. Too much of a mess to deal with.
95 return array(
96 self::CONFIG_AUX_PHID => true,
97 self::CONFIG_TIMESTAMPS => false,
98 self::CONFIG_SERIALIZATION => array(
99 'objectTranscript' => self::SERIALIZATION_PHP,
100 'ruleTranscripts' => self::SERIALIZATION_PHP,
101 'conditionTranscripts' => self::SERIALIZATION_PHP,
102 'applyTranscripts' => self::SERIALIZATION_PHP,
103 ),
104 self::CONFIG_BINARY => array(
105 'objectTranscript' => true,
106 'ruleTranscripts' => true,
107 'conditionTranscripts' => true,
108 'applyTranscripts' => true,
109 ),
110 self::CONFIG_COLUMN_SCHEMA => array(
111 'time' => 'epoch',
112 'host' => 'text255',
113 'duration' => 'double',
114 'dryRun' => 'bool',
115 'garbageCollected' => 'bool',
116 ),
117 self::CONFIG_KEY_SCHEMA => array(
118 'key_phid' => null,
119 'phid' => array(
120 'columns' => array('phid'),
121 'unique' => true,
122 ),
123 'objectPHID' => array(
124 'columns' => array('objectPHID'),
125 ),
126 'garbageCollected' => array(
127 'columns' => array('garbageCollected', 'time'),
128 ),
129 ),
130 ) + parent::getConfiguration();
131 }
132
133 public function __construct() {
134 $this->time = time();
135 $this->host = php_uname('n');
136 }
137
138 public function addApplyTranscript(HeraldApplyTranscript $transcript) {
139 $this->applyTranscripts[] = $transcript;
140 return $this;
141 }
142
143 public function getApplyTranscripts() {
144 return nonempty($this->applyTranscripts, array());
145 }
146
147 public function setDuration($duration) {
148 $this->duration = $duration;
149 return $this;
150 }
151
152 public function setObjectTranscript(HeraldObjectTranscript $transcript) {
153 $this->objectTranscript = $transcript;
154 return $this;
155 }
156
157 public function getObjectTranscript() {
158 return $this->objectTranscript;
159 }
160
161 public function addRuleTranscript(HeraldRuleTranscript $transcript) {
162 $this->ruleTranscripts[$transcript->getRuleID()] = $transcript;
163 return $this;
164 }
165
166 public function discardDetails() {
167 $this->applyTranscripts = null;
168 $this->ruleTranscripts = null;
169 $this->objectTranscript = null;
170 $this->conditionTranscripts = null;
171 }
172
173 public function getRuleTranscripts() {
174 return nonempty($this->ruleTranscripts, array());
175 }
176
177 public function addConditionTranscript(
178 HeraldConditionTranscript $transcript) {
179 $rule_id = $transcript->getRuleID();
180 $cond_id = $transcript->getConditionID();
181
182 $this->conditionTranscripts[$rule_id][$cond_id] = $transcript;
183 return $this;
184 }
185
186 public function getConditionTranscriptsForRule($rule_id) {
187 return idx($this->conditionTranscripts, $rule_id, array());
188 }
189
190 public function getMetadataMap() {
191 return array(
192 pht('Run At Epoch') => date('F jS, g:i:s A', $this->time),
193 pht('Run On Host') => $this->host,
194 pht('Run Duration') => (int)(1000 * $this->duration).' ms',
195 );
196 }
197
198 public function generatePHID() {
199 return PhabricatorPHID::generateNewPHID(
200 HeraldTranscriptPHIDType::TYPECONST);
201 }
202
203 public function attachObject($object = null) {
204 $this->object = $object;
205 return $this;
206 }
207
208 public function getObject() {
209 return $this->assertAttached($this->object);
210 }
211
212/* -( PhabricatorPolicyInterface )----------------------------------------- */
213
214 public function getCapabilities() {
215 return array(
216 PhabricatorPolicyCapability::CAN_VIEW,
217 );
218 }
219
220 public function getPolicy($capability) {
221 switch ($capability) {
222 case PhabricatorPolicyCapability::CAN_VIEW:
223 return PhabricatorPolicies::POLICY_USER;
224 }
225 }
226
227 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
228 return false;
229 }
230
231 public function describeAutomaticCapability($capability) {
232 return pht(
233 'To view a transcript, you must be able to view the object the '.
234 'transcript is about.');
235 }
236
237
238/* -( PhabricatorDestructibleInterface )----------------------------------- */
239
240
241 public function destroyObjectPermanently(
242 PhabricatorDestructionEngine $engine) {
243
244 $this->openTransaction();
245 $this->delete();
246 $this->saveTransaction();
247 }
248
249
250}