Path: blob/master/src/applications/diffusion/query/lowlevel/DiffusionLowLevelCommitFieldsQuery.php
12242 views
<?php12final class DiffusionLowLevelCommitFieldsQuery3extends DiffusionLowLevelQuery {45private $ref;6private $revisionMatchData = array(7'usedURI' => null,8'foundURI' => null,9'validDomain' => null,10'matchHashType' => null,11'matchHashValue' => null,12);1314public function withCommitRef(DiffusionCommitRef $ref) {15$this->ref = $ref;16return $this;17}1819public function getRevisionMatchData() {20return $this->revisionMatchData;21}2223private function setRevisionMatchData($key, $value) {24$this->revisionMatchData[$key] = $value;25return $this;26}2728protected function executeQuery() {29$ref = $this->ref;30$message = $ref->getMessage();31$hashes = $ref->getHashes();3233$params = array(34'corpus' => $message,35'partial' => true,36);3738$result = id(new ConduitCall('differential.parsecommitmessage', $params))39->setUser(PhabricatorUser::getOmnipotentUser())40->execute();41$fields = $result['fields'];4243$revision_id = idx($fields, 'revisionID');44if ($revision_id) {45$this->setRevisionMatchData('usedURI', true);46} else {47$this->setRevisionMatchData('usedURI', false);48}49$revision_id_info = $result['revisionIDFieldInfo'];50$this->setRevisionMatchData('foundURI', $revision_id_info['value']);51$this->setRevisionMatchData(52'validDomain',53$revision_id_info['validDomain']);5455// If there is no "Differential Revision:" field in the message, try to56// identify the revision by doing a hash lookup.5758if (!$revision_id && $hashes) {59$hash_list = array();60foreach ($hashes as $hash) {61$hash_list[] = array($hash->getHashType(), $hash->getHashValue());62}63$revisions = id(new DifferentialRevisionQuery())64->setViewer(PhabricatorUser::getOmnipotentUser())65->needHashes(true)66->withCommitHashes($hash_list)67->execute();6869if ($revisions) {70$revision = $this->pickBestRevision($revisions);7172$fields['revisionID'] = $revision->getID();73$revision_hashes = $revision->getHashes();7475$revision_hashes = DiffusionCommitHash::convertArrayToObjects(76$revision_hashes);77$revision_hashes = mpull($revision_hashes, null, 'getHashType');7879// sort the hashes in the order the mighty80// @{class:ArcanstDifferentialRevisionHash} does; probably unnecessary81// but should future proof things nicely.82$revision_hashes = array_select_keys(83$revision_hashes,84ArcanistDifferentialRevisionHash::getTypes());8586foreach ($hashes as $hash) {87$revision_hash = idx($revision_hashes, $hash->getHashType());88if (!$revision_hash) {89continue;90}91if ($revision_hash->getHashValue() == $hash->getHashValue()) {92$this->setRevisionMatchData(93'matchHashType',94$hash->getHashType());95$this->setRevisionMatchData(96'matchHashValue',97$hash->getHashValue());98break;99}100}101}102}103104return $fields;105}106107108/**109* When querying for revisions by hash, more than one revision may be found.110* This function identifies the "best" revision from such a set. Typically,111* there is only one revision found. Otherwise, we try to pick an accepted112* revision first, followed by an open revision, and otherwise we go with a113* closed or abandoned revision as a last resort.114*/115private function pickBestRevision(array $revisions) {116assert_instances_of($revisions, 'DifferentialRevision');117118// If we have more than one revision of a given status, choose the most119// recently updated one.120$revisions = msort($revisions, 'getDateModified');121$revisions = array_reverse($revisions);122123// Try to find an accepted revision first.124foreach ($revisions as $revision) {125if ($revision->isAccepted()) {126return $revision;127}128}129130// Try to find an open revision.131foreach ($revisions as $revision) {132if (!$revision->isClosed()) {133return $revision;134}135}136137// Settle for whatever's left.138return head($revisions);139}140141}142143144