@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 PhabricatorEditEngineConfiguration
4 extends PhabricatorSearchDAO
5 implements
6 PhabricatorApplicationTransactionInterface,
7 PhabricatorPolicyInterface {
8
9 protected $engineKey;
10 protected $builtinKey;
11 protected $name;
12 protected $viewPolicy;
13 protected $properties = array();
14 protected $isDisabled = 0;
15 protected $isDefault = 0;
16 protected $isEdit = 0;
17 protected $createOrder = 0;
18 protected $editOrder = 0;
19 protected $subtype;
20
21 private $engine = self::ATTACHABLE;
22
23 const LOCK_VISIBLE = 'visible';
24 const LOCK_LOCKED = 'locked';
25 const LOCK_HIDDEN = 'hidden';
26
27 public function getTableName() {
28 return 'search_editengineconfiguration';
29 }
30
31 public static function initializeNewConfiguration(
32 PhabricatorUser $actor,
33 PhabricatorEditEngine $engine) {
34
35 return id(new PhabricatorEditEngineConfiguration())
36 ->setSubtype(PhabricatorEditEngine::SUBTYPE_DEFAULT)
37 ->setEngineKey($engine->getEngineKey())
38 ->attachEngine($engine)
39 ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy());
40 }
41
42 public function generatePHID() {
43 return PhabricatorPHID::generateNewPHID(
44 PhabricatorEditEngineConfigurationPHIDType::TYPECONST);
45 }
46
47 public function getCreateSortKey() {
48 return $this->getSortKey($this->createOrder);
49 }
50
51 public function getEditSortKey() {
52 return $this->getSortKey($this->editOrder);
53 }
54
55 private function getSortKey($order) {
56 // Put objects at the bottom by default if they haven't previously been
57 // reordered. When they're explicitly reordered, the smallest sort key we
58 // assign is 1, so if the object has a value of 0 it means it hasn't been
59 // ordered yet.
60 if ($order != 0) {
61 $group = 'A';
62 } else {
63 $group = 'B';
64 }
65
66 return sprintf(
67 "%s%012d%s\0%012d",
68 $group,
69 $order,
70 $this->getName(),
71 $this->getID());
72 }
73
74 protected function getConfiguration() {
75 return array(
76 self::CONFIG_AUX_PHID => true,
77 self::CONFIG_SERIALIZATION => array(
78 'properties' => self::SERIALIZATION_JSON,
79 ),
80 self::CONFIG_COLUMN_SCHEMA => array(
81 'engineKey' => 'text64',
82 'builtinKey' => 'text64?',
83 'name' => 'text255',
84 'isDisabled' => 'bool',
85 'isDefault' => 'bool',
86 'isEdit' => 'bool',
87 'createOrder' => 'uint32',
88 'editOrder' => 'uint32',
89 'subtype' => 'text64',
90 ),
91 self::CONFIG_KEY_SCHEMA => array(
92 'key_engine' => array(
93 'columns' => array('engineKey', 'builtinKey'),
94 'unique' => true,
95 ),
96 'key_default' => array(
97 'columns' => array('engineKey', 'isDefault', 'isDisabled'),
98 ),
99 'key_edit' => array(
100 'columns' => array('engineKey', 'isEdit', 'isDisabled'),
101 ),
102 ),
103 ) + parent::getConfiguration();
104 }
105
106 public function getProperty($key, $default = null) {
107 return idx($this->properties, $key, $default);
108 }
109
110 public function setProperty($key, $value) {
111 $this->properties[$key] = $value;
112 return $this;
113 }
114
115 public function setBuiltinKey($key) {
116 if (strpos($key, '/') !== false) {
117 throw new Exception(
118 pht('EditEngine BuiltinKey contains an invalid key character "/".'));
119 }
120 return parent::setBuiltinKey($key);
121 }
122
123 public function attachEngine(PhabricatorEditEngine $engine) {
124 $this->engine = $engine;
125 return $this;
126 }
127
128 public function getEngine() {
129 return $this->assertAttached($this->engine);
130 }
131
132 public function applyConfigurationToFields(
133 PhabricatorEditEngine $engine,
134 $object,
135 array $fields) {
136 $fields = mpull($fields, null, 'getKey');
137
138 $is_new = !$object->getID();
139
140 $values = $this->getProperty('defaults', array());
141 foreach ($fields as $key => $field) {
142 if (!$field->getIsFormField()) {
143 continue;
144 }
145
146 if (!$field->getIsDefaultable()) {
147 continue;
148 }
149
150 if ($is_new) {
151 if (array_key_exists($key, $values)) {
152 $field->readDefaultValueFromConfiguration($values[$key]);
153 }
154 }
155 }
156
157 $locks = $this->getFieldLocks();
158 foreach ($fields as $field) {
159 $key = $field->getKey();
160 switch (idx($locks, $key)) {
161 case self::LOCK_LOCKED:
162 $field->setIsHidden(false);
163 if ($field->getIsLockable()) {
164 $field->setIsLocked(true);
165 }
166 break;
167 case self::LOCK_HIDDEN:
168 $field->setIsHidden(true);
169 if ($field->getIsLockable()) {
170 $field->setIsLocked(false);
171 }
172 break;
173 case self::LOCK_VISIBLE:
174 $field->setIsHidden(false);
175 if ($field->getIsLockable()) {
176 $field->setIsLocked(false);
177 }
178 break;
179 default:
180 // If we don't have an explicit value, don't make any adjustments.
181 break;
182 }
183 }
184
185 $fields = $this->reorderFields($fields);
186
187 $preamble = $this->getPreamble();
188 if ($preamble !== null && strlen($preamble)) {
189 $fields = array(
190 'config.preamble' => id(new PhabricatorInstructionsEditField())
191 ->setKey('config.preamble')
192 ->setIsReorderable(false)
193 ->setIsDefaultable(false)
194 ->setIsLockable(false)
195 ->setValue($preamble),
196 ) + $fields;
197 }
198
199 return $fields;
200 }
201
202 private function reorderFields(array $fields) {
203 // Fields which can not be reordered are fixed in order at the top of the
204 // form. These are used to show instructions or contextual information.
205
206 $fixed = array();
207 foreach ($fields as $key => $field) {
208 if (!$field->getIsReorderable()) {
209 $fixed[$key] = $field;
210 }
211 }
212
213 $keys = $this->getFieldOrder();
214
215 $fields = $fixed + array_select_keys($fields, $keys) + $fields;
216
217 return $fields;
218 }
219
220 public function getURI() {
221 $engine_key = $this->getEngineKey();
222 $key = $this->getIdentifier();
223
224 return "/transactions/editengine/{$engine_key}/view/{$key}/";
225 }
226
227 public function getCreateURI() {
228 $form_key = $this->getIdentifier();
229 $engine = $this->getEngine();
230 return $engine->getCreateURI($form_key);
231 }
232
233 public function getIdentifier() {
234 $key = $this->getID();
235 if (!$key) {
236 $key = $this->getBuiltinKey();
237 }
238 return $key;
239 }
240
241 public function getDisplayName() {
242 $name = $this->getName();
243 if (strlen($name)) {
244 return $name;
245 }
246
247 $builtin = $this->getBuiltinKey();
248 if ($builtin !== null) {
249 return pht('Builtin Form "%s"', $builtin);
250 }
251
252 return pht('Untitled Form');
253 }
254
255 public function getPreamble() {
256 return $this->getProperty('preamble');
257 }
258
259 public function setPreamble($preamble) {
260 return $this->setProperty('preamble', $preamble);
261 }
262
263 public function setFieldOrder(array $field_order) {
264 return $this->setProperty('order', $field_order);
265 }
266
267 public function getFieldOrder() {
268 return $this->getProperty('order', array());
269 }
270
271 public function setFieldLocks(array $field_locks) {
272 return $this->setProperty('locks', $field_locks);
273 }
274
275 public function getFieldLocks() {
276 return $this->getProperty('locks', array());
277 }
278
279 public function getFieldDefault($key) {
280 $defaults = $this->getProperty('defaults', array());
281 return idx($defaults, $key);
282 }
283
284 public function setFieldDefault($key, $value) {
285 $defaults = $this->getProperty('defaults', array());
286 $defaults[$key] = $value;
287 return $this->setProperty('defaults', $defaults);
288 }
289
290 public function getIcon() {
291 return $this->getEngine()->getIcon();
292 }
293
294
295/* -( PhabricatorPolicyInterface )----------------------------------------- */
296
297
298 public function getCapabilities() {
299 return array(
300 PhabricatorPolicyCapability::CAN_VIEW,
301 PhabricatorPolicyCapability::CAN_EDIT,
302 );
303 }
304
305 public function getPolicy($capability) {
306 switch ($capability) {
307 case PhabricatorPolicyCapability::CAN_VIEW:
308 return $this->getViewPolicy();
309 case PhabricatorPolicyCapability::CAN_EDIT:
310 return $this->getEngine()
311 ->getApplication()
312 ->getPolicy($capability);
313 }
314 }
315
316 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
317 switch ($capability) {
318 case PhabricatorPolicyCapability::CAN_VIEW:
319 return PhabricatorPolicyFilter::hasCapability(
320 $viewer,
321 $this->getEngine()->getApplication(),
322 PhabricatorPolicyCapability::CAN_EDIT);
323 }
324
325 return false;
326 }
327
328/* -( PhabricatorApplicationTransactionInterface )------------------------- */
329
330
331 public function getApplicationTransactionEditor() {
332 return new PhabricatorEditEngineConfigurationEditor();
333 }
334
335 public function getApplicationTransactionTemplate() {
336 return new PhabricatorEditEngineConfigurationTransaction();
337 }
338
339}