diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 56e90ac27a..24d9f52536 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -674,7 +674,7 @@ celerity_register_resource_map(array( ), 'aphront-table-view-css' => array( - 'uri' => '/res/fd33a0f0/rsrc/css/aphront/table-view.css', + 'uri' => '/res/fa7af0ad/rsrc/css/aphront/table-view.css', 'type' => 'css', 'requires' => array( @@ -2511,6 +2511,15 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/application/core/DropdownMenu.js', ), + 'phabricator-fatal-config-template-css' => + array( + 'uri' => '/res/6e1a8d22/rsrc/css/application/config/config-template.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/config/config-template.css', + ), 'phabricator-feed-css' => array( 'uri' => '/res/94a04b24/rsrc/css/application/feed/feed.css', @@ -3147,7 +3156,7 @@ celerity_register_resource_map(array( ), 'setup-issue-css' => array( - 'uri' => '/res/638ebcfb/rsrc/css/application/config/setup-issue.css', + 'uri' => '/res/efbb3673/rsrc/css/application/config/setup-issue.css', 'type' => 'css', 'requires' => array( @@ -3238,7 +3247,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - '2b575971' => + '86c4a3b2' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -3282,7 +3291,7 @@ celerity_register_resource_map(array( 36 => 'phabricator-object-item-list-view-css', 37 => 'global-drag-and-drop-css', ), - 'uri' => '/res/pkg/2b575971/core.pkg.css', + 'uri' => '/res/pkg/86c4a3b2/core.pkg.css', 'type' => 'css', ), 'c90b892e' => @@ -3472,19 +3481,19 @@ celerity_register_resource_map(array( 'reverse' => array( 'aphront-attached-file-view-css' => '83f07678', - 'aphront-crumbs-view-css' => '2b575971', - 'aphront-dialog-view-css' => '2b575971', - 'aphront-error-view-css' => '2b575971', - 'aphront-form-view-css' => '2b575971', + 'aphront-crumbs-view-css' => '86c4a3b2', + 'aphront-dialog-view-css' => '86c4a3b2', + 'aphront-error-view-css' => '86c4a3b2', + 'aphront-form-view-css' => '86c4a3b2', 'aphront-headsup-action-list-view-css' => 'ec01d039', - 'aphront-headsup-view-css' => '2b575971', - 'aphront-list-filter-view-css' => '2b575971', - 'aphront-pager-view-css' => '2b575971', - 'aphront-panel-view-css' => '2b575971', - 'aphront-table-view-css' => '2b575971', - 'aphront-tokenizer-control-css' => '2b575971', - 'aphront-tooltip-css' => '2b575971', - 'aphront-typeahead-control-css' => '2b575971', + 'aphront-headsup-view-css' => '86c4a3b2', + 'aphront-list-filter-view-css' => '86c4a3b2', + 'aphront-pager-view-css' => '86c4a3b2', + 'aphront-panel-view-css' => '86c4a3b2', + 'aphront-table-view-css' => '86c4a3b2', + 'aphront-tokenizer-control-css' => '86c4a3b2', + 'aphront-tooltip-css' => '86c4a3b2', + 'aphront-typeahead-control-css' => '86c4a3b2', 'differential-changeset-view-css' => 'ec01d039', 'differential-core-view-css' => 'ec01d039', 'differential-inline-comment-editor' => 'ac53d36a', @@ -3498,7 +3507,7 @@ celerity_register_resource_map(array( 'differential-table-of-contents-css' => 'ec01d039', 'diffusion-commit-view-css' => 'c8ce2d88', 'diffusion-icons-css' => 'c8ce2d88', - 'global-drag-and-drop-css' => '2b575971', + 'global-drag-and-drop-css' => '86c4a3b2', 'inline-comment-summary-css' => 'ec01d039', 'javelin-aphlict' => 'c90b892e', 'javelin-behavior' => 'fbeded59', @@ -3568,48 +3577,48 @@ celerity_register_resource_map(array( 'javelin-util' => 'fbeded59', 'javelin-vector' => 'fbeded59', 'javelin-workflow' => 'fbeded59', - 'lightbox-attachment-css' => '2b575971', + 'lightbox-attachment-css' => '86c4a3b2', 'maniphest-task-summary-css' => '83f07678', 'maniphest-transaction-detail-css' => '83f07678', 'phabricator-busy' => 'c90b892e', 'phabricator-content-source-view-css' => 'ec01d039', - 'phabricator-core-buttons-css' => '2b575971', - 'phabricator-core-css' => '2b575971', - 'phabricator-crumbs-view-css' => '2b575971', - 'phabricator-directory-css' => '2b575971', + 'phabricator-core-buttons-css' => '86c4a3b2', + 'phabricator-core-css' => '86c4a3b2', + 'phabricator-crumbs-view-css' => '86c4a3b2', + 'phabricator-directory-css' => '86c4a3b2', 'phabricator-drag-and-drop-file-upload' => 'ac53d36a', 'phabricator-dropdown-menu' => 'c90b892e', 'phabricator-file-upload' => 'c90b892e', - 'phabricator-filetree-view-css' => '2b575971', - 'phabricator-flag-css' => '2b575971', - 'phabricator-form-view-css' => '2b575971', - 'phabricator-header-view-css' => '2b575971', - 'phabricator-jump-nav' => '2b575971', + 'phabricator-filetree-view-css' => '86c4a3b2', + 'phabricator-flag-css' => '86c4a3b2', + 'phabricator-form-view-css' => '86c4a3b2', + 'phabricator-header-view-css' => '86c4a3b2', + 'phabricator-jump-nav' => '86c4a3b2', 'phabricator-keyboard-shortcut' => 'c90b892e', 'phabricator-keyboard-shortcut-manager' => 'c90b892e', - 'phabricator-main-menu-view' => '2b575971', + 'phabricator-main-menu-view' => '86c4a3b2', 'phabricator-menu-item' => 'c90b892e', - 'phabricator-nav-view-css' => '2b575971', + 'phabricator-nav-view-css' => '86c4a3b2', 'phabricator-notification' => 'c90b892e', - 'phabricator-notification-css' => '2b575971', - 'phabricator-notification-menu-css' => '2b575971', - 'phabricator-object-item-list-view-css' => '2b575971', + 'phabricator-notification-css' => '86c4a3b2', + 'phabricator-notification-menu-css' => '86c4a3b2', + 'phabricator-object-item-list-view-css' => '86c4a3b2', 'phabricator-object-selector-css' => 'ec01d039', 'phabricator-paste-file-upload' => 'c90b892e', 'phabricator-prefab' => 'c90b892e', 'phabricator-project-tag-css' => '83f07678', - 'phabricator-remarkup-css' => '2b575971', + 'phabricator-remarkup-css' => '86c4a3b2', 'phabricator-shaped-request' => 'ac53d36a', - 'phabricator-side-menu-view-css' => '2b575971', - 'phabricator-standard-page-view' => '2b575971', + 'phabricator-side-menu-view-css' => '86c4a3b2', + 'phabricator-standard-page-view' => '86c4a3b2', 'phabricator-textareautils' => 'c90b892e', 'phabricator-tooltip' => 'c90b892e', - 'phabricator-transaction-view-css' => '2b575971', - 'phabricator-zindex-css' => '2b575971', - 'sprite-apps-large-css' => '2b575971', - 'sprite-gradient-css' => '2b575971', - 'sprite-icon-css' => '2b575971', - 'sprite-menu-css' => '2b575971', - 'syntax-highlighting-css' => '2b575971', + 'phabricator-transaction-view-css' => '86c4a3b2', + 'phabricator-zindex-css' => '86c4a3b2', + 'sprite-apps-large-css' => '86c4a3b2', + 'sprite-gradient-css' => '86c4a3b2', + 'sprite-icon-css' => '86c4a3b2', + 'sprite-menu-css' => '86c4a3b2', + 'syntax-highlighting-css' => '86c4a3b2', ), )); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 706581d849..dce5763203 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -726,6 +726,7 @@ phutil_register_library_map(array( 'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php', 'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php', 'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php', + 'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php', 'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php', 'PhabricatorConfigStackSource' => 'infrastructure/env/PhabricatorConfigStackSource.php', 'PhabricatorConfigTransaction' => 'applications/config/storage/PhabricatorConfigTransaction.php', @@ -1213,6 +1214,7 @@ phutil_register_library_map(array( 'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php', 'PhabricatorSetupCheckAPC' => 'applications/config/check/PhabricatorSetupCheckAPC.php', 'PhabricatorSetupCheckBaseURI' => 'applications/config/check/PhabricatorSetupCheckBaseURI.php', + 'PhabricatorSetupCheckExtensions' => 'applications/config/check/PhabricatorSetupCheckExtensions.php', 'PhabricatorSetupCheckExtraConfig' => 'applications/config/check/PhabricatorSetupCheckExtraConfig.php', 'PhabricatorSetupCheckFacebook' => 'applications/config/check/PhabricatorSetupCheckFacebook.php', 'PhabricatorSetupCheckGD' => 'applications/config/check/PhabricatorSetupCheckGD.php', @@ -2132,6 +2134,7 @@ phutil_register_library_map(array( 1 => 'PhabricatorMarkupInterface', ), 'PhabricatorConfigProxySource' => 'PhabricatorConfigSource', + 'PhabricatorConfigResponse' => 'AphrontHTMLResponse', 'PhabricatorConfigStackSource' => 'PhabricatorConfigSource', 'PhabricatorConfigTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery', @@ -2576,6 +2579,7 @@ phutil_register_library_map(array( 'PhabricatorSettingsPanelSearchPreferences' => 'PhabricatorSettingsPanel', 'PhabricatorSetupCheckAPC' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckBaseURI' => 'PhabricatorSetupCheck', + 'PhabricatorSetupCheckExtensions' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckExtraConfig' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckFacebook' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckGD' => 'PhabricatorSetupCheck', diff --git a/src/applications/config/check/PhabricatorSetupCheck.php b/src/applications/config/check/PhabricatorSetupCheck.php index 4648965e4e..e8de542715 100644 --- a/src/applications/config/check/PhabricatorSetupCheck.php +++ b/src/applications/config/check/PhabricatorSetupCheck.php @@ -6,6 +6,10 @@ abstract class PhabricatorSetupCheck { abstract protected function executeChecks(); + public function getExecutionOrder() { + return 1; + } + final protected function newIssue($key) { $issue = id(new PhabricatorSetupIssue()) ->setIssueKey($key); @@ -57,6 +61,14 @@ abstract class PhabricatorSetupCheck { $issue_count = self::getOpenSetupIssueCount(); if ($issue_count === null) { $issues = self::runAllChecks(); + foreach ($issues as $issue) { + if ($issue->getIsFatal()) { + $view = id(new PhabricatorSetupIssueView()) + ->setIssue($issue); + return id(new PhabricatorConfigResponse()) + ->setView($view); + } + } self::setOpenSetupIssueCount(count($issues)); } @@ -82,6 +94,8 @@ abstract class PhabricatorSetupCheck { $checks[] = newv($symbol['name'], array()); } + $checks = msort($checks, 'getExecutionOrder'); + $issues = array(); foreach ($checks as $check) { $check->runSetupChecks(); @@ -91,6 +105,9 @@ abstract class PhabricatorSetupCheck { "Two setup checks raised an issue with key '{$key}'!"); } $issues[$key] = $issue; + if ($issue->getIsFatal()) { + break 2; + } } } diff --git a/src/applications/config/check/PhabricatorSetupCheckExtensions.php b/src/applications/config/check/PhabricatorSetupCheckExtensions.php new file mode 100644 index 0000000000..a536e2eb02 --- /dev/null +++ b/src/applications/config/check/PhabricatorSetupCheckExtensions.php @@ -0,0 +1,50 @@ +newIssue('php.extensions') + ->setIsFatal(true) + ->setName(pht('Missing Required Extensions')) + ->setMessage($message); + + foreach ($need as $extension) { + $issue->addPHPExtension($extension); + } + } +} diff --git a/src/applications/config/response/PhabricatorConfigResponse.php b/src/applications/config/response/PhabricatorConfigResponse.php new file mode 100644 index 0000000000..02fc190816 --- /dev/null +++ b/src/applications/config/response/PhabricatorConfigResponse.php @@ -0,0 +1,51 @@ +view = $view; + return $this; + } + + public function buildResponseString() { + $resources = $this->buildResources(); + + $view = $this->view->render(); + + $template = << + + + Phabricator Setup + {$resources} + + + {$view} + + +EOTEMPLATE; + + return $template; + } + + private function buildResources() { + $css = array( + 'application/config/config-template.css', + 'application/config/setup-issue.css', + ); + + $webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/'; + + $resources = array(); + foreach ($css as $path) { + $resources[] = ''; + } + return implode("\n", $resources); + } + + +} diff --git a/src/infrastructure/PhabricatorSetup.php b/src/infrastructure/PhabricatorSetup.php index 3797d23bad..1c1398bd75 100644 --- a/src/infrastructure/PhabricatorSetup.php +++ b/src/infrastructure/PhabricatorSetup.php @@ -109,32 +109,8 @@ final class PhabricatorSetup { self::write("[OKAY] Core configuration OKAY.\n"); - self::writeHeader("REQUIRED PHP EXTENSIONS"); - $extensions = array( - 'mysql', - 'hash', - 'json', - 'openssl', - 'mbstring', - 'iconv', - - // There is a chance we might not need this, but some configurations (like - // OAuth or Amazon SES) will require it. Just mark it 'required' since - // it's widely available and relatively core. - 'curl', - ); - foreach ($extensions as $extension) { - $ok = self::requireExtension($extension); - if (!$ok) { - self::writeFailure(); - self::write("Setup failure! Install PHP extension '{$extension}'."); - return; - } - } - $root = dirname(phutil_get_library_root('phabricator')); - self::writeHeader("BASIC CONFIGURATION"); $env = PhabricatorEnv::getEnvConfig('phabricator.env'); @@ -231,16 +207,6 @@ final class PhabricatorSetup { } - public static function requireExtension($extension) { - if (extension_loaded($extension)) { - self::write(" okay Extension '{$extension}' installed.\n"); - return true; - } else { - self::write("[FAIL] Extension '{$extension}' is NOT INSTALLED!\n"); - return false; - } - } - private static function writeFailure() { self::write("\n\n<<< *** FAILURE! *** >>>\n"); } diff --git a/webroot/index.php b/webroot/index.php index 0745798258..e751bb36cd 100644 --- a/webroot/index.php +++ b/webroot/index.php @@ -38,7 +38,11 @@ try { return; } - PhabricatorSetupCheck::willProcessRequest(); + $response = PhabricatorSetupCheck::willProcessRequest(); + if ($response) { + $sink->writeResponse($response); + return; + } $host = $_SERVER['HTTP_HOST']; $path = $_REQUEST['__path__']; diff --git a/webroot/rsrc/css/application/config/config-template.css b/webroot/rsrc/css/application/config/config-template.css new file mode 100644 index 0000000000..4621487a41 --- /dev/null +++ b/webroot/rsrc/css/application/config/config-template.css @@ -0,0 +1,12 @@ +/** + * @provides phabricator-fatal-config-template-css + */ +body { + overflow-y: scroll; + background: #f9f9f9; + margin: 0; + padding: 0; + font: 13px/1.231 'Helvetica Neue', Arial, sans-serif; + text-align: left; + -webkit-text-size-adjust: none; +} diff --git a/webroot/rsrc/css/application/config/setup-issue.css b/webroot/rsrc/css/application/config/setup-issue.css index 1d365511fe..0ca42e7fb2 100644 --- a/webroot/rsrc/css/application/config/setup-issue.css +++ b/webroot/rsrc/css/application/config/setup-issue.css @@ -65,6 +65,10 @@ border-bottom: 1px solid #bfbfbf; } +.setup-fatal .setup-issue-instructions { + background: #ffdfdf; +} + .setup-issue-name { padding: 15px; background: #35393d;