diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 27e6b4e969..328a634aad 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -516,6 +516,7 @@ phutil_register_library_map(array( 'DiffusionRepositoryEditController' => 'applications/diffusion/controller/DiffusionRepositoryEditController.php', 'DiffusionRepositoryEditDeleteController' => 'applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php', 'DiffusionRepositoryEditEncodingController' => 'applications/diffusion/controller/DiffusionRepositoryEditEncodingController.php', + 'DiffusionRepositoryEditHostingController' => 'applications/diffusion/controller/DiffusionRepositoryEditHostingController.php', 'DiffusionRepositoryEditLocalController' => 'applications/diffusion/controller/DiffusionRepositoryEditLocalController.php', 'DiffusionRepositoryEditMainController' => 'applications/diffusion/controller/DiffusionRepositoryEditMainController.php', 'DiffusionRepositoryEditPolicyController' => 'applications/diffusion/controller/DiffusionRepositoryEditPolicyController.php', @@ -2697,6 +2698,7 @@ phutil_register_library_map(array( 'DiffusionRepositoryEditController' => 'DiffusionController', 'DiffusionRepositoryEditDeleteController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditEncodingController' => 'DiffusionRepositoryEditController', + 'DiffusionRepositoryEditHostingController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditLocalController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditMainController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditPolicyController' => 'DiffusionRepositoryEditController', diff --git a/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php b/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php index d14b250a32..bf0faf3d5e 100644 --- a/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php +++ b/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php @@ -75,6 +75,8 @@ final class PhabricatorApplicationDiffusion extends PhabricatorApplication { '(?Premote)/' => 'DiffusionRepositoryCreateController', 'local/' => 'DiffusionRepositoryEditLocalController', 'delete/' => 'DiffusionRepositoryEditDeleteController', + 'hosting/' => 'DiffusionRepositoryEditHostingController', + '(?Pserve)/' => 'DiffusionRepositoryEditHostingController', ), ), 'inline/' => array( @@ -110,6 +112,8 @@ final class PhabricatorApplicationDiffusion extends PhabricatorApplication { DiffusionCapabilityDefaultEdit::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, ), + DiffusionCapabilityDefaultPush::CAPABILITY => array( + ), DiffusionCapabilityCreateRepositories::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, ), diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditHostingController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditHostingController.php new file mode 100644 index 0000000000..293272e44e --- /dev/null +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditHostingController.php @@ -0,0 +1,229 @@ +serve = idx($data, 'serve'); + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + $drequest = $this->diffusionRequest; + $repository = $drequest->getRepository(); + + $repository = id(new PhabricatorRepositoryQuery()) + ->setViewer($user) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->withIDs(array($repository->getID())) + ->executeOne(); + if (!$repository) { + return new Aphront404Response(); + } + + if (!$this->serve) { + return $this->handleHosting($repository); + } else { + return $this->handleProtocols($repository); + } + } + + public function handleHosting(PhabricatorRepository $repository) { + $request = $this->getRequest(); + $user = $request->getUser(); + + $v_hosting = $repository->isHosted(); + + $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); + $next_uri = $this->getRepositoryControllerURI($repository, 'edit/serve/'); + + if ($request->isFormPost()) { + $v_hosting = $request->getBool('hosting'); + + $xactions = array(); + $template = id(new PhabricatorRepositoryTransaction()); + + $type_hosting = PhabricatorRepositoryTransaction::TYPE_HOSTING; + + $xactions[] = id(clone $template) + ->setTransactionType($type_hosting) + ->setNewValue($v_hosting); + + id(new PhabricatorRepositoryEditor()) + ->setContinueOnNoEffect(true) + ->setContentSourceFromRequest($request) + ->setActor($user) + ->applyTransactions($repository, $xactions); + + return id(new AphrontRedirectResponse())->setURI($next_uri); + } + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Edit Hosting'))); + + $title = pht('Edit Hosting (%s)', $repository->getName()); + + $hosted_control = id(new AphrontFormRadioButtonControl()) + ->setName('hosting') + ->setLabel(pht('Hosting')) + ->addButton( + true, + pht('Host Repository on Phabricator'), + pht( + 'Phabricator will host this repository. Users will be able to '. + 'push commits to Phabricator. Phabricator will not pull '. + 'changes from elsewhere.')) + ->addButton( + false, + pht('Host Repository Elsewhere'), + pht( + 'Phabricator will pull updates to this repository from a master '. + 'repository elsewhere (for example, on GitHub or Bitbucket). '. + 'Users will not be able to push commits to this repository.')) + ->setValue($v_hosting); + + $form = id(new AphrontFormView()) + ->setUser($user) + ->appendRemarkupInstructions( + pht( + 'NOTE: Hosting is extremely new and barely works! Use it at '. + 'your own risk.'. + "\n\n". + 'Phabricator can host repositories, or it can track repositories '. + 'hosted elsewhere (like on GitHub or Bitbucket).')) + ->appendChild($hosted_control) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue(pht('Save and Continue')) + ->addCancelButton($edit_uri)); + + $object_box = id(new PHUIObjectBoxView()) + ->setHeaderText($title) + ->setForm($form); + + return $this->buildApplicationPage( + array( + $crumbs, + $object_box, + ), + array( + 'title' => $title, + 'device' => true, + )); + } + + public function handleProtocols(PhabricatorRepository $repository) { + $request = $this->getRequest(); + $user = $request->getUser(); + + $v_http_mode = $repository->getServeOverHTTP(); + $v_ssh_mode = $repository->getServeOverSSH(); + + $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); + $prev_uri = $this->getRepositoryControllerURI($repository, 'edit/hosting/'); + + if ($request->isFormPost()) { + $v_http_mode = $request->getStr('http'); + $v_ssh_mode = PhabricatorRepository::SERVE_OFF; + + $xactions = array(); + $template = id(new PhabricatorRepositoryTransaction()); + + $type_http = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP; + $type_ssh = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH; + + $xactions[] = id(clone $template) + ->setTransactionType($type_http) + ->setNewValue($v_http_mode); + + $xactions[] = id(clone $template) + ->setTransactionType($type_ssh) + ->setNewValue($v_ssh_mode); + + id(new PhabricatorRepositoryEditor()) + ->setContinueOnNoEffect(true) + ->setContentSourceFromRequest($request) + ->setActor($user) + ->applyTransactions($repository, $xactions); + + return id(new AphrontRedirectResponse())->setURI($edit_uri); + } + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Edit Protocols'))); + + $title = pht('Edit Protocols (%s)', $repository->getName()); + + + if ($repository->isHosted()) { + $rw_message = pht( + 'Phabricator will serve a read-write copy of this repository'); + } else { + $rw_message = pht( + 'This repository is hosted elsewhere, so Phabricator can not perform '. + 'writes.'); + } + + $http_control = + id(new AphrontFormRadioButtonControl()) + ->setName('http') + ->setLabel(pht('HTTP')) + ->setValue($v_http_mode) + ->addButton( + PhabricatorRepository::SERVE_OFF, + PhabricatorRepository::getProtocolAvailabilityName( + PhabricatorRepository::SERVE_OFF), + pht('Phabricator will not serve this repository.')) + ->addButton( + PhabricatorRepository::SERVE_READONLY, + PhabricatorRepository::getProtocolAvailabilityName( + PhabricatorRepository::SERVE_READONLY), + pht('Phabricator will serve a read-only copy of this repository.')) + ->addButton( + PhabricatorRepository::SERVE_READWRITE, + PhabricatorRepository::getProtocolAvailabilityName( + PhabricatorRepository::SERVE_READWRITE), + $rw_message, + $repository->isHosted() ? null : 'disabled', + $repository->isHosted() ? null : true); + + $form = id(new AphrontFormView()) + ->setUser($user) + ->appendRemarkupInstructions( + pht( + 'Phabricator can serve repositories over various protocols. You can '. + 'configure server protocols here.')) + ->appendChild($http_control) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue(pht('Save Changes')) + ->addCancelButton($prev_uri, pht('Back'))); + + $object_box = id(new PHUIObjectBoxView()) + ->setHeaderText($title) + ->setForm($form); + + return $this->buildApplicationPage( + array( + $crumbs, + $object_box, + ), + array( + 'title' => $title, + 'device' => true, + )); + } + +} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php index 9642f9266f..f0140ebdc7 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php @@ -23,8 +23,7 @@ final class DiffusionRepositoryEditMainController $is_git = true; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - // TOOD: This will be true for hosted SVN repositories. - $has_local = false; + $has_local = $repository->isHosted(); $is_svn = true; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: @@ -63,6 +62,10 @@ final class DiffusionRepositoryEditMainController $encoding_properties = $this->buildEncodingProperties($repository, $encoding_actions); + $hosting_properties = $this->buildHostingProperties( + $repository, + $this->buildHostingActions($repository)); + $branches_properties = null; if ($has_branches) { $branches_properties = $this->buildBranchesProperties( @@ -114,6 +117,7 @@ final class DiffusionRepositoryEditMainController ->setHeader($header) ->addPropertyList($basic_properties) ->addPropertyList($policy_properties) + ->addPropertyList($hosting_properties) ->addPropertyList($remote_properties); if ($local_properties) { @@ -298,6 +302,10 @@ final class DiffusionRepositoryEditMainController pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); + $pushable = $repository->isHosted() + ? $descriptions[DiffusionCapabilityPush::CAPABILITY] + : phutil_tag('em', array(), pht('Not a Hosted Repository')); + $view->addProperty(pht('Pushable By'), $pushable); return $view; } @@ -501,4 +509,57 @@ final class DiffusionRepositoryEditMainController return $view; } + + private function buildHostingActions(PhabricatorRepository $repository) { + $user = $this->getRequest()->getUser(); + + $view = id(new PhabricatorActionListView()) + ->setObjectURI($this->getRequest()->getRequestURI()) + ->setUser($user); + + $edit = id(new PhabricatorActionView()) + ->setIcon('edit') + ->setName(pht('Edit Hosting')) + ->setHref( + $this->getRepositoryControllerURI($repository, 'edit/hosting/')); + $view->addAction($edit); + + return $view; + } + + private function buildHostingProperties( + PhabricatorRepository $repository, + PhabricatorActionListView $actions) { + + $user = $this->getRequest()->getUser(); + + $view = id(new PHUIPropertyListView()) + ->setUser($user) + ->setActionList($actions) + ->addSectionHeader(pht('Hosting')); + + $hosting = $repository->isHosted() + ? pht('Hosted on Phabricator') + : pht('Hosted Elsewhere'); + $view->addProperty(pht('Hosting'), phutil_tag('em', array(), $hosting)); + + $view->addProperty( + pht('Serve over HTTP'), + phutil_tag( + 'em', + array(), + PhabricatorRepository::getProtocolAvailabilityName( + $repository->getServeOverHTTP()))); + + $view->addProperty( + pht('Serve over SSH'), + phutil_tag( + 'em', + array(), + PhabricatorRepository::getProtocolAvailabilityName( + $repository->getServeOverSSH()))); + + return $view; + } + } diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditPolicyController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditPolicyController.php index b68057adb3..1a6f7dff2e 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditPolicyController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditPolicyController.php @@ -27,16 +27,19 @@ final class DiffusionRepositoryEditPolicyController $v_view = $repository->getViewPolicy(); $v_edit = $repository->getEditPolicy(); + $v_push = $repository->getPushPolicy(); if ($request->isFormPost()) { $v_view = $request->getStr('viewPolicy'); $v_edit = $request->getStr('editPolicy'); + $v_push = $request->getStr('pushPolicy'); $xactions = array(); $template = id(new PhabricatorRepositoryTransaction()); $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY; $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY; + $type_push = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY; $xactions[] = id(clone $template) ->setTransactionType($type_view) @@ -46,6 +49,12 @@ final class DiffusionRepositoryEditPolicyController ->setTransactionType($type_edit) ->setNewValue($v_edit); + if ($repository->isHosted()) { + $xactions[] = id(clone $template) + ->setTransactionType($type_push) + ->setNewValue($v_push); + } + id(new PhabricatorRepositoryEditor()) ->setContinueOnNoEffect(true) ->setContentSourceFromRequest($request) @@ -62,7 +71,7 @@ final class DiffusionRepositoryEditPolicyController id(new PhabricatorCrumbView()) ->setName(pht('Edit Policies'))); - $title = pht('Edit %s', $repository->getName()); + $title = pht('Edit Policies (%s)', $repository->getName()); $policies = id(new PhabricatorPolicyQuery()) ->setViewer($viewer) @@ -84,7 +93,25 @@ final class DiffusionRepositoryEditPolicyController ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) ->setPolicyObject($repository) ->setPolicies($policies) - ->setName('editPolicy')) + ->setName('editPolicy')); + + if ($repository->isHosted()) { + $form->appendChild( + id(new AphrontFormPolicyControl()) + ->setUser($viewer) + ->setCapability(DiffusionCapabilityPush::CAPABILITY) + ->setPolicyObject($repository) + ->setPolicies($policies) + ->setName('pushPolicy')); + } else { + $form->appendChild( + id(new AphrontFormMarkupControl()) + ->setLabel(pht('Can Push')) + ->setValue( + phutil_tag('em', array(), pht('Not a Hosted Repository')))); + } + + $form ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Save Policies')) diff --git a/src/applications/repository/editor/PhabricatorRepositoryEditor.php b/src/applications/repository/editor/PhabricatorRepositoryEditor.php index cbe0f4d9f4..cf28febdf0 100644 --- a/src/applications/repository/editor/PhabricatorRepositoryEditor.php +++ b/src/applications/repository/editor/PhabricatorRepositoryEditor.php @@ -25,6 +25,10 @@ final class PhabricatorRepositoryEditor $types[] = PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN; $types[] = PhabricatorRepositoryTransaction::TYPE_HTTP_PASS; $types[] = PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH; + $types[] = PhabricatorRepositoryTransaction::TYPE_HOSTING; + $types[] = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP; + $types[] = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH; + $types[] = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; @@ -75,6 +79,14 @@ final class PhabricatorRepositoryEditor return $object->getDetail('http-pass'); case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: return $object->getDetail('local-path'); + case PhabricatorRepositoryTransaction::TYPE_HOSTING: + return $object->isHosted(); + case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: + return $object->getServeOverHTTP(); + case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: + return $object->getServeOverSSH(); + case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: + return $object->getPushPolicy(); } } @@ -100,6 +112,10 @@ final class PhabricatorRepositoryEditor case PhabricatorRepositoryTransaction::TYPE_HTTP_PASS: case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: case PhabricatorRepositoryTransaction::TYPE_VCS: + case PhabricatorRepositoryTransaction::TYPE_HOSTING: + case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: + case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: + case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: return $xaction->getNewValue(); case PhabricatorRepositoryTransaction::TYPE_NOTIFY: case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: @@ -170,6 +186,14 @@ final class PhabricatorRepositoryEditor case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: $object->setDetail('local-path', $xaction->getNewValue()); break; + case PhabricatorRepositoryTransaction::TYPE_HOSTING: + return $object->setHosted($xaction->getNewValue()); + case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: + return $object->setServeOverHTTP($xaction->getNewValue()); + case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: + return $object->setServeOverSSH($xaction->getNewValue()); + case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: + return $object->setPushPolicy($xaction->getNewValue()); case PhabricatorRepositoryTransaction::TYPE_ENCODING: // Make sure the encoding is valid by converting to UTF-8. This tests // that the user has mbstring installed, and also that they didn't type @@ -250,6 +274,10 @@ final class PhabricatorRepositoryEditor case PhabricatorRepositoryTransaction::TYPE_VCS: case PhabricatorRepositoryTransaction::TYPE_NOTIFY: case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: + case PhabricatorRepositoryTransaction::TYPE_HOSTING: + case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: + case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: + case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: PhabricatorPolicyFilter::requireCapability( $this->requireActor(), $object, diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index 726da449a6..3e4b7ee63f 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -26,6 +26,10 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO const TABLE_BADCOMMIT = 'repository_badcommit'; const TABLE_LINTMESSAGE = 'repository_lintmessage'; + const SERVE_OFF = 'off'; + const SERVE_READONLY = 'readonly'; + const SERVE_READWRITE = 'readwrite'; + protected $name; protected $callsign; protected $uuid; @@ -708,6 +712,43 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO return ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL); } + public function isHosted() { + return (bool)$this->getDetail('hosting-enabled', false); + } + + public function setHosted($enabled) { + return $this->setDetail('hosting-enabled', $enabled); + } + + public function getServeOverHTTP() { + return $this->getDetail('serve-over-http', self::SERVE_OFF); + } + + public function setServeOverHTTP($mode) { + return $this->setDetail('serve-over-http', $mode); + } + + public function getServeOverSSH() { + return $this->getDetail('serve-over-ssh', self::SERVE_OFF); + } + + public function setServeOverSSH($mode) { + return $this->setDetail('serve-over-ssh', $mode); + } + + public static function getProtocolAvailabilityName($constant) { + switch ($constant) { + case self::SERVE_OFF: + return pht('Off'); + case self::SERVE_READONLY: + return pht('Read Only'); + case self::SERVE_READWRITE: + return pht('Read/Write'); + default: + return pht('Unknown'); + } + } + /* -( PhabricatorPolicyInterface )----------------------------------------- */ diff --git a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php index 54f0e59eab..e40c139cf4 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php +++ b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php @@ -22,6 +22,10 @@ final class PhabricatorRepositoryTransaction const TYPE_HTTP_LOGIN = 'repo:http-login'; const TYPE_HTTP_PASS = 'repo:http-pass'; const TYPE_LOCAL_PATH = 'repo:local-path'; + const TYPE_HOSTING = 'repo:hosting'; + const TYPE_PROTOCOL_HTTP = 'repo:serve-http'; + const TYPE_PROTOCOL_SSH = 'repo:serve-ssh'; + const TYPE_PUSH_POLICY = 'repo:push-policy'; public function getApplicationName() { return 'repository'; @@ -35,6 +39,22 @@ final class PhabricatorRepositoryTransaction return null; } + public function getRequiredHandlePHIDs() { + $phids = parent::getRequiredHandlePHIDs(); + + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + switch ($this->getTransactionType()) { + case self::TYPE_PUSH_POLICY: + $phids[] = $old; + $phids[] = $new; + break; + } + + return $phids; + } + public function shouldHide() { $old = $this->getOldValue(); $new = $this->getNewValue(); @@ -285,6 +305,36 @@ final class PhabricatorRepositoryTransaction $this->renderHandleLink($author_phid), $old, $new); + case self::TYPE_HOSTING: + if ($new) { + return pht( + '%s changed this repository to be hosted on Phabricator.', + $this->renderHandleLink($author_phid)); + } else { + return pht( + '%s changed this repository to track a remote elsewhere.', + $this->renderHandleLink($author_phid)); + } + case self::TYPE_PROTOCOL_HTTP: + return pht( + '%s changed the availability of this repository over HTTP from '. + '"%s" to "%s".', + $this->renderHandleLink($author_phid), + PhabricatorRepository::getProtocolAvailabilityName($old), + PhabricatorRepository::getProtocolAvailabilityName($new)); + case self::TYPE_PROTOCOL_SSH: + return pht( + '%s changed the availability of this repository over SSH from '. + '"%s" to "%s".', + $this->renderHandleLink($author_phid), + PhabricatorRepository::getProtocolAvailabilityName($old), + PhabricatorRepository::getProtocolAvailabilityName($new)); + case self::TYPE_PUSH_POLICY: + return pht( + '%s changed the push policy of this repository from "%s" to "%s".', + $this->renderHandleLink($author_phid), + $this->renderPolicyName($old), + $this->renderPolicyName($new)); } return parent::getTitle(); @@ -310,6 +360,5 @@ final class PhabricatorRepositoryTransaction return $view->render(); } - } diff --git a/src/view/form/control/AphrontFormPolicyControl.php b/src/view/form/control/AphrontFormPolicyControl.php index 473c1b3cb8..8f9a7b7441 100644 --- a/src/view/form/control/AphrontFormPolicyControl.php +++ b/src/view/form/control/AphrontFormPolicyControl.php @@ -26,7 +26,18 @@ final class AphrontFormPolicyControl extends AphrontFormControl { PhabricatorPolicyCapability::CAN_JOIN => pht('Joinable By'), ); - $this->setLabel(idx($labels, $this->capability, pht('Unknown Policy'))); + if (isset($labels[$capability])) { + $label = $labels[$capability]; + } else { + $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability); + if ($capobj) { + $label = $capobj->getCapabilityName(); + } else { + $label = pht('Capability "%s"', $capability); + } + } + + $this->setLabel($label); return $this; }