Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / diffusion / query / lowlevel / DiffusionLowLevelCommitFieldsQuery.php
bloba0548d51789ae0f47e25a9d58c99948d7f6fdb31
1 <?php
3 final class DiffusionLowLevelCommitFieldsQuery
4 extends DiffusionLowLevelQuery {
6 private $ref;
7 private $revisionMatchData = array(
8 'usedURI' => null,
9 'foundURI' => null,
10 'validDomain' => null,
11 'matchHashType' => null,
12 'matchHashValue' => null,
15 public function withCommitRef(DiffusionCommitRef $ref) {
16 $this->ref = $ref;
17 return $this;
20 public function getRevisionMatchData() {
21 return $this->revisionMatchData;
24 private function setRevisionMatchData($key, $value) {
25 $this->revisionMatchData[$key] = $value;
26 return $this;
29 protected function executeQuery() {
30 $ref = $this->ref;
31 $message = $ref->getMessage();
32 $hashes = $ref->getHashes();
34 $params = array(
35 'corpus' => $message,
36 'partial' => true,
39 $result = id(new ConduitCall('differential.parsecommitmessage', $params))
40 ->setUser(PhabricatorUser::getOmnipotentUser())
41 ->execute();
42 $fields = $result['fields'];
44 $revision_id = idx($fields, 'revisionID');
45 if ($revision_id) {
46 $this->setRevisionMatchData('usedURI', true);
47 } else {
48 $this->setRevisionMatchData('usedURI', false);
50 $revision_id_info = $result['revisionIDFieldInfo'];
51 $this->setRevisionMatchData('foundURI', $revision_id_info['value']);
52 $this->setRevisionMatchData(
53 'validDomain',
54 $revision_id_info['validDomain']);
56 // If there is no "Differential Revision:" field in the message, try to
57 // identify the revision by doing a hash lookup.
59 if (!$revision_id && $hashes) {
60 $hash_list = array();
61 foreach ($hashes as $hash) {
62 $hash_list[] = array($hash->getHashType(), $hash->getHashValue());
64 $revisions = id(new DifferentialRevisionQuery())
65 ->setViewer(PhabricatorUser::getOmnipotentUser())
66 ->needHashes(true)
67 ->withCommitHashes($hash_list)
68 ->execute();
70 if ($revisions) {
71 $revision = $this->pickBestRevision($revisions);
73 $fields['revisionID'] = $revision->getID();
74 $revision_hashes = $revision->getHashes();
76 $revision_hashes = DiffusionCommitHash::convertArrayToObjects(
77 $revision_hashes);
78 $revision_hashes = mpull($revision_hashes, null, 'getHashType');
80 // sort the hashes in the order the mighty
81 // @{class:ArcanstDifferentialRevisionHash} does; probably unnecessary
82 // but should future proof things nicely.
83 $revision_hashes = array_select_keys(
84 $revision_hashes,
85 ArcanistDifferentialRevisionHash::getTypes());
87 foreach ($hashes as $hash) {
88 $revision_hash = idx($revision_hashes, $hash->getHashType());
89 if (!$revision_hash) {
90 continue;
92 if ($revision_hash->getHashValue() == $hash->getHashValue()) {
93 $this->setRevisionMatchData(
94 'matchHashType',
95 $hash->getHashType());
96 $this->setRevisionMatchData(
97 'matchHashValue',
98 $hash->getHashValue());
99 break;
105 return $fields;
110 * When querying for revisions by hash, more than one revision may be found.
111 * This function identifies the "best" revision from such a set. Typically,
112 * there is only one revision found. Otherwise, we try to pick an accepted
113 * revision first, followed by an open revision, and otherwise we go with a
114 * closed or abandoned revision as a last resort.
116 private function pickBestRevision(array $revisions) {
117 assert_instances_of($revisions, 'DifferentialRevision');
119 // If we have more than one revision of a given status, choose the most
120 // recently updated one.
121 $revisions = msort($revisions, 'getDateModified');
122 $revisions = array_reverse($revisions);
124 // Try to find an accepted revision first.
125 foreach ($revisions as $revision) {
126 if ($revision->isAccepted()) {
127 return $revision;
131 // Try to find an open revision.
132 foreach ($revisions as $revision) {
133 if (!$revision->isClosed()) {
134 return $revision;
138 // Settle for whatever's left.
139 return head($revisions);