[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/releeph/storage/ -> ReleephRequest.php (source)

   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  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1