1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +01:00

Add repository URI view pages and IO/Display edit logic

Summary:
Ref T10748.

  - New View page for repository URIs.
  - Make display and I/O behavior (observe, mirror, read, read/write) editable.
  - Add a bunch of checks to prevent you from completely screwing up a repository by making it writable from a bunch of differnet sources.

Test Plan:
{F1249866}

{F1249867}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10748

Differential Revision: https://secure.phabricator.com/D15816
This commit is contained in:
epriestley 2016-04-28 10:40:35 -07:00
parent 616c9ae887
commit c8711da5ff
9 changed files with 549 additions and 43 deletions

View file

@ -790,6 +790,7 @@ phutil_register_library_map(array(
'DiffusionRepositoryTag' => 'applications/diffusion/data/DiffusionRepositoryTag.php',
'DiffusionRepositoryTestAutomationController' => 'applications/diffusion/controller/DiffusionRepositoryTestAutomationController.php',
'DiffusionRepositoryURIEditController' => 'applications/diffusion/controller/DiffusionRepositoryURIEditController.php',
'DiffusionRepositoryURIViewController' => 'applications/diffusion/controller/DiffusionRepositoryURIViewController.php',
'DiffusionRepositoryURIsIndexEngineExtension' => 'applications/diffusion/engineextension/DiffusionRepositoryURIsIndexEngineExtension.php',
'DiffusionRepositoryURIsManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php',
'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
@ -3244,6 +3245,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryURIQuery' => 'applications/repository/query/PhabricatorRepositoryURIQuery.php',
'PhabricatorRepositoryURITestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php',
'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php',
'PhabricatorRepositoryURITransactionQuery' => 'applications/repository/query/PhabricatorRepositoryURITransactionQuery.php',
'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php',
'PhabricatorRepositoryVersion' => 'applications/repository/constants/PhabricatorRepositoryVersion.php',
'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php',
@ -5016,6 +5018,7 @@ phutil_register_library_map(array(
'DiffusionRepositoryTag' => 'Phobject',
'DiffusionRepositoryTestAutomationController' => 'DiffusionRepositoryEditController',
'DiffusionRepositoryURIEditController' => 'DiffusionRepositoryEditController',
'DiffusionRepositoryURIViewController' => 'DiffusionController',
'DiffusionRepositoryURIsIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
'DiffusionRepositoryURIsManagementPanel' => 'DiffusionRepositoryManagementPanel',
'DiffusionRequest' => 'Phobject',
@ -7935,6 +7938,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryURIQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryVersion' => 'Phobject',
'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO',

View file

@ -91,8 +91,11 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
=> 'DiffusionCommitEditController',
'manage/(?:(?P<panel>[^/]+)/)?'
=> 'DiffusionRepositoryManageController',
$this->getEditRoutePattern('uri/edit/')
=> 'DiffusionRepositoryURIEditController',
'uri/' => array(
'view/(?P<id>[0-9]\d*)/' => 'DiffusionRepositoryURIViewController',
$this->getEditRoutePattern('edit/')
=> 'DiffusionRepositoryURIEditController',
),
'edit/' => array(
'' => 'DiffusionRepositoryEditMainController',
'basic/' => 'DiffusionRepositoryEditBasicController',

View file

@ -0,0 +1,162 @@
<?php
final class DiffusionRepositoryURIViewController
extends DiffusionController {
public function handleRequest(AphrontRequest $request) {
$response = $this->loadDiffusionContext();
if ($response) {
return $response;
}
$viewer = $this->getViewer();
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$id = $request->getURIData('id');
$uri = id(new PhabricatorRepositoryURIQuery())
->setViewer($viewer)
->withIDs(array($id))
->withRepositories(array($repository))
->executeOne();
if (!$uri) {
return new Aphront404Response();
}
$title = array(
pht('URI'),
$repository->getDisplayName(),
);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
$repository->getDisplayName(),
$repository->getURI());
$crumbs->addTextCrumb(
pht('Manage'),
$repository->getPathURI('manage/'));
$panel_label = id(new DiffusionRepositoryURIsManagementPanel())
->getManagementPanelLabel();
$panel_uri = $repository->getPathURI('manage/uris/');
$crumbs->addTextCrumb($panel_label, $panel_uri);
$crumbs->addTextCrumb(pht('URI %d', $uri->getID()));
$header_text = pht(
'%s: URI %d',
$repository->getDisplayName(),
$uri->getID());
$header = id(new PHUIHeaderView())
->setHeader($header_text)
->setHeaderIcon('fa-pencil');
if ($uri->getIsDisabled()) {
$header->setStatus('fa-ban', 'dark', pht('Disabled'));
} else {
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
}
$curtain = $this->buildCurtain($uri);
$details = $this->buildPropertySection($uri);
$timeline = $this->buildTransactionTimeline(
$uri,
new PhabricatorRepositoryURITransactionQuery());
$timeline->setShouldTerminate(true);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setMainColumn(
array(
$details,
$timeline,
))
->setCurtain($curtain);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildCurtain(PhabricatorRepositoryURI $uri) {
$viewer = $this->getViewer();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$uri,
PhabricatorPolicyCapability::CAN_EDIT);
$edit_uri = $uri->getEditURI();
$curtain = $this->newCurtainView($uri);
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit URI'))
->setHref($edit_uri)
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $curtain;
}
private function buildPropertySection(PhabricatorRepositoryURI $uri) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
$properties->addProperty(pht('URI'), $uri->getDisplayURI());
$properties->addProperty(pht('Credential'), 'TODO');
$io_type = $uri->getEffectiveIOType();
$io_map = PhabricatorRepositoryURI::getIOTypeMap();
$io_spec = idx($io_map, $io_type, array());
$io_icon = idx($io_spec, 'icon');
$io_color = idx($io_spec, 'color');
$io_label = idx($io_spec, 'label', $io_type);
$io_note = idx($io_spec, 'note');
$io_item = id(new PHUIStatusItemView())
->setIcon($io_icon, $io_color)
->setTarget(phutil_tag('strong', array(), $io_label))
->setNote($io_note);
$io_view = id(new PHUIStatusListView())
->addItem($io_item);
$properties->addProperty(pht('I/O'), $io_view);
$display_type = $uri->getEffectiveDisplayType();
$display_map = PhabricatorRepositoryURI::getDisplayTypeMap();
$display_spec = idx($display_map, $display_type, array());
$display_icon = idx($display_spec, 'icon');
$display_color = idx($display_spec, 'color');
$display_label = idx($display_spec, 'label', $display_type);
$display_note = idx($display_spec, 'note');
$display_item = id(new PHUIStatusItemView())
->setIcon($display_icon, $display_color)
->setTarget(phutil_tag('strong', array(), $display_label))
->setNote($display_note);
$display_view = id(new PHUIStatusListView())
->addItem($display_item);
$properties->addProperty(pht('Display'), $display_view);
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($properties);
}
}

View file

@ -54,11 +54,11 @@ final class DiffusionURIEditEngine
}
protected function getObjectEditTitleText($object) {
return pht('Edit Repository URI: %s', $object->getDisplayURI());
return pht('Edit Repository URI %d', $object->getID());
}
protected function getObjectEditShortText($object) {
return $object->getDisplayURI();
return pht('URI %d', $object->getID());
}
protected function getObjectCreateShortText() {
@ -70,8 +70,7 @@ final class DiffusionURIEditEngine
}
protected function getObjectViewURI($object) {
$repository = $this->getRepository();
return $repository->getPathURI('manage/uris/');
return $object->getViewURI();
}
protected function buildCustomEditFields($object) {
@ -87,6 +86,24 @@ final class DiffusionURIEditEngine
->setConduitDescription(pht('Change the repository URI.'))
->setConduitTypeDescription(pht('New repository URI.'))
->setValue($object->getURI()),
id(new PhabricatorSelectEditField())
->setKey('io')
->setLabel(pht('I/O Type'))
->setTransactionType(PhabricatorRepositoryURITransaction::TYPE_IO)
->setDescription(pht('URI I/O behavior.'))
->setConduitDescription(pht('Adjust I/O behavior.'))
->setConduitTypeDescription(pht('New I/O behavior.'))
->setValue($object->getIOType())
->setOptions($object->getAvailableIOTypeOptions()),
id(new PhabricatorSelectEditField())
->setKey('display')
->setLabel(pht('Display Type'))
->setTransactionType(PhabricatorRepositoryURITransaction::TYPE_DISPLAY)
->setDescription(pht('URI display behavior.'))
->setConduitDescription(pht('Change display behavior.'))
->setConduitTypeDescription(pht('New display behavior.'))
->setValue($object->getDisplayType())
->setOptions($object->getAvailableDisplayTypeOptions()),
);
}

View file

@ -15,6 +15,8 @@ final class DiffusionURIEditor
$types = parent::getTransactionTypes();
$types[] = PhabricatorRepositoryURITransaction::TYPE_URI;
$types[] = PhabricatorRepositoryURITransaction::TYPE_IO;
$types[] = PhabricatorRepositoryURITransaction::TYPE_DISPLAY;
return $types;
}
@ -26,6 +28,10 @@ final class DiffusionURIEditor
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryURITransaction::TYPE_URI:
return $object->getURI();
case PhabricatorRepositoryURITransaction::TYPE_IO:
return $object->getIOType();
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
return $object->getDisplayType();
}
return parent::getCustomTransactionOldValue($object, $xaction);
@ -37,6 +43,8 @@ final class DiffusionURIEditor
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryURITransaction::TYPE_URI:
case PhabricatorRepositoryURITransaction::TYPE_IO:
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
return $xaction->getNewValue();
}
@ -51,6 +59,12 @@ final class DiffusionURIEditor
case PhabricatorRepositoryURITransaction::TYPE_URI:
$object->setURI($xaction->getNewValue());
break;
case PhabricatorRepositoryURITransaction::TYPE_IO:
$object->setIOType($xaction->getNewValue());
break;
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
$object->setDisplayType($xaction->getNewValue());
break;
}
}
@ -60,6 +74,8 @@ final class DiffusionURIEditor
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryURITransaction::TYPE_URI:
case PhabricatorRepositoryURITransaction::TYPE_IO:
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
return;
}
@ -91,6 +107,134 @@ final class DiffusionURIEditor
break;
}
break;
case PhabricatorRepositoryURITransaction::TYPE_IO:
$available = $object->getAvailableIOTypeOptions();
foreach ($xactions as $xaction) {
$new = $xaction->getNewValue();
if (empty($available[$new])) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Value "%s" is not a valid display setting for this URI. '.
'Available types for this URI are: %s.',
implode(', ', array_keys($available))),
$xaction);
continue;
}
// If we are setting this URI to use "Observe", we must have no
// other "Observe" URIs and must also have no "Read/Write" URIs.
// If we are setting this URI to "Read/Write", we must have no
// other "Observe" URIs. It's OK to have other "Read/Write" URIs.
$no_observers = false;
$no_readwrite = false;
switch ($new) {
case PhabricatorRepositoryURI::IO_OBSERVE:
$no_readwrite = true;
$no_observers = true;
break;
case PhabricatorRepositoryURI::IO_READWRITE:
$no_observers = true;
break;
}
if ($no_observers || $no_readwrite) {
$repository = id(new PhabricatorRepositoryQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs(array($object->getRepositoryPHID()))
->needURIs(true)
->executeOne();
$uris = $repository->getURIs();
$observe_conflict = null;
$readwrite_conflict = null;
foreach ($uris as $uri) {
// If this is the URI being edited, it can not conflict with
// itself.
if ($uri->getID() == $object->getID()) {
continue;
}
$io_type = $uri->getIoType();
if ($io_type == PhabricatorRepositoryURI::IO_READWRITE) {
if ($no_readwrite) {
$readwite_conflict = $uri;
break;
}
}
if ($io_type == PhabricatorRepositoryURI::IO_OBSERVE) {
if ($no_observers) {
$observe_conflict = $uri;
break;
}
}
}
if ($observe_conflict) {
if ($new == PhabricatorRepositoryURI::IO_OBSERVE) {
$message = pht(
'You can not set this URI to use Observe IO because '.
'another URI for this repository is already configured '.
'in Observe IO mode. A repository can not observe two '.
'different remotes simultaneously. Turn off IO for the '.
'other URI first.');
} else {
$message = pht(
'You can not set this URI to use Read/Write IO because '.
'another URI for this repository is already configured '.
'in Observe IO mode. An observed repository can not be '.
'made writable. Turn off IO for the other URI first.');
}
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
$message,
$xaction);
continue;
}
if ($readwrite_conflict) {
$message = pht(
'You can not set this URI to use Observe IO because '.
'another URI for this repository is already configured '.
'in Read/Write IO mode. A repository can not simultaneously '.
'be writable and observe a remote. Turn off IO for the '.
'other URI first.');
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
$message,
$xaction);
continue;
}
}
}
break;
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
$available = $object->getAvailableDisplayTypeOptions();
foreach ($xactions as $xaction) {
$new = $xaction->getNewValue();
if (empty($available[$new])) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Value "%s" is not a valid display setting for this URI. '.
'Available types for this URI are: %s.',
implode(', ', array_keys($available))));
}
}
break;
}
return $errors;

