Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php
12242 views
1
<?php
2
3
abstract class DiffusionQueryConduitAPIMethod
4
extends DiffusionConduitAPIMethod {
5
6
public function shouldAllowPublic() {
7
return true;
8
}
9
10
private $diffusionRequest;
11
private $repository;
12
13
protected function setDiffusionRequest(DiffusionRequest $request) {
14
$this->diffusionRequest = $request;
15
return $this;
16
}
17
18
protected function getDiffusionRequest() {
19
return $this->diffusionRequest;
20
}
21
22
protected function getRepository(ConduitAPIRequest $request) {
23
return $this->getDiffusionRequest()->getRepository();
24
}
25
26
final protected function defineErrorTypes() {
27
return $this->defineCustomErrorTypes() +
28
array(
29
'ERR-UNKNOWN-REPOSITORY' =>
30
pht('There is no matching repository.'),
31
'ERR-UNKNOWN-VCS-TYPE' =>
32
pht('Unknown repository VCS type.'),
33
'ERR-UNSUPPORTED-VCS' =>
34
pht('VCS is not supported for this method.'),
35
);
36
}
37
38
/**
39
* Subclasses should override this to specify custom error types.
40
*/
41
protected function defineCustomErrorTypes() {
42
return array();
43
}
44
45
final protected function defineParamTypes() {
46
return $this->defineCustomParamTypes() +
47
array(
48
'callsign' => 'optional string (deprecated)',
49
'repository' => 'optional string',
50
'branch' => 'optional string',
51
);
52
}
53
54
/**
55
* Subclasses should override this to specify custom param types.
56
*/
57
protected function defineCustomParamTypes() {
58
return array();
59
}
60
61
/**
62
* Subclasses should override these methods with the proper result for the
63
* pertinent version control system, e.g. getGitResult for Git.
64
*
65
* If the result is not supported for that VCS, do not implement it. e.g.
66
* Subversion (SVN) does not support branches.
67
*/
68
protected function getGitResult(ConduitAPIRequest $request) {
69
throw new ConduitException('ERR-UNSUPPORTED-VCS');
70
}
71
protected function getSVNResult(ConduitAPIRequest $request) {
72
throw new ConduitException('ERR-UNSUPPORTED-VCS');
73
}
74
protected function getMercurialResult(ConduitAPIRequest $request) {
75
throw new ConduitException('ERR-UNSUPPORTED-VCS');
76
}
77
78
/**
79
* This method is final because most queries will need to construct a
80
* @{class:DiffusionRequest} and use it. Consolidating this codepath and
81
* enforcing @{method:getDiffusionRequest} works when we need it is good.
82
*
83
* @{method:getResult} should be overridden by subclasses as necessary, e.g.
84
* there is a common operation across all version control systems that
85
* should occur after @{method:getResult}, like formatting a timestamp.
86
*/
87
final protected function execute(ConduitAPIRequest $request) {
88
$drequest = $this->getDiffusionRequest();
89
90
// We pass this flag on to prevent proxying of any other Conduit calls
91
// which we need to make in order to respond to this one. Although we
92
// could safely proxy them, we take a big performance hit in the common
93
// case, and doing more proxying wouldn't exercise any additional code so
94
// we wouldn't gain a testability/predictability benefit.
95
$is_cluster_request = $request->getIsClusterRequest();
96
$drequest->setIsClusterRequest($is_cluster_request);
97
98
$viewer = $request->getViewer();
99
$repository = $drequest->getRepository();
100
101
// TODO: Allow web UI queries opt out of this if they don't care about
102
// fetching the most up-to-date data? Synchronization can be slow, and a
103
// lot of web reads are probably fine if they're a few seconds out of
104
// date.
105
id(new DiffusionRepositoryClusterEngine())
106
->setViewer($viewer)
107
->setRepository($repository)
108
->synchronizeWorkingCopyBeforeRead();
109
110
return $this->getResult($request);
111
}
112
113
114
protected function newConduitCallProxyClient(ConduitAPIRequest $request) {
115
$viewer = $request->getViewer();
116
117
$identifier = $request->getValue('repository');
118
if ($identifier === null) {
119
$identifier = $request->getValue('callsign');
120
}
121
122
$drequest = DiffusionRequest::newFromDictionary(
123
array(
124
'user' => $viewer,
125
'repository' => $identifier,
126
'branch' => $request->getValue('branch'),
127
'path' => $request->getValue('path'),
128
'commit' => $request->getValue('commit'),
129
));
130
131
if (!$drequest) {
132
throw new Exception(
133
pht(
134
'Repository "%s" is not a valid repository.',
135
$identifier));
136
}
137
138
$repository = $drequest->getRepository();
139
140
$client = $repository->newConduitClientForRequest($request);
141
if ($client) {
142
return $client;
143
}
144
145
$this->setDiffusionRequest($drequest);
146
147
return null;
148
}
149
150
protected function getResult(ConduitAPIRequest $request) {
151
$repository = $this->getRepository($request);
152
$result = null;
153
switch ($repository->getVersionControlSystem()) {
154
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
155
$result = $this->getGitResult($request);
156
break;
157
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
158
$result = $this->getMercurialResult($request);
159
break;
160
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
161
$result = $this->getSVNResult($request);
162
break;
163
default:
164
throw new ConduitException('ERR-UNKNOWN-VCS-TYPE');
165
break;
166
}
167
return $result;
168
}
169
170
}
171
172