diff --git a/resources/builtin/projects/v3/archive.png b/resources/builtin/projects/v3/archive.png new file mode 100644 index 0000000000..77ff79e555 Binary files /dev/null and b/resources/builtin/projects/v3/archive.png differ diff --git a/resources/builtin/projects/v3/basic-book.png b/resources/builtin/projects/v3/basic-book.png new file mode 100644 index 0000000000..b2a6d99415 Binary files /dev/null and b/resources/builtin/projects/v3/basic-book.png differ diff --git a/resources/builtin/projects/v3/contact.png b/resources/builtin/projects/v3/contact.png new file mode 100644 index 0000000000..6b3095dc3d Binary files /dev/null and b/resources/builtin/projects/v3/contact.png differ diff --git a/resources/builtin/projects/v3/discussion.png b/resources/builtin/projects/v3/discussion.png new file mode 100644 index 0000000000..e4519d664f Binary files /dev/null and b/resources/builtin/projects/v3/discussion.png differ diff --git a/resources/builtin/projects/v3/download.png b/resources/builtin/projects/v3/download.png new file mode 100644 index 0000000000..f086222212 Binary files /dev/null and b/resources/builtin/projects/v3/download.png differ diff --git a/resources/builtin/projects/v3/gears.png b/resources/builtin/projects/v3/gears.png new file mode 100644 index 0000000000..ecbef1a9cf Binary files /dev/null and b/resources/builtin/projects/v3/gears.png differ diff --git a/resources/builtin/projects/v3/gold.png b/resources/builtin/projects/v3/gold.png new file mode 100644 index 0000000000..630f45bc61 Binary files /dev/null and b/resources/builtin/projects/v3/gold.png differ diff --git a/resources/builtin/projects/v3/home.png b/resources/builtin/projects/v3/home.png new file mode 100644 index 0000000000..808d639f0d Binary files /dev/null and b/resources/builtin/projects/v3/home.png differ diff --git a/resources/builtin/projects/v3/library.png b/resources/builtin/projects/v3/library.png new file mode 100644 index 0000000000..1f9ea1a64a Binary files /dev/null and b/resources/builtin/projects/v3/library.png differ diff --git a/resources/builtin/projects/v3/manage.png b/resources/builtin/projects/v3/manage.png new file mode 100644 index 0000000000..7804360a29 Binary files /dev/null and b/resources/builtin/projects/v3/manage.png differ diff --git a/resources/builtin/projects/v3/one-server.png b/resources/builtin/projects/v3/one-server.png new file mode 100644 index 0000000000..d8fbff8a17 Binary files /dev/null and b/resources/builtin/projects/v3/one-server.png differ diff --git a/resources/builtin/projects/v3/police-badge.png b/resources/builtin/projects/v3/police-badge.png new file mode 100644 index 0000000000..8b729bc35a Binary files /dev/null and b/resources/builtin/projects/v3/police-badge.png differ diff --git a/resources/builtin/projects/v3/purchase-order.png b/resources/builtin/projects/v3/purchase-order.png new file mode 100644 index 0000000000..906d72a529 Binary files /dev/null and b/resources/builtin/projects/v3/purchase-order.png differ diff --git a/resources/builtin/projects/v3/server-documentation.png b/resources/builtin/projects/v3/server-documentation.png new file mode 100644 index 0000000000..d71dd53b72 Binary files /dev/null and b/resources/builtin/projects/v3/server-documentation.png differ diff --git a/resources/builtin/projects/v3/shield.png b/resources/builtin/projects/v3/shield.png new file mode 100644 index 0000000000..fd938307fd Binary files /dev/null and b/resources/builtin/projects/v3/shield.png differ diff --git a/resources/builtin/projects/v3/silver.png b/resources/builtin/projects/v3/silver.png new file mode 100644 index 0000000000..afe0e84b35 Binary files /dev/null and b/resources/builtin/projects/v3/silver.png differ diff --git a/resources/builtin/projects/v3/support.png b/resources/builtin/projects/v3/support.png new file mode 100644 index 0000000000..88a9746708 Binary files /dev/null and b/resources/builtin/projects/v3/support.png differ diff --git a/resources/builtin/projects/v3/sword.png b/resources/builtin/projects/v3/sword.png new file mode 100644 index 0000000000..30040633fd Binary files /dev/null and b/resources/builtin/projects/v3/sword.png differ diff --git a/resources/builtin/projects/v3/three-servers.png b/resources/builtin/projects/v3/three-servers.png new file mode 100644 index 0000000000..3361d8967b Binary files /dev/null and b/resources/builtin/projects/v3/three-servers.png differ diff --git a/resources/builtin/projects/v3/two-servers.png b/resources/builtin/projects/v3/two-servers.png new file mode 100644 index 0000000000..d5d408d9ad Binary files /dev/null and b/resources/builtin/projects/v3/two-servers.png differ diff --git a/resources/builtin/projects/v3/upload.png b/resources/builtin/projects/v3/upload.png new file mode 100644 index 0000000000..13e33507bb Binary files /dev/null and b/resources/builtin/projects/v3/upload.png differ diff --git a/resources/builtin/projects/v3/wand.png b/resources/builtin/projects/v3/wand.png new file mode 100644 index 0000000000..6de1cb55ab Binary files /dev/null and b/resources/builtin/projects/v3/wand.png differ diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 86c6567f0e..d50a470c34 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,7 +9,7 @@ return array( 'names' => array( 'conpherence.pkg.css' => 'e68cf1fa', 'conpherence.pkg.js' => 'b5b51108', - 'core.pkg.css' => 'd9c9cfd0', + 'core.pkg.css' => 'cc0772c6', 'core.pkg.js' => '5d80e0db', 'darkconsole.pkg.js' => '1f9a31bc', 'differential.pkg.css' => '45951e9e', @@ -42,7 +42,7 @@ return array( 'rsrc/css/application/base/main-menu-view.css' => '16053029', 'rsrc/css/application/base/notification-menu.css' => '73fefdfa', 'rsrc/css/application/base/phui-theme.css' => '9f261c6b', - 'rsrc/css/application/base/standard-page-view.css' => 'eb5b80c5', + 'rsrc/css/application/base/standard-page-view.css' => 'a0dae682', 'rsrc/css/application/chatlog/chatlog.css' => 'd295b020', 'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4', 'rsrc/css/application/config/config-options.css' => 'd55ed093', @@ -139,10 +139,10 @@ return array( 'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'bf094950', 'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => 'a8beebea', 'rsrc/css/phui/phui-action-list.css' => '6ee16164', - 'rsrc/css/phui/phui-action-panel.css' => '91c7b835', + 'rsrc/css/phui/phui-action-panel.css' => 'b4798122', 'rsrc/css/phui/phui-badge.css' => '22c0cf4f', 'rsrc/css/phui/phui-basic-nav-view.css' => 'a0705f53', - 'rsrc/css/phui/phui-big-info-view.css' => 'd13afcde', + 'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c', 'rsrc/css/phui/phui-box.css' => '745e881d', 'rsrc/css/phui/phui-chart.css' => '6bf6f78e', 'rsrc/css/phui/phui-cms.css' => '504b4b23', @@ -163,7 +163,6 @@ return array( 'rsrc/css/phui/phui-icon-set-selector.css' => '87db8fee', 'rsrc/css/phui/phui-icon.css' => '5c4a5de6', 'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c', - 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 'rsrc/css/phui/phui-info-view.css' => 'e1b4ec37', 'rsrc/css/phui/phui-invisible-character-view.css' => '6993d9f0', 'rsrc/css/phui/phui-left-right.css' => 'f60c67e7', @@ -179,7 +178,7 @@ return array( 'rsrc/css/phui/phui-status.css' => 'd5263e49', 'rsrc/css/phui/phui-tag-view.css' => 'b4719c50', 'rsrc/css/phui/phui-timeline-view.css' => 'f21db7ca', - 'rsrc/css/phui/phui-two-column-view.css' => '5b8cd553', + 'rsrc/css/phui/phui-two-column-view.css' => 'ae38a939', 'rsrc/css/phui/workboards/phui-workboard-color.css' => '783cdff5', 'rsrc/css/phui/workboards/phui-workboard.css' => '3bc85455', 'rsrc/css/phui/workboards/phui-workcard.css' => 'cca5fa92', @@ -529,7 +528,7 @@ return array( 'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9', 'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8', 'rsrc/js/phuix/PHUIXActionView.js' => '442efd08', - 'rsrc/js/phuix/PHUIXAutocomplete.js' => 'f6699267', + 'rsrc/js/phuix/PHUIXAutocomplete.js' => '4b7430ab', 'rsrc/js/phuix/PHUIXButtonView.js' => 'a37126bd', 'rsrc/js/phuix/PHUIXDropdownMenu.js' => '8018ee50', 'rsrc/js/phuix/PHUIXExample.js' => '68af71ca', @@ -803,7 +802,7 @@ return array( 'phabricator-shaped-request' => '7cbe244b', 'phabricator-slowvote-css' => 'a94b7230', 'phabricator-source-code-view-css' => 'aea41829', - 'phabricator-standard-page-view' => 'eb5b80c5', + 'phabricator-standard-page-view' => 'a0dae682', 'phabricator-textareautils' => '320810c8', 'phabricator-title' => '485aaa6c', 'phabricator-tooltip' => '358b8c04', @@ -819,10 +818,10 @@ return array( 'phortune-invoice-css' => '476055e2', 'phrequent-css' => 'ffc185ad', 'phriction-document-css' => '4282e4ad', - 'phui-action-panel-css' => '91c7b835', + 'phui-action-panel-css' => 'b4798122', 'phui-badge-view-css' => '22c0cf4f', 'phui-basic-nav-view-css' => 'a0705f53', - 'phui-big-info-view-css' => 'd13afcde', + 'phui-big-info-view-css' => 'acc3492c', 'phui-box-css' => '745e881d', 'phui-button-bar-css' => 'f1ff5494', 'phui-button-css' => '3ca51caa', @@ -852,7 +851,6 @@ return array( 'phui-icon-set-selector-css' => '87db8fee', 'phui-icon-view-css' => '5c4a5de6', 'phui-image-mask-css' => 'a8498f9c', - 'phui-info-panel-css' => '27ea50a1', 'phui-info-view-css' => 'e1b4ec37', 'phui-inline-comment-view-css' => '65ae3bc2', 'phui-invisible-character-view-css' => '6993d9f0', @@ -876,14 +874,14 @@ return array( 'phui-tag-view-css' => 'b4719c50', 'phui-theme-css' => '9f261c6b', 'phui-timeline-view-css' => 'f21db7ca', - 'phui-two-column-view-css' => '5b8cd553', + 'phui-two-column-view-css' => 'ae38a939', 'phui-workboard-color-css' => '783cdff5', 'phui-workboard-view-css' => '3bc85455', 'phui-workcard-view-css' => 'cca5fa92', 'phui-workpanel-view-css' => 'a3a63478', 'phuix-action-list-view' => 'b5c256b8', 'phuix-action-view' => '442efd08', - 'phuix-autocomplete' => 'f6699267', + 'phuix-autocomplete' => '4b7430ab', 'phuix-button-view' => 'a37126bd', 'phuix-dropdown-menu' => '8018ee50', 'phuix-form-control-view' => '83e03671', @@ -1239,6 +1237,12 @@ return array( 'javelin-util', 'phabricator-shaped-request', ), + '4b7430ab' => array( + 'javelin-install', + 'javelin-dom', + 'phuix-icon-view', + 'phabricator-prefab', + ), '4c193c96' => array( 'javelin-behavior', 'javelin-uri', @@ -2129,12 +2133,6 @@ return array( 'javelin-util', 'javelin-reactor', ), - 'f6699267' => array( - 'javelin-install', - 'javelin-dom', - 'phuix-icon-view', - 'phabricator-prefab', - ), 'f7fc67ec' => array( 'javelin-install', 'javelin-typeahead', diff --git a/scripts/repository/commit_hook.php b/scripts/repository/commit_hook.php index 44c772225c..51abcb6c89 100755 --- a/scripts/repository/commit_hook.php +++ b/scripts/repository/commit_hook.php @@ -48,8 +48,13 @@ if (!$repository) { } if (!$repository->isHosted()) { - // This should be redundant, but double check just in case. - throw new Exception(pht('Repository "%s" is not hosted!', $argv[1])); + // In Mercurial, the "pretxnchangegroup" hook fires for both pulls and + // pushes. Normally we only install the hook for hosted repositories, but + // if a hosted repository is later converted into an observed repository we + // can end up with an observed repository that has the hook installed. + // If we're running hooks from an observed repository, just exit without + // taking action. For more discussion, see PHI24. + return 0; } $engine->setRepository($repository); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1527091575..afaccaacf9 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -747,7 +747,6 @@ phutil_register_library_map(array( 'DiffusionLowLevelGitRefQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php', 'DiffusionLowLevelMercurialBranchesQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialBranchesQuery.php', 'DiffusionLowLevelMercurialPathsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php', - 'DiffusionLowLevelMercurialPathsQueryTests' => 'applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php', 'DiffusionLowLevelParentsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelParentsQuery.php', 'DiffusionLowLevelQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php', 'DiffusionLowLevelResolveRefsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php', @@ -1770,8 +1769,6 @@ phutil_register_library_map(array( 'PHUIImageMaskExample' => 'applications/uiexample/examples/PHUIImageMaskExample.php', 'PHUIImageMaskView' => 'view/phui/PHUIImageMaskView.php', 'PHUIInfoExample' => 'applications/uiexample/examples/PHUIInfoExample.php', - 'PHUIInfoPanelExample' => 'applications/uiexample/examples/PHUIInfoPanelExample.php', - 'PHUIInfoPanelView' => 'view/phui/PHUIInfoPanelView.php', 'PHUIInfoView' => 'view/form/PHUIInfoView.php', 'PHUIInvisibleCharacterTestCase' => 'view/phui/__tests__/PHUIInvisibleCharacterTestCase.php', 'PHUIInvisibleCharacterView' => 'view/phui/PHUIInvisibleCharacterView.php', @@ -2645,6 +2642,8 @@ phutil_register_library_map(array( 'PhabricatorDefaultSyntaxStyle' => 'infrastructure/syntax/PhabricatorDefaultSyntaxStyle.php', 'PhabricatorDesktopNotificationsSetting' => 'applications/settings/setting/PhabricatorDesktopNotificationsSetting.php', 'PhabricatorDesktopNotificationsSettingsPanel' => 'applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php', + 'PhabricatorDestructibleCodex' => 'applications/system/codex/PhabricatorDestructibleCodex.php', + 'PhabricatorDestructibleCodexInterface' => 'applications/system/interface/PhabricatorDestructibleCodexInterface.php', 'PhabricatorDestructibleInterface' => 'applications/system/interface/PhabricatorDestructibleInterface.php', 'PhabricatorDestructionEngine' => 'applications/system/engine/PhabricatorDestructionEngine.php', 'PhabricatorDestructionEngineExtension' => 'applications/system/engine/PhabricatorDestructionEngineExtension.php', @@ -3783,6 +3782,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryCommitTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php', 'PhabricatorRepositoryConfigOptions' => 'applications/repository/config/PhabricatorRepositoryConfigOptions.php', 'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php', + 'PhabricatorRepositoryDestructibleCodex' => 'applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php', 'PhabricatorRepositoryDiscoveryEngine' => 'applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php', 'PhabricatorRepositoryEditor' => 'applications/repository/editor/PhabricatorRepositoryEditor.php', 'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php', @@ -3859,7 +3859,6 @@ phutil_register_library_map(array( 'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php', 'PhabricatorRepositoryURITransactionQuery' => 'applications/repository/query/PhabricatorRepositoryURITransactionQuery.php', 'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php', - 'PhabricatorRepositoryVersion' => 'applications/repository/constants/PhabricatorRepositoryVersion.php', 'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php', 'PhabricatorRequestExceptionHandler' => 'aphront/handler/PhabricatorRequestExceptionHandler.php', 'PhabricatorResourceSite' => 'aphront/site/PhabricatorResourceSite.php', @@ -5743,7 +5742,6 @@ phutil_register_library_map(array( 'DiffusionLowLevelGitRefQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelMercurialBranchesQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelMercurialPathsQuery' => 'DiffusionLowLevelQuery', - 'DiffusionLowLevelMercurialPathsQueryTests' => 'PhabricatorTestCase', 'DiffusionLowLevelParentsQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelQuery' => 'Phobject', 'DiffusionLowLevelResolveRefsQuery' => 'DiffusionLowLevelQuery', @@ -6928,8 +6926,6 @@ phutil_register_library_map(array( 'PHUIImageMaskExample' => 'PhabricatorUIExample', 'PHUIImageMaskView' => 'AphrontTagView', 'PHUIInfoExample' => 'PhabricatorUIExample', - 'PHUIInfoPanelExample' => 'PhabricatorUIExample', - 'PHUIInfoPanelView' => 'AphrontView', 'PHUIInfoView' => 'AphrontTagView', 'PHUIInvisibleCharacterTestCase' => 'PhabricatorTestCase', 'PHUIInvisibleCharacterView' => 'AphrontView', @@ -7944,6 +7940,7 @@ phutil_register_library_map(array( 'PhabricatorDefaultSyntaxStyle' => 'PhabricatorSyntaxStyle', 'PhabricatorDesktopNotificationsSetting' => 'PhabricatorInternalSetting', 'PhabricatorDesktopNotificationsSettingsPanel' => 'PhabricatorSettingsPanel', + 'PhabricatorDestructibleCodex' => 'Phobject', 'PhabricatorDestructionEngine' => 'Phobject', 'PhabricatorDestructionEngineExtension' => 'Phobject', 'PhabricatorDestructionEngineExtensionModule' => 'PhabricatorConfigModule', @@ -9248,6 +9245,7 @@ phutil_register_library_map(array( 'PhabricatorFlaggableInterface', 'PhabricatorMarkupInterface', 'PhabricatorDestructibleInterface', + 'PhabricatorDestructibleCodexInterface', 'PhabricatorProjectInterface', 'PhabricatorSpacesInterface', 'PhabricatorConduitResultInterface', @@ -9290,6 +9288,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryCommitTestCase' => 'PhabricatorTestCase', 'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO', + 'PhabricatorRepositoryDestructibleCodex' => 'PhabricatorDestructibleCodex', 'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine', 'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorRepositoryEngine' => 'Phobject', @@ -9391,7 +9390,6 @@ phutil_register_library_map(array( 'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO', - 'PhabricatorRepositoryVersion' => 'Phobject', 'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO', 'PhabricatorRequestExceptionHandler' => 'AphrontRequestExceptionHandler', 'PhabricatorResourceSite' => 'PhabricatorSite', diff --git a/src/applications/auth/controller/PhabricatorAuthFinishController.php b/src/applications/auth/controller/PhabricatorAuthFinishController.php index 387679b44e..4b775a2e4b 100644 --- a/src/applications/auth/controller/PhabricatorAuthFinishController.php +++ b/src/applications/auth/controller/PhabricatorAuthFinishController.php @@ -54,7 +54,7 @@ final class PhabricatorAuthFinishController ->addHiddenInput(AphrontRequest::TYPE_HISEC, true) ->appendParagraph( pht( - 'Welcome, %s. To complete the login process, provide your '. + 'Welcome, %s. To complete the process of logging in, provide your '. 'multi-factor credentials.', phutil_tag('strong', array(), $viewer->getUsername()))) ->appendChild($form->buildLayoutView()) diff --git a/src/applications/auth/controller/PhabricatorAuthLoginController.php b/src/applications/auth/controller/PhabricatorAuthLoginController.php index 3264e61216..39b6318481 100644 --- a/src/applications/auth/controller/PhabricatorAuthLoginController.php +++ b/src/applications/auth/controller/PhabricatorAuthLoginController.php @@ -92,8 +92,8 @@ final class PhabricatorAuthLoginController } else { return $this->renderError( pht( - 'The external account ("%s") you just used to login is already '. - 'associated with another Phabricator user account. Login to the '. + 'The external account ("%s") you just used to log in is already '. + 'associated with another Phabricator user account. Log in to the '. 'other Phabricator account and unlink the external account before '. 'linking it to a new Phabricator account.', $provider->getProviderName())); @@ -214,7 +214,7 @@ final class PhabricatorAuthLoginController if (!$provider) { return $this->renderError( pht( - 'The account you are attempting to login with uses a nonexistent '. + 'The account you are attempting to log in with uses a nonexistent '. 'or disabled authentication provider (with key "%s"). An '. 'administrator may have recently disabled this provider.', $this->providerKey)); @@ -240,14 +240,14 @@ final class PhabricatorAuthLoginController if ($this->getRequest()->getUser()->isLoggedIn()) { $crumbs->addTextCrumb(pht('Link Account'), $provider->getSettingsURI()); } else { - $crumbs->addTextCrumb(pht('Login'), $this->getApplicationURI('start/')); + $crumbs->addTextCrumb(pht('Log In'), $this->getApplicationURI('start/')); } $crumbs->addTextCrumb($provider->getProviderName()); $crumbs->setBorder(true); return $this->newPage() - ->setTitle(pht('Login')) + ->setTitle(pht('Log In')) ->setCrumbs($crumbs) ->appendChild($content); } @@ -257,9 +257,8 @@ final class PhabricatorAuthLoginController $message) { $message = pht( - 'Authentication provider ("%s") encountered an error during login. %s', - $provider->getProviderName(), - $message); + 'Authentication provider ("%s") encountered an error while attempting '. + 'to log in. %s', $provider->getProviderName(), $message); return $this->renderError($message); } diff --git a/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php b/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php index ebfd07e7ac..534bda3f35 100644 --- a/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php +++ b/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php @@ -68,7 +68,7 @@ final class PhabricatorAuthOneTimeLoginController if (!$token) { return $this->newDialog() - ->setTitle(pht('Unable to Login')) + ->setTitle(pht('Unable to Log In')) ->setShortTitle(pht('Login Failure')) ->appendParagraph( pht( @@ -170,7 +170,7 @@ final class PhabricatorAuthOneTimeLoginController case PhabricatorAuthSessionEngine::ONETIME_USERNAME: case PhabricatorAuthSessionEngine::ONETIME_RESET: default: - $title = pht('Login to Phabricator'); + $title = pht('Log in to Phabricator'); break; } @@ -193,7 +193,7 @@ final class PhabricatorAuthOneTimeLoginController $dialog = $this->newDialog() ->setTitle($title) - ->addSubmitButton(pht('Login (%s)', $target_user->getUsername())) + ->addSubmitButton(pht('Log In (%s)', $target_user->getUsername())) ->addCancelButton('/'); foreach ($body as $paragraph) { diff --git a/src/applications/auth/controller/PhabricatorAuthRegisterController.php b/src/applications/auth/controller/PhabricatorAuthRegisterController.php index cdb7980a16..a68e12c801 100644 --- a/src/applications/auth/controller/PhabricatorAuthRegisterController.php +++ b/src/applications/auth/controller/PhabricatorAuthRegisterController.php @@ -483,14 +483,14 @@ final class PhabricatorAuthRegisterController if ($can_edit_username) { $form->appendChild( id(new AphrontFormTextControl()) - ->setLabel(pht('Phabricator Username')) + ->setLabel(pht('Username')) ->setName('username') ->setValue($value_username) ->setError($e_username)); } else { $form->appendChild( id(new AphrontFormMarkupControl()) - ->setLabel(pht('Phabricator Username')) + ->setLabel(pht('Username')) ->setValue($value_username) ->setError($e_username)); } @@ -546,7 +546,7 @@ final class PhabricatorAuthRegisterController } else { $submit ->addCancelButton($this->getApplicationURI('start/')) - ->setValue(pht('Register Phabricator Account')); + ->setValue(pht('Register Account')); } @@ -560,7 +560,7 @@ final class PhabricatorAuthRegisterController } else { $crumbs->addTextCrumb(pht('Register')); $crumbs->addTextCrumb($provider->getProviderName()); - $title = pht('Phabricator Registration'); + $title = pht('Create a New Account'); } $crumbs->setBorder(true); diff --git a/src/applications/auth/controller/PhabricatorAuthStartController.php b/src/applications/auth/controller/PhabricatorAuthStartController.php index 5cfcb9b9ef..9af8f25bc7 100644 --- a/src/applications/auth/controller/PhabricatorAuthStartController.php +++ b/src/applications/auth/controller/PhabricatorAuthStartController.php @@ -198,7 +198,7 @@ final class PhabricatorAuthStartController $crumbs->addTextCrumb(pht('Login')); $crumbs->setBorder(true); - $title = pht('Login to Phabricator'); + $title = pht('Login'); $view = array( $header, $invite_message, @@ -239,8 +239,8 @@ final class PhabricatorAuthStartController return $this->newDialog() ->setTitle(pht('Login Required')) - ->appendParagraph(pht('You must login to take this action.')) - ->addSubmitButton(pht('Login')) + ->appendParagraph(pht('You must log in to take this action.')) + ->addSubmitButton(pht('Log In')) ->addCancelButton('/'); } diff --git a/src/applications/auth/controller/PhabricatorAuthUnlinkController.php b/src/applications/auth/controller/PhabricatorAuthUnlinkController.php index 2c21f63407..6211e78110 100644 --- a/src/applications/auth/controller/PhabricatorAuthUnlinkController.php +++ b/src/applications/auth/controller/PhabricatorAuthUnlinkController.php @@ -104,7 +104,7 @@ final class PhabricatorAuthUnlinkController pht( 'You can not unlink this account because you have no other '. 'valid login accounts. If you removed it, you would be unable '. - 'to login. Add another authentication method before removing '. + 'to log in. Add another authentication method before removing '. 'this one.')) ->addCancelButton($this->getDoneURI()); diff --git a/src/applications/auth/controller/PhabricatorEmailLoginController.php b/src/applications/auth/controller/PhabricatorEmailLoginController.php index e9cf693514..92accc7494 100644 --- a/src/applications/auth/controller/PhabricatorEmailLoginController.php +++ b/src/applications/auth/controller/PhabricatorEmailLoginController.php @@ -114,7 +114,7 @@ final class PhabricatorEmailLoginController ->setTitle(pht('Check Your Email')) ->setShortTitle(pht('Email Sent')) ->appendParagraph( - pht('An email has been sent with a link you can use to login.')) + pht('An email has been sent with a link you can use to log in.')) ->addCancelButton('/', pht('Done')); } } diff --git a/src/applications/auth/controller/PhabricatorLogoutController.php b/src/applications/auth/controller/PhabricatorLogoutController.php index f4b61f88a3..47592e0a2d 100644 --- a/src/applications/auth/controller/PhabricatorLogoutController.php +++ b/src/applications/auth/controller/PhabricatorLogoutController.php @@ -52,9 +52,9 @@ final class PhabricatorLogoutController if ($viewer->getPHID()) { return $this->newDialog() - ->setTitle(pht('Log out of Phabricator?')) + ->setTitle(pht('Log Out?')) ->appendChild(pht('Are you sure you want to log out?')) - ->addSubmitButton(pht('Logout')) + ->addSubmitButton(pht('Log Out')) ->addCancelButton('/'); } diff --git a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php index 670a95f977..bf3410139d 100644 --- a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php +++ b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php @@ -33,7 +33,7 @@ final class PhabricatorMustVerifyEmailController } $must_verify = pht( - 'You must verify your email address to login. You should have a '. + 'You must verify your email address to log in. You should have a '. 'new email message from Phabricator with verification instructions '. 'in your inbox (%s).', phutil_tag('strong', array(), $email_address)); diff --git a/src/applications/auth/provider/PhabricatorAuthProvider.php b/src/applications/auth/provider/PhabricatorAuthProvider.php index 4dd7f4da1b..d655efd790 100644 --- a/src/applications/auth/provider/PhabricatorAuthProvider.php +++ b/src/applications/auth/provider/PhabricatorAuthProvider.php @@ -389,7 +389,7 @@ abstract class PhabricatorAuthProvider extends Phobject { * @param AphrontRequest HTTP request. * @param string Request mode string. * @param map Additional parameters, see above. - * @return wild Login button. + * @return wild Log in button. */ protected function renderStandardLoginButton( AphrontRequest $request, @@ -414,9 +414,9 @@ abstract class PhabricatorAuthProvider extends Phobject { } else if ($mode == 'invite') { $button_text = pht('Register Account'); } else if ($this->shouldAllowRegistration()) { - $button_text = pht('Login or Register'); + $button_text = pht('Log In or Register'); } else { - $button_text = pht('Login'); + $button_text = pht('Log In'); } $icon = id(new PHUIIconView()) diff --git a/src/applications/auth/provider/PhabricatorLDAPAuthProvider.php b/src/applications/auth/provider/PhabricatorLDAPAuthProvider.php index 013cd21736..7c2bf38618 100644 --- a/src/applications/auth/provider/PhabricatorLDAPAuthProvider.php +++ b/src/applications/auth/provider/PhabricatorLDAPAuthProvider.php @@ -80,11 +80,11 @@ final class PhabricatorLDAPAuthProvider extends PhabricatorAuthProvider { $dialog->addCancelButton($this->getSettingsURI()); } else { if ($this->shouldAllowRegistration()) { - $dialog->setTitle(pht('Login or Register with LDAP')); - $dialog->addSubmitButton(pht('Login or Register')); + $dialog->setTitle(pht('Log In or Register with LDAP')); + $dialog->addSubmitButton(pht('Log In or Register')); } else { - $dialog->setTitle(pht('Login with LDAP')); - $dialog->addSubmitButton(pht('Login')); + $dialog->setTitle(pht('Log In with LDAP')); + $dialog->addSubmitButton(pht('Log In')); } if ($mode == 'login') { $dialog->addCancelButton($this->getStartURI()); @@ -315,7 +315,7 @@ final class PhabricatorLDAPAuthProvider extends PhabricatorAuthProvider { "credentials (which is more complicated, but more powerful).\n\n". "For many installs, direct binding is sufficient. However, you may ". "want to search first if:\n\n". - " - You want users to be able to login with either their username ". + " - You want users to be able to log in with either their username ". " or their email address.\n". " - The login/username is not part of the distinguished name in ". " your LDAP records.\n". @@ -344,16 +344,16 @@ final class PhabricatorLDAPAuthProvider extends PhabricatorAuthProvider { "`sn`, which will work the same way direct binding works:\n\n". " lang=text,name=Simple Example\n". " sn\n\n". - "A slightly more complex configuration might let the user login with ". + "A slightly more complex configuration might let the user log in with ". "either their login name or email address:\n\n". " lang=text,name=Match Several Attributes\n". " mail\n". " sn\n\n". "If your LDAP directory is more complex, or you want to perform ". "sophisticated filtering, you can use more complex queries. Depending ". - "on your directory structure, this example might allow users to login ". - "with either their email address or username, but only if they're in ". - "specific departments:\n\n". + "on your directory structure, this example might allow users to log ". + "in with either their email address or username, but only if they're ". + "in specific departments:\n\n". " lang=text,name=Complex Example\n". " (&(mail=\${login})(|(departmentNumber=1)(departmentNumber=2)))\n". " (&(sn=\${login})(|(departmentNumber=1)(departmentNumber=2)))\n\n". diff --git a/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php b/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php index 68dbf1e879..206eba4578 100644 --- a/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php +++ b/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php @@ -100,7 +100,7 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider { public function getDescriptionForCreate() { return pht( - 'Allow users to login or register using a username and password.'); + 'Allow users to log in or register using a username and password.'); } public function getAdapter() { @@ -174,8 +174,8 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider { $dialog = id(new AphrontDialogView()) ->setSubmitURI($this->getLoginURI()) ->setUser($viewer) - ->setTitle(pht('Login to Phabricator')) - ->addSubmitButton(pht('Login')); + ->setTitle(pht('Log In')) + ->addSubmitButton(pht('Log In')); if ($this->shouldAllowRegistration()) { $dialog->addCancelButton( diff --git a/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php b/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php index fc89d310e1..3da467e4f4 100644 --- a/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php +++ b/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php @@ -108,6 +108,7 @@ final class PhabricatorConduitTokensSettingsPanel $panel = id(new PHUIObjectBoxView()) ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); return $panel; diff --git a/src/applications/config/check/PhabricatorBinariesSetupCheck.php b/src/applications/config/check/PhabricatorBinariesSetupCheck.php index 0d577b5297..cf3c87f480 100644 --- a/src/applications/config/check/PhabricatorBinariesSetupCheck.php +++ b/src/applications/config/check/PhabricatorBinariesSetupCheck.php @@ -99,12 +99,12 @@ final class PhabricatorBinariesSetupCheck extends PhabricatorSetupCheck { continue; } - $version = null; + $version = PhutilBinaryAnalyzer::getForBinary($binary) + ->getBinaryVersion(); + switch ($vcs['versionControlSystem']) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $bad_versions = array(); - list($err, $stdout, $stderr) = exec_manual('git --version'); - $version = trim(substr($stdout, strlen('git version '))); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $bad_versions = array( @@ -117,8 +117,6 @@ final class PhabricatorBinariesSetupCheck extends PhabricatorSetupCheck { 'for files added in rN (Subversion issue #2873), fixed in 1.7.2.', 'svn diff -c N'), ); - list($err, $stdout, $stderr) = exec_manual('svn --version --quiet'); - $version = trim($stdout); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $bad_versions = array( @@ -134,7 +132,6 @@ final class PhabricatorBinariesSetupCheck extends PhabricatorSetupCheck { 'in 2.2.1. Pushing fails with this version as well; see %s.', 'T3046#54922'), ); - $version = PhabricatorRepositoryVersion::getMercurialVersion(); break; } diff --git a/src/applications/config/controller/PhabricatorConfigVersionController.php b/src/applications/config/controller/PhabricatorConfigVersionController.php index 8f43192b3b..ca638051e4 100644 --- a/src/applications/config/controller/PhabricatorConfigVersionController.php +++ b/src/applications/config/controller/PhabricatorConfigVersionController.php @@ -64,6 +64,29 @@ final class PhabricatorConfigVersionController $version_from_file); } + $binaries = PhutilBinaryAnalyzer::getAllBinaries(); + foreach ($binaries as $binary) { + if (!$binary->isBinaryAvailable()) { + $binary_info = pht('Not Available'); + } else { + $version = $binary->getBinaryVersion(); + $path = $binary->getBinaryPath(); + if ($path === null && $version === null) { + $binary_info = pht('-'); + } else if ($path === null) { + $binary_info = $version; + } else if ($version === null) { + $binary_info = pht('- at %s', $path); + } else { + $binary_info = pht('%s at %s', $version, $path); + } + } + + $version_property_list->addProperty( + $binary->getBinaryName(), + $binary_info); + } + return $version_property_list; } diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php index 792a7f8182..996417a307 100644 --- a/src/applications/conpherence/controller/ConpherenceViewController.php +++ b/src/applications/conpherence/controller/ConpherenceViewController.php @@ -195,7 +195,7 @@ final class ConpherenceViewController extends ->appendChild( id(new PHUIButtonView()) ->setTag('a') - ->setText(pht('Login to Participate')) + ->setText(pht('Log In to Participate')) ->setHref((string)$login_href)); } } diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php index 12b9e661d7..f4e27db670 100644 --- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php +++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php @@ -24,11 +24,12 @@ final class DiffusionLowLevelMercurialPathsQuery $path = $this->path; $commit = $this->commit; - $hg_paths_command = 'locate --print0 --rev %s -I %s'; - $hg_version = PhabricatorRepositoryVersion::getMercurialVersion(); - if (PhabricatorRepositoryVersion::isMercurialFilesCommandAvailable( - $hg_version)) { + $has_files = PhutilBinaryAnalyzer::getForBinary('hg') + ->isMercurialFilesCommandAvailable(); + if ($has_files) { $hg_paths_command = 'files --print0 --rev %s -I %s'; + } else { + $hg_paths_command = 'locate --print0 --rev %s -I %s'; } $match_against = trim($path, '/'); diff --git a/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php b/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php deleted file mode 100644 index 075ca2f1a5..0000000000 --- a/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php +++ /dev/null @@ -1,31 +0,0 @@ - pht('Versions which should not use `files`'), - 'versions' => array('2.6.2', '2.9', '3.1'), - 'match' => false, - ), - - array( - 'name' => pht('Versions which should use `files`'), - 'versions' => array('3.2', '3.3', '3.5.2'), - 'match' => true, - ), - ); - - foreach ($cases as $case) { - foreach ($case['versions'] as $version) { - $actual = PhabricatorRepositoryVersion - ::isMercurialFilesCommandAvailable($version); - $expect = $case['match']; - $this->assertEqual($expect, $actual, $case['name']); - } - } - } - -} diff --git a/src/applications/files/controller/PhabricatorFileLightboxController.php b/src/applications/files/controller/PhabricatorFileLightboxController.php index 11d4b95bc1..1f679d621b 100644 --- a/src/applications/files/controller/PhabricatorFileLightboxController.php +++ b/src/applications/files/controller/PhabricatorFileLightboxController.php @@ -76,7 +76,7 @@ final class PhabricatorFileLightboxController ->appendChild( id(new PHUIButtonView()) ->setTag('a') - ->setText(pht('Login to Comment')) + ->setText(pht('Log In to Comment')) ->setHref((string)$login_href)); } diff --git a/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php b/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php index 024d9101dd..90e2d5a7dd 100644 --- a/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php +++ b/src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php @@ -23,7 +23,7 @@ final class PhabricatorOAuthServerApplication extends PhabricatorApplication { } public function getFlavorText() { - return pht('Login with Phabricator'); + return pht('Log In with Phabricator'); } public function getApplicationGroup() { diff --git a/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php b/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php index 596f3decc9..cfc0bc91a8 100644 --- a/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php +++ b/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php @@ -134,6 +134,7 @@ final class PhabricatorOAuthServerAuthorizationsSettingsPanel $panel = id(new PHUIObjectBoxView()) ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); return $panel; diff --git a/src/applications/ponder/view/PonderAddAnswerView.php b/src/applications/ponder/view/PonderAddAnswerView.php index d958e9843e..43bfd0d6ba 100644 --- a/src/applications/ponder/view/PonderAddAnswerView.php +++ b/src/applications/ponder/view/PonderAddAnswerView.php @@ -72,7 +72,7 @@ final class PonderAddAnswerView extends AphrontView { ->appendChild( id(new PHUIButtonView()) ->setTag('a') - ->setText(pht('Login to Answer')) + ->setText(pht('Log In to Answer')) ->setHref((string)$login_href)); } diff --git a/src/applications/project/controller/PhabricatorProjectEditPictureController.php b/src/applications/project/controller/PhabricatorProjectEditPictureController.php index 97b7fe1792..e601d744c0 100644 --- a/src/applications/project/controller/PhabricatorProjectEditPictureController.php +++ b/src/applications/project/controller/PhabricatorProjectEditPictureController.php @@ -124,38 +124,16 @@ final class PhabricatorProjectEditPictureController } } - $builtins = array( - 'projects/v3/book.png', - 'projects/v3/bug.png', - 'projects/v3/calendar.png', - 'projects/v3/clipboard.png', - 'projects/v3/cloud.png', - 'projects/v3/creditcard.png', - 'projects/v3/database.png', - 'projects/v3/desktop.png', - 'projects/v3/experimental.png', - 'projects/v3/flag.png', - 'projects/v3/folder.png', - 'projects/v3/lightbulb.png', - 'projects/v3/lock.png', - 'projects/v3/mail.png', - 'projects/v3/marker.png', - 'projects/v3/mobile.png', - 'projects/v3/organization.png', - 'projects/v3/people.png', - 'projects/v3/piechart.png', - 'projects/v3/robot.png', - 'projects/v3/rocket.png', - 'projects/v3/servers.png', - 'projects/v3/sitemap.png', - 'projects/v3/tag.png', - 'projects/v3/trash.png', - 'projects/v3/truck.png', - 'projects/v3/umbrella.png', - ); + $root = dirname(phutil_get_library_root('phabricator')); + $root = $root.'/resources/builtin/projects/v3/'; + + $builtins = id(new FileFinder($root)) + ->withType('f') + ->withFollowSymlinks(true) + ->find(); foreach ($builtins as $builtin) { - $file = PhabricatorFile::loadBuiltin($viewer, $builtin); + $file = PhabricatorFile::loadBuiltin($viewer, 'projects/v3/'.$builtin); $images[$file->getPHID()] = array( 'uri' => $file->getBestURI(), 'tip' => pht('Builtin Image'), diff --git a/src/applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php b/src/applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php new file mode 100644 index 0000000000..eaa5cf4a77 --- /dev/null +++ b/src/applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php @@ -0,0 +1,23 @@ +getObject(); + + $notes = array(); + + if ($repository->hasLocalWorkingCopy()) { + $notes[] = pht( + 'Database records for repository "%s" were destroyed, but this '. + 'script does not remove working copies on disk. If you also want to '. + 'destroy the repository working copy, manually remove "%s".', + $repository->getDisplayName(), + $repository->getLocalPath()); + } + + return $notes; + } + +} diff --git a/src/applications/repository/constants/PhabricatorRepositoryVersion.php b/src/applications/repository/constants/PhabricatorRepositoryVersion.php deleted file mode 100644 index 5f722fa40a..0000000000 --- a/src/applications/repository/constants/PhabricatorRepositoryVersion.php +++ /dev/null @@ -1,40 +0,0 @@ -='); - } - -} diff --git a/src/applications/repository/engine/PhabricatorRepositoryEngine.php b/src/applications/repository/engine/PhabricatorRepositoryEngine.php index 445357e783..244ed0cd45 100644 --- a/src/applications/repository/engine/PhabricatorRepositoryEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryEngine.php @@ -135,6 +135,11 @@ abstract class PhabricatorRepositoryEngine extends Phobject { $exists = true; } + // These URIs may have plaintext HTTP credentials. If they do, censor + // them for display. See T12945. + $display_remote = phutil_censor_credentials($remote_uri); + $display_expect = phutil_censor_credentials($expect_remote); + if (!$valid) { if (!$exists) { // If there's no "origin" remote, just create it regardless of how @@ -172,8 +177,8 @@ abstract class PhabricatorRepositoryEngine extends Phobject { 'set the remote URI correctly. To avoid breaking anything, '. 'Phabricator will not automatically fix this.', $repository->getLocalPath(), - $remote_uri, - $expect_remote); + $display_remote, + $display_expect); throw new Exception($message); } } diff --git a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php index b144ecfd96..32e99e619d 100644 --- a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php @@ -485,8 +485,8 @@ final class PhabricatorRepositoryPullEngine // On vulnerable versions of Mercurial, we refuse to clone remotes which // contain characters which may be interpreted by the shell. - $hg_version = PhabricatorRepositoryVersion::getMercurialVersion(); - $is_vulnerable = version_compare($hg_version, '3.2.4', '<'); + $hg_binary = PhutilBinaryAnalyzer::getForBinary('hg'); + $is_vulnerable = $hg_binary->isMercurialVulnerableToInjection(); if ($is_vulnerable) { $cleartext = $remote->openEnvelope(); // The use of "%R" here is an attempt to limit collateral damage @@ -501,7 +501,7 @@ final class PhabricatorRepositoryPullEngine 'command injection security vulnerability. The remote URI for '. 'this repository (%s) is potentially unsafe. Upgrade Mercurial '. 'to at least 3.2.4 to clone it.', - $hg_version, + $hg_binary->getBinaryVersion(), $repository->getMonogram())); } } diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index eb6608eb57..b660ff9aa7 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -12,6 +12,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO PhabricatorFlaggableInterface, PhabricatorMarkupInterface, PhabricatorDestructibleInterface, + PhabricatorDestructibleCodexInterface, PhabricatorProjectInterface, PhabricatorSpacesInterface, PhabricatorConduitResultInterface, @@ -2557,6 +2558,14 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO } +/* -( PhabricatorDestructibleCodexInterface )------------------------------ */ + + + public function newDestructibleCodex() { + return new PhabricatorRepositoryDestructibleCodex(); + } + + /* -( PhabricatorSpacesInterface )----------------------------------------- */ diff --git a/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php b/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php index 4ccc85f085..fe526a8133 100644 --- a/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php +++ b/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php @@ -554,9 +554,10 @@ final class PhabricatorMySQLFulltextStorageEngine // "ab.cd", where short substrings are separated by periods, do not produce // any queryable tokens. These terms are meaningful if at least one // substring is longer than the minimum length, like "example.py". See - // T12928. + // T12928. This also applies to words with intermediate apostrophes, like + // "to's". - $parts = preg_split('/[.]+/', $value); + $parts = preg_split('/[.\']+/', $value); foreach ($parts as $part) { if (phutil_utf8_strlen($part) >= $min_length) { diff --git a/src/applications/settings/controller/PhabricatorSettingsMainController.php b/src/applications/settings/controller/PhabricatorSettingsMainController.php index 841529a051..4c1bfab6f1 100644 --- a/src/applications/settings/controller/PhabricatorSettingsMainController.php +++ b/src/applications/settings/controller/PhabricatorSettingsMainController.php @@ -112,15 +112,27 @@ final class PhabricatorSettingsMainController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($panel->getPanelName()); + $crumbs->setBorder(true); + + if ($this->user) { + $header_text = pht('Edit Settings (%s)', $user->getUserName()); + } else { + $header_text = pht('Edit Global Settings'); + } + + $header = id(new PHUIHeaderView()) + ->setHeader($header_text) + ->setHeaderIcon('fa-pencil'); $title = $panel->getPanelName(); $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn($response); + ->setHeader($header) + ->setFooter($response); return $this->newPage() ->setTitle($title) + ->setNavigation($nav) ->setCrumbs($crumbs) ->appendChild($view); diff --git a/src/applications/settings/editor/PhabricatorSettingsEditEngine.php b/src/applications/settings/editor/PhabricatorSettingsEditEngine.php index 4bcfa08d1d..e12654e1a4 100644 --- a/src/applications/settings/editor/PhabricatorSettingsEditEngine.php +++ b/src/applications/settings/editor/PhabricatorSettingsEditEngine.php @@ -63,7 +63,12 @@ final class PhabricatorSettingsEditEngine } protected function getObjectEditTitleText($object) { - return pht('Edit Settings'); + $user = $object->getUser(); + if ($user) { + return pht('Edit Settings (%s)', $user->getUserName()); + } else { + return pht('Edit Global Settings'); + } } protected function getObjectEditShortText($object) { diff --git a/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php b/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php index a16984c140..0b3533f287 100644 --- a/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php @@ -48,6 +48,7 @@ final class PhabricatorActivitySettingsPanel extends PhabricatorSettingsPanel { $panel = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Account Activity Logs')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); $pager_box = id(new PHUIBoxView()) diff --git a/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php b/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php index c08a833f1b..f94de959cd 100644 --- a/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php @@ -157,6 +157,7 @@ final class PhabricatorDesktopNotificationsSettingsPanel ->setHeader(pht('Desktop Notifications')) ->addActionLink($test_button)) ->setForm($form) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setInfoView($status_box) ->setFormSaved($request->getBool('saved')); diff --git a/src/applications/settings/panel/PhabricatorEditEngineSettingsPanel.php b/src/applications/settings/panel/PhabricatorEditEngineSettingsPanel.php index 27161218d1..5aad71785e 100644 --- a/src/applications/settings/panel/PhabricatorEditEngineSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEditEngineSettingsPanel.php @@ -22,7 +22,6 @@ abstract class PhabricatorEditEngineSettingsPanel $engine = id(new PhabricatorSettingsEditEngine()) ->setController($this->getController()) ->setNavigation($this->getNavigation()) - ->setHideHeader(true) ->setIsSelfEdit($is_self) ->setProfileURI($profile_uri); diff --git a/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php b/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php index d628341dea..66fd0396ad 100644 --- a/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php @@ -153,6 +153,7 @@ final class PhabricatorEmailAddressesSettingsPanel } $view->setHeader($header); $view->setTable($table); + $view->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); return $view; } diff --git a/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php b/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php index 0c775c5a4d..77364e0aa0 100644 --- a/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php @@ -136,6 +136,7 @@ final class PhabricatorEmailPreferencesSettingsPanel ->setHeaderText(pht('Email Preferences')) ->setFormSaved($request->getStr('saved')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); return $form_box; diff --git a/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php b/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php index 662d4e6cf6..068c58d549 100644 --- a/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php @@ -131,10 +131,12 @@ final class PhabricatorExternalAccountsSettingsPanel $linked_box = id(new PHUIObjectBoxView()) ->setHeader($linked_head) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setObjectList($linked); $linkable_box = id(new PHUIObjectBoxView()) ->setHeader($linkable_head) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setObjectList($linkable); return array( diff --git a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php index 8f1a5c643c..68d1812616 100644 --- a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php @@ -126,6 +126,7 @@ final class PhabricatorMultiFactorSettingsPanel $panel->setHeader($header); $panel->setTable($table); + $panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); return $panel; } diff --git a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php index 17b8cdde95..2a1b482c80 100644 --- a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php @@ -206,6 +206,7 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel { ->setHeaderText(pht('Change Password')) ->setFormSaved($request->getStr('saved')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); return array( diff --git a/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php b/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php index 54a217300d..3e339e9145 100644 --- a/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php @@ -50,6 +50,7 @@ final class PhabricatorSSHKeysSettingsPanel extends PhabricatorSettingsPanel { $panel->setHeader($header); $panel->setTable($table); + $panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); return $panel; } diff --git a/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php b/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php index e643f2ee08..fb60e40d81 100644 --- a/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php @@ -136,7 +136,8 @@ final class PhabricatorSessionsSettingsPanel extends PhabricatorSettingsPanel { $panel = id(new PHUIObjectBoxView()) ->setHeader($header) - ->setTable($table); + ->setTable($table) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); return $panel; } diff --git a/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php b/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php index c2659d5226..d2cc0dedb6 100644 --- a/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php @@ -84,6 +84,7 @@ final class PhabricatorTokensSettingsPanel extends PhabricatorSettingsPanel { $panel = id(new PHUIObjectBoxView()) ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); return $panel; diff --git a/src/applications/system/codex/PhabricatorDestructibleCodex.php b/src/applications/system/codex/PhabricatorDestructibleCodex.php new file mode 100644 index 0000000000..1c37907c34 --- /dev/null +++ b/src/applications/system/codex/PhabricatorDestructibleCodex.php @@ -0,0 +1,66 @@ +viewer = $viewer; + return $this; + } + + final public function getViewer() { + return $this->viewer; + } + + final public function setObject( + PhabricatorDestructibleCodexInterface $object) { + $this->object = $object; + return $this; + } + + final public function getObject() { + return $this->object; + } + + final public static function newFromObject( + PhabricatorDestructibleCodexInterface $object, + PhabricatorUser $viewer) { + + if (!($object instanceof PhabricatorDestructibleInterface)) { + throw new Exception( + pht( + 'Object (of class "%s") implements interface "%s", but must also '. + 'implement interface "%s".', + get_class($object), + 'PhabricatorDestructibleCodexInterface', + 'PhabricatorDestructibleInterface')); + } + + $codex = $object->newDestructibleCodex(); + if (!($codex instanceof PhabricatorDestructibleCodex)) { + throw new Exception( + pht( + 'Object (of class "%s") implements interface "%s", but defines '. + 'method "%s" incorrectly: this method must return an object of '. + 'class "%s".', + get_class($object), + 'PhabricatorDestructibleCodexInterface', + 'newDestructibleCodex()', + __CLASS__)); + } + + $codex + ->setObject($object) + ->setViewer($viewer); + + return $codex; + } + +} diff --git a/src/applications/system/engine/PhabricatorDestructionEngine.php b/src/applications/system/engine/PhabricatorDestructionEngine.php index f8e5be2ccc..336df57756 100644 --- a/src/applications/system/engine/PhabricatorDestructionEngine.php +++ b/src/applications/system/engine/PhabricatorDestructionEngine.php @@ -3,6 +3,17 @@ final class PhabricatorDestructionEngine extends Phobject { private $rootLogID; + private $collectNotes; + private $notes = array(); + + public function setCollectNotes($collect_notes) { + $this->collectNotes = $collect_notes; + return $this; + } + + public function getNotes() { + return $this->notes; + } public function getViewer() { return PhabricatorUser::getOmnipotentUser(); @@ -36,6 +47,18 @@ final class PhabricatorDestructionEngine extends Phobject { $this->rootLogID = $log->getID(); } + if ($this->collectNotes) { + if ($object instanceof PhabricatorDestructibleCodexInterface) { + $codex = PhabricatorDestructibleCodex::newFromObject( + $object, + $this->getViewer()); + + foreach ($codex->getDestructionNotes() as $note) { + $this->notes[] = $note; + } + } + } + $object->destroyObjectPermanently($this); if ($object_phid) { diff --git a/src/applications/system/interface/PhabricatorDestructibleCodexInterface.php b/src/applications/system/interface/PhabricatorDestructibleCodexInterface.php new file mode 100644 index 0000000000..3725990ee6 --- /dev/null +++ b/src/applications/system/interface/PhabricatorDestructibleCodexInterface.php @@ -0,0 +1,18 @@ +>DestructibleCodex(); + } + +*/ diff --git a/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php b/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php index 4e9d745540..bd6b4e361a 100644 --- a/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php +++ b/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php @@ -145,6 +145,7 @@ EOBANNER; $console->writeOut("%s\n", pht('Destroying objects...')); + $notes = array(); foreach ($named_objects as $object_name => $object) { $console->writeOut( pht( @@ -152,8 +153,14 @@ EOBANNER; get_class($object), $object_name)); - id(new PhabricatorDestructionEngine()) - ->destroyObject($object); + $engine = id(new PhabricatorDestructionEngine()) + ->setCollectNotes(true); + + $engine->destroyObject($object); + + foreach ($engine->getNotes() as $note) { + $notes[] = $note; + } } $console->writeOut( @@ -162,6 +169,12 @@ EOBANNER; 'Permanently destroyed %s object(s).', phutil_count($named_objects))); + if ($notes) { + id(new PhutilConsoleList()) + ->addItems($notes) + ->draw(); + } + return 0; } diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index 1b891cddee..c9d8a6887f 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -29,7 +29,6 @@ abstract class PhabricatorEditEngine private $page; private $pages; private $navigation; - private $hideHeader; final public function setViewer(PhabricatorUser $viewer) { $this->viewer = $viewer; @@ -127,15 +126,6 @@ abstract class PhabricatorEditEngine return $this->navigation; } - public function setHideHeader($hide_header) { - $this->hideHeader = $hide_header; - return $this; - } - - public function getHideHeader() { - return $this->hideHeader; - } - /* -( Managing Fields )---------------------------------------------------- */ @@ -1194,15 +1184,10 @@ abstract class PhabricatorEditEngine $crumbs = $this->buildCrumbs($object, $final = true); - if ($this->getHideHeader()) { - $header = null; - $crumbs->setBorder(false); - } else { - $header = id(new PHUIHeaderView()) - ->setHeader($header_text) - ->setHeaderIcon($header_icon); - $crumbs->setBorder(true); - } + $header = id(new PHUIHeaderView()) + ->setHeader($header_text) + ->setHeaderIcon($header_icon); + $crumbs->setBorder(true); if ($action_button) { $header->addActionLink($action_button); @@ -1231,19 +1216,19 @@ abstract class PhabricatorEditEngine $view->setHeader($header); } - $navigation = $this->getNavigation(); - if ($navigation) { - $view - ->setNavigation($navigation) - ->setMainColumn($content); - } else { - $view->setFooter($content); - } + $view->setFooter($content); - return $controller->newPage() + $page = $controller->newPage() ->setTitle($header_text) ->setCrumbs($crumbs) ->appendChild($view); + + $navigation = $this->getNavigation(); + if ($navigation) { + $page->setNavigation($navigation); + } + + return $page; } protected function newEditResponse( diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php index 232420d4c2..a5dcfcb4ae 100644 --- a/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php +++ b/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php @@ -199,7 +199,7 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView { 'class' => 'login-to-comment button', 'href' => $uri, ), - pht('Login to Comment'))); + pht('Log In to Comment'))); } $data = array(); diff --git a/src/applications/uiexample/examples/PHUIActionPanelExample.php b/src/applications/uiexample/examples/PHUIActionPanelExample.php index 9294dcbea6..e71f2ce846 100644 --- a/src/applications/uiexample/examples/PHUIActionPanelExample.php +++ b/src/applications/uiexample/examples/PHUIActionPanelExample.php @@ -11,10 +11,15 @@ final class PHUIActionPanelExample extends PhabricatorUIExample { } public function renderExample() { + $viewer = $this->getRequest()->getUser(); $view = id(new AphrontMultiColumnView()) ->setFluidLayout(true); + $credit = PhabricatorFile::loadBuiltin( + $viewer, 'projects/v3/creditcard.png'); + $image = $credit->getBestURI(); + /* Action Panels */ $panel1 = id(new PHUIActionPanelView()) ->setIcon('fa-book') @@ -53,7 +58,7 @@ final class PHUIActionPanelExample extends PhabricatorUIExample { /* Action Panels */ $panel1 = id(new PHUIActionPanelView()) - ->setIcon('fa-credit-card') + ->setImage($image) ->setHeader(pht('Account Balance')) ->setHref('#') ->setSubHeader(pht('You were last billed $2,245.12 on Dec 12, 2014.')) diff --git a/src/applications/uiexample/examples/PHUIButtonExample.php b/src/applications/uiexample/examples/PHUIButtonExample.php index fe58123f03..a5ece198fd 100644 --- a/src/applications/uiexample/examples/PHUIButtonExample.php +++ b/src/applications/uiexample/examples/PHUIButtonExample.php @@ -158,7 +158,7 @@ final class PHUIButtonExample extends PhabricatorUIExample { ->setSize(PHUIButtonView::BIG) ->setColor(PHUIButtonView::GREY) ->setIcon($image) - ->setText(pht('Login or Register')) + ->setText(pht('Log In or Register')) ->setSubtext($icon) ->addClass(PHUI::MARGIN_MEDIUM_RIGHT); } diff --git a/src/applications/uiexample/examples/PHUIInfoPanelExample.php b/src/applications/uiexample/examples/PHUIInfoPanelExample.php deleted file mode 100644 index 74ed18f37c..0000000000 --- a/src/applications/uiexample/examples/PHUIInfoPanelExample.php +++ /dev/null @@ -1,138 +0,0 @@ -setHeader(pht('Conpherence')); - - $header2 = id(new PHUIHeaderView()) - ->setHeader(pht('Diffusion')); - - $header3 = id(new PHUIHeaderView()) - ->setHeader(pht('Backend Ops Projects')); - - $header4 = id(new PHUIHeaderView()) - ->setHeader(pht('Revamp Liberty')) - ->setSubHeader(pht('For great justice')) - ->setImage( - celerity_get_resource_uri('/rsrc/image/people/washington.png')); - - $header5 = id(new PHUIHeaderView()) - ->setHeader(pht('Phacility Redesign')) - ->setSubHeader(pht('Move them pixels')) - ->setImage( - celerity_get_resource_uri('/rsrc/image/people/harding.png')); - - $header6 = id(new PHUIHeaderView()) - ->setHeader(pht('Python Phlux')) - ->setSubHeader(pht('No. Sleep. Till Brooklyn.')) - ->setImage( - celerity_get_resource_uri('/rsrc/image/people/taft.png')); - - $column1 = id(new PHUIInfoPanelView()) - ->setHeader($header1) - ->setColumns(3) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')) - ->addInfoBlock(12, pht('Low')) - ->addInfoBlock(123, pht('Wishlist')); - - $column2 = id(new PHUIInfoPanelView()) - ->setHeader($header2) - ->setColumns(3) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')) - ->addInfoBlock(12, pht('Low')) - ->addInfoBlock(123, pht('Wishlist')); - - $column3 = id(new PHUIInfoPanelView()) - ->setHeader($header3) - ->setColumns(3) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')) - ->addInfoBlock(12, pht('Low')) - ->addInfoBlock(123, pht('Wishlist')); - - $column4 = id(new PHUIInfoPanelView()) - ->setHeader($header4) - ->setColumns(3) - ->setProgress(90) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')) - ->addInfoBlock(0, pht('Wishlist')); - - $column5 = id(new PHUIInfoPanelView()) - ->setHeader($header5) - ->setColumns(2) - ->setProgress(25) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')); - - $column6 = id(new PHUIInfoPanelView()) - ->setHeader($header6) - ->setColumns(2) - ->setProgress(50) - ->addInfoBlock(3, pht('Needs Triage')) - ->addInfoBlock(5, pht('Unbreak Now')) - ->addInfoBlock(0, pht('High')) - ->addInfoBlock(0, pht('Normal')); - - $layout1 = id(new AphrontMultiColumnView()) - ->addColumn($column1) - ->addColumn($column2) - ->addColumn($column3) - ->setFluidLayout(true); - - $layout2 = id(new AphrontMultiColumnView()) - ->addColumn($column4) - ->addColumn($column5) - ->addColumn($column6) - ->setFluidLayout(true); - - - $head1 = id(new PHUIHeaderView()) - ->setHeader(pht('Flagged')); - - $head2 = id(new PHUIHeaderView()) - ->setHeader(pht('Sprints')); - - - $wrap1 = id(new PHUIBoxView()) - ->appendChild($layout1) - ->addMargin(PHUI::MARGIN_LARGE_BOTTOM); - - $wrap2 = id(new PHUIBoxView()) - ->appendChild($layout2) - ->addMargin(PHUI::MARGIN_LARGE_BOTTOM); - - - return phutil_tag( - 'div', - array(), - array( - $head1, - $wrap1, - $head2, - $wrap2, - )); - } -} diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index a138d077b5..d26cca945f 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -19,6 +19,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView private $showFooter = true; private $showDurableColumn = true; private $quicksandConfig = array(); + private $tabs; private $crumbs; private $navigation; @@ -159,6 +160,17 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView return $this->crumbs; } + public function setTabs(PHUIListView $tabs) { + $tabs->setType(PHUIListView::TABBAR_LIST); + $tabs->addClass('phabricator-standard-page-tabs'); + $this->tabs = $tabs; + return $this; + } + + public function getTabs() { + return $this->tabs; + } + public function setNavigation(AphrontSideNavFilterView $navigation) { $this->navigation = $navigation; return $this; @@ -528,6 +540,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView $footer = $this->renderFooter(); $nav = $this->getNavigation(); + $tabs = $this->getTabs(); if ($nav) { $crumbs = $this->getCrumbs(); if ($crumbs) { @@ -541,9 +554,17 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView $crumbs = $this->getCrumbs(); if ($crumbs) { + if ($this->getTabs()) { + $crumbs->setBorder(true); + } $content[] = $crumbs; } + $tabs = $this->getTabs(); + if ($tabs) { + $content[] = $tabs; + } + $content[] = $body; $content[] = $footer; diff --git a/src/view/phui/PHUIActionPanelView.php b/src/view/phui/PHUIActionPanelView.php index f5f74b2807..8ced0a642b 100644 --- a/src/view/phui/PHUIActionPanelView.php +++ b/src/view/phui/PHUIActionPanelView.php @@ -4,6 +4,7 @@ final class PHUIActionPanelView extends AphrontTagView { private $href; private $fontIcon; + private $image; private $header; private $subHeader; private $bigText; @@ -29,6 +30,11 @@ final class PHUIActionPanelView extends AphrontTagView { return $this; } + public function setImage($image) { + $this->image = $image; + return $this; + } + public function setBigText($text) { $this->bigText = $text; return $this; @@ -89,6 +95,21 @@ final class PHUIActionPanelView extends AphrontTagView { $fonticon); } + if ($this->image) { + $image = phutil_tag( + 'img', + array( + 'class' => 'phui-action-panel-image', + 'src' => $this->image, + )); + $icon = phutil_tag( + 'span', + array( + 'class' => 'phui-action-panel-icon', + ), + $image); + } + $header = null; if ($this->header) { $header = phutil_tag( diff --git a/src/view/phui/PHUIBigInfoView.php b/src/view/phui/PHUIBigInfoView.php index 0f5bcecfbd..ad10a9fa4a 100644 --- a/src/view/phui/PHUIBigInfoView.php +++ b/src/view/phui/PHUIBigInfoView.php @@ -5,6 +5,7 @@ final class PHUIBigInfoView extends AphrontTagView { private $icon; private $title; private $description; + private $image; private $actions = array(); public function setIcon($icon) { @@ -22,6 +23,11 @@ final class PHUIBigInfoView extends AphrontTagView { return $this; } + public function setImage($image) { + $this->image = $image; + return $this; + } + public function addAction(PHUIButtonView $button) { $this->actions[] = $button; return $this; @@ -43,16 +49,33 @@ final class PHUIBigInfoView extends AphrontTagView { protected function getTagContent() { require_celerity_resource('phui-big-info-view-css'); - $icon = id(new PHUIIconView()) - ->setIcon($this->icon) - ->addClass('phui-big-info-icon'); + if ($this->icon) { + $icon = id(new PHUIIconView()) + ->setIcon($this->icon) + ->addClass('phui-big-info-icon'); - $icon = phutil_tag( - 'div', - array( - 'class' => 'phui-big-info-icon-container', - ), - $icon); + $icon = phutil_tag( + 'div', + array( + 'class' => 'phui-big-info-icon-container', + ), + $icon); + } + + if ($this->image) { + $image = phutil_tag( + 'img', + array( + 'class' => 'phui-big-info-image', + 'src' => $this->image, + )); + $icon = phutil_tag( + 'span', + array( + 'class' => 'phui-big-info-icon-container', + ), + $image); + } $title = phutil_tag( 'div', diff --git a/src/view/phui/PHUIInfoPanelView.php b/src/view/phui/PHUIInfoPanelView.php deleted file mode 100644 index 91f9d2b8e4..0000000000 --- a/src/view/phui/PHUIInfoPanelView.php +++ /dev/null @@ -1,120 +0,0 @@ -header = $header; - return $this; - } - - public function setProgress($progress) { - $this->progress = $progress; - return $this; - } - - public function setColumns($columns) { - $this->columns = $columns; - return $this; - } - - public function addInfoblock($num, $text) { - $this->infoblock[] = array($num, $text); - return $this; - } - - public function render() { - require_celerity_resource('phui-info-panel-css'); - - $trs = array(); - $rows = ceil(count($this->infoblock) / $this->columns); - for ($i = 0; $i < $rows; $i++) { - $tds = array(); - $ii = 1; - foreach ($this->infoblock as $key => $cell) { - $tds[] = $this->renderCell($cell); - unset($this->infoblock[$key]); - $ii++; - if ($ii > $this->columns) { - break; - } - } - $trs[] = phutil_tag( - 'tr', - array( - 'class' => 'phui-info-panel-table-row', - ), - $tds); - } - - $table = phutil_tag( - 'table', - array( - 'class' => 'phui-info-panel-table', - ), - $trs); - - $table = id(new PHUIBoxView()) - ->addPadding(PHUI::PADDING_MEDIUM) - ->appendChild($table); - - $progress = null; - if ($this->progress) { - $progress = phutil_tag( - 'div', - array( - 'class' => 'phui-info-panel-progress', - 'style' => 'width: '.(int)$this->progress.'%;', - ), - null); - } - - $box = id(new PHUIObjectBoxView()) - ->setHeader($this->header) - ->appendChild($table) - ->appendChild($progress); - - return phutil_tag( - 'div', - array( - 'class' => 'phui-info-panel', - ), - $box); - } - - private function renderCell($cell) { - $number = phutil_tag( - 'div', - array( - 'class' => 'phui-info-panel-number', - ), - $cell[0]); - - $text = phutil_tag( - 'div', - array( - 'class' => 'phui-info-panel-text', - ), - $cell[1]); - - return phutil_tag( - 'td', - array( - 'class' => 'phui-info-panel-table-cell', - 'align' => 'center', - 'width' => floor(100 / $this->columns).'%', - ), - array( - $number, - $text, - )); - } -} diff --git a/src/view/phui/PHUITwoColumnView.php b/src/view/phui/PHUITwoColumnView.php index d0443280b6..6e261ffeeb 100644 --- a/src/view/phui/PHUITwoColumnView.php +++ b/src/view/phui/PHUITwoColumnView.php @@ -6,7 +6,7 @@ final class PHUITwoColumnView extends AphrontTagView { private $sideColumn = null; private $navigation; private $display; - private $fluid; + private $fixed; private $header; private $subheader; private $footer; @@ -71,8 +71,8 @@ final class PHUITwoColumnView extends AphrontTagView { return $this->curtain; } - public function setFluid($fluid) { - $this->fluid = $fluid; + public function setFixed($fixed) { + $this->fixed = $fixed; return $this; } @@ -94,8 +94,8 @@ final class PHUITwoColumnView extends AphrontTagView { $classes[] = 'phui-two-column-view'; $classes[] = $this->getDisplay(); - if ($this->fluid) { - $classes[] = 'phui-two-column-fluid'; + if ($this->fixed) { + $classes[] = 'phui-two-column-fixed'; } if ($this->tabs) { diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index 89cbfdbd2e..f697b1f7a8 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -176,3 +176,14 @@ a.handle-status-closed:hover { position: absolute; left: -50px; } + +.phabricator-standard-page-tabs { + padding: 0 32px; + margin-bottom: 32px; + background: {$page.content}; + box-shadow: 0 0 3px 0 rgba(0,0,0,0.2); +} + +.phabricator-standard-page-tabs.phui-list-tabbar .phui-list-item-href { + padding: 12px 24px; +} diff --git a/webroot/rsrc/css/phui/phui-action-panel.css b/webroot/rsrc/css/phui/phui-action-panel.css index d52a1cbaae..63bd351807 100644 --- a/webroot/rsrc/css/phui/phui-action-panel.css +++ b/webroot/rsrc/css/phui/phui-action-panel.css @@ -47,6 +47,12 @@ display: table-cell; } +.phui-action-panel-image { + width: 48px; + height: 48px; + margin: 0 auto; +} + .phui-action-panel-icon a { display: block; } diff --git a/webroot/rsrc/css/phui/phui-big-info-view.css b/webroot/rsrc/css/phui/phui-big-info-view.css index 38951aa059..b8fbab55ce 100644 --- a/webroot/rsrc/css/phui/phui-big-info-view.css +++ b/webroot/rsrc/css/phui/phui-big-info-view.css @@ -35,3 +35,10 @@ .phui-big-info-button + .phui-big-info-button { margin-left: 12px; } + +.phui-big-info-view .phui-big-info-image { + height: 64px; + width: 64px; + margin: 0 auto; + padding-bottom: 12px; +} diff --git a/webroot/rsrc/css/phui/phui-info-panel.css b/webroot/rsrc/css/phui/phui-info-panel.css deleted file mode 100644 index a182292a89..0000000000 --- a/webroot/rsrc/css/phui/phui-info-panel.css +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @provides phui-info-panel-css - */ - -.phui-info-panel .phui-object-box .phui-header-has-image { - padding: 2px 0 0 2px; -} - -.phui-info-panel .phui-object-box .phui-header-image { - margin: 0 8px 0 0; -} - -.phui-info-panel-table { - border-collapse: collapse; - border-style: hidden; - width: 100%; -} - -.phui-info-panel-table td, -.phui-info-panel-table th { - border: 1px solid {$thinblueborder}; -} - -.phui-info-panel-table-cell { - padding: 8px; -} - -.phui-info-panel-number, -.phui-info-panel-number a { - font-size: 30px; - font-weight: bold; - color: {$lightgreytext}; - -webkit-font-smoothing: antialiased; -} - -.phui-info-panel-text, -.phui-info-panel-text a { - color: {$lightgreytext}; -} - -.phui-info-panel-number a:hover, -.phui-info-panel-text a:hover { - color: {$greytext}; - text-decoration: none; -} - -.phui-info-panel-progress { - background: {$green}; - height: 6px; -} diff --git a/webroot/rsrc/css/phui/phui-two-column-view.css b/webroot/rsrc/css/phui/phui-two-column-view.css index 75162619c4..2957528929 100644 --- a/webroot/rsrc/css/phui/phui-two-column-view.css +++ b/webroot/rsrc/css/phui/phui-two-column-view.css @@ -2,6 +2,11 @@ * @provides phui-two-column-view-css */ +.phui-two-column-fixed { + max-width: 1140px; + margin: 0 auto; +} + .phui-two-column-view .phui-two-column-header { background-color: {$page.content}; border-bottom: 1px solid rgba({$alphagrey}, .12); diff --git a/webroot/rsrc/js/phuix/PHUIXAutocomplete.js b/webroot/rsrc/js/phuix/PHUIXAutocomplete.js index ac073a0e38..df4a031377 100644 --- a/webroot/rsrc/js/phuix/PHUIXAutocomplete.js +++ b/webroot/rsrc/js/phuix/PHUIXAutocomplete.js @@ -199,7 +199,7 @@ JX.install('PHUIXAutocomplete', { // to press Alt to type characters like "@" on a German keyboard layout. // The cost of misfiring autocompleters is very small since we do not // eat the keystroke. See T10252. - if (r.metaKey || r.ctrlKey) { + if (r.metaKey || (r.ctrlKey && !r.altKey)) { return; }