View file

@ -26,7 +26,7 @@ final class DiffusionRepositoryURIsManagementPanel
$uri_name = phutil_tag(
'a',
array(
'href' => $repository->getPathURI('uri/edit/'.$uri->getID().'/'),
'href' => $uri->getViewURI(),
),
$uri_name);
@ -38,48 +38,30 @@ final class DiffusionRepositoryURIsManagementPanel
$uri_status = id(new PHUIIconView())->setIcon($status_icon);
switch ($uri->getEffectiveIOType()) {
case PhabricatorRepositoryURI::IO_OBSERVE:
$io_icon = 'fa-download green';
$io_label = pht('Observe');
break;
case PhabricatorRepositoryURI::IO_MIRROR:
$io_icon = 'fa-upload green';
$io_label = pht('Mirror');
break;
case PhabricatorRepositoryURI::IO_NONE:
$io_icon = 'fa-times grey';
$io_label = pht('No I/O');
break;
case PhabricatorRepositoryURI::IO_READ:
$io_icon = 'fa-folder blue';
$io_label = pht('Read Only');
break;
case PhabricatorRepositoryURI::IO_READWRITE:
$io_icon = 'fa-folder-open blue';
$io_label = pht('Read/Write');
break;
}
$io_type = $uri->getEffectiveIOType();
$io_map = PhabricatorRepositoryURI::getIOTypeMap();
$io_spec = idx($io_map, $io_type, array());
$io_icon = idx($io_spec, 'icon');
$io_color = idx($io_spec, 'color');
$io_label = idx($io_spec, 'label', $io_type);
$uri_io = array(
id(new PHUIIconView())->setIcon($io_icon),
id(new PHUIIconView())->setIcon("{$io_icon} {$io_color}"),
' ',
$io_label,
);
switch ($uri->getEffectiveDisplayType()) {
case PhabricatorRepositoryURI::DISPLAY_NEVER:
$display_icon = 'fa-eye-slash grey';
$display_label = pht('Hidden');
break;
case PhabricatorRepositoryURI::DISPLAY_ALWAYS:
$display_icon = 'fa-eye green';
$display_label = pht('Visible');
break;
}
$display_type = $uri->getEffectiveDisplayType();
$display_map = PhabricatorRepositoryURI::getDisplayTypeMap();
$display_spec = idx($display_map, $display_type, array());
$display_icon = idx($display_spec, 'icon');
$display_color = idx($display_spec, 'color');
$display_label = idx($display_spec, 'label', $display_type);
$uri_display = array(
id(new PHUIIconView())->setIcon($display_icon),
id(new PHUIIconView())->setIcon("{$display_icon} {$display_color}"),
' ',
$display_label,
);

