Path: blob/master/src/applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php
12242 views
<?php12abstract class DiffusionQueryConduitAPIMethod3extends DiffusionConduitAPIMethod {45public function shouldAllowPublic() {6return true;7}89private $diffusionRequest;10private $repository;1112protected function setDiffusionRequest(DiffusionRequest $request) {13$this->diffusionRequest = $request;14return $this;15}1617protected function getDiffusionRequest() {18return $this->diffusionRequest;19}2021protected function getRepository(ConduitAPIRequest $request) {22return $this->getDiffusionRequest()->getRepository();23}2425final protected function defineErrorTypes() {26return $this->defineCustomErrorTypes() +27array(28'ERR-UNKNOWN-REPOSITORY' =>29pht('There is no matching repository.'),30'ERR-UNKNOWN-VCS-TYPE' =>31pht('Unknown repository VCS type.'),32'ERR-UNSUPPORTED-VCS' =>33pht('VCS is not supported for this method.'),34);35}3637/**38* Subclasses should override this to specify custom error types.39*/40protected function defineCustomErrorTypes() {41return array();42}4344final protected function defineParamTypes() {45return $this->defineCustomParamTypes() +46array(47'callsign' => 'optional string (deprecated)',48'repository' => 'optional string',49'branch' => 'optional string',50);51}5253/**54* Subclasses should override this to specify custom param types.55*/56protected function defineCustomParamTypes() {57return array();58}5960/**61* Subclasses should override these methods with the proper result for the62* pertinent version control system, e.g. getGitResult for Git.63*64* If the result is not supported for that VCS, do not implement it. e.g.65* Subversion (SVN) does not support branches.66*/67protected function getGitResult(ConduitAPIRequest $request) {68throw new ConduitException('ERR-UNSUPPORTED-VCS');69}70protected function getSVNResult(ConduitAPIRequest $request) {71throw new ConduitException('ERR-UNSUPPORTED-VCS');72}73protected function getMercurialResult(ConduitAPIRequest $request) {74throw new ConduitException('ERR-UNSUPPORTED-VCS');75}7677/**78* This method is final because most queries will need to construct a79* @{class:DiffusionRequest} and use it. Consolidating this codepath and80* enforcing @{method:getDiffusionRequest} works when we need it is good.81*82* @{method:getResult} should be overridden by subclasses as necessary, e.g.83* there is a common operation across all version control systems that84* should occur after @{method:getResult}, like formatting a timestamp.85*/86final protected function execute(ConduitAPIRequest $request) {87$drequest = $this->getDiffusionRequest();8889// We pass this flag on to prevent proxying of any other Conduit calls90// which we need to make in order to respond to this one. Although we91// could safely proxy them, we take a big performance hit in the common92// case, and doing more proxying wouldn't exercise any additional code so93// we wouldn't gain a testability/predictability benefit.94$is_cluster_request = $request->getIsClusterRequest();95$drequest->setIsClusterRequest($is_cluster_request);9697$viewer = $request->getViewer();98$repository = $drequest->getRepository();99100// TODO: Allow web UI queries opt out of this if they don't care about101// fetching the most up-to-date data? Synchronization can be slow, and a102// lot of web reads are probably fine if they're a few seconds out of103// date.104id(new DiffusionRepositoryClusterEngine())105->setViewer($viewer)106->setRepository($repository)107->synchronizeWorkingCopyBeforeRead();108109return $this->getResult($request);110}111112113protected function newConduitCallProxyClient(ConduitAPIRequest $request) {114$viewer = $request->getViewer();115116$identifier = $request->getValue('repository');117if ($identifier === null) {118$identifier = $request->getValue('callsign');119}120121$drequest = DiffusionRequest::newFromDictionary(122array(123'user' => $viewer,124'repository' => $identifier,125'branch' => $request->getValue('branch'),126'path' => $request->getValue('path'),127'commit' => $request->getValue('commit'),128));129130if (!$drequest) {131throw new Exception(132pht(133'Repository "%s" is not a valid repository.',134$identifier));135}136137$repository = $drequest->getRepository();138139$client = $repository->newConduitClientForRequest($request);140if ($client) {141return $client;142}143144$this->setDiffusionRequest($drequest);145146return null;147}148149protected function getResult(ConduitAPIRequest $request) {150$repository = $this->getRepository($request);151$result = null;152switch ($repository->getVersionControlSystem()) {153case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:154$result = $this->getGitResult($request);155break;156case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:157$result = $this->getMercurialResult($request);158break;159case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:160$result = $this->getSVNResult($request);161break;162default:163throw new ConduitException('ERR-UNKNOWN-VCS-TYPE');164break;165}166return $result;167}168169}170171172