mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-19 13:22:42 +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:
parent
616c9ae887
commit
c8711da5ff
9 changed files with 549 additions and 43 deletions
|
@ -790,6 +790,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionRepositoryTag' => 'applications/diffusion/data/DiffusionRepositoryTag.php',
|
'DiffusionRepositoryTag' => 'applications/diffusion/data/DiffusionRepositoryTag.php',
|
||||||
'DiffusionRepositoryTestAutomationController' => 'applications/diffusion/controller/DiffusionRepositoryTestAutomationController.php',
|
'DiffusionRepositoryTestAutomationController' => 'applications/diffusion/controller/DiffusionRepositoryTestAutomationController.php',
|
||||||
'DiffusionRepositoryURIEditController' => 'applications/diffusion/controller/DiffusionRepositoryURIEditController.php',
|
'DiffusionRepositoryURIEditController' => 'applications/diffusion/controller/DiffusionRepositoryURIEditController.php',
|
||||||
|
'DiffusionRepositoryURIViewController' => 'applications/diffusion/controller/DiffusionRepositoryURIViewController.php',
|
||||||
'DiffusionRepositoryURIsIndexEngineExtension' => 'applications/diffusion/engineextension/DiffusionRepositoryURIsIndexEngineExtension.php',
|
'DiffusionRepositoryURIsIndexEngineExtension' => 'applications/diffusion/engineextension/DiffusionRepositoryURIsIndexEngineExtension.php',
|
||||||
'DiffusionRepositoryURIsManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php',
|
'DiffusionRepositoryURIsManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php',
|
||||||
'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
|
'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
|
||||||
|
@ -3244,6 +3245,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryURIQuery' => 'applications/repository/query/PhabricatorRepositoryURIQuery.php',
|
'PhabricatorRepositoryURIQuery' => 'applications/repository/query/PhabricatorRepositoryURIQuery.php',
|
||||||
'PhabricatorRepositoryURITestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php',
|
'PhabricatorRepositoryURITestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php',
|
||||||
'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php',
|
'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php',
|
||||||
|
'PhabricatorRepositoryURITransactionQuery' => 'applications/repository/query/PhabricatorRepositoryURITransactionQuery.php',
|
||||||
'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php',
|
'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php',
|
||||||
'PhabricatorRepositoryVersion' => 'applications/repository/constants/PhabricatorRepositoryVersion.php',
|
'PhabricatorRepositoryVersion' => 'applications/repository/constants/PhabricatorRepositoryVersion.php',
|
||||||
'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php',
|
'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php',
|
||||||
|
@ -5016,6 +5018,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionRepositoryTag' => 'Phobject',
|
'DiffusionRepositoryTag' => 'Phobject',
|
||||||
'DiffusionRepositoryTestAutomationController' => 'DiffusionRepositoryEditController',
|
'DiffusionRepositoryTestAutomationController' => 'DiffusionRepositoryEditController',
|
||||||
'DiffusionRepositoryURIEditController' => 'DiffusionRepositoryEditController',
|
'DiffusionRepositoryURIEditController' => 'DiffusionRepositoryEditController',
|
||||||
|
'DiffusionRepositoryURIViewController' => 'DiffusionController',
|
||||||
'DiffusionRepositoryURIsIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
|
'DiffusionRepositoryURIsIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
|
||||||
'DiffusionRepositoryURIsManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
'DiffusionRepositoryURIsManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
||||||
'DiffusionRequest' => 'Phobject',
|
'DiffusionRequest' => 'Phobject',
|
||||||
|
@ -7935,6 +7938,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryURIQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorRepositoryURIQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase',
|
'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction',
|
'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction',
|
||||||
|
'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO',
|
'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO',
|
||||||
'PhabricatorRepositoryVersion' => 'Phobject',
|
'PhabricatorRepositoryVersion' => 'Phobject',
|
||||||
'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO',
|
'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO',
|
||||||
|
|
|
@ -91,8 +91,11 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
|
||||||
=> 'DiffusionCommitEditController',
|
=> 'DiffusionCommitEditController',
|
||||||
'manage/(?:(?P<panel>[^/]+)/)?'
|
'manage/(?:(?P<panel>[^/]+)/)?'
|
||||||
=> 'DiffusionRepositoryManageController',
|
=> 'DiffusionRepositoryManageController',
|
||||||
$this->getEditRoutePattern('uri/edit/')
|
'uri/' => array(
|
||||||
|
'view/(?P<id>[0-9]\d*)/' => 'DiffusionRepositoryURIViewController',
|
||||||
|
$this->getEditRoutePattern('edit/')
|
||||||
=> 'DiffusionRepositoryURIEditController',
|
=> 'DiffusionRepositoryURIEditController',
|
||||||
|
),
|
||||||
'edit/' => array(
|
'edit/' => array(
|
||||||
'' => 'DiffusionRepositoryEditMainController',
|
'' => 'DiffusionRepositoryEditMainController',
|
||||||
'basic/' => 'DiffusionRepositoryEditBasicController',
|
'basic/' => 'DiffusionRepositoryEditBasicController',
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -54,11 +54,11 @@ final class DiffusionURIEditEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getObjectEditTitleText($object) {
|
protected function getObjectEditTitleText($object) {
|
||||||
return pht('Edit Repository URI: %s', $object->getDisplayURI());
|
return pht('Edit Repository URI %d', $object->getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getObjectEditShortText($object) {
|
protected function getObjectEditShortText($object) {
|
||||||
return $object->getDisplayURI();
|
return pht('URI %d', $object->getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getObjectCreateShortText() {
|
protected function getObjectCreateShortText() {
|
||||||
|
@ -70,8 +70,7 @@ final class DiffusionURIEditEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getObjectViewURI($object) {
|
protected function getObjectViewURI($object) {
|
||||||
$repository = $this->getRepository();
|
return $object->getViewURI();
|
||||||
return $repository->getPathURI('manage/uris/');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildCustomEditFields($object) {
|
protected function buildCustomEditFields($object) {
|
||||||
|
@ -87,6 +86,24 @@ final class DiffusionURIEditEngine
|
||||||
->setConduitDescription(pht('Change the repository URI.'))
|
->setConduitDescription(pht('Change the repository URI.'))
|
||||||
->setConduitTypeDescription(pht('New repository URI.'))
|
->setConduitTypeDescription(pht('New repository URI.'))
|
||||||
->setValue($object->getURI()),
|
->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()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ final class DiffusionURIEditor
|
||||||
$types = parent::getTransactionTypes();
|
$types = parent::getTransactionTypes();
|
||||||
|
|
||||||
$types[] = PhabricatorRepositoryURITransaction::TYPE_URI;
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_URI;
|
||||||
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_IO;
|
||||||
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_DISPLAY;
|
||||||
|
|
||||||
return $types;
|
return $types;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +28,10 @@ final class DiffusionURIEditor
|
||||||
switch ($xaction->getTransactionType()) {
|
switch ($xaction->getTransactionType()) {
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
||||||
return $object->getURI();
|
return $object->getURI();
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_IO:
|
||||||
|
return $object->getIOType();
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
||||||
|
return $object->getDisplayType();
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||||
|
@ -37,6 +43,8 @@ final class DiffusionURIEditor
|
||||||
|
|
||||||
switch ($xaction->getTransactionType()) {
|
switch ($xaction->getTransactionType()) {
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_IO:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
||||||
return $xaction->getNewValue();
|
return $xaction->getNewValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +59,12 @@ final class DiffusionURIEditor
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
||||||
$object->setURI($xaction->getNewValue());
|
$object->setURI($xaction->getNewValue());
|
||||||
break;
|
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()) {
|
switch ($xaction->getTransactionType()) {
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_IO:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +107,134 @@ final class DiffusionURIEditor
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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;
|
return $errors;
|
||||||
|
|
|
@ -26,7 +26,7 @@ final class DiffusionRepositoryURIsManagementPanel
|
||||||
$uri_name = phutil_tag(
|
$uri_name = phutil_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
'href' => $repository->getPathURI('uri/edit/'.$uri->getID().'/'),
|
'href' => $uri->getViewURI(),
|
||||||
),
|
),
|
||||||
$uri_name);
|
$uri_name);
|
||||||
|
|
||||||
|
@ -38,48 +38,30 @@ final class DiffusionRepositoryURIsManagementPanel
|
||||||
|
|
||||||
$uri_status = id(new PHUIIconView())->setIcon($status_icon);
|
$uri_status = id(new PHUIIconView())->setIcon($status_icon);
|
||||||
|
|
||||||
switch ($uri->getEffectiveIOType()) {
|
$io_type = $uri->getEffectiveIOType();
|
||||||
case PhabricatorRepositoryURI::IO_OBSERVE:
|
$io_map = PhabricatorRepositoryURI::getIOTypeMap();
|
||||||
$io_icon = 'fa-download green';
|
$io_spec = idx($io_map, $io_type, array());
|
||||||
$io_label = pht('Observe');
|
|
||||||
break;
|
$io_icon = idx($io_spec, 'icon');
|
||||||
case PhabricatorRepositoryURI::IO_MIRROR:
|
$io_color = idx($io_spec, 'color');
|
||||||
$io_icon = 'fa-upload green';
|
$io_label = idx($io_spec, 'label', $io_type);
|
||||||
$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;
|
|
||||||
}
|
|
||||||
|
|
||||||
$uri_io = array(
|
$uri_io = array(
|
||||||
id(new PHUIIconView())->setIcon($io_icon),
|
id(new PHUIIconView())->setIcon("{$io_icon} {$io_color}"),
|
||||||
' ',
|
' ',
|
||||||
$io_label,
|
$io_label,
|
||||||
);
|
);
|
||||||
|
|
||||||
switch ($uri->getEffectiveDisplayType()) {
|
$display_type = $uri->getEffectiveDisplayType();
|
||||||
case PhabricatorRepositoryURI::DISPLAY_NEVER:
|
$display_map = PhabricatorRepositoryURI::getDisplayTypeMap();
|
||||||
$display_icon = 'fa-eye-slash grey';
|
$display_spec = idx($display_map, $display_type, array());
|
||||||
$display_label = pht('Hidden');
|
|
||||||
break;
|
$display_icon = idx($display_spec, 'icon');
|
||||||
case PhabricatorRepositoryURI::DISPLAY_ALWAYS:
|
$display_color = idx($display_spec, 'color');
|
||||||
$display_icon = 'fa-eye green';
|
$display_label = idx($display_spec, 'label', $display_type);
|
||||||
$display_label = pht('Visible');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$uri_display = array(
|
$uri_display = array(
|
||||||
id(new PHUIIconView())->setIcon($display_icon),
|
id(new PHUIIconView())->setIcon("{$display_icon} {$display_color}"),
|
||||||
' ',
|
' ',
|
||||||
$display_label,
|
$display_label,
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorRepositoryURITransactionQuery
|
||||||
|
extends PhabricatorApplicationTransactionQuery {
|
||||||
|
|
||||||
|
public function getTemplateApplicationTransaction() {
|
||||||
|
return new PhabricatorRepositoryURITransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -94,6 +94,7 @@ final class PhabricatorRepositoryURI
|
||||||
$this->getBuiltinProtocol(),
|
$this->getBuiltinProtocol(),
|
||||||
$this->getBuiltinIdentifier(),
|
$this->getBuiltinIdentifier(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return implode('.', $parts);
|
return implode('.', $parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +109,10 @@ final class PhabricatorRepositoryURI
|
||||||
return $display;
|
return $display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->getDefaultDisplayType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultDisplayType() {
|
||||||
switch ($this->getEffectiveIOType()) {
|
switch ($this->getEffectiveIOType()) {
|
||||||
case self::IO_MIRROR:
|
case self::IO_MIRROR:
|
||||||
case self::IO_OBSERVE:
|
case self::IO_OBSERVE:
|
||||||
|
@ -156,6 +161,8 @@ final class PhabricatorRepositoryURI
|
||||||
|
|
||||||
return self::DISPLAY_ALWAYS;
|
return self::DISPLAY_ALWAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return self::DISPLAY_NEVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,6 +173,10 @@ final class PhabricatorRepositoryURI
|
||||||
return $io;
|
return $io;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->getDefaultIOType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultIOType() {
|
||||||
if ($this->isBuiltin()) {
|
if ($this->isBuiltin()) {
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
$other_uris = $repository->getURIs();
|
$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 )------------------------- */
|
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ final class PhabricatorRepositoryURITransaction
|
||||||
extends PhabricatorApplicationTransaction {
|
extends PhabricatorApplicationTransaction {
|
||||||
|
|
||||||
const TYPE_URI = 'diffusion.uri.uri';
|
const TYPE_URI = 'diffusion.uri.uri';
|
||||||
|
const TYPE_IO = 'diffusion.uri.io';
|
||||||
|
const TYPE_DISPLAY = 'diffusion.uri.display';
|
||||||
|
|
||||||
public function getApplicationName() {
|
public function getApplicationName() {
|
||||||
return 'repository';
|
return 'repository';
|
||||||
|
@ -13,8 +15,43 @@ final class PhabricatorRepositoryURITransaction
|
||||||
return PhabricatorRepositoryURIPHIDType::TYPECONST;
|
return PhabricatorRepositoryURIPHIDType::TYPECONST;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getApplicationTransactionCommentObject() {
|
public function getTitle() {
|
||||||
return null;
|
$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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue