[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class ReleephRequest extends ReleephDAO 4 implements 5 PhabricatorPolicyInterface, 6 PhabricatorCustomFieldInterface { 7 8 protected $branchID; 9 protected $requestUserPHID; 10 protected $details = array(); 11 protected $userIntents = array(); 12 protected $inBranch; 13 protected $pickStatus; 14 protected $mailKey; 15 16 /** 17 * The object which is being requested. Normally this is a commit, but it 18 * might also be a revision. In the future, it could be a repository branch 19 * or an external object (like a GitHub pull request). 20 */ 21 protected $requestedObjectPHID; 22 23 // Information about the thing being requested 24 protected $requestCommitPHID; 25 26 // Information about the last commit to the releeph branch 27 protected $commitIdentifier; 28 protected $commitPHID; 29 30 31 private $customFields = self::ATTACHABLE; 32 private $branch = self::ATTACHABLE; 33 private $requestedObject = self::ATTACHABLE; 34 35 36 /* -( Constants and helper methods )--------------------------------------- */ 37 38 const INTENT_WANT = 'want'; 39 const INTENT_PASS = 'pass'; 40 41 const PICK_PENDING = 1; // old 42 const PICK_FAILED = 2; 43 const PICK_OK = 3; 44 const PICK_MANUAL = 4; // old 45 const REVERT_OK = 5; 46 const REVERT_FAILED = 6; 47 48 public function shouldBeInBranch() { 49 return 50 $this->getPusherIntent() == self::INTENT_WANT && 51 /** 52 * We use "!= pass" instead of "== want" in case the requestor intent is 53 * not present. In other words, only revert if the requestor explicitly 54 * passed. 55 */ 56 $this->getRequestorIntent() != self::INTENT_PASS; 57 } 58 59 /** 60 * Will return INTENT_WANT if any pusher wants this request, and no pusher 61 * passes on this request. 62 */ 63 public function getPusherIntent() { 64 $product = $this->getBranch()->getProduct(); 65 66 if (!$product->getPushers()) { 67 return self::INTENT_WANT; 68 } 69 70 $found_pusher_want = false; 71 foreach ($this->userIntents as $phid => $intent) { 72 if ($product->isAuthoritativePHID($phid)) { 73 if ($intent == self::INTENT_PASS) { 74 return self::INTENT_PASS; 75 } 76 77 $found_pusher_want = true; 78 } 79 } 80 81 if ($found_pusher_want) { 82 return self::INTENT_WANT; 83 } else { 84 return null; 85 } 86 } 87 88 public function getRequestorIntent() { 89 return idx($this->userIntents, $this->requestUserPHID); 90 } 91 92 public function getStatus() { 93 return $this->calculateStatus(); 94 } 95 96 public function getMonogram() { 97 return 'Y'.$this->getID(); 98 } 99 100 public function getBranch() { 101 return $this->assertAttached($this->branch); 102 } 103 104 public function attachBranch(ReleephBranch $branch) { 105 $this->branch = $branch; 106 return $this; 107 } 108 109 public function getRequestedObject() { 110 return $this->assertAttached($this->requestedObject); 111 } 112 113 public function attachRequestedObject($object) { 114 $this->requestedObject = $object; 115 return $this; 116 } 117 118 private function calculateStatus() { 119 if ($this->shouldBeInBranch()) { 120 if ($this->getInBranch()) { 121 return ReleephRequestStatus::STATUS_PICKED; 122 } else { 123 return ReleephRequestStatus::STATUS_NEEDS_PICK; 124 } 125 } else { 126 if ($this->getInBranch()) { 127 return ReleephRequestStatus::STATUS_NEEDS_REVERT; 128 } else { 129 $has_been_in_branch = $this->getCommitIdentifier(); 130 // Regardless of why we reverted something, always say reverted if it 131 // was once in the branch. 132 if ($has_been_in_branch) { 133 return ReleephRequestStatus::STATUS_REVERTED; 134 } else if ($this->getPusherIntent() === ReleephRequest::INTENT_PASS) { 135 // Otherwise, if it has never been in the branch, explicitly say why: 136 return ReleephRequestStatus::STATUS_REJECTED; 137 } else if ($this->getRequestorIntent() === ReleephRequest::INTENT_WANT) { 138 return ReleephRequestStatus::STATUS_REQUESTED; 139 } else { 140 return ReleephRequestStatus::STATUS_ABANDONED; 141 } 142 } 143 } 144 } 145 146 147 /* -( Lisk mechanics )----------------------------------------------------- */ 148 149 public function getConfiguration() { 150 return array( 151 self::CONFIG_AUX_PHID => true, 152 self::CONFIG_SERIALIZATION => array( 153 'details' => self::SERIALIZATION_JSON, 154 'userIntents' => self::SERIALIZATION_JSON, 155 ), 156 self::CONFIG_COLUMN_SCHEMA => array( 157 'requestCommitPHID' => 'phid?', 158 'commitIdentifier' => 'text40?', 159 'commitPHID' => 'phid?', 160 'pickStatus' => 'uint32?', 161 'inBranch' => 'bool', 162 'mailKey' => 'bytes20', 163 'userIntents' => 'text?', 164 ), 165 self::CONFIG_KEY_SCHEMA => array( 166 'key_phid' => null, 167 'phid' => array( 168 'columns' => array('phid'), 169 'unique' => true, 170 ), 171 'requestIdentifierBranch' => array( 172 'columns' => array('requestCommitPHID', 'branchID'), 173 'unique' => true, 174 ), 175 'branchID' => array( 176 'columns' => array('branchID'), 177 ), 178 'key_requestedObject' => array( 179 'columns' => array('requestedObjectPHID'), 180 ), 181 ), 182 ) + parent::getConfiguration(); 183 } 184 185 public function generatePHID() { 186 return PhabricatorPHID::generateNewPHID( 187 ReleephRequestPHIDType::TYPECONST); 188 } 189 190 public function save() { 191 if (!$this->getMailKey()) { 192 $this->setMailKey(Filesystem::readRandomCharacters(20)); 193 } 194 return parent::save(); 195 } 196 197 198 /* -( Helpful accessors )--------------------------------------------------- */ 199 200 201 public function getDetail($key, $default = null) { 202 return idx($this->getDetails(), $key, $default); 203 } 204 205 public function setDetail($key, $value) { 206 $this->details[$key] = $value; 207 return $this; 208 } 209 210 211 /** 212 * Get the commit PHIDs this request is requesting. 213 * 214 * NOTE: For now, this always returns one PHID. 215 * 216 * @return list<phid> Commit PHIDs requested by this request. 217 */ 218 public function getCommitPHIDs() { 219 return array( 220 $this->requestCommitPHID, 221 ); 222 } 223 224 public function getReason() { 225 // Backward compatibility: reason used to be called comments 226 $reason = $this->getDetail('reason'); 227 if (!$reason) { 228 return $this->getDetail('comments'); 229 } 230 return $reason; 231 } 232 233 /** 234 * Allow a null summary, and fall back to the title of the commit. 235 */ 236 public function getSummaryForDisplay() { 237 $summary = $this->getDetail('summary'); 238 239 if (!strlen($summary)) { 240 $commit = $this->loadPhabricatorRepositoryCommit(); 241 if ($commit) { 242 $summary = $commit->getSummary(); 243 } 244 } 245 246 if (!strlen($summary)) { 247 $summary = pht('None'); 248 } 249 250 return $summary; 251 } 252 253 /* -( Loading external objects )------------------------------------------- */ 254 255 public function loadPhabricatorRepositoryCommit() { 256 return $this->loadOneRelative( 257 new PhabricatorRepositoryCommit(), 258 'phid', 259 'getRequestCommitPHID'); 260 } 261 262 public function loadPhabricatorRepositoryCommitData() { 263 $commit = $this->loadPhabricatorRepositoryCommit(); 264 if ($commit) { 265 return $commit->loadOneRelative( 266 new PhabricatorRepositoryCommitData(), 267 'commitID'); 268 } 269 } 270 271 272 /* -( State change helpers )----------------------------------------------- */ 273 274 public function setUserIntent(PhabricatorUser $user, $intent) { 275 $this->userIntents[$user->getPHID()] = $intent; 276 return $this; 277 } 278 279 280 /* -( Migrating to status-less ReleephRequests )--------------------------- */ 281 282 protected function didReadData() { 283 if ($this->userIntents === null) { 284 $this->userIntents = array(); 285 } 286 } 287 288 public function setStatus($value) { 289 throw new Exception('`status` is now deprecated!'); 290 } 291 292 /* -( Make magic Lisk methods private )------------------------------------ */ 293 294 private function setUserIntents(array $ar) { 295 return parent::setUserIntents($ar); 296 } 297 298 299 /* -( PhabricatorPolicyInterface )----------------------------------------- */ 300 301 302 public function getCapabilities() { 303 return array( 304 PhabricatorPolicyCapability::CAN_VIEW, 305 PhabricatorPolicyCapability::CAN_EDIT, 306 ); 307 } 308 309 public function getPolicy($capability) { 310 return $this->getBranch()->getPolicy($capability); 311 } 312 313 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 314 return $this->getBranch()->hasAutomaticCapability($capability, $viewer); 315 } 316 317 public function describeAutomaticCapability($capability) { 318 return pht( 319 'Pull requests have the same policies as the branches they are '. 320 'requested against.'); 321 } 322 323 324 325 /* -( PhabricatorCustomFieldInterface )------------------------------------ */ 326 327 328 public function getCustomFieldSpecificationForRole($role) { 329 return PhabricatorEnv::getEnvConfig('releeph.fields'); 330 } 331 332 public function getCustomFieldBaseClass() { 333 return 'ReleephFieldSpecification'; 334 } 335 336 public function getCustomFields() { 337 return $this->assertAttached($this->customFields); 338 } 339 340 public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) { 341 $this->customFields = $fields; 342 return $this; 343 } 344 345 346 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |