@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
3/**
4 * @task autoplan Autoplans
5 */
6final class HarbormasterBuildPlan extends HarbormasterDAO
7 implements
8 PhabricatorApplicationTransactionInterface,
9 PhabricatorPolicyInterface,
10 PhabricatorSubscribableInterface,
11 PhabricatorNgramsInterface,
12 PhabricatorConduitResultInterface,
13 PhabricatorProjectInterface,
14 PhabricatorPolicyCodexInterface {
15
16 protected $name;
17 protected $planStatus;
18 protected $planAutoKey;
19 protected $viewPolicy;
20 protected $editPolicy;
21 protected $properties = array();
22
23 const STATUS_ACTIVE = 'active';
24 const STATUS_DISABLED = 'disabled';
25
26 private $buildSteps = self::ATTACHABLE;
27
28 public static function initializeNewBuildPlan(PhabricatorUser $actor) {
29 $app = id(new PhabricatorApplicationQuery())
30 ->setViewer($actor)
31 ->withClasses(array(PhabricatorHarbormasterApplication::class))
32 ->executeOne();
33
34 $view_policy = $app->getPolicy(
35 HarbormasterBuildPlanDefaultViewCapability::CAPABILITY);
36 $edit_policy = $app->getPolicy(
37 HarbormasterBuildPlanDefaultEditCapability::CAPABILITY);
38
39 return id(new HarbormasterBuildPlan())
40 ->setName('')
41 ->setPlanStatus(self::STATUS_ACTIVE)
42 ->attachBuildSteps(array())
43 ->setViewPolicy($view_policy)
44 ->setEditPolicy($edit_policy);
45 }
46
47 protected function getConfiguration() {
48 return array(
49 self::CONFIG_AUX_PHID => true,
50 self::CONFIG_SERIALIZATION => array(
51 'properties' => self::SERIALIZATION_JSON,
52 ),
53 self::CONFIG_COLUMN_SCHEMA => array(
54 'name' => 'sort128',
55 'planStatus' => 'text32',
56 'planAutoKey' => 'text32?',
57 ),
58 self::CONFIG_KEY_SCHEMA => array(
59 'key_status' => array(
60 'columns' => array('planStatus'),
61 ),
62 'key_name' => array(
63 'columns' => array('name'),
64 ),
65 'key_planautokey' => array(
66 'columns' => array('planAutoKey'),
67 'unique' => true,
68 ),
69 ),
70 ) + parent::getConfiguration();
71 }
72
73 public function generatePHID() {
74 return PhabricatorPHID::generateNewPHID(
75 HarbormasterBuildPlanPHIDType::TYPECONST);
76 }
77
78 /**
79 * @param array<HarbormasterBuildStep> $steps
80 */
81 public function attachBuildSteps(array $steps) {
82 assert_instances_of($steps, HarbormasterBuildStep::class);
83 $this->buildSteps = $steps;
84 return $this;
85 }
86
87 public function getBuildSteps() {
88 return $this->assertAttached($this->buildSteps);
89 }
90
91 public function isDisabled() {
92 return ($this->getPlanStatus() == self::STATUS_DISABLED);
93 }
94
95 public function getURI() {
96 return urisprintf(
97 '/harbormaster/plan/%s/',
98 $this->getID());
99 }
100
101 public function getObjectName() {
102 return pht('Plan %d', $this->getID());
103 }
104
105 public function getPlanProperty($key, $default = null) {
106 return idx($this->properties, $key, $default);
107 }
108
109 public function setPlanProperty($key, $value) {
110 $this->properties[$key] = $value;
111 return $this;
112 }
113
114
115/* -( Autoplans )---------------------------------------------------------- */
116
117
118 public function isAutoplan() {
119 return ($this->getPlanAutoKey() !== null);
120 }
121
122
123 public function getAutoplan() {
124 if (!$this->isAutoplan()) {
125 return null;
126 }
127
128 return HarbormasterBuildAutoplan::getAutoplan($this->getPlanAutoKey());
129 }
130
131
132 public function canRunManually() {
133 if ($this->isAutoplan()) {
134 return false;
135 }
136
137 return true;
138 }
139
140 public function getName() {
141 $autoplan = $this->getAutoplan();
142 if ($autoplan) {
143 return $autoplan->getAutoplanName();
144 }
145
146 return parent::getName();
147 }
148
149 public function hasRunCapability(PhabricatorUser $viewer) {
150 try {
151 $this->assertHasRunCapability($viewer);
152 return true;
153 } catch (PhabricatorPolicyException $ex) {
154 return false;
155 }
156 }
157
158 public function canRunWithoutEditCapability() {
159 $runnable = HarbormasterBuildPlanBehavior::BEHAVIOR_RUNNABLE;
160 $if_viewable = HarbormasterBuildPlanBehavior::RUNNABLE_IF_VIEWABLE;
161
162 $option = HarbormasterBuildPlanBehavior::getBehavior($runnable)
163 ->getPlanOption($this);
164
165 return ($option->getKey() === $if_viewable);
166 }
167
168 public function assertHasRunCapability(PhabricatorUser $viewer) {
169 if ($this->canRunWithoutEditCapability()) {
170 $capability = PhabricatorPolicyCapability::CAN_VIEW;
171 } else {
172 $capability = PhabricatorPolicyCapability::CAN_EDIT;
173 }
174
175 PhabricatorPolicyFilter::requireCapability(
176 $viewer,
177 $this,
178 $capability);
179 }
180
181
182/* -( PhabricatorSubscribableInterface )----------------------------------- */
183
184
185 public function isAutomaticallySubscribed($phid) {
186 return false;
187 }
188
189
190/* -( PhabricatorApplicationTransactionInterface )------------------------- */
191
192
193 public function getApplicationTransactionEditor() {
194 return new HarbormasterBuildPlanEditor();
195 }
196
197 public function getApplicationTransactionTemplate() {
198 return new HarbormasterBuildPlanTransaction();
199 }
200
201/* -( PhabricatorPolicyInterface )----------------------------------------- */
202
203
204 public function getCapabilities() {
205 return array(
206 PhabricatorPolicyCapability::CAN_VIEW,
207 PhabricatorPolicyCapability::CAN_EDIT,
208 );
209 }
210
211 public function getPolicy($capability) {
212 switch ($capability) {
213 case PhabricatorPolicyCapability::CAN_VIEW:
214 if ($this->isAutoplan()) {
215 return PhabricatorPolicies::getMostOpenPolicy();
216 }
217 return $this->getViewPolicy();
218 case PhabricatorPolicyCapability::CAN_EDIT:
219 if ($this->isAutoplan()) {
220 return PhabricatorPolicies::POLICY_NOONE;
221 }
222 return $this->getEditPolicy();
223 }
224 }
225
226 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
227 return false;
228 }
229
230 public function describeAutomaticCapability($capability) {
231 $messages = array();
232
233 switch ($capability) {
234 case PhabricatorPolicyCapability::CAN_EDIT:
235 if ($this->isAutoplan()) {
236 $messages[] = pht(
237 'This is an autoplan (a builtin plan provided by an application) '.
238 'so it can not be edited.');
239 }
240 break;
241 }
242
243 return $messages;
244 }
245
246
247/* -( PhabricatorNgramsInterface )----------------------------------------- */
248
249
250 public function newNgrams() {
251 return array(
252 id(new HarbormasterBuildPlanNameNgrams())
253 ->setValue($this->getName()),
254 );
255 }
256
257
258/* -( PhabricatorConduitResultInterface )---------------------------------- */
259
260
261 public function getFieldSpecificationsForConduit() {
262 return array(
263 id(new PhabricatorConduitSearchFieldSpecification())
264 ->setKey('name')
265 ->setType('string')
266 ->setDescription(pht('The name of this build plan.')),
267 id(new PhabricatorConduitSearchFieldSpecification())
268 ->setKey('status')
269 ->setType('map<string, wild>')
270 ->setDescription(pht('The current status of this build plan.')),
271 id(new PhabricatorConduitSearchFieldSpecification())
272 ->setKey('behaviors')
273 ->setType('map<string, string>')
274 ->setDescription(pht('Behavior configuration for the build plan.')),
275 );
276 }
277
278 public function getFieldValuesForConduit() {
279 $behavior_map = array();
280
281 $behaviors = HarbormasterBuildPlanBehavior::newPlanBehaviors();
282 foreach ($behaviors as $behavior) {
283 $option = $behavior->getPlanOption($this);
284
285 $behavior_map[$behavior->getKey()] = array(
286 'value' => $option->getKey(),
287 );
288 }
289
290 return array(
291 'name' => $this->getName(),
292 'status' => array(
293 'value' => $this->getPlanStatus(),
294 ),
295 'behaviors' => $behavior_map,
296 );
297 }
298
299 public function getConduitSearchAttachments() {
300 return array();
301 }
302
303
304/* -( PhabricatorPolicyCodexInterface )------------------------------------ */
305
306
307 public function newPolicyCodex() {
308 return new HarbormasterBuildPlanPolicyCodex();
309 }
310
311}