diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -790,6 +790,7 @@ '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 @@ '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 @@ 'DiffusionRepositoryTag' => 'Phobject', 'DiffusionRepositoryTestAutomationController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryURIEditController' => 'DiffusionRepositoryEditController', + 'DiffusionRepositoryURIViewController' => 'DiffusionController', 'DiffusionRepositoryURIsIndexEngineExtension' => 'PhabricatorIndexEngineExtension', 'DiffusionRepositoryURIsManagementPanel' => 'DiffusionRepositoryManagementPanel', 'DiffusionRequest' => 'Phobject', @@ -7935,6 +7938,7 @@ 'PhabricatorRepositoryURIQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase', 'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction', + 'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryVersion' => 'Phobject', 'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO', diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -91,8 +91,11 @@ => 'DiffusionCommitEditController', 'manage/(?:(?P[^/]+)/)?' => 'DiffusionRepositoryManageController', - $this->getEditRoutePattern('uri/edit/') - => 'DiffusionRepositoryURIEditController', + 'uri/' => array( + 'view/(?P[0-9]\d*)/' => 'DiffusionRepositoryURIViewController', + $this->getEditRoutePattern('edit/') + => 'DiffusionRepositoryURIEditController', + ), 'edit/' => array( '' => 'DiffusionRepositoryEditMainController', 'basic/' => 'DiffusionRepositoryEditBasicController', diff --git a/src/applications/diffusion/controller/DiffusionRepositoryURIViewController.php b/src/applications/diffusion/controller/DiffusionRepositoryURIViewController.php new file mode 100644 --- /dev/null +++ b/src/applications/diffusion/controller/DiffusionRepositoryURIViewController.php @@ -0,0 +1,162 @@ +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); + } + +} diff --git a/src/applications/diffusion/editor/DiffusionURIEditEngine.php b/src/applications/diffusion/editor/DiffusionURIEditEngine.php --- a/src/applications/diffusion/editor/DiffusionURIEditEngine.php +++ b/src/applications/diffusion/editor/DiffusionURIEditEngine.php @@ -54,11 +54,11 @@ } 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 @@ } protected function getObjectViewURI($object) { - $repository = $this->getRepository(); - return $repository->getPathURI('manage/uris/'); + return $object->getViewURI(); } protected function buildCustomEditFields($object) { @@ -87,6 +86,24 @@ ->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()), ); } diff --git a/src/applications/diffusion/editor/DiffusionURIEditor.php b/src/applications/diffusion/editor/DiffusionURIEditor.php --- a/src/applications/diffusion/editor/DiffusionURIEditor.php +++ b/src/applications/diffusion/editor/DiffusionURIEditor.php @@ -15,6 +15,8 @@ $types = parent::getTransactionTypes(); $types[] = PhabricatorRepositoryURITransaction::TYPE_URI; + $types[] = PhabricatorRepositoryURITransaction::TYPE_IO; + $types[] = PhabricatorRepositoryURITransaction::TYPE_DISPLAY; return $types; } @@ -26,6 +28,10 @@ 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 @@ switch ($xaction->getTransactionType()) { case PhabricatorRepositoryURITransaction::TYPE_URI: + case PhabricatorRepositoryURITransaction::TYPE_IO: + case PhabricatorRepositoryURITransaction::TYPE_DISPLAY: return $xaction->getNewValue(); } @@ -51,6 +59,12 @@ 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 @@ switch ($xaction->getTransactionType()) { case PhabricatorRepositoryURITransaction::TYPE_URI: + case PhabricatorRepositoryURITransaction::TYPE_IO: + case PhabricatorRepositoryURITransaction::TYPE_DISPLAY: return; } @@ -91,6 +107,134 @@ 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; diff --git a/src/applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php --- a/src/applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php @@ -26,7 +26,7 @@ $uri_name = phutil_tag( 'a', array( - 'href' => $repository->getPathURI('uri/edit/'.$uri->getID().'/'), + 'href' => $uri->getViewURI(), ), $uri_name); @@ -38,48 +38,30 @@ $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, ); diff --git a/src/applications/repository/query/PhabricatorRepositoryURITransactionQuery.php b/src/applications/repository/query/PhabricatorRepositoryURITransactionQuery.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/query/PhabricatorRepositoryURITransactionQuery.php @@ -0,0 +1,10 @@ +getBuiltinProtocol(), $this->getBuiltinIdentifier(), ); + return implode('.', $parts); } @@ -108,6 +109,10 @@ return $display; } + return $this->getDefaultDisplayType(); + } + + public function getDefaultDisplayType() { switch ($this->getEffectiveIOType()) { case self::IO_MIRROR: case self::IO_OBSERVE: @@ -156,6 +161,8 @@ return self::DISPLAY_ALWAYS; } + + return self::DISPLAY_NEVER; } @@ -166,6 +173,10 @@ return $io; } + return $this->getDefaultIOType(); + } + + public function getDefaultIOType() { if ($this->isBuiltin()) { $repository = $this->getRepository(); $other_uris = $repository->getURIs(); @@ -307,6 +318,142 @@ } } + 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 )------------------------- */ diff --git a/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php b/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php --- a/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php +++ b/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php @@ -4,6 +4,8 @@ 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 @@ 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(); } }