View file

@ -0,0 +1,10 @@
<?php
final class PhabricatorRepositoryURITransactionQuery
extends PhabricatorApplicationTransactionQuery {
public function getTemplateApplicationTransaction() {
return new PhabricatorRepositoryURITransaction();
}
}

View file

@ -94,6 +94,7 @@ final class PhabricatorRepositoryURI
$this->getBuiltinProtocol(),
$this->getBuiltinIdentifier(),
);
return implode('.', $parts);
}
@ -108,6 +109,10 @@ final class PhabricatorRepositoryURI
return $display;
}
return $this->getDefaultDisplayType();
}
public function getDefaultDisplayType() {
switch ($this->getEffectiveIOType()) {
case self::IO_MIRROR:
case self::IO_OBSERVE:
@ -156,6 +161,8 @@ final class PhabricatorRepositoryURI
return self::DISPLAY_ALWAYS;
}
return self::DISPLAY_NEVER;
}
@ -166,6 +173,10 @@ final class PhabricatorRepositoryURI
return $io;
}
return $this->getDefaultIOType();
}
public function getDefaultIOType() {
if ($this->isBuiltin()) {
$repository = $this->getRepository();
$other_uris = $repository->getURIs();
@ -307,6 +318,142 @@ final class PhabricatorRepositoryURI
}
}
public function getViewURI() {
$id = $this->getID();
return $this->getRepository()->getPathURI("uri/view/{$id}/");
}
public function getEditURI() {
$id = $this->getID();
return $this->getRepository()->getPathURI("uri/edit/{$id}/");
}
public function getAvailableIOTypeOptions() {
$options = array(
self::IO_DEFAULT,
self::IO_NONE,
);
if ($this->isBuiltin()) {
$options[] = self::IO_READ;
$options[] = self::IO_WRITE;
} else {
$options[] = self::IO_OBSERVE;
$options[] = self::IO_MIRROR;
}
$map = array();
$io_map = self::getIOTypeMap();
foreach ($options as $option) {
$spec = idx($io_map, $option, array());
$label = idx($spec, 'label', $option);
$short = idx($spec, 'short');
$name = pht('%s: %s', $label, $short);
$map[$option] = $name;
}
return $map;
}
public function getAvailableDisplayTypeOptions() {
$options = array(
self::DISPLAY_DEFAULT,
self::DISPLAY_ALWAYS,
self::DISPLAY_NEVER,
);
$map = array();
$display_map = self::getDisplayTypeMap();
foreach ($options as $option) {
$spec = idx($display_map, $option, array());
$label = idx($spec, 'label', $option);
$short = idx($spec, 'short');
$name = pht('%s: %s', $label, $short);
$map[$option] = $name;
}
return $map;
}
public static function getIOTypeMap() {
return array(
self::IO_DEFAULT => array(
'label' => pht('Default'),
'short' => pht('Use default behavior.'),
),
self::IO_OBSERVE => array(
'icon' => 'fa-download',
'color' => 'green',
'label' => pht('Observe'),
'note' => pht(
'Phabricator will observe changes to this URI and copy them.'),
'short' => pht('Copy from a remote.'),
),
self::IO_MIRROR => array(
'icon' => 'fa-upload',
'color' => 'green',
'label' => pht('Mirror'),
'note' => pht(
'Phabricator will push a copy of any changes to this URI.'),
'short' => pht('Push a copy to a remote.'),
),
self::IO_NONE => array(
'icon' => 'fa-times',
'color' => 'grey',
'label' => pht('No I/O'),
'note' => pht(
'Phabricator will not push or pull any changes to this URI.'),
'short' => pht('Do not perform any I/O.'),
),
self::IO_READ => array(
'icon' => 'fa-folder',
'color' => 'blue',
'label' => pht('Read Only'),
'note' => pht(
'Phabricator will serve a read-only copy of the repository from '.
'this URI.'),
'short' => pht('Serve repository in read-only mode.'),
),
self::IO_READWRITE => array(
'icon' => 'fa-folder-open',
'color' => 'blue',
'label' => pht('Read/Write'),
'note' => pht(
'Phabricator will serve a read/write copy of the repository from '.
'this URI.'),
'short' => pht('Serve repository in read/write mode.'),
),
);
}
public static function getDisplayTypeMap() {
return array(
self::DISPLAY_DEFAULT => array(
'label' => pht('Default'),
'short' => pht('Use default behavior.'),
),
self::DISPLAY_ALWAYS => array(
'icon' => 'fa-eye',
'color' => 'green',
'label' => pht('Visible'),
'note' => pht('This URI will be shown to users as a clone URI.'),
'short' => pht('Show as a clone URI.'),
),
self::DISPLAY_NEVER => array(
'icon' => 'fa-eye-slash',
'color' => 'grey',
'label' => pht('Hidden'),
'note' => pht(
'This URI will be hidden from users.'),
'short' => pht('Do not show as a clone URI.'),
),
);
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -4,6 +4,8 @@ final class PhabricatorRepositoryURITransaction
extends PhabricatorApplicationTransaction {
const TYPE_URI = 'diffusion.uri.uri';
const TYPE_IO = 'diffusion.uri.io';
const TYPE_DISPLAY = 'diffusion.uri.display';
public function getApplicationName() {
return 'repository';
@ -13,8 +15,43 @@ final class PhabricatorRepositoryURITransaction
return PhabricatorRepositoryURIPHIDType::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return null;
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_URI:
return pht(
'%s changed this URI from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
case self::TYPE_IO:
$map = PhabricatorRepositoryURI::getIOTypeMap();
$old_label = idx(idx($map, $old, array()), 'label', $old);
$new_label = idx(idx($map, $new, array()), 'label', $new);
return pht(
'%s changed the display type for this URI from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old_label,
$new_label);
case self::TYPE_DISPLAY:
$map = PhabricatorRepositoryURI::getDisplayTypeMap();
$old_label = idx(idx($map, $old, array()), 'label', $old);
$new_label = idx(idx($map, $new, array()), 'label', $new);
return pht(
'%s changed the display type for this URI from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old_label,
$new_label);
}
return parent::getTitle();
}
}