diff --git a/src/applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php b/src/applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php index 8a9f258ebe..a5541acabc 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php @@ -1,133 +1,138 @@ navigation) { return $this->navigation->getMenu(); } return parent::buildApplicationMenu(); } public function handleRequest(AphrontRequest $request) { $response = $this->loadDiffusionContext(); if ($response) { return $response; } $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $panels = DiffusionRepositoryManagementPanel::getAllPanels(); - foreach ($panels as $panel) { + foreach ($panels as $key => $panel) { $panel ->setViewer($viewer) ->setRepository($repository) ->setController($this); + + if (!$panel->shouldEnableForRepository($repository)) { + unset($panels[$key]); + continue; + } } $selected = $request->getURIData('panel'); if (!strlen($selected)) { $selected = head_key($panels); } if (empty($panels[$selected])) { return new Aphront404Response(); } $nav = $this->renderSideNav($repository, $panels, $selected); $this->navigation = $nav; $panel = $panels[$selected]; $content = $panel->buildManagementPanelContent(); $title = array( $panel->getManagementPanelLabel(), $repository->getDisplayName(), ); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($panel->getManagementPanelLabel()); $header_text = pht( '%s: %s', $repository->getDisplayName(), $panel->getManagementPanelLabel()); $header = id(new PHUIHeaderView()) ->setHeader($header_text) ->setHeaderIcon('fa-pencil'); if ($repository->isTracked()) { $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { $header->setStatus('fa-ban', 'dark', pht('Inactive')); } $view = id(new PHUITwoColumnView()) ->setHeader($header) ->setNavigation($nav) ->setMainColumn($content); $curtain = $panel->buildManagementPanelCurtain(); if ($curtain) { $view->setCurtain($curtain); } return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->appendChild($view); } private function renderSideNav( PhabricatorRepository $repository, array $panels, $selected) { $base_uri = $repository->getPathURI('manage/'); $base_uri = new PhutilURI($base_uri); $nav = id(new AphrontSideNavFilterView()) ->setBaseURI($base_uri); foreach ($panels as $panel) { $key = $panel->getManagementPanelKey(); $label = $panel->getManagementPanelLabel(); $icon = $panel->getManagementPanelIcon(); $href = $panel->getPanelNavigationURI(); $item = id(new PHUIListItemView()) ->setKey($key) ->setName($label) ->setType(PHUIListItemView::TYPE_LINK) ->setHref($href) ->setIcon($icon); $nav->addMenuItem($item); } $nav->selectFilter($selected); return $nav; } public function newTimeline(PhabricatorRepository $repository) { $timeline = $this->buildTransactionTimeline( $repository, new PhabricatorRepositoryTransactionQuery()); $timeline->setShouldTerminate(true); return $timeline; } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryAutomationManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryAutomationManagementPanel.php index 764f58c5bd..14182a0444 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryAutomationManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryAutomationManagementPanel.php @@ -1,97 +1,102 @@ isGit(); + } + protected function getEditEngineFieldKeys() { return array( 'automationBlueprintPHIDs', ); } public function getManagementPanelIcon() { $repository = $this->getRepository(); if (!$repository->canPerformAutomation()) { return 'fa-truck grey'; } $blueprint_phids = $repository->getAutomationBlueprintPHIDs(); if (!$blueprint_phids) { return 'fa-truck grey'; } $is_authorized = DrydockAuthorizationQuery::isFullyAuthorized( $repository->getPHID(), $blueprint_phids); if (!$is_authorized) { return 'fa-exclamation-triangle yellow'; } return 'fa-truck'; } protected function buildManagementPanelActions() { $repository = $this->getRepository(); $viewer = $this->getViewer(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $repository, PhabricatorPolicyCapability::CAN_EDIT); $can_test = $can_edit && $repository->canPerformAutomation(); $automation_uri = $this->getEditPageURI(); $test_uri = $repository->getPathURI('edit/testautomation/'); return array( id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Automation')) ->setHref($automation_uri) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit), id(new PhabricatorActionView()) ->setIcon('fa-gamepad') ->setName(pht('Test Configuration')) ->setWorkflow(true) ->setDisabled(!$can_test) ->setHref($test_uri), ); } public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); $view = id(new PHUIPropertyListView()) ->setViewer($viewer) ->setActionList($this->newActions()); $blueprint_phids = $repository->getAutomationBlueprintPHIDs(); if (!$blueprint_phids) { $blueprint_view = phutil_tag('em', array(), pht('Not Configured')); } else { $blueprint_view = id(new DrydockObjectAuthorizationView()) ->setUser($viewer) ->setObjectPHID($repository->getPHID()) ->setBlueprintPHIDs($blueprint_phids); } $view->addProperty(pht('Automation'), $blueprint_view); return $this->newBox(pht('Automation'), $view); } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryBranchesManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryBranchesManagementPanel.php index 66ac0877dd..b3e7926cfc 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryBranchesManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryBranchesManagementPanel.php @@ -1,91 +1,96 @@ isGit() || $repository->isHg()); + } + public function getManagementPanelIcon() { $repository = $this->getRepository(); $has_any = $repository->getDetail('default-branch') || $repository->getDetail('branch-filter') || $repository->getDetail('close-commits-filter'); if ($has_any) { return 'fa-code-fork'; } else { return 'fa-code-fork grey'; } } protected function getEditEngineFieldKeys() { return array( 'defaultBranch', 'trackOnly', 'autocloseOnly', ); } protected function buildManagementPanelActions() { $repository = $this->getRepository(); $viewer = $this->getViewer(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $repository, PhabricatorPolicyCapability::CAN_EDIT); $branches_uri = $this->getEditPageURI(); return array( id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Branches')) ->setHref($branches_uri) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit), ); } public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); $view = id(new PHUIPropertyListView()) ->setViewer($viewer) ->setActionList($this->newActions()); $default_branch = nonempty( $repository->getHumanReadableDetail('default-branch'), phutil_tag('em', array(), $repository->getDefaultBranch())); $view->addProperty(pht('Default Branch'), $default_branch); $track_only = nonempty( $repository->getHumanReadableDetail('branch-filter', array()), phutil_tag('em', array(), pht('Track All Branches'))); $view->addProperty(pht('Track Only'), $track_only); $autoclose_only = nonempty( $repository->getHumanReadableDetail('close-commits-filter', array()), phutil_tag('em', array(), pht('Autoclose On All Branches'))); if ($repository->getDetail('disable-autoclose')) { $autoclose_only = phutil_tag('em', array(), pht('Disabled')); } $view->addProperty(pht('Autoclose Only'), $autoclose_only); return $this->newBox(pht('Branches'), $view); } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php index 8d23e87406..34047cdb89 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php @@ -1,146 +1,151 @@ viewer = $viewer; return $this; } final public function getViewer() { return $this->viewer; } final public function setRepository(PhabricatorRepository $repository) { $this->repository = $repository; return $this; } final public function getRepository() { return $this->repository; } final public function setController(PhabricatorController $controller) { $this->controller = $controller; return $this; } final public function getManagementPanelKey() { return $this->getPhobjectClassConstant('PANELKEY'); } abstract public function getManagementPanelLabel(); abstract public function getManagementPanelOrder(); abstract public function buildManagementPanelContent(); public function getManagementPanelIcon() { return 'fa-pencil'; } protected function buildManagementPanelActions() { return array(); } + public function shouldEnableForRepository( + PhabricatorRepository $repository) { + return true; + } + final protected function newActions() { $actions = $this->buildManagementPanelActions(); if (!$actions) { return null; } $viewer = $this->getViewer(); $action_list = id(new PhabricatorActionListView()) ->setViewer($viewer); foreach ($actions as $action) { $action_list->addAction($action); } return $action_list; } public function buildManagementPanelCurtain() { // TODO: Delete or fix this, curtains always render in the left gutter // at the moment. return null; $actions = $this->newActions(); if (!$actions) { return null; } $viewer = $this->getViewer(); $curtain = id(new PHUICurtainView()) ->setViewer($viewer) ->setActionList($actions); return $curtain; } public static function getAllPanels() { return id(new PhutilClassMapQuery()) ->setAncestorClass(__CLASS__) ->setUniqueMethod('getManagementPanelKey') ->setSortMethod('getManagementPanelOrder') ->execute(); } final protected function newBox($header_text, $body) { return id(new PHUIObjectBoxView()) ->setHeaderText($header_text) ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->appendChild($body); } final protected function newTimeline() { return $this->controller->newTimeline($this->getRepository()); } final public function getPanelURI() { $repository = $this->getRepository(); $key = $this->getManagementPanelKey(); return $repository->getPathURI("manage/{$key}/"); } final public function newEditEnginePage() { $field_keys = $this->getEditEngineFieldKeys(); if (!$field_keys) { return null; } $key = $this->getManagementPanelKey(); $label = $this->getManagementPanelLabel(); $panel_uri = $this->getPanelURI(); return id(new PhabricatorEditPage()) ->setKey($key) ->setLabel($label) ->setViewURI($panel_uri) ->setFieldKeys($field_keys); } protected function getEditEngineFieldKeys() { return array(); } protected function getEditPageURI($page = null) { if ($page === null) { $page = $this->getManagementPanelKey(); } $repository = $this->getRepository(); $id = $repository->getID(); return "/diffusion/edit/{$id}/page/{$page}/"; } public function getPanelNavigationURI() { return $this->getPanelURI(); } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php index 0d8f9379be..79b716e82a 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php @@ -1,73 +1,79 @@ isGit(); + } + + public function getManagementPanelIcon() { $repository = $this->getRepository(); $staging_uri = $repository->getStagingURI(); if ($staging_uri) { return 'fa-upload'; } else { return 'fa-upload grey'; } } protected function getEditEngineFieldKeys() { return array( 'stagingAreaURI', ); } protected function buildManagementPanelActions() { $repository = $this->getRepository(); $viewer = $this->getViewer(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $repository, PhabricatorPolicyCapability::CAN_EDIT); $staging_uri = $this->getEditPageURI(); return array( id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Staging')) ->setHref($staging_uri) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit), ); } public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); $view = id(new PHUIPropertyListView()) ->setViewer($viewer) ->setActionList($this->newActions()); $staging_uri = $repository->getStagingURI(); if (!$staging_uri) { $staging_uri = phutil_tag('em', array(), pht('No Staging Area')); } $view->addProperty(pht('Staging Area URI'), $staging_uri); return $this->newBox(pht('Staging Area'), $view); } } diff --git a/src/applications/repository/storage/PhabricatorRepositoryURI.php b/src/applications/repository/storage/PhabricatorRepositoryURI.php index 227b13012f..21fc791de5 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryURI.php +++ b/src/applications/repository/storage/PhabricatorRepositoryURI.php @@ -1,715 +1,722 @@ true, self::CONFIG_COLUMN_SCHEMA => array( 'uri' => 'text255', 'builtinProtocol' => 'text32?', 'builtinIdentifier' => 'text32?', 'credentialPHID' => 'phid?', 'ioType' => 'text32', 'displayType' => 'text32', 'isDisabled' => 'bool', ), self::CONFIG_KEY_SCHEMA => array( 'key_builtin' => array( 'columns' => array( 'repositoryPHID', 'builtinProtocol', 'builtinIdentifier', ), 'unique' => true, ), ), ) + parent::getConfiguration(); } public static function initializeNewURI() { return id(new self()) ->setIoType(self::IO_DEFAULT) ->setDisplayType(self::DISPLAY_DEFAULT) ->setIsDisabled(0); } public function generatePHID() { return PhabricatorPHID::generateNewPHID( PhabricatorRepositoryURIPHIDType::TYPECONST); } public function attachRepository(PhabricatorRepository $repository) { $this->repository = $repository; return $this; } public function getRepository() { return $this->assertAttached($this->repository); } public function getRepositoryURIBuiltinKey() { if (!$this->getBuiltinProtocol()) { return null; } $parts = array( $this->getBuiltinProtocol(), $this->getBuiltinIdentifier(), ); return implode('.', $parts); } public function isBuiltin() { return (bool)$this->getBuiltinProtocol(); } public function getEffectiveDisplayType() { $display = $this->getDisplayType(); if ($display != self::DISPLAY_DEFAULT) { return $display; } return $this->getDefaultDisplayType(); } public function getDefaultDisplayType() { switch ($this->getEffectiveIOType()) { case self::IO_MIRROR: case self::IO_OBSERVE: case self::IO_NONE: return self::DISPLAY_NEVER; case self::IO_READ: case self::IO_READWRITE: // By default, only show the "best" version of the builtin URI, not the // other redundant versions. $repository = $this->getRepository(); $other_uris = $repository->getURIs(); $identifier_value = array( self::BUILTIN_IDENTIFIER_CALLSIGN => 3, self::BUILTIN_IDENTIFIER_SHORTNAME => 2, self::BUILTIN_IDENTIFIER_ID => 1, ); $have_identifiers = array(); foreach ($other_uris as $other_uri) { if ($other_uri->getIsDisabled()) { continue; } $identifier = $other_uri->getBuiltinIdentifier(); if (!$identifier) { continue; } $have_identifiers[$identifier] = $identifier_value[$identifier]; } $best_identifier = max($have_identifiers); $this_identifier = $identifier_value[$this->getBuiltinIdentifier()]; if ($this_identifier < $best_identifier) { return self::DISPLAY_NEVER; } return self::DISPLAY_ALWAYS; } return self::DISPLAY_NEVER; } public function getEffectiveIOType() { $io = $this->getIoType(); if ($io != self::IO_DEFAULT) { return $io; } return $this->getDefaultIOType(); } public function getDefaultIOType() { if ($this->isBuiltin()) { $repository = $this->getRepository(); $other_uris = $repository->getURIs(); $any_observe = false; foreach ($other_uris as $other_uri) { if ($other_uri->getIoType() == self::IO_OBSERVE) { $any_observe = true; break; } } if ($any_observe) { return self::IO_READ; } else { return self::IO_READWRITE; } } return self::IO_NONE; } public function getDisplayURI() { return $this->getURIObject(false); } public function getEffectiveURI() { return $this->getURIObject(true); } public function getURIEnvelope() { $uri = $this->getEffectiveURI(); $command_engine = $this->newCommandEngine(); $is_http = $command_engine->isAnyHTTPProtocol(); // For SVN, we use `--username` and `--password` flags separately in the // CommandEngine, so we don't need to add any credentials here. $is_svn = $this->getRepository()->isSVN(); $credential_phid = $this->getCredentialPHID(); if ($is_http && !$is_svn && $credential_phid) { $key = PassphrasePasswordKey::loadFromPHID( $credential_phid, PhabricatorUser::getOmnipotentUser()); $uri->setUser($key->getUsernameEnvelope()->openEnvelope()); $uri->setPass($key->getPasswordEnvelope()->openEnvelope()); } return new PhutilOpaqueEnvelope((string)$uri); } private function getURIObject($normalize) { // Users can provide Git/SCP-style URIs in the form "user@host:path". // These are equivalent to "ssh://user@host/path". We use the more standard // form internally, and convert to it if we need to specify a port number, // but try to preserve what the user typed when displaying the URI. if ($this->isBuiltin()) { $builtin_protocol = $this->getForcedProtocol(); $builtin_domain = $this->getForcedHost(); $raw_uri = "{$builtin_protocol}://{$builtin_domain}"; } else { $raw_uri = $this->getURI(); } $port = $this->getForcedPort(); $default_ports = array( 'ssh' => 22, 'http' => 80, 'https' => 443, ); $uri = new PhutilURI($raw_uri); // Make sure to remove any password from the URI before we do anything // with it; this should always be provided by the associated credential. $uri->setPass(null); if (!$uri->getProtocol()) { $git_uri = new PhutilGitURI($raw_uri); // We must normalize this Git-style URI into a normal URI $must_normalize = ($port && ($port != $default_ports['ssh'])); if ($must_normalize || $normalize) { $domain = $git_uri->getDomain(); $uri = id(new PhutilURI("ssh://{$domain}")) ->setUser($git_uri->getUser()) ->setPath($git_uri->getPath()); } else { $uri = $git_uri; } } $is_normal = ($uri instanceof PhutilURI); if ($is_normal) { $protocol = $this->getForcedProtocol(); if ($protocol) { $uri->setProtocol($protocol); } if ($port) { $uri->setPort($port); } // Remove any explicitly set default ports. $uri_port = $uri->getPort(); $uri_protocol = $uri->getProtocol(); $uri_default = idx($default_ports, $uri_protocol); if ($uri_default && ($uri_default == $uri_port)) { $uri->setPort(null); } } $user = $this->getForcedUser(); if ($user) { $uri->setUser($user); } $host = $this->getForcedHost(); if ($host) { $uri->setDomain($host); } $path = $this->getForcedPath(); if ($path) { $uri->setPath($path); } return $uri; } private function getForcedProtocol() { + $repository = $this->getRepository(); + switch ($this->getBuiltinProtocol()) { case self::BUILTIN_PROTOCOL_SSH: - return 'ssh'; + if ($repository->isSVN()) { + return 'svn+ssh'; + } else { + return 'ssh'; + } case self::BUILTIN_PROTOCOL_HTTP: return 'http'; case self::BUILTIN_PROTOCOL_HTTPS: return 'https'; default: return null; } } private function getForcedUser() { switch ($this->getBuiltinProtocol()) { case self::BUILTIN_PROTOCOL_SSH: return AlmanacKeys::getClusterSSHUser(); default: return null; } } private function getForcedHost() { $phabricator_uri = PhabricatorEnv::getURI('/'); $phabricator_uri = new PhutilURI($phabricator_uri); $phabricator_host = $phabricator_uri->getDomain(); switch ($this->getBuiltinProtocol()) { case self::BUILTIN_PROTOCOL_SSH: $ssh_host = PhabricatorEnv::getEnvConfig('diffusion.ssh-host'); if ($ssh_host !== null) { return $ssh_host; } return $phabricator_host; case self::BUILTIN_PROTOCOL_HTTP: case self::BUILTIN_PROTOCOL_HTTPS: return $phabricator_host; default: return null; } } private function getForcedPort() { switch ($this->getBuiltinProtocol()) { case self::BUILTIN_PROTOCOL_SSH: return PhabricatorEnv::getEnvConfig('diffusion.ssh-port'); case self::BUILTIN_PROTOCOL_HTTP: case self::BUILTIN_PROTOCOL_HTTPS: default: return null; } } private function getForcedPath() { if (!$this->isBuiltin()) { return null; } $repository = $this->getRepository(); $id = $repository->getID(); $callsign = $repository->getCallsign(); $short_name = $repository->getRepositorySlug(); $clone_name = $repository->getCloneName(); if ($repository->isGit()) { $suffix = '.git'; } else if ($repository->isHg()) { $suffix = '/'; } else { $suffix = ''; + $clone_name = ''; } switch ($this->getBuiltinIdentifier()) { case self::BUILTIN_IDENTIFIER_ID: return "/diffusion/{$id}/{$clone_name}{$suffix}"; case self::BUILTIN_IDENTIFIER_SHORTNAME: return "/source/{$short_name}{$suffix}"; case self::BUILTIN_IDENTIFIER_CALLSIGN: return "/diffusion/{$callsign}/{$clone_name}{$suffix}"; default: return null; } } 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_READWRITE; } 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.'), ), ); } public function newCommandEngine() { $repository = $this->getRepository(); $protocol = $this->getEffectiveURI()->getProtocol(); return DiffusionCommandEngine::newCommandEngine($repository) ->setCredentialPHID($this->getCredentialPHID()) ->setProtocol($protocol); } public function getURIScore() { $score = 0; $io_points = array( self::IO_READWRITE => 20, self::IO_READ => 10, ); $score += idx($io_points, $this->getEffectiveIoType(), 0); $protocol_points = array( self::BUILTIN_PROTOCOL_SSH => 3, self::BUILTIN_PROTOCOL_HTTPS => 2, self::BUILTIN_PROTOCOL_HTTP => 1, ); $score += idx($protocol_points, $this->getBuiltinProtocol(), 0); return $score; } /* -( PhabricatorApplicationTransactionInterface )------------------------- */ public function getApplicationTransactionEditor() { return new DiffusionURIEditor(); } public function getApplicationTransactionObject() { return $this; } public function getApplicationTransactionTemplate() { return new PhabricatorRepositoryURITransaction(); } public function willRenderTimeline( PhabricatorApplicationTransactionView $timeline, AphrontRequest $request) { return $timeline; } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: case PhabricatorPolicyCapability::CAN_EDIT: return PhabricatorPolicies::getMostOpenPolicy(); } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return false; } public function describeAutomaticCapability($capability) { return null; } /* -( PhabricatorExtendedPolicyInterface )--------------------------------- */ public function getExtendedPolicy($capability, PhabricatorUser $viewer) { $extended = array(); switch ($capability) { case PhabricatorPolicyCapability::CAN_EDIT: // To edit a repository URI, you must be able to edit the // corresponding repository. $extended[] = array($this->getRepository(), $capability); break; } return $extended; } /* -( PhabricatorConduitResultInterface )---------------------------------- */ public function getFieldSpecificationsForConduit() { return array( id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('repositoryPHID') ->setType('phid') ->setDescription(pht('The associated repository PHID.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('uri') ->setType('map') ->setDescription(pht('The raw and effective URI.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('io') ->setType('map') ->setDescription( pht('The raw, default, and effective I/O Type settings.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('display') ->setType('map') ->setDescription( pht('The raw, default, and effective Display Type settings.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('credentialPHID') ->setType('phid?') ->setDescription( pht('The associated credential PHID, if one exists.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('disabled') ->setType('bool') ->setDescription(pht('True if the URI is disabled.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('builtin') ->setType('map') ->setDescription( pht('Information about builtin URIs.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('dateCreated') ->setType('int') ->setDescription( pht('Epoch timestamp when the object was created.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('dateModified') ->setType('int') ->setDescription( pht('Epoch timestamp when the object was last updated.')), ); } public function getFieldValuesForConduit() { return array( 'repositoryPHID' => $this->getRepositoryPHID(), 'uri' => array( 'raw' => $this->getURI(), 'display' => (string)$this->getDisplayURI(), 'effective' => (string)$this->getEffectiveURI(), ), 'io' => array( 'raw' => $this->getIOType(), 'default' => $this->getDefaultIOType(), 'effective' => $this->getEffectiveIOType(), ), 'display' => array( 'raw' => $this->getDisplayType(), 'default' => $this->getDefaultDisplayType(), 'effective' => $this->getEffectiveDisplayType(), ), 'credentialPHID' => $this->getCredentialPHID(), 'disabled' => (bool)$this->getIsDisabled(), 'builtin' => array( 'protocol' => $this->getBuiltinProtocol(), 'identifier' => $this->getBuiltinIdentifier(), ), 'dateCreated' => $this->getDateCreated(), 'dateModified' => $this->getDateModified(), ); } public function getConduitSearchAttachments() { return array(); } }