@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Give "Config" a full-width, hierarchical layout

Summary:
Depends on D20933. Ref T13362. This reorganizes Config a bit and attempts to simplify it.

Subsections are now in a landing page console and groupings have been removed. We "only" have 75 values you can edit from the web UI nowadays, which is still a lot, but less overwhelming than it was in the past. And the trend is generally downward, as config is removed/simplified or moved into application settings.

This also gets rid of the "gigantic blobs of JSON in the UI".

Test Plan: Browsed all Config sections.

Maniphest Tasks: T13362

Differential Revision: https://secure.phabricator.com/D20934

+580 -675
+16 -20
src/__phutil_library_map__.php
··· 2799 2799 'PhabricatorConduitTokenQuery' => 'applications/conduit/query/PhabricatorConduitTokenQuery.php', 2800 2800 'PhabricatorConduitTokenTerminateController' => 'applications/conduit/controller/PhabricatorConduitTokenTerminateController.php', 2801 2801 'PhabricatorConduitTokensSettingsPanel' => 'applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php', 2802 - 'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php', 2803 2802 'PhabricatorConfigApplication' => 'applications/config/application/PhabricatorConfigApplication.php', 2804 - 'PhabricatorConfigApplicationController' => 'applications/config/controller/PhabricatorConfigApplicationController.php', 2805 2803 'PhabricatorConfigCacheController' => 'applications/config/controller/services/PhabricatorConfigCacheController.php', 2806 2804 'PhabricatorConfigClusterDatabasesController' => 'applications/config/controller/services/PhabricatorConfigClusterDatabasesController.php', 2807 2805 'PhabricatorConfigClusterNotificationsController' => 'applications/config/controller/services/PhabricatorConfigClusterNotificationsController.php', ··· 2810 2808 'PhabricatorConfigCollectorsModule' => 'applications/config/module/PhabricatorConfigCollectorsModule.php', 2811 2809 'PhabricatorConfigColumnSchema' => 'applications/config/schema/PhabricatorConfigColumnSchema.php', 2812 2810 'PhabricatorConfigConfigPHIDType' => 'applications/config/phid/PhabricatorConfigConfigPHIDType.php', 2811 + 'PhabricatorConfigConsoleController' => 'applications/config/controller/PhabricatorConfigConsoleController.php', 2813 2812 'PhabricatorConfigConstants' => 'applications/config/constants/PhabricatorConfigConstants.php', 2814 2813 'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php', 2815 2814 'PhabricatorConfigCoreSchemaSpec' => 'applications/config/schema/PhabricatorConfigCoreSchemaSpec.php', ··· 2821 2820 'PhabricatorConfigDefaultSource' => 'infrastructure/env/PhabricatorConfigDefaultSource.php', 2822 2821 'PhabricatorConfigDictionarySource' => 'infrastructure/env/PhabricatorConfigDictionarySource.php', 2823 2822 'PhabricatorConfigEdgeModule' => 'applications/config/module/PhabricatorConfigEdgeModule.php', 2824 - 'PhabricatorConfigEditController' => 'applications/config/controller/PhabricatorConfigEditController.php', 2823 + 'PhabricatorConfigEditController' => 'applications/config/controller/settings/PhabricatorConfigEditController.php', 2825 2824 'PhabricatorConfigEditor' => 'applications/config/editor/PhabricatorConfigEditor.php', 2826 2825 'PhabricatorConfigEntry' => 'applications/config/storage/PhabricatorConfigEntry.php', 2827 2826 'PhabricatorConfigEntryDAO' => 'applications/config/storage/PhabricatorConfigEntryDAO.php', 2828 2827 'PhabricatorConfigEntryQuery' => 'applications/config/query/PhabricatorConfigEntryQuery.php', 2829 2828 'PhabricatorConfigFileSource' => 'infrastructure/env/PhabricatorConfigFileSource.php', 2830 2829 'PhabricatorConfigGroupConstants' => 'applications/config/constants/PhabricatorConfigGroupConstants.php', 2831 - 'PhabricatorConfigGroupController' => 'applications/config/controller/PhabricatorConfigGroupController.php', 2832 2830 'PhabricatorConfigHTTPParameterTypesModule' => 'applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php', 2833 - 'PhabricatorConfigHistoryController' => 'applications/config/controller/PhabricatorConfigHistoryController.php', 2834 - 'PhabricatorConfigIgnoreController' => 'applications/config/controller/PhabricatorConfigIgnoreController.php', 2835 - 'PhabricatorConfigIssueListController' => 'applications/config/controller/PhabricatorConfigIssueListController.php', 2836 - 'PhabricatorConfigIssuePanelController' => 'applications/config/controller/PhabricatorConfigIssuePanelController.php', 2837 - 'PhabricatorConfigIssueViewController' => 'applications/config/controller/PhabricatorConfigIssueViewController.php', 2831 + 'PhabricatorConfigIgnoreController' => 'applications/config/controller/issue/PhabricatorConfigIgnoreController.php', 2832 + 'PhabricatorConfigIssueListController' => 'applications/config/controller/issue/PhabricatorConfigIssueListController.php', 2833 + 'PhabricatorConfigIssuePanelController' => 'applications/config/controller/issue/PhabricatorConfigIssuePanelController.php', 2834 + 'PhabricatorConfigIssueViewController' => 'applications/config/controller/issue/PhabricatorConfigIssueViewController.php', 2838 2835 'PhabricatorConfigJSON' => 'applications/config/json/PhabricatorConfigJSON.php', 2839 2836 'PhabricatorConfigJSONOptionType' => 'applications/config/custom/PhabricatorConfigJSONOptionType.php', 2840 2837 'PhabricatorConfigKeySchema' => 'applications/config/schema/PhabricatorConfigKeySchema.php', 2841 - 'PhabricatorConfigListController' => 'applications/config/controller/PhabricatorConfigListController.php', 2842 2838 'PhabricatorConfigLocalSource' => 'infrastructure/env/PhabricatorConfigLocalSource.php', 2843 2839 'PhabricatorConfigManagementDeleteWorkflow' => 'applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php', 2844 2840 'PhabricatorConfigManagementDoneWorkflow' => 'applications/config/management/PhabricatorConfigManagementDoneWorkflow.php', ··· 2849 2845 'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php', 2850 2846 'PhabricatorConfigManualActivity' => 'applications/config/storage/PhabricatorConfigManualActivity.php', 2851 2847 'PhabricatorConfigModule' => 'applications/config/module/PhabricatorConfigModule.php', 2852 - 'PhabricatorConfigModuleController' => 'applications/config/controller/PhabricatorConfigModuleController.php', 2848 + 'PhabricatorConfigModuleController' => 'applications/config/controller/module/PhabricatorConfigModuleController.php', 2853 2849 'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php', 2854 2850 'PhabricatorConfigOptionType' => 'applications/config/custom/PhabricatorConfigOptionType.php', 2855 2851 'PhabricatorConfigPHIDModule' => 'applications/config/module/PhabricatorConfigPHIDModule.php', 2856 2852 'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php', 2857 - 'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/PhabricatorConfigPurgeCacheController.php', 2853 + 'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/services/PhabricatorConfigPurgeCacheController.php', 2858 2854 'PhabricatorConfigRegexOptionType' => 'applications/config/custom/PhabricatorConfigRegexOptionType.php', 2859 2855 'PhabricatorConfigRemarkupRule' => 'infrastructure/markup/rule/PhabricatorConfigRemarkupRule.php', 2860 2856 'PhabricatorConfigRequestExceptionHandlerModule' => 'applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php', ··· 2863 2859 'PhabricatorConfigSchemaSpec' => 'applications/config/schema/PhabricatorConfigSchemaSpec.php', 2864 2860 'PhabricatorConfigServerSchema' => 'applications/config/schema/PhabricatorConfigServerSchema.php', 2865 2861 'PhabricatorConfigServicesController' => 'applications/config/controller/services/PhabricatorConfigServicesController.php', 2862 + 'PhabricatorConfigSettingsController' => 'applications/config/controller/settings/PhabricatorConfigSettingsController.php', 2863 + 'PhabricatorConfigSettingsHistoryController' => 'applications/config/controller/settings/PhabricatorConfigSettingsHistoryController.php', 2864 + 'PhabricatorConfigSettingsListController' => 'applications/config/controller/settings/PhabricatorConfigSettingsListController.php', 2866 2865 'PhabricatorConfigSetupCheckModule' => 'applications/config/module/PhabricatorConfigSetupCheckModule.php', 2867 2866 'PhabricatorConfigSiteModule' => 'applications/config/module/PhabricatorConfigSiteModule.php', 2868 2867 'PhabricatorConfigSiteSource' => 'infrastructure/env/PhabricatorConfigSiteSource.php', ··· 2874 2873 'PhabricatorConfigTransactionQuery' => 'applications/config/query/PhabricatorConfigTransactionQuery.php', 2875 2874 'PhabricatorConfigType' => 'applications/config/type/PhabricatorConfigType.php', 2876 2875 'PhabricatorConfigValidationException' => 'applications/config/exception/PhabricatorConfigValidationException.php', 2877 - 'PhabricatorConfigVersionController' => 'applications/config/controller/PhabricatorConfigVersionController.php', 2878 2876 'PhabricatorConpherenceApplication' => 'applications/conpherence/application/PhabricatorConpherenceApplication.php', 2879 2877 'PhabricatorConpherenceColumnMinimizeSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnMinimizeSetting.php', 2880 2878 'PhabricatorConpherenceColumnVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnVisibleSetting.php', ··· 9134 9132 'PhabricatorConduitTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 9135 9133 'PhabricatorConduitTokenTerminateController' => 'PhabricatorConduitController', 9136 9134 'PhabricatorConduitTokensSettingsPanel' => 'PhabricatorSettingsPanel', 9137 - 'PhabricatorConfigAllController' => 'PhabricatorConfigController', 9138 9135 'PhabricatorConfigApplication' => 'PhabricatorApplication', 9139 - 'PhabricatorConfigApplicationController' => 'PhabricatorConfigController', 9140 9136 'PhabricatorConfigCacheController' => 'PhabricatorConfigServicesController', 9141 9137 'PhabricatorConfigClusterDatabasesController' => 'PhabricatorConfigServicesController', 9142 9138 'PhabricatorConfigClusterNotificationsController' => 'PhabricatorConfigServicesController', ··· 9145 9141 'PhabricatorConfigCollectorsModule' => 'PhabricatorConfigModule', 9146 9142 'PhabricatorConfigColumnSchema' => 'PhabricatorConfigStorageSchema', 9147 9143 'PhabricatorConfigConfigPHIDType' => 'PhabricatorPHIDType', 9144 + 'PhabricatorConfigConsoleController' => 'PhabricatorConfigController', 9148 9145 'PhabricatorConfigConstants' => 'Phobject', 9149 9146 'PhabricatorConfigController' => 'PhabricatorController', 9150 9147 'PhabricatorConfigCoreSchemaSpec' => 'PhabricatorConfigSchemaSpec', ··· 9156 9153 'PhabricatorConfigDefaultSource' => 'PhabricatorConfigProxySource', 9157 9154 'PhabricatorConfigDictionarySource' => 'PhabricatorConfigSource', 9158 9155 'PhabricatorConfigEdgeModule' => 'PhabricatorConfigModule', 9159 - 'PhabricatorConfigEditController' => 'PhabricatorConfigController', 9156 + 'PhabricatorConfigEditController' => 'PhabricatorConfigSettingsController', 9160 9157 'PhabricatorConfigEditor' => 'PhabricatorApplicationTransactionEditor', 9161 9158 'PhabricatorConfigEntry' => array( 9162 9159 'PhabricatorConfigEntryDAO', ··· 9167 9164 'PhabricatorConfigEntryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 9168 9165 'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource', 9169 9166 'PhabricatorConfigGroupConstants' => 'PhabricatorConfigConstants', 9170 - 'PhabricatorConfigGroupController' => 'PhabricatorConfigController', 9171 9167 'PhabricatorConfigHTTPParameterTypesModule' => 'PhabricatorConfigModule', 9172 - 'PhabricatorConfigHistoryController' => 'PhabricatorConfigController', 9173 9168 'PhabricatorConfigIgnoreController' => 'PhabricatorConfigController', 9174 9169 'PhabricatorConfigIssueListController' => 'PhabricatorConfigController', 9175 9170 'PhabricatorConfigIssuePanelController' => 'PhabricatorConfigController', ··· 9177 9172 'PhabricatorConfigJSON' => 'Phobject', 9178 9173 'PhabricatorConfigJSONOptionType' => 'PhabricatorConfigOptionType', 9179 9174 'PhabricatorConfigKeySchema' => 'PhabricatorConfigStorageSchema', 9180 - 'PhabricatorConfigListController' => 'PhabricatorConfigController', 9181 9175 'PhabricatorConfigLocalSource' => 'PhabricatorConfigProxySource', 9182 9176 'PhabricatorConfigManagementDeleteWorkflow' => 'PhabricatorConfigManagementWorkflow', 9183 9177 'PhabricatorConfigManagementDoneWorkflow' => 'PhabricatorConfigManagementWorkflow', ··· 9202 9196 'PhabricatorConfigSchemaSpec' => 'Phobject', 9203 9197 'PhabricatorConfigServerSchema' => 'PhabricatorConfigStorageSchema', 9204 9198 'PhabricatorConfigServicesController' => 'PhabricatorConfigController', 9199 + 'PhabricatorConfigSettingsController' => 'PhabricatorConfigController', 9200 + 'PhabricatorConfigSettingsHistoryController' => 'PhabricatorConfigSettingsController', 9201 + 'PhabricatorConfigSettingsListController' => 'PhabricatorConfigSettingsController', 9205 9202 'PhabricatorConfigSetupCheckModule' => 'PhabricatorConfigModule', 9206 9203 'PhabricatorConfigSiteModule' => 'PhabricatorConfigModule', 9207 9204 'PhabricatorConfigSiteSource' => 'PhabricatorConfigProxySource', ··· 9213 9210 'PhabricatorConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 9214 9211 'PhabricatorConfigType' => 'Phobject', 9215 9212 'PhabricatorConfigValidationException' => 'Exception', 9216 - 'PhabricatorConfigVersionController' => 'PhabricatorConfigController', 9217 9213 'PhabricatorConpherenceApplication' => 'PhabricatorApplication', 9218 9214 'PhabricatorConpherenceColumnMinimizeSetting' => 'PhabricatorInternalSetting', 9219 9215 'PhabricatorConpherenceColumnVisibleSetting' => 'PhabricatorInternalSetting',
+1 -2
src/applications/almanac/controller/AlmanacConsoleController.php
··· 10 10 $viewer = $request->getViewer(); 11 11 12 12 $menu = id(new PHUIObjectItemListView()) 13 - ->setUser($viewer) 13 + ->setViewer($viewer) 14 14 ->setBig(true); 15 15 16 16 $menu->addItem( ··· 84 84 ->setTitle(pht('Almanac Console')) 85 85 ->setCrumbs($crumbs) 86 86 ->appendChild($view); 87 - 88 87 } 89 88 90 89 }
+7 -2
src/applications/config/application/PhabricatorConfigApplication.php
··· 37 37 public function getRoutes() { 38 38 return array( 39 39 '/config/' => array( 40 - '' => 'PhabricatorConfigListController', 40 + '' => 'PhabricatorConfigConsoleController', 41 41 'application/' => 'PhabricatorConfigApplicationController', 42 42 'all/' => 'PhabricatorConfigAllController', 43 43 'history/' => 'PhabricatorConfigHistoryController', 44 44 'edit/(?P<key>[\w\.\-]+)/' => 'PhabricatorConfigEditController', 45 45 'group/(?P<key>[^/]+)/' => 'PhabricatorConfigGroupController', 46 - 'version/' => 'PhabricatorConfigVersionController', 47 46 'database/'. 48 47 '(?:(?P<ref>[^/]+)/'. 49 48 '(?:(?P<database>[^/]+)/'. ··· 70 69 'notifications/' => 'PhabricatorConfigClusterNotificationsController', 71 70 'repositories/' => 'PhabricatorConfigClusterRepositoriesController', 72 71 'search/' => 'PhabricatorConfigClusterSearchController', 72 + ), 73 + 'settings/' => array( 74 + '' => 'PhabricatorConfigSettingsListController', 75 + '(?P<filter>advanced|all)/' 76 + => 'PhabricatorConfigSettingsListController', 77 + 'history/' => 'PhabricatorConfigSettingsHistoryController', 73 78 ), 74 79 ), 75 80 );
+12 -9
src/applications/config/check/PhabricatorAuthSetupCheck.php
··· 53 53 "\n\n". 54 54 'Leaving your authentication provider configuration unlocked '. 55 55 'increases the damage that a compromised administrator account can '. 56 - 'do to your install, by, for example, changing the authentication '. 57 - 'provider to a server they control and intercepting usernames and '. 56 + 'do to your install. For example, an attacker who compromises an '. 57 + 'administrator account can change authentication providers to point '. 58 + 'at a server they control and attempt to intercept usernames and '. 58 59 'passwords.'. 59 60 "\n\n". 60 - 'To prevent this attack, you should configure your authentication '. 61 - 'providers, and then lock the configuration by doing `%s` '. 62 - 'from the command line. This will prevent changing the '. 63 - 'authentication provider config without first doing `%s`.', 64 - 'bin/auth lock', 65 - 'bin/auth unlock'); 61 + 'To prevent this attack, you should configure authentication, and '. 62 + 'then lock the configuration by running "bin/auth lock" from the '. 63 + 'command line. This will prevent changing the authentication config '. 64 + 'without first running "bin/auth unlock".'); 66 65 $this 67 66 ->newIssue('auth.config-unlocked') 68 67 ->setShortName(pht('Auth Config Unlocked')) 69 - ->setName(pht('Authenticaton Provider Configuration Unlocked')) 68 + ->setName(pht('Authenticaton Configuration Unlocked')) 69 + ->setSummary( 70 + pht( 71 + 'Authentication configuration is currently unlocked. Once you '. 72 + 'finish configuring authentication, you should lock it.')) 70 73 ->setMessage($message) 71 74 ->addRelatedPhabricatorConfig('auth.lock-config') 72 75 ->addCommand(
+1 -2
src/applications/config/check/PhabricatorSecuritySetupCheck.php
··· 58 58 ->setName(pht('Alternate File Domain Not Configured')) 59 59 ->setSummary( 60 60 pht( 61 - 'Increase security (and improve performance) by configuring '. 62 - 'a CDN or alternate file domain.')) 61 + 'Improve security by configuring an alternate file domain.')) 63 62 ->setMessage( 64 63 pht( 65 64 'Phabricator is currently configured to serve user uploads '.
-77
src/applications/config/controller/PhabricatorConfigAllController.php
··· 1 - <?php 2 - 3 - final class PhabricatorConfigAllController 4 - extends PhabricatorConfigController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $viewer = $request->getViewer(); 8 - 9 - $db_values = id(new PhabricatorConfigEntry()) 10 - ->loadAllWhere('namespace = %s', 'default'); 11 - $db_values = mpull($db_values, null, 'getConfigKey'); 12 - 13 - $rows = array(); 14 - $options = PhabricatorApplicationConfigOptions::loadAllOptions(); 15 - ksort($options); 16 - foreach ($options as $option) { 17 - $key = $option->getKey(); 18 - 19 - if ($option->getHidden()) { 20 - $value = phutil_tag('em', array(), pht('Hidden')); 21 - } else { 22 - $value = PhabricatorEnv::getEnvConfig($key); 23 - $value = PhabricatorConfigJSON::prettyPrintJSON($value); 24 - } 25 - 26 - $db_value = idx($db_values, $key); 27 - $rows[] = array( 28 - phutil_tag( 29 - 'a', 30 - array( 31 - 'href' => $this->getApplicationURI('edit/'.$key.'/'), 32 - ), 33 - $key), 34 - $value, 35 - $db_value && !$db_value->getIsDeleted() ? pht('Customized') : '', 36 - ); 37 - } 38 - $table = id(new AphrontTableView($rows)) 39 - ->setColumnClasses( 40 - array( 41 - '', 42 - 'wide', 43 - )) 44 - ->setHeaders( 45 - array( 46 - pht('Key'), 47 - pht('Value'), 48 - pht('Customized'), 49 - )); 50 - 51 - $title = pht('Current Settings'); 52 - $header = $this->buildHeaderView($title); 53 - 54 - $nav = $this->buildSideNavView(); 55 - $nav->selectFilter('all/'); 56 - 57 - $view = $this->buildConfigBoxView( 58 - pht('All Settings'), 59 - $table); 60 - 61 - $crumbs = $this->buildApplicationCrumbs() 62 - ->addTextCrumb($title) 63 - ->setBorder(true); 64 - 65 - $content = id(new PHUITwoColumnView()) 66 - ->setHeader($header) 67 - ->setFooter($view); 68 - 69 - return $this->newPage() 70 - ->setTitle($title) 71 - ->setCrumbs($crumbs) 72 - ->setNavigation($nav) 73 - ->appendChild($content); 74 - 75 - } 76 - 77 - }
-57
src/applications/config/controller/PhabricatorConfigApplicationController.php
··· 1 - <?php 2 - 3 - final class PhabricatorConfigApplicationController 4 - extends PhabricatorConfigController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $viewer = $request->getViewer(); 8 - 9 - $nav = $this->buildSideNavView(); 10 - $nav->selectFilter('application/'); 11 - 12 - $groups = PhabricatorApplicationConfigOptions::loadAll(); 13 - $apps_list = $this->buildConfigOptionsList($groups, 'apps'); 14 - $apps_list = $this->buildConfigBoxView(pht('Applications'), $apps_list); 15 - 16 - $title = pht('Application Settings'); 17 - $header = $this->buildHeaderView($title); 18 - 19 - $content = id(new PHUITwoColumnView()) 20 - ->setHeader($header) 21 - ->setFooter($apps_list); 22 - 23 - $crumbs = $this->buildApplicationCrumbs() 24 - ->addTextCrumb($title) 25 - ->setBorder(true); 26 - 27 - return $this->newPage() 28 - ->setTitle($title) 29 - ->setCrumbs($crumbs) 30 - ->setNavigation($nav) 31 - ->appendChild($content); 32 - } 33 - 34 - private function buildConfigOptionsList(array $groups, $type) { 35 - assert_instances_of($groups, 'PhabricatorApplicationConfigOptions'); 36 - 37 - $list = new PHUIObjectItemListView(); 38 - $list->setBig(true); 39 - $groups = msort($groups, 'getName'); 40 - foreach ($groups as $group) { 41 - if ($group->getGroup() == $type) { 42 - $icon = id(new PHUIIconView()) 43 - ->setIcon($group->getIcon()) 44 - ->setBackground('bg-violet'); 45 - $item = id(new PHUIObjectItemView()) 46 - ->setHeader($group->getName()) 47 - ->setHref('/config/group/'.$group->getKey().'/') 48 - ->addAttribute($group->getDescription()) 49 - ->setImageIcon($icon); 50 - $list->addItem($item); 51 - } 52 - } 53 - 54 - return $list; 55 - } 56 - 57 - }
+337
src/applications/config/controller/PhabricatorConfigConsoleController.php
··· 1 + <?php 2 + 3 + final class PhabricatorConfigConsoleController 4 + extends PhabricatorConfigController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $request->getViewer(); 8 + 9 + $menu = id(new PHUIObjectItemListView()) 10 + ->setViewer($viewer) 11 + ->setBig(true); 12 + 13 + $menu->addItem( 14 + id(new PHUIObjectItemView()) 15 + ->setHeader(pht('Settings')) 16 + ->setHref($this->getApplicationURI('settings/')) 17 + ->setImageIcon('fa-wrench') 18 + ->setClickable(true) 19 + ->addAttribute( 20 + pht( 21 + 'Review and modify configuration settings.'))); 22 + 23 + $menu->addItem( 24 + id(new PHUIObjectItemView()) 25 + ->setHeader(pht('Setup Issues')) 26 + ->setHref($this->getApplicationURI('issue/')) 27 + ->setImageIcon('fa-exclamation-triangle') 28 + ->setClickable(true) 29 + ->addAttribute( 30 + pht( 31 + 'Show unresolved issues with setup and configuration.'))); 32 + 33 + $menu->addItem( 34 + id(new PHUIObjectItemView()) 35 + ->setHeader(pht('Services')) 36 + ->setHref($this->getApplicationURI('cluster/databases/')) 37 + ->setImageIcon('fa-server') 38 + ->setClickable(true) 39 + ->addAttribute( 40 + pht( 41 + 'View status information for databases, caches, repositories, '. 42 + 'and other services.'))); 43 + 44 + $menu->addItem( 45 + id(new PHUIObjectItemView()) 46 + ->setHeader(pht('Extensions/Modules')) 47 + ->setHref($this->getApplicationURI('module/')) 48 + ->setImageIcon('fa-gear') 49 + ->setClickable(true) 50 + ->addAttribute( 51 + pht( 52 + 'Show installed extensions and modules.'))); 53 + 54 + $crumbs = $this->buildApplicationCrumbs() 55 + ->addTextCrumb(pht('Console')) 56 + ->setBorder(true); 57 + 58 + $box = id(new PHUIObjectBoxView()) 59 + ->setHeaderText(pht('Phabricator Configuation')) 60 + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) 61 + ->setObjectList($menu); 62 + 63 + $versions = $this->newLibraryVersionTable($viewer); 64 + $binary_versions = $this->newBinaryVersionTable(); 65 + 66 + $launcher_view = id(new PHUILauncherView()) 67 + ->appendChild($box) 68 + ->appendChild($versions) 69 + ->appendChild($binary_versions); 70 + 71 + $view = id(new PHUITwoColumnView()) 72 + ->setFooter($launcher_view); 73 + 74 + return $this->newPage() 75 + ->setTitle(pht('Phabricator Configuation')) 76 + ->setCrumbs($crumbs) 77 + ->appendChild($view); 78 + } 79 + 80 + public function newLibraryVersionTable() { 81 + $viewer = $this->getViewer(); 82 + 83 + $versions = $this->loadVersions($viewer); 84 + 85 + $rows = array(); 86 + foreach ($versions as $name => $info) { 87 + $branchpoint = $info['branchpoint']; 88 + if (strlen($branchpoint)) { 89 + $branchpoint = substr($branchpoint, 0, 12); 90 + } else { 91 + $branchpoint = null; 92 + } 93 + 94 + $version = $info['hash']; 95 + if (strlen($version)) { 96 + $version = substr($version, 0, 12); 97 + } else { 98 + $version = pht('Unknown'); 99 + } 100 + 101 + 102 + $epoch = $info['epoch']; 103 + if ($epoch) { 104 + $epoch = phabricator_date($epoch, $viewer); 105 + } else { 106 + $epoch = null; 107 + } 108 + 109 + $rows[] = array( 110 + $name, 111 + $version, 112 + $epoch, 113 + $branchpoint, 114 + ); 115 + } 116 + 117 + $table_view = id(new AphrontTableView($rows)) 118 + ->setHeaders( 119 + array( 120 + pht('Library'), 121 + pht('Version'), 122 + pht('Date'), 123 + pht('Branchpoint'), 124 + )) 125 + ->setColumnClasses( 126 + array( 127 + 'pri', 128 + null, 129 + null, 130 + 'wide', 131 + )); 132 + 133 + return id(new PHUIObjectBoxView()) 134 + ->setHeaderText(pht('Phabricator Version Information')) 135 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 136 + ->appendChild($table_view); 137 + } 138 + 139 + private function loadVersions(PhabricatorUser $viewer) { 140 + $specs = array( 141 + 'phabricator', 142 + 'arcanist', 143 + 'phutil', 144 + ); 145 + 146 + $all_libraries = PhutilBootloader::getInstance()->getAllLibraries(); 147 + // This puts the core libraries at the top: 148 + $other_libraries = array_diff($all_libraries, $specs); 149 + $specs = array_merge($specs, $other_libraries); 150 + 151 + $log_futures = array(); 152 + $remote_futures = array(); 153 + 154 + foreach ($specs as $lib) { 155 + $root = dirname(phutil_get_library_root($lib)); 156 + 157 + $log_command = csprintf( 158 + 'git log --format=%s -n 1 --', 159 + '%H %ct'); 160 + 161 + $remote_command = csprintf( 162 + 'git remote -v'); 163 + 164 + $log_futures[$lib] = id(new ExecFuture('%C', $log_command)) 165 + ->setCWD($root); 166 + 167 + $remote_futures[$lib] = id(new ExecFuture('%C', $remote_command)) 168 + ->setCWD($root); 169 + } 170 + 171 + $all_futures = array_merge($log_futures, $remote_futures); 172 + 173 + id(new FutureIterator($all_futures)) 174 + ->resolveAll(); 175 + 176 + // A repository may have a bunch of remotes, but we're only going to look 177 + // for remotes we host to try to figure out where this repository branched. 178 + $upstream_pattern = '(github\.com/phacility/|secure\.phabricator\.com/)'; 179 + 180 + $upstream_futures = array(); 181 + $lib_upstreams = array(); 182 + foreach ($specs as $lib) { 183 + $remote_future = $remote_futures[$lib]; 184 + 185 + list($err, $stdout) = $remote_future->resolve(); 186 + if ($err) { 187 + // If this fails for whatever reason, just move on. 188 + continue; 189 + } 190 + 191 + // These look like this, with a tab separating the first two fields: 192 + // remote-name http://remote.uri/ (push) 193 + 194 + $upstreams = array(); 195 + 196 + $remotes = phutil_split_lines($stdout, false); 197 + foreach ($remotes as $remote) { 198 + $remote_pattern = '/^([^\t]+)\t([^ ]+) \(([^)]+)\)\z/'; 199 + $matches = null; 200 + if (!preg_match($remote_pattern, $remote, $matches)) { 201 + continue; 202 + } 203 + 204 + // Remote URIs are either "push" or "fetch": we only care about "fetch" 205 + // URIs. 206 + $type = $matches[3]; 207 + if ($type != 'fetch') { 208 + continue; 209 + } 210 + 211 + $uri = $matches[2]; 212 + $is_upstream = preg_match($upstream_pattern, $uri); 213 + if (!$is_upstream) { 214 + continue; 215 + } 216 + 217 + $name = $matches[1]; 218 + $upstreams[$name] = $name; 219 + } 220 + 221 + // If we have several suitable upstreams, try to pick the one named 222 + // "origin", if it exists. Otherwise, just pick the first one. 223 + if (isset($upstreams['origin'])) { 224 + $upstream = $upstreams['origin']; 225 + } else if ($upstreams) { 226 + $upstream = head($upstreams); 227 + } else { 228 + $upstream = null; 229 + } 230 + 231 + if (!$upstream) { 232 + continue; 233 + } 234 + 235 + $lib_upstreams[$lib] = $upstream; 236 + 237 + $merge_base_command = csprintf( 238 + 'git merge-base HEAD %s/master --', 239 + $upstream); 240 + 241 + $root = dirname(phutil_get_library_root($lib)); 242 + 243 + $upstream_futures[$lib] = id(new ExecFuture('%C', $merge_base_command)) 244 + ->setCWD($root); 245 + } 246 + 247 + if ($upstream_futures) { 248 + id(new FutureIterator($upstream_futures)) 249 + ->resolveAll(); 250 + } 251 + 252 + $results = array(); 253 + foreach ($log_futures as $lib => $future) { 254 + list($err, $stdout) = $future->resolve(); 255 + if (!$err) { 256 + list($hash, $epoch) = explode(' ', $stdout); 257 + } else { 258 + $hash = null; 259 + $epoch = null; 260 + } 261 + 262 + $result = array( 263 + 'hash' => $hash, 264 + 'epoch' => $epoch, 265 + 'upstream' => null, 266 + 'branchpoint' => null, 267 + ); 268 + 269 + $upstream_future = idx($upstream_futures, $lib); 270 + if ($upstream_future) { 271 + list($err, $stdout) = $upstream_future->resolve(); 272 + if (!$err) { 273 + $branchpoint = trim($stdout); 274 + if (strlen($branchpoint)) { 275 + // We only list a branchpoint if it differs from HEAD. 276 + if ($branchpoint != $hash) { 277 + $result['upstream'] = $lib_upstreams[$lib]; 278 + $result['branchpoint'] = trim($stdout); 279 + } 280 + } 281 + } 282 + } 283 + 284 + $results[$lib] = $result; 285 + } 286 + 287 + return $results; 288 + } 289 + 290 + private function newBinaryVersionTable() { 291 + $rows = array(); 292 + 293 + $rows[] = array( 294 + 'php', 295 + phpversion(), 296 + php_sapi_name(), 297 + ); 298 + 299 + $binaries = PhutilBinaryAnalyzer::getAllBinaries(); 300 + foreach ($binaries as $binary) { 301 + if (!$binary->isBinaryAvailable()) { 302 + $binary_version = pht('Not Available'); 303 + $binary_path = null; 304 + } else { 305 + $binary_version = $binary->getBinaryVersion(); 306 + $binary_path = $binary->getBinaryPath(); 307 + } 308 + 309 + $rows[] = array( 310 + $binary->getBinaryName(), 311 + $binary_version, 312 + $binary_path, 313 + ); 314 + } 315 + 316 + $table_view = id(new AphrontTableView($rows)) 317 + ->setHeaders( 318 + array( 319 + pht('Binary'), 320 + pht('Version'), 321 + pht('Path'), 322 + )) 323 + ->setColumnClasses( 324 + array( 325 + 'pri', 326 + null, 327 + 'wide', 328 + )); 329 + 330 + return id(new PHUIObjectBoxView()) 331 + ->setHeaderText(pht('Other Version Information')) 332 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 333 + ->appendChild($table_view); 334 + } 335 + 336 + 337 + }
-27
src/applications/config/controller/PhabricatorConfigController.php
··· 6 6 return true; 7 7 } 8 8 9 - public function buildSideNavView($filter = null, $for_app = false) { 10 - $guide_href = new PhutilURI('/guides/'); 11 - $nav = new AphrontSideNavFilterView(); 12 - $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); 13 - $nav->addFilter('/', 14 - pht('Core Settings'), null, 'fa-gear'); 15 - $nav->addFilter('application/', 16 - pht('Application Settings'), null, 'fa-globe'); 17 - $nav->addFilter('history/', 18 - pht('Settings History'), null, 'fa-history'); 19 - $nav->addFilter('version/', 20 - pht('Version Information'), null, 'fa-download'); 21 - $nav->addFilter('all/', 22 - pht('All Settings'), null, 'fa-list-ul'); 23 - $nav->addLabel(pht('Setup')); 24 - $nav->addFilter('issue/', 25 - pht('Setup Issues'), null, 'fa-warning'); 26 - $nav->addFilter(null, 27 - pht('Installation Guide'), $guide_href, 'fa-book'); 28 - 29 - return $nav; 30 - } 31 - 32 - public function buildApplicationMenu() { 33 - return $this->buildSideNavView(null, true)->getMenu(); 34 - } 35 - 36 9 public function buildHeaderView($text, $action = null) { 37 10 $viewer = $this->getViewer(); 38 11
+4 -23
src/applications/config/controller/PhabricatorConfigEditController.php src/applications/config/controller/settings/PhabricatorConfigEditController.php
··· 1 1 <?php 2 2 3 3 final class PhabricatorConfigEditController 4 - extends PhabricatorConfigController { 4 + extends PhabricatorConfigSettingsController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $request->getViewer(); ··· 30 30 ->setDefault(null) 31 31 ->setDescription($desc); 32 32 $group = null; 33 - $group_uri = $this->getApplicationURI(); 34 33 } else { 35 34 $option = $options[$key]; 36 35 $group = $option->getGroup(); 37 - $group_uri = $this->getApplicationURI('group/'.$group->getKey().'/'); 38 36 } 39 37 40 38 $issue = $request->getStr('issue'); ··· 42 40 // If the user came here from an open setup issue, send them back. 43 41 $done_uri = $this->getApplicationURI('issue/'.$issue.'/'); 44 42 } else { 45 - $done_uri = $group_uri; 43 + $done_uri = $this->getApplicationURI('settings/'); 46 44 } 47 45 48 46 // Check if the config key is already stored in the database. ··· 205 203 $title = $key; 206 204 207 205 $box_header = array(); 208 - if ($group) { 209 - $box_header[] = phutil_tag( 210 - 'a', 211 - array( 212 - 'href' => $group_uri, 213 - ), 214 - $group->getName()); 215 - $box_header[] = " \xC2\xBB "; 216 - } 217 206 $box_header[] = $key; 218 207 219 - $crumbs = $this->buildApplicationCrumbs(); 220 - if ($group) { 221 - $crumbs->addTextCrumb($group->getName(), $group_uri); 222 - } 223 - $crumbs->addTextCrumb($key, '/config/edit/'.$key); 224 - $crumbs->setBorder(true); 208 + $crumbs = $this->newCrumbs() 209 + ->addTextCrumb($key, '/config/edit/'.$key); 225 210 226 211 $form_box = $this->buildConfigBoxView($box_header, $form, $tag); 227 212 ··· 229 214 $config_entry, 230 215 new PhabricatorConfigTransactionQuery()); 231 216 $timeline->setShouldTerminate(true); 232 - 233 - $nav = $this->buildSideNavView(); 234 - $nav->selectFilter($group_uri); 235 217 236 218 $header = $this->buildHeaderView($title); 237 219 ··· 249 231 return $this->newPage() 250 232 ->setTitle($title) 251 233 ->setCrumbs($crumbs) 252 - ->setNavigation($nav) 253 234 ->appendChild($view); 254 235 } 255 236
-112
src/applications/config/controller/PhabricatorConfigGroupController.php
··· 1 - <?php 2 - 3 - final class PhabricatorConfigGroupController 4 - extends PhabricatorConfigController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $viewer = $request->getViewer(); 8 - $group_key = $request->getURIData('key'); 9 - 10 - $groups = PhabricatorApplicationConfigOptions::loadAll(); 11 - $options = idx($groups, $group_key); 12 - if (!$options) { 13 - return new Aphront404Response(); 14 - } 15 - 16 - $group_uri = PhabricatorConfigGroupConstants::getGroupFullURI( 17 - $options->getGroup()); 18 - $group_name = PhabricatorConfigGroupConstants::getGroupShortName( 19 - $options->getGroup()); 20 - 21 - $nav = $this->buildSideNavView(); 22 - $nav->selectFilter($group_uri); 23 - 24 - $title = pht('%s Configuration', $options->getName()); 25 - $header = $this->buildHeaderView($title); 26 - $list = $this->buildOptionList($options->getOptions()); 27 - $group_url = phutil_tag('a', array('href' => $group_uri), $group_name); 28 - 29 - $box_header = pht("%s \xC2\xBB %s", $group_url, $options->getName()); 30 - $view = $this->buildConfigBoxView($box_header, $list); 31 - 32 - $crumbs = $this->buildApplicationCrumbs() 33 - ->addTextCrumb($group_name, $group_uri) 34 - ->addTextCrumb($options->getName()) 35 - ->setBorder(true); 36 - 37 - $content = id(new PHUITwoColumnView()) 38 - ->setHeader($header) 39 - ->setFooter($view); 40 - 41 - return $this->newPage() 42 - ->setTitle($title) 43 - ->setCrumbs($crumbs) 44 - ->setNavigation($nav) 45 - ->appendChild($content); 46 - } 47 - 48 - private function buildOptionList(array $options) { 49 - assert_instances_of($options, 'PhabricatorConfigOption'); 50 - 51 - require_celerity_resource('config-options-css'); 52 - 53 - $db_values = array(); 54 - if ($options) { 55 - $db_values = id(new PhabricatorConfigEntry())->loadAllWhere( 56 - 'configKey IN (%Ls) AND namespace = %s', 57 - mpull($options, 'getKey'), 58 - 'default'); 59 - $db_values = mpull($db_values, null, 'getConfigKey'); 60 - } 61 - 62 - $list = new PHUIObjectItemListView(); 63 - $list->setBig(true); 64 - foreach ($options as $option) { 65 - $summary = $option->getSummary(); 66 - 67 - $item = id(new PHUIObjectItemView()) 68 - ->setHeader($option->getKey()) 69 - ->setHref('/config/edit/'.$option->getKey().'/') 70 - ->addAttribute($summary); 71 - 72 - $color = null; 73 - $db_value = idx($db_values, $option->getKey()); 74 - if ($db_value && !$db_value->getIsDeleted()) { 75 - $item->setEffect('visited'); 76 - $color = 'violet'; 77 - } 78 - 79 - if ($option->getHidden()) { 80 - $item->setStatusIcon('fa-eye-slash grey', pht('Hidden')); 81 - $item->setDisabled(true); 82 - } else if ($option->getLocked()) { 83 - $item->setStatusIcon('fa-lock '.$color, pht('Locked')); 84 - } else if ($color) { 85 - $item->setStatusIcon('fa-pencil '.$color, pht('Editable')); 86 - } else { 87 - $item->setStatusIcon('fa-pencil-square-o '.$color, pht('Editable')); 88 - } 89 - 90 - if (!$option->getHidden()) { 91 - $current_value = PhabricatorEnv::getEnvConfig($option->getKey()); 92 - $current_value = PhabricatorConfigJSON::prettyPrintJSON( 93 - $current_value); 94 - $current_value = phutil_tag( 95 - 'div', 96 - array( 97 - 'class' => 'config-options-current-value '.$color, 98 - ), 99 - array( 100 - $current_value, 101 - )); 102 - 103 - $item->setSideColumn($current_value); 104 - } 105 - 106 - $list->addItem($item); 107 - } 108 - 109 - return $list; 110 - } 111 - 112 - }
+5 -7
src/applications/config/controller/PhabricatorConfigHistoryController.php src/applications/config/controller/settings/PhabricatorConfigSettingsHistoryController.php
··· 1 1 <?php 2 2 3 - final class PhabricatorConfigHistoryController 4 - extends PhabricatorConfigController { 3 + final class PhabricatorConfigSettingsHistoryController 4 + extends PhabricatorConfigSettingsController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $request->getViewer(); ··· 27 27 $title = pht('Settings History'); 28 28 $header = $this->buildHeaderView($title); 29 29 30 - $nav = $this->buildSideNavView(); 31 - $nav->selectFilter('history/'); 30 + $nav = $this->newNavigation('history'); 32 31 33 - $crumbs = $this->buildApplicationCrumbs() 34 - ->addTextCrumb($title) 35 - ->setBorder(true); 32 + $crumbs = $this->newCrumbs() 33 + ->addTextCrumb($title); 36 34 37 35 $content = id(new PHUITwoColumnView()) 38 36 ->setHeader($header)
src/applications/config/controller/PhabricatorConfigIgnoreController.php src/applications/config/controller/issue/PhabricatorConfigIgnoreController.php
+31 -29
src/applications/config/controller/PhabricatorConfigIssueListController.php src/applications/config/controller/issue/PhabricatorConfigIssueListController.php
··· 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $request->getViewer(); 8 8 9 - $nav = $this->buildSideNavView(); 10 - $nav->selectFilter('issue/'); 11 - 12 9 $engine = new PhabricatorSetupEngine(); 13 10 $response = $engine->execute(); 14 11 if ($response) { ··· 34 31 'fa-question-circle'); 35 32 36 33 $title = pht('Setup Issues'); 37 - $header = $this->buildHeaderView($title); 38 34 39 35 if (!$issues) { 40 36 $issue_list = id(new PHUIInfoView()) ··· 50 46 $other, 51 47 ); 52 48 53 - $issue_list = $this->buildConfigBoxView(pht('Issues'), $issue_list); 49 + $issue_list = $this->buildConfigBoxView( 50 + pht('Unresolved Setup Issues'), 51 + $issue_list); 54 52 } 55 53 56 54 $crumbs = $this->buildApplicationCrumbs() 57 55 ->addTextCrumb($title) 58 56 ->setBorder(true); 59 57 58 + $launcher_view = id(new PHUILauncherView()) 59 + ->appendChild($issue_list); 60 + 60 61 $content = id(new PHUITwoColumnView()) 61 - ->setHeader($header) 62 - ->setFooter($issue_list); 62 + ->setFooter($launcher_view); 63 63 64 64 return $this->newPage() 65 65 ->setTitle($title) 66 66 ->setCrumbs($crumbs) 67 - ->setNavigation($nav) 68 67 ->appendChild($content); 69 68 } 70 69 ··· 76 75 $items = 0; 77 76 78 77 foreach ($issues as $issue) { 79 - if ($issue->getGroup() == $group) { 80 - $items++; 81 - $href = $this->getApplicationURI('/issue/'.$issue->getIssueKey().'/'); 82 - $item = id(new PHUIObjectItemView()) 83 - ->setHeader($issue->getName()) 84 - ->setHref($href) 85 - ->addAttribute($issue->getSummary()); 86 - if (!$issue->getIsIgnored()) { 87 - $icon = id(new PHUIIconView()) 88 - ->setIcon($fonticon) 89 - ->setBackground('bg-sky'); 90 - $item->setImageIcon($icon); 91 - $list->addItem($item); 92 - } else { 93 - $icon = id(new PHUIIconView()) 94 - ->setIcon('fa-eye-slash') 95 - ->setBackground('bg-grey'); 96 - $item->setDisabled(true); 97 - $item->setImageIcon($icon); 98 - $ignored_items[] = $item; 99 - } 78 + if ($issue->getGroup() != $group) { 79 + continue; 80 + } 81 + 82 + $items++; 83 + $href = $this->getApplicationURI('/issue/'.$issue->getIssueKey().'/'); 84 + $item = id(new PHUIObjectItemView()) 85 + ->setHeader($issue->getName()) 86 + ->setHref($href) 87 + ->setClickable(true) 88 + ->addAttribute($issue->getSummary()); 89 + if (!$issue->getIsIgnored()) { 90 + $icon = id(new PHUIIconView()) 91 + ->setIcon($fonticon) 92 + ->setBackground('bg-sky'); 93 + $item->setImageIcon($icon); 94 + $list->addItem($item); 95 + } else { 96 + $icon = id(new PHUIIconView()) 97 + ->setIcon('fa-eye-slash') 98 + ->setBackground('bg-grey'); 99 + $item->setDisabled(true); 100 + $item->setImageIcon($icon); 101 + $ignored_items[] = $item; 100 102 } 101 103 } 102 104
src/applications/config/controller/PhabricatorConfigIssuePanelController.php src/applications/config/controller/issue/PhabricatorConfigIssuePanelController.php
+4 -9
src/applications/config/controller/PhabricatorConfigIssueViewController.php src/applications/config/controller/issue/PhabricatorConfigIssueViewController.php
··· 14 14 } 15 15 $issues = $engine->getIssues(); 16 16 17 - $nav = $this->buildSideNavView(); 18 - $nav->selectFilter('issue/'); 19 - 20 17 if (empty($issues[$issue_key])) { 21 18 $content = id(new PHUIInfoView()) 22 19 ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) ··· 36 33 $title = $issue->getShortName(); 37 34 } 38 35 39 - $header = $this->buildHeaderView($title); 40 - 41 36 $crumbs = $this 42 37 ->buildApplicationCrumbs() 43 - ->setBorder(true) 44 38 ->addTextCrumb(pht('Setup Issues'), $this->getApplicationURI('issue/')) 45 39 ->addTextCrumb($title, $request->getRequestURI()) 46 40 ->setBorder(true); 47 41 42 + $launcher_view = id(new PHUILauncherView()) 43 + ->appendChild($content); 44 + 48 45 $content = id(new PHUITwoColumnView()) 49 - ->setHeader($header) 50 - ->setFooter($content); 46 + ->setFooter($launcher_view); 51 47 52 48 return $this->newPage() 53 49 ->setTitle($title) 54 50 ->setCrumbs($crumbs) 55 - ->setNavigation($nav) 56 51 ->appendChild($content); 57 52 } 58 53
-57
src/applications/config/controller/PhabricatorConfigListController.php
··· 1 - <?php 2 - 3 - final class PhabricatorConfigListController 4 - extends PhabricatorConfigController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $viewer = $request->getViewer(); 8 - 9 - $nav = $this->buildSideNavView(); 10 - $nav->selectFilter('/'); 11 - 12 - $groups = PhabricatorApplicationConfigOptions::loadAll(); 13 - $core_list = $this->buildConfigOptionsList($groups, 'core'); 14 - $core_list = $this->buildConfigBoxView(pht('Core'), $core_list); 15 - 16 - $title = pht('Core Settings'); 17 - $header = $this->buildHeaderView($title); 18 - 19 - $crumbs = $this->buildApplicationCrumbs() 20 - ->addTextCrumb($title) 21 - ->setBorder(true); 22 - 23 - $content = id(new PHUITwoColumnView()) 24 - ->setHeader($header) 25 - ->setFooter($core_list); 26 - 27 - return $this->newPage() 28 - ->setTitle($title) 29 - ->setCrumbs($crumbs) 30 - ->setNavigation($nav) 31 - ->appendChild($content); 32 - } 33 - 34 - private function buildConfigOptionsList(array $groups, $type) { 35 - assert_instances_of($groups, 'PhabricatorApplicationConfigOptions'); 36 - 37 - $list = new PHUIObjectItemListView(); 38 - $list->setBig(true); 39 - $groups = msort($groups, 'getName'); 40 - foreach ($groups as $group) { 41 - if ($group->getGroup() == $type) { 42 - $icon = id(new PHUIIconView()) 43 - ->setIcon($group->getIcon()) 44 - ->setBackground('bg-blue'); 45 - $item = id(new PHUIObjectItemView()) 46 - ->setHeader($group->getName()) 47 - ->setHref('/config/group/'.$group->getKey().'/') 48 - ->addAttribute($group->getDescription()) 49 - ->setImageIcon($icon); 50 - $list->addItem($item); 51 - } 52 - } 53 - 54 - return $list; 55 - } 56 - 57 - }
src/applications/config/controller/PhabricatorConfigModuleController.php src/applications/config/controller/module/PhabricatorConfigModuleController.php
src/applications/config/controller/PhabricatorConfigPurgeCacheController.php src/applications/config/controller/services/PhabricatorConfigPurgeCacheController.php
-242
src/applications/config/controller/PhabricatorConfigVersionController.php
··· 1 - <?php 2 - 3 - final class PhabricatorConfigVersionController 4 - extends PhabricatorConfigController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $viewer = $request->getViewer(); 8 - 9 - $title = pht('Version Information'); 10 - $versions = $this->renderModuleStatus($viewer); 11 - 12 - $nav = $this->buildSideNavView(); 13 - $nav->selectFilter('version/'); 14 - $header = $this->buildHeaderView($title); 15 - 16 - $view = $this->buildConfigBoxView( 17 - pht('Installed Versions'), 18 - $versions); 19 - 20 - $crumbs = $this->buildApplicationCrumbs() 21 - ->addTextCrumb($title) 22 - ->setBorder(true); 23 - 24 - $content = id(new PHUITwoColumnView()) 25 - ->setHeader($header) 26 - ->setFooter($view); 27 - 28 - return $this->newPage() 29 - ->setTitle($title) 30 - ->setCrumbs($crumbs) 31 - ->setNavigation($nav) 32 - ->appendChild($content); 33 - } 34 - 35 - public function renderModuleStatus($viewer) { 36 - $versions = $this->loadVersions($viewer); 37 - 38 - $version_property_list = id(new PHUIPropertyListView()); 39 - foreach ($versions as $name => $info) { 40 - $version = $info['version']; 41 - 42 - if ($info['branchpoint']) { 43 - $display = pht( 44 - '%s (branched from %s on %s)', 45 - $version, 46 - $info['branchpoint'], 47 - $info['upstream']); 48 - } else { 49 - $display = $version; 50 - } 51 - 52 - $version_property_list->addProperty($name, $display); 53 - } 54 - 55 - $phabricator_root = dirname(phutil_get_library_root('phabricator')); 56 - $version_path = $phabricator_root.'/conf/local/VERSION'; 57 - if (Filesystem::pathExists($version_path)) { 58 - $version_from_file = Filesystem::readFile($version_path); 59 - $version_property_list->addProperty( 60 - pht('Local Version'), 61 - $version_from_file); 62 - } 63 - 64 - $version_property_list->addProperty('php', phpversion()); 65 - 66 - $binaries = PhutilBinaryAnalyzer::getAllBinaries(); 67 - foreach ($binaries as $binary) { 68 - if (!$binary->isBinaryAvailable()) { 69 - $binary_info = pht('Not Available'); 70 - } else { 71 - $version = $binary->getBinaryVersion(); 72 - $path = $binary->getBinaryPath(); 73 - if ($path === null && $version === null) { 74 - $binary_info = pht('-'); 75 - } else if ($path === null) { 76 - $binary_info = $version; 77 - } else if ($version === null) { 78 - $binary_info = pht('- at %s', $path); 79 - } else { 80 - $binary_info = pht('%s at %s', $version, $path); 81 - } 82 - } 83 - 84 - $version_property_list->addProperty( 85 - $binary->getBinaryName(), 86 - $binary_info); 87 - } 88 - 89 - return $version_property_list; 90 - } 91 - 92 - private function loadVersions(PhabricatorUser $viewer) { 93 - $specs = array( 94 - 'phabricator', 95 - 'arcanist', 96 - 'phutil', 97 - ); 98 - 99 - $all_libraries = PhutilBootloader::getInstance()->getAllLibraries(); 100 - // This puts the core libraries at the top: 101 - $other_libraries = array_diff($all_libraries, $specs); 102 - $specs = array_merge($specs, $other_libraries); 103 - 104 - $log_futures = array(); 105 - $remote_futures = array(); 106 - 107 - foreach ($specs as $lib) { 108 - $root = dirname(phutil_get_library_root($lib)); 109 - 110 - $log_command = csprintf( 111 - 'git log --format=%s -n 1 --', 112 - '%H %ct'); 113 - 114 - $remote_command = csprintf( 115 - 'git remote -v'); 116 - 117 - $log_futures[$lib] = id(new ExecFuture('%C', $log_command)) 118 - ->setCWD($root); 119 - 120 - $remote_futures[$lib] = id(new ExecFuture('%C', $remote_command)) 121 - ->setCWD($root); 122 - } 123 - 124 - $all_futures = array_merge($log_futures, $remote_futures); 125 - 126 - id(new FutureIterator($all_futures)) 127 - ->resolveAll(); 128 - 129 - // A repository may have a bunch of remotes, but we're only going to look 130 - // for remotes we host to try to figure out where this repository branched. 131 - $upstream_pattern = '(github\.com/phacility/|secure\.phabricator\.com/)'; 132 - 133 - $upstream_futures = array(); 134 - $lib_upstreams = array(); 135 - foreach ($specs as $lib) { 136 - $remote_future = $remote_futures[$lib]; 137 - 138 - list($err, $stdout) = $remote_future->resolve(); 139 - if ($err) { 140 - // If this fails for whatever reason, just move on. 141 - continue; 142 - } 143 - 144 - // These look like this, with a tab separating the first two fields: 145 - // remote-name http://remote.uri/ (push) 146 - 147 - $upstreams = array(); 148 - 149 - $remotes = phutil_split_lines($stdout, false); 150 - foreach ($remotes as $remote) { 151 - $remote_pattern = '/^([^\t]+)\t([^ ]+) \(([^)]+)\)\z/'; 152 - $matches = null; 153 - if (!preg_match($remote_pattern, $remote, $matches)) { 154 - continue; 155 - } 156 - 157 - // Remote URIs are either "push" or "fetch": we only care about "fetch" 158 - // URIs. 159 - $type = $matches[3]; 160 - if ($type != 'fetch') { 161 - continue; 162 - } 163 - 164 - $uri = $matches[2]; 165 - $is_upstream = preg_match($upstream_pattern, $uri); 166 - if (!$is_upstream) { 167 - continue; 168 - } 169 - 170 - $name = $matches[1]; 171 - $upstreams[$name] = $name; 172 - } 173 - 174 - // If we have several suitable upstreams, try to pick the one named 175 - // "origin", if it exists. Otherwise, just pick the first one. 176 - if (isset($upstreams['origin'])) { 177 - $upstream = $upstreams['origin']; 178 - } else if ($upstreams) { 179 - $upstream = head($upstreams); 180 - } else { 181 - $upstream = null; 182 - } 183 - 184 - if (!$upstream) { 185 - continue; 186 - } 187 - 188 - $lib_upstreams[$lib] = $upstream; 189 - 190 - $merge_base_command = csprintf( 191 - 'git merge-base HEAD %s/master --', 192 - $upstream); 193 - 194 - $root = dirname(phutil_get_library_root($lib)); 195 - 196 - $upstream_futures[$lib] = id(new ExecFuture('%C', $merge_base_command)) 197 - ->setCWD($root); 198 - } 199 - 200 - if ($upstream_futures) { 201 - id(new FutureIterator($upstream_futures)) 202 - ->resolveAll(); 203 - } 204 - 205 - $results = array(); 206 - foreach ($log_futures as $lib => $future) { 207 - list($err, $stdout) = $future->resolve(); 208 - if (!$err) { 209 - list($hash, $epoch) = explode(' ', $stdout); 210 - $version = pht('%s (%s)', $hash, phabricator_date($epoch, $viewer)); 211 - } else { 212 - $version = pht('Unknown'); 213 - } 214 - 215 - $result = array( 216 - 'version' => $version, 217 - 'upstream' => null, 218 - 'branchpoint' => null, 219 - ); 220 - 221 - $upstream_future = idx($upstream_futures, $lib); 222 - if ($upstream_future) { 223 - list($err, $stdout) = $upstream_future->resolve(); 224 - if (!$err) { 225 - $branchpoint = trim($stdout); 226 - if (strlen($branchpoint)) { 227 - // We only list a branchpoint if it differs from HEAD. 228 - if ($branchpoint != $hash) { 229 - $result['upstream'] = $lib_upstreams[$lib]; 230 - $result['branchpoint'] = trim($stdout); 231 - } 232 - } 233 - } 234 - } 235 - 236 - $results[$lib] = $result; 237 - } 238 - 239 - return $results; 240 - } 241 - 242 - }
+51
src/applications/config/controller/settings/PhabricatorConfigSettingsController.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorConfigSettingsController 4 + extends PhabricatorConfigController { 5 + 6 + public function newNavigation($select_filter) { 7 + $settings_uri = $this->getApplicationURI('settings/'); 8 + 9 + $nav = id(new AphrontSideNavFilterView()) 10 + ->setBaseURI(new PhutilURI($settings_uri)); 11 + 12 + $nav->addLabel(pht('Configuration')); 13 + 14 + $nav->newLink('settings') 15 + ->setName(pht('Core Settings')) 16 + ->setIcon('fa-wrench') 17 + ->setHref($settings_uri); 18 + 19 + $nav->newLink('advanced') 20 + ->setName(pht('Advanced Settings')) 21 + ->setIcon('fa-cogs') 22 + ->setHref(urisprintf('%s%s/', $settings_uri, 'advanced')); 23 + 24 + $nav->newLink('all') 25 + ->setName(pht('All Settings')) 26 + ->setIcon('fa-list') 27 + ->setHref(urisprintf('%s%s/', $settings_uri, 'all')); 28 + 29 + $nav->addLabel(pht('History')); 30 + 31 + $nav->newLink('history') 32 + ->setName(pht('View History')) 33 + ->setIcon('fa-history') 34 + ->setHref(urisprintf('%s%s/', $settings_uri, 'history')); 35 + 36 + if ($select_filter) { 37 + $nav->selectFilter($select_filter); 38 + } 39 + 40 + return $nav; 41 + } 42 + 43 + public function newCrumbs() { 44 + $settings_uri = $this->getApplicationURI('settings/'); 45 + 46 + return $this->buildApplicationCrumbs() 47 + ->addTextCrumb(pht('Settings'), $settings_uri) 48 + ->setBorder(true); 49 + } 50 + 51 + }
+107
src/applications/config/controller/settings/PhabricatorConfigSettingsListController.php
··· 1 + <?php 2 + 3 + final class PhabricatorConfigSettingsListController 4 + extends PhabricatorConfigSettingsController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $request->getViewer(); 8 + 9 + $filter = $request->getURIData('filter'); 10 + if (!strlen($filter)) { 11 + $filter = 'settings'; 12 + } 13 + 14 + $is_core = ($filter === 'settings'); 15 + $is_advanced = ($filter === 'advanced'); 16 + $is_all = ($filter === 'all'); 17 + 18 + $show_core = ($is_core || $is_all); 19 + $show_advanced = ($is_advanced || $is_all); 20 + 21 + if ($is_core) { 22 + $title = pht('Core Settings'); 23 + } else if ($is_advanced) { 24 + $title = pht('Advanced Settings'); 25 + } else { 26 + $title = pht('All Settings'); 27 + } 28 + 29 + $db_values = id(new PhabricatorConfigEntry()) 30 + ->loadAllWhere('namespace = %s', 'default'); 31 + $db_values = mpull($db_values, null, 'getConfigKey'); 32 + 33 + $list = id(new PHUIObjectItemListView()) 34 + ->setBig(true) 35 + ->setFlush(true); 36 + 37 + $rows = array(); 38 + $options = PhabricatorApplicationConfigOptions::loadAllOptions(); 39 + ksort($options); 40 + foreach ($options as $option) { 41 + $key = $option->getKey(); 42 + 43 + $is_advanced = (bool)$option->getLocked(); 44 + if ($is_advanced && !$show_advanced) { 45 + continue; 46 + } 47 + 48 + if (!$is_advanced && !$show_core) { 49 + continue; 50 + } 51 + 52 + $db_value = idx($db_values, $key); 53 + 54 + $item = $this->newConfigOptionView($option, $db_value); 55 + $list->addItem($item); 56 + } 57 + 58 + $header = $this->buildHeaderView($title); 59 + 60 + $crumbs = $this->newCrumbs() 61 + ->addTextCrumb($title); 62 + 63 + $content = id(new PHUITwoColumnView()) 64 + ->setHeader($header) 65 + ->setFooter($list); 66 + 67 + $nav = $this->newNavigation($filter); 68 + 69 + return $this->newPage() 70 + ->setTitle($title) 71 + ->setCrumbs($crumbs) 72 + ->setNavigation($nav) 73 + ->appendChild($content); 74 + } 75 + 76 + private function newConfigOptionView( 77 + PhabricatorConfigOption $option, 78 + PhabricatorConfigEntry $stored_value = null) { 79 + 80 + $summary = $option->getSummary(); 81 + 82 + $item = id(new PHUIObjectItemView()) 83 + ->setHeader($option->getKey()) 84 + ->setClickable(true) 85 + ->setHref('/config/edit/'.$option->getKey().'/') 86 + ->addAttribute($summary); 87 + 88 + $color = null; 89 + if ($stored_value && !$stored_value->getIsDeleted()) { 90 + $item->setEffect('visited'); 91 + $color = 'violet'; 92 + } 93 + 94 + if ($option->getHidden()) { 95 + $item->setStatusIcon('fa-eye-slash', pht('Hidden')); 96 + } else if ($option->getLocked()) { 97 + $item->setStatusIcon('fa-lock '.$color, pht('Locked')); 98 + } else if ($color) { 99 + $item->setStatusIcon('fa-pencil '.$color, pht('Editable')); 100 + } else { 101 + $item->setStatusIcon('fa-circle-o grey', pht('Default')); 102 + } 103 + 104 + return $item; 105 + } 106 + 107 + }
+4
src/applications/notification/setup/PhabricatorAphlictSetupCheck.php
··· 24 24 $this->newIssue('aphlict.connect') 25 25 ->setShortName(pht('Notification Server Down')) 26 26 ->setName(pht('Unable to Connect to Notification Server')) 27 + ->setSummary( 28 + pht( 29 + 'Phabricator is configured to use a notification server, '. 30 + 'but is not able to connect to it.')) 27 31 ->setMessage($message) 28 32 ->addRelatedPhabricatorConfig('notification.servers') 29 33 ->addCommand(