1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-15 19:32:40 +01:00
phorge-phorge/src/applications/diffusion/controller/DiffusionController.php

253 lines
6.4 KiB
PHP
Raw Normal View History

<?php
abstract class DiffusionController extends PhabricatorController {
protected $diffusionRequest;
public function setDiffusionRequest(DiffusionRequest $request) {
$this->diffusionRequest = $request;
return $this;
}
protected function getDiffusionRequest() {
if (!$this->diffusionRequest) {
throw new Exception('No Diffusion request object!');
}
return $this->diffusionRequest;
}
public function willBeginExecution() {
$request = $this->getRequest();
// Check if this is a VCS request, e.g. from "git clone", "hg clone", or
// "svn checkout". If it is, we jump off into repository serving code to
// process the request.
if (DiffusionServeController::isVCSRequest($request)) {
Decouple some aspects of request routing and construction Summary: Ref T5702. This is a forward-looking change which provides some very broad API improvements but does not implement them. In particular: - Controllers no longer require `$request` to construct. This is mostly for T5702, directly, but simplifies things in general. Instead, we call `setRequest()` before using a controller. Only a small number of sites activate controllers, so this is less code overall, and more consistent with most constructors not having any parameters or effects. - `$request` now offers `getURIData($key, ...)`. This is an alternate way of accessing `$data` which is currently only available on `willProcessRequest(array $data)`. Almost all controllers which implement this method do so in order to read one or two things out of the URI data. Instead, let them just read this data directly when processing the request. - Introduce `handleRequest(AphrontRequest $request)` and deprecate (very softly) `processRequest()`. The majority of `processRequest()` calls begin `$request = $this->getRequest()`, which is avoided with the more practical signature. - Provide `getViewer()` on `$request`, and a convenience `getViewer()` on `$controller`. This fixes `$viewer = $request->getUser();` into `$viewer = $request->getViewer();`, and converts the `$request + $viewer` two-liner into a single `$this->getViewer()`. Test Plan: - Browsed around in general. - Hit special controllers (redirect, 404). - Hit AuditList controller (uses new style). Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5702 Differential Revision: https://secure.phabricator.com/D10698
2014-10-17 14:01:40 +02:00
$serve_controller = id(new DiffusionServeController())
->setCurrentApplication($this->getCurrentApplication());
return $this->delegateToController($serve_controller);
}
return parent::willBeginExecution();
}
protected function shouldLoadDiffusionRequest() {
return true;
}
final public function handleRequest(AphrontRequest $request) {
if ($request->getURIData('callsign') &&
$this->shouldLoadDiffusionRequest()) {
try {
$drequest = DiffusionRequest::newFromAphrontRequestDictionary(
$request->getURIMap(),
$request);
} catch (Exception $ex) {
return id(new Aphront404Response())
->setRequest($request);
}
$this->setDiffusionRequest($drequest);
Fix many encoding and architecture problems in Diffusion request and URI handling Summary: Diffusion request/uri handling is currently a big, hastily ported mess. In particular, it has: - Tons and tons of duplicated code. - Bugs with handling unusual branch and file names. - An excessively large (and yet insufficiently expressive) API on DiffusionRequest, including a nonsensical concrete base class. - Other tools were doing hacky things like passing ":" branch names. This diff attempts to fix these issues. - Make the base class abstract (it was concrete ONLY for "/diffusion/"). - Move all URI generation to DiffusionRequest. Make the core static. Add unit tests. - Delete the 300 copies of URI generation code throughout Diffusion. - Move all URI parsing to DiffusionRequest. Make the core static. Add unit tests. - Add an appropriate static initializer for other callers. - Convert all code calling `newFromAphrontRequestDictionary` outside of Diffusion to the new `newFromDictionary` API. - Refactor static initializers to be sensibly-sized. - Refactor derived DiffusionRequest classes to remove duplicated code. - Properly encode branch names (fixes branches with "/", see <https://github.com/facebook/phabricator/issues/100>). - Properly encode path names (fixes issues in D1742). - Properly escape delimiter characters ";" and "$" in path names so files like "$100" are not interpreted as "line 100". - Fix a couple warnings. - Fix a couple lint issues. - Fix a bug where we would not parse filenames with spaces in them correctly in the Git browse query. - Fix a bug where Git change queries would fail unnecessarily. - Provide or improve some documentation. This thing is pretty gigantic but also kind of hard to split up. If it's unreasonably difficult to review, let me know and I can take a stab at it though. This supplants D1742. Test Plan: - Used home, repository, branch, browse, change, history, diff (ajax), lastmodified (ajax) views of Diffusion. - Used Owners typeaheads and search. - Used diffusion.getrecentcommitsbypath method. - Pushed a change to an absurdly-named file on an absurdly-named branch, everything worked properly. {F9185} Reviewers: nh, vrana, btrahan Reviewed By: btrahan CC: aran, epriestley Differential Revision: https://secure.phabricator.com/D1921
2012-03-20 03:52:14 +01:00
}
return $this->processDiffusionRequest($request);
}
abstract protected function processDiffusionRequest(AphrontRequest $request);
public function buildCrumbs(array $spec = array()) {
$crumbs = $this->buildApplicationCrumbs();
2011-03-31 07:08:41 +02:00
$crumb_list = $this->buildCrumbList($spec);
foreach ($crumb_list as $crumb) {
$crumbs->addCrumb($crumb);
}
2011-03-31 07:08:41 +02:00
return $crumbs;
}
private function buildCrumbList(array $spec = array()) {
$spec = $spec + array(
'commit' => null,
'tags' => null,
'branches' => null,
'view' => null,
);
$crumb_list = array();
Fix many encoding and architecture problems in Diffusion request and URI handling Summary: Diffusion request/uri handling is currently a big, hastily ported mess. In particular, it has: - Tons and tons of duplicated code. - Bugs with handling unusual branch and file names. - An excessively large (and yet insufficiently expressive) API on DiffusionRequest, including a nonsensical concrete base class. - Other tools were doing hacky things like passing ":" branch names. This diff attempts to fix these issues. - Make the base class abstract (it was concrete ONLY for "/diffusion/"). - Move all URI generation to DiffusionRequest. Make the core static. Add unit tests. - Delete the 300 copies of URI generation code throughout Diffusion. - Move all URI parsing to DiffusionRequest. Make the core static. Add unit tests. - Add an appropriate static initializer for other callers. - Convert all code calling `newFromAphrontRequestDictionary` outside of Diffusion to the new `newFromDictionary` API. - Refactor static initializers to be sensibly-sized. - Refactor derived DiffusionRequest classes to remove duplicated code. - Properly encode branch names (fixes branches with "/", see <https://github.com/facebook/phabricator/issues/100>). - Properly encode path names (fixes issues in D1742). - Properly escape delimiter characters ";" and "$" in path names so files like "$100" are not interpreted as "line 100". - Fix a couple warnings. - Fix a couple lint issues. - Fix a bug where we would not parse filenames with spaces in them correctly in the Git browse query. - Fix a bug where Git change queries would fail unnecessarily. - Provide or improve some documentation. This thing is pretty gigantic but also kind of hard to split up. If it's unreasonably difficult to review, let me know and I can take a stab at it though. This supplants D1742. Test Plan: - Used home, repository, branch, browse, change, history, diff (ajax), lastmodified (ajax) views of Diffusion. - Used Owners typeaheads and search. - Used diffusion.getrecentcommitsbypath method. - Pushed a change to an absurdly-named file on an absurdly-named branch, everything worked properly. {F9185} Reviewers: nh, vrana, btrahan Reviewed By: btrahan CC: aran, epriestley Differential Revision: https://secure.phabricator.com/D1921
2012-03-20 03:52:14 +01:00
// On the home page, we don't have a DiffusionRequest.
if ($this->diffusionRequest) {
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
} else {
$drequest = null;
$repository = null;
}
if (!$repository) {
2011-03-31 07:08:41 +02:00
return $crumb_list;
}
$callsign = $repository->getCallsign();
$repository_name = $repository->getName();
if (!$spec['commit'] && !$spec['tags'] && !$spec['branches']) {
$branch_name = $drequest->getBranch();
if ($branch_name) {
$repository_name .= ' ('.$branch_name.')';
}
}
$crumb = id(new PHUICrumbView())
->setName($repository_name);
if (!$spec['view'] && !$spec['commit'] &&
!$spec['tags'] && !$spec['branches']) {
$crumb_list[] = $crumb;
return $crumb_list;
}
$crumb->setHref(
$drequest->generateURI(
array(
'action' => 'branch',
'path' => '/',
)));
$crumb_list[] = $crumb;
$stable_commit = $drequest->getStableCommit();
if ($spec['tags']) {
$crumb = new PHUICrumbView();
if ($spec['commit']) {
$crumb->setName(
pht('Tags for %s', 'r'.$callsign.$stable_commit));
$crumb->setHref($drequest->generateURI(
array(
'action' => 'commit',
'commit' => $drequest->getStableCommit(),
)));
} else {
$crumb->setName(pht('Tags'));
}
$crumb_list[] = $crumb;
2011-03-31 07:08:41 +02:00
return $crumb_list;
}
if ($spec['branches']) {
$crumb = id(new PHUICrumbView())
->setName(pht('Branches'));
$crumb_list[] = $crumb;
return $crumb_list;
}
if ($spec['commit']) {
$crumb = id(new PHUICrumbView())
->setName("r{$callsign}{$stable_commit}")
->setHref("r{$callsign}{$stable_commit}");
$crumb_list[] = $crumb;
return $crumb_list;
}
$crumb = new PHUICrumbView();
$view = $spec['view'];
switch ($view) {
case 'history':
$view_name = pht('History');
break;
case 'browse':
$view_name = pht('Browse');
break;
case 'lint':
$view_name = pht('Lint');
break;
2011-03-14 06:03:30 +01:00
case 'change':
$view_name = pht('Change');
break;
}
$crumb = id(new PHUICrumbView())
->setName($view_name);
$crumb_list[] = $crumb;
2011-03-31 07:08:41 +02:00
return $crumb_list;
}
protected function callConduitWithDiffusionRequest(
$method,
array $params = array()) {
$user = $this->getRequest()->getUser();
$drequest = $this->getDiffusionRequest();
return DiffusionQuery::callConduitWithDiffusionRequest(
$user,
$drequest,
$method,
$params);
}
protected function getRepositoryControllerURI(
PhabricatorRepository $repository,
$path) {
return $this->getApplicationURI($repository->getCallsign().'/'.$path);
}
protected function renderPathLinks(DiffusionRequest $drequest, $action) {
$path = $drequest->getPath();
$path_parts = array_filter(explode('/', trim($path, '/')));
$divider = phutil_tag(
'span',
array(
'class' => 'phui-header-divider',
),
'/');
$links = array();
if ($path_parts) {
$links[] = phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => $action,
'path' => '',
)),
),
'r'.$drequest->getRepository()->getCallsign());
$links[] = $divider;
$accum = '';
$last_key = last_key($path_parts);
foreach ($path_parts as $key => $part) {
$accum .= '/'.$part;
if ($key === $last_key) {
$links[] = $part;
} else {
$links[] = phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => $action,
'path' => $accum.'/',
)),
),
$part);
$links[] = $divider;
}
}
} else {
$links[] = 'r'.$drequest->getRepository()->getCallsign();
$links[] = $divider;
}
return $links;
}
protected function renderStatusMessage($title, $body) {
return id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setTitle($title)
->appendChild($body);
}
}