1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-11 16:16:14 +01:00
phorge-phorge/src/applications/diffusion/view/DiffusionView.php

266 lines
6.3 KiB
PHP
Raw Normal View History

<?php
abstract class DiffusionView extends AphrontView {
private $diffusionRequest;
final public function setDiffusionRequest(DiffusionRequest $request) {
$this->diffusionRequest = $request;
return $this;
}
final public function getDiffusionRequest() {
return $this->diffusionRequest;
}
final public function linkHistory($path) {
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
$href = $this->getDiffusionRequest()->generateURI(
array(
'action' => 'history',
'path' => $path,
));
return $this->renderHistoryLink($href);
}
final public function linkBranchHistory($branch) {
$href = $this->getDiffusionRequest()->generateURI(
array(
'action' => 'history',
'branch' => $branch,
));
return $this->renderHistoryLink($href);
}
final public function linkTagHistory($tag) {
$href = $this->getDiffusionRequest()->generateURI(
array(
'action' => 'history',
'commit' => $tag,
));
return $this->renderHistoryLink($href);
}
private function renderHistoryLink($href) {
return javelin_tag(
'a',
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
'href' => $href,
'class' => 'diffusion-link-icon',
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => pht('History'),
'align' => 'E',
),
),
id(new PHUIIconView())->setIcon('fa-history bluegrey'));
}
final public function linkBrowse(
$path,
array $details = array(),
$button = false) {
require_celerity_resource('diffusion-icons-css');
Javelin::initBehavior('phabricator-tooltips');
$file_type = idx($details, 'type');
unset($details['type']);
$display_name = idx($details, 'name');
unset($details['name']);
if (strlen($display_name)) {
$display_name = phutil_tag(
'span',
array(
'class' => 'diffusion-browse-name',
),
$display_name);
}
if (isset($details['external'])) {
$href = id(new PhutilURI('/diffusion/external/'))
->setQueryParams(
array(
'uri' => idx($details, 'external'),
'id' => idx($details, 'hash'),
));
$tip = pht('Browse External');
} else {
$href = $this->getDiffusionRequest()->generateURI(
$details + array(
'action' => 'browse',
'path' => $path,
));
$tip = pht('Browse');
}
$icon = DifferentialChangeType::getIconForFileType($file_type);
$color = DifferentialChangeType::getIconColorForFileType($file_type);
$icon_view = id(new PHUIIconView())
->setIcon($icon.' '.$color);
// If we're rendering a file or directory name, don't show the tooltip.
if ($display_name !== null) {
$sigil = null;
$meta = null;
} else {
$sigil = 'has-tooltip';
$meta = array(
'tip' => $tip,
'align' => 'E',
);
}
if ($button) {
return id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-code')
->setHref($href)
->setToolTip(pht('Browse'))
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE);
}
return javelin_tag(
'a',
array(
'href' => $href,
'class' => 'diffusion-link-icon',
'sigil' => $sigil,
'meta' => $meta,
),
array(
$icon_view,
$display_name,
));
}
final public static function linkCommit(
PhabricatorRepository $repository,
$commit,
$summary = '') {
$commit_name = $repository->formatCommitName($commit, $local = true);
if (strlen($summary)) {
$commit_name .= ': '.$summary;
}
return phutil_tag(
'a',
array(
'href' => $repository->getCommitURI($commit),
),
$commit_name);
}
final public static function linkDetail(
PhabricatorRepository $repository,
$commit,
$detail) {
return phutil_tag(
'a',
array(
'href' => $repository->getCommitURI($commit),
),
$detail);
}
final public static function linkRevision($id) {
if (!$id) {
return null;
}
return phutil_tag(
'a',
array(
'href' => "/D{$id}",
),
"D{$id}");
}
final public static function renderName($name) {
$email = new PhutilEmailAddress($name);
if ($email->getDisplayName() && $email->getDomainName()) {
Javelin::initBehavior('phabricator-tooltips', array());
require_celerity_resource('aphront-tooltip-css');
return javelin_tag(
'span',
array(
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $email->getAddress(),
'align' => 'S',
'size' => 'auto',
),
),
$email->getDisplayName());
}
2013-02-13 23:50:15 +01:00
return hsprintf('%s', $name);
}
final protected function renderBuildable(
HarbormasterBuildable $buildable,
$type = null) {
Javelin::initBehavior('phabricator-tooltips');
$icon = $buildable->getStatusIcon();
$color = $buildable->getStatusColor();
$name = $buildable->getStatusDisplayName();
if ($type == 'button') {
return id(new PHUIButtonView())
->setTag('a')
->setText($name)
->setIcon($icon)
->setColor($color)
->setHref('/'.$buildable->getMonogram())
->addClass('mmr')
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)
->addClass('diffusion-list-build-status');
}
return id(new PHUIIconView())
->setIcon($icon.' '.$color)
->addSigil('has-tooltip')
->setHref('/'.$buildable->getMonogram())
->setMetadata(
array(
'tip' => $name,
));
}
final protected function loadBuildables(array $commits) {
assert_instances_of($commits, 'PhabricatorRepositoryCommit');
if (!$commits) {
return array();
}
$viewer = $this->getUser();
$harbormaster_app = 'PhabricatorHarbormasterApplication';
$have_harbormaster = PhabricatorApplication::isClassInstalledForViewer(
$harbormaster_app,
$viewer);
if ($have_harbormaster) {
$buildables = id(new HarbormasterBuildableQuery())
->setViewer($viewer)
->withBuildablePHIDs(mpull($commits, 'getPHID'))
->withManualBuildables(false)
->execute();
$buildables = mpull($buildables, null, 'getBuildablePHID');
} else {
$buildables = array();
}
return $buildables;
}
}