Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/herald/field/HeraldField.php
12256 views
1
<?php
2
3
abstract class HeraldField extends Phobject {
4
5
private $adapter;
6
7
const STANDARD_BOOL = 'standard.bool';
8
const STANDARD_TEXT = 'standard.text';
9
const STANDARD_TEXT_LIST = 'standard.text.list';
10
const STANDARD_TEXT_MAP = 'standard.text.map';
11
const STANDARD_PHID = 'standard.phid';
12
const STANDARD_PHID_LIST = 'standard.phid.list';
13
const STANDARD_PHID_BOOL = 'standard.phid.bool';
14
const STANDARD_PHID_NULLABLE = 'standard.phid.nullable';
15
16
abstract public function getHeraldFieldName();
17
abstract public function getHeraldFieldValue($object);
18
19
public function getFieldGroupKey() {
20
return null;
21
}
22
23
public function getRequiredAdapterStates() {
24
return array();
25
}
26
27
protected function getHeraldFieldStandardType() {
28
throw new PhutilMethodNotImplementedException();
29
}
30
31
protected function getDatasource() {
32
throw new PhutilMethodNotImplementedException();
33
}
34
35
protected function getDatasourceValueMap() {
36
return null;
37
}
38
39
public function getHeraldFieldConditions() {
40
$standard_type = $this->getHeraldFieldStandardType();
41
switch ($standard_type) {
42
case self::STANDARD_BOOL:
43
return array(
44
HeraldAdapter::CONDITION_IS_TRUE,
45
HeraldAdapter::CONDITION_IS_FALSE,
46
);
47
case self::STANDARD_TEXT:
48
return array(
49
HeraldAdapter::CONDITION_CONTAINS,
50
HeraldAdapter::CONDITION_NOT_CONTAINS,
51
HeraldAdapter::CONDITION_IS,
52
HeraldAdapter::CONDITION_IS_NOT,
53
HeraldAdapter::CONDITION_REGEXP,
54
HeraldAdapter::CONDITION_NOT_REGEXP,
55
);
56
case self::STANDARD_PHID:
57
return array(
58
HeraldAdapter::CONDITION_IS_ANY,
59
HeraldAdapter::CONDITION_IS_NOT_ANY,
60
);
61
case self::STANDARD_PHID_LIST:
62
return array(
63
HeraldAdapter::CONDITION_INCLUDE_ALL,
64
HeraldAdapter::CONDITION_INCLUDE_ANY,
65
HeraldAdapter::CONDITION_INCLUDE_NONE,
66
HeraldAdapter::CONDITION_EXISTS,
67
HeraldAdapter::CONDITION_NOT_EXISTS,
68
);
69
case self::STANDARD_PHID_BOOL:
70
return array(
71
HeraldAdapter::CONDITION_EXISTS,
72
HeraldAdapter::CONDITION_NOT_EXISTS,
73
);
74
case self::STANDARD_PHID_NULLABLE:
75
return array(
76
HeraldAdapter::CONDITION_IS_ANY,
77
HeraldAdapter::CONDITION_IS_NOT_ANY,
78
HeraldAdapter::CONDITION_EXISTS,
79
HeraldAdapter::CONDITION_NOT_EXISTS,
80
);
81
case self::STANDARD_TEXT_LIST:
82
return array(
83
HeraldAdapter::CONDITION_CONTAINS,
84
HeraldAdapter::CONDITION_NOT_CONTAINS,
85
HeraldAdapter::CONDITION_REGEXP,
86
HeraldAdapter::CONDITION_NOT_REGEXP,
87
HeraldAdapter::CONDITION_EXISTS,
88
HeraldAdapter::CONDITION_NOT_EXISTS,
89
);
90
case self::STANDARD_TEXT_MAP:
91
return array(
92
HeraldAdapter::CONDITION_CONTAINS,
93
HeraldAdapter::CONDITION_NOT_CONTAINS,
94
HeraldAdapter::CONDITION_REGEXP,
95
HeraldAdapter::CONDITION_NOT_REGEXP,
96
HeraldAdapter::CONDITION_REGEXP_PAIR,
97
);
98
}
99
100
throw new Exception(
101
pht(
102
'Herald field "%s" has unknown standard type "%s".',
103
get_class($this),
104
$standard_type));
105
}
106
107
public function getHeraldFieldValueType($condition) {
108
109
// NOTE: The condition type may be "null" to indicate that the caller
110
// wants a generic field value type. This is used when rendering field
111
// values in the object transcript.
112
113
$standard_type = $this->getHeraldFieldStandardType();
114
switch ($standard_type) {
115
case self::STANDARD_BOOL:
116
case self::STANDARD_PHID_BOOL:
117
return new HeraldBoolFieldValue();
118
case self::STANDARD_TEXT:
119
case self::STANDARD_TEXT_LIST:
120
case self::STANDARD_TEXT_MAP:
121
switch ($condition) {
122
case HeraldAdapter::CONDITION_EXISTS:
123
case HeraldAdapter::CONDITION_NOT_EXISTS:
124
return new HeraldEmptyFieldValue();
125
default:
126
return new HeraldTextFieldValue();
127
}
128
case self::STANDARD_PHID:
129
case self::STANDARD_PHID_NULLABLE:
130
case self::STANDARD_PHID_LIST:
131
switch ($condition) {
132
case HeraldAdapter::CONDITION_EXISTS:
133
case HeraldAdapter::CONDITION_NOT_EXISTS:
134
return new HeraldEmptyFieldValue();
135
default:
136
$tokenizer = id(new HeraldTokenizerFieldValue())
137
->setKey($this->getHeraldFieldName())
138
->setDatasource($this->getDatasource());
139
140
$value_map = $this->getDatasourceValueMap();
141
if ($value_map !== null) {
142
$tokenizer->setValueMap($value_map);
143
}
144
145
return $tokenizer;
146
}
147
break;
148
149
}
150
151
throw new Exception(
152
pht(
153
'Herald field "%s" has unknown standard type "%s".',
154
get_class($this),
155
$standard_type));
156
}
157
158
abstract public function supportsObject($object);
159
160
public function getFieldsForObject($object) {
161
return array($this->getFieldConstant() => $this);
162
}
163
164
public function renderConditionValue(
165
PhabricatorUser $viewer,
166
$condition,
167
$value) {
168
169
$value_type = $this->getHeraldFieldValueType($condition);
170
$value_type->setViewer($viewer);
171
return $value_type->renderFieldValue($value);
172
}
173
174
public function getEditorValue(
175
PhabricatorUser $viewer,
176
$condition,
177
$value) {
178
179
$value_type = $this->getHeraldFieldValueType($condition);
180
$value_type->setViewer($viewer);
181
return $value_type->renderEditorValue($value);
182
}
183
184
public function renderTranscriptValue(
185
PhabricatorUser $viewer,
186
$field_value) {
187
$value_type = $this->getHeraldFieldValueType($condition_type = null);
188
$value_type->setViewer($viewer);
189
return $value_type->renderTranscriptValue($field_value);
190
}
191
192
public function getPHIDsAffectedByCondition(HeraldCondition $condition) {
193
try {
194
$standard_type = $this->getHeraldFieldStandardType();
195
} catch (PhutilMethodNotImplementedException $ex) {
196
$standard_type = null;
197
}
198
199
switch ($standard_type) {
200
case self::STANDARD_PHID:
201
case self::STANDARD_PHID_NULLABLE:
202
case self::STANDARD_PHID_LIST:
203
$phids = $condition->getValue();
204
205
if (!is_array($phids)) {
206
$phids = array();
207
}
208
209
return $phids;
210
}
211
212
return array();
213
}
214
215
final public function setAdapter(HeraldAdapter $adapter) {
216
$this->adapter = $adapter;
217
return $this;
218
}
219
220
final public function getAdapter() {
221
return $this->adapter;
222
}
223
224
final public function getFieldConstant() {
225
return $this->getPhobjectClassConstant(
226
'FIELDCONST',
227
self::getFieldConstantByteLimit());
228
}
229
230
final public static function getFieldConstantByteLimit() {
231
return 64;
232
}
233
234
final public static function getAllFields() {
235
return id(new PhutilClassMapQuery())
236
->setAncestorClass(__CLASS__)
237
->setUniqueMethod('getFieldConstant')
238
->execute();
239
}
240
241
final protected function hasAppliedTransactionOfType($type) {
242
$xactions = $this->getAdapter()->getAppliedTransactions();
243
244
if (!$xactions) {
245
return false;
246
}
247
248
foreach ($xactions as $xaction) {
249
if ($xaction->getTransactionType() === $type) {
250
return true;
251
}
252
}
253
254
return false;
255
}
256
257
final protected function getAppliedTransactionsOfTypes(array $types) {
258
$types = array_fuse($types);
259
$xactions = $this->getAdapter()->getAppliedTransactions();
260
261
$result = array();
262
foreach ($xactions as $key => $xaction) {
263
$xaction_type = $xaction->getTransactionType();
264
if (isset($types[$xaction_type])) {
265
$result[$key] = $xaction;
266
}
267
}
268
269
return $result;
270
}
271
272
final protected function getAppliedEdgeTransactionOfType($edge_type) {
273
$edge_xactions = $this->getAppliedTransactionsOfTypes(
274
array(
275
PhabricatorTransactions::TYPE_EDGE,
276
));
277
278
$results = array();
279
foreach ($edge_xactions as $edge_xaction) {
280
$xaction_edge_type = $edge_xaction->getMetadataValue('edge:type');
281
if ($xaction_edge_type == $edge_type) {
282
$results[] = $edge_xaction;
283
}
284
}
285
286
if (count($results) > 1) {
287
throw new Exception(
288
pht(
289
'Found more than one ("%s") applied edge transactions with given '.
290
'edge type ("%s"); expected zero or one.',
291
phutil_count($results),
292
$edge_type));
293
}
294
295
if ($results) {
296
return head($results);
297
}
298
299
return null;
300
}
301
302
public function isFieldAvailable() {
303
return true;
304
}
305
306
}
307
308