diff --git a/conf/default.conf.php b/conf/default.conf.php index a668c27d79..b265976e23 100644 --- a/conf/default.conf.php +++ b/conf/default.conf.php @@ -1,77 +1,99 @@ null, 'phabricator.csrf-key' => '0b7ec0592e0a2829d8b71df2fa269b2c6172eca3', + + 'phabricator.version' => 'UNSTABLE', + 'user.default-profile-image-phid' => 'PHID-FILE-f57aaefce707fc4060ef', + + // When email is sent, try to hand it off to the MTA immediately. The only + // reason to disable this is if your MTA infrastructure is completely + // terrible. If you disable this option, you must run the 'metamta_mta.php' + // daemon or mail won't be handed off to the MTA. + 'metamta.send-immediately' => true, + + +// -- DarkConsole ----------------------------------------------------------- // + + // DarkConsole is a administrative debugging/profiling tool built into + // Phabricator. You can leave it disabled unless you're developing against + // Phabricator. + + // Determines whether or not DarkConsole is available. DarkConsole exposes + // some data like queries and stack traces, so you should be careful about + // turning it on in production (although users can not normally see it, even + // if the deployment configuration enables it). + 'darkconsole.enabled' => true, + + // Always enable DarkConsole, even for logged out users. This potentially + // exposes sensitive information to users, so make sure untrusted users can + // not access an install running in this mode. You should definitely leave + // this off in production. It is only really useful for using DarkConsole + // utilties to debug or profile logged-out pages. You must set + // 'darkconsole.enabled' to use this option. + 'darkconsole.always-on' => false, + // -- MySQL --------------------------------------------------------------- // // The username to use when connecting to MySQL. 'mysql.user' => 'root', // The password to use when connecting to MySQL. 'mysql.pass' => '', // The MySQL server to connect to. 'mysql.host' => 'localhost', // -- Facebook ------------------------------------------------------------ // // Can users use Facebook credentials to login to Phabricator? 'facebook.auth-enabled' => false, // The Facebook "Application ID" to use for Facebook API access. 'facebook.application-id' => null, // The Facebook "Application Secret" to use for Facebook API access. 'facebook.application-secret' => null, // -- Recaptcha ------------------------------------------------------------- // // Is Recaptcha enabled? If disabled, captchas will not appear. 'recaptcha.enabled' => false, // Your Recaptcha public key, obtained from Recaptcha. 'recaptcha.public-key' => null, // Your Recaptcha private key, obtained from Recaptcha. 'recaptcha.private-key' => null, - 'user.default-profile-image-phid' => 'PHID-FILE-f57aaefce707fc4060ef', - - // When email is sent, try to hand it off to the MTA immediately. The only - // reason to disable this is if your MTA infrastructure is completely - // terrible. If you disable this option, you must run the 'metamta_mta.php' - // daemon or mail won't be handed off to the MTA. - 'metamta.send-immediately' => true, - - ); diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 85b13652c0..6b34bd6c71 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -1,474 +1,484 @@ array( 'uri' => '/res/056b0c12/rsrc/css/aphront/dark-console.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/dark-console.css', ), 'aphront-dialog-view-css' => array( 'uri' => '/res/a05107ae/rsrc/css/aphront/dialog-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/dialog-view.css', ), 'aphront-form-view-css' => array( 'uri' => '/res/785ac1c6/rsrc/css/aphront/form-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/form-view.css', ), 'aphront-panel-view-css' => array( 'uri' => '/res/63672373/rsrc/css/aphront/panel-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/panel-view.css', ), 'aphront-request-failure-view-css' => array( 'uri' => '/res/97b8337a/rsrc/css/aphront/request-failure-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/request-failure-view.css', ), 'aphront-side-nav-view-css' => array( 'uri' => '/res/0fc0545c/rsrc/css/aphront/side-nav-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/side-nav-view.css', ), 'aphront-table-view-css' => array( 'uri' => '/res/6a70f0f0/rsrc/css/aphront/table-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/table-view.css', ), 'aphront-tokenizer-control-css' => array( 'uri' => '/res/a3d23074/rsrc/css/aphront/tokenizer.css', 'type' => 'css', 'requires' => array( 0 => 'aphront-typeahead-control-css', ), 'disk' => '/rsrc/css/aphront/tokenizer.css', ), 'aphront-typeahead-control-css' => array( 'uri' => '/res/928df9f0/rsrc/css/aphront/typeahead.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/typeahead.css', ), 'phabricator-standard-page-view' => array( - 'uri' => '/res/fb02fb0e/rsrc/css/application/base/standard-page-view.css', + 'uri' => '/res/c7dedb5f/rsrc/css/application/base/standard-page-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/base/standard-page-view.css', ), 'differential-revision-add-comment-css' => array( 'uri' => '/res/9be761de/rsrc/css/application/differential/add-comment.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/add-comment.css', ), 'differential-changeset-view-css' => array( 'uri' => '/res/8b893b8e/rsrc/css/application/differential/changeset-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/changeset-view.css', ), 'differential-core-view-css' => array( 'uri' => '/res/525d1a12/rsrc/css/application/differential/core.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/core.css', ), 'differential-revision-comment-list-css' => array( - 'uri' => '/res/afbc5f6f/rsrc/css/application/differential/revision-comment-list.css', + 'uri' => '/res/10b9a829/rsrc/css/application/differential/revision-comment-list.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/revision-comment-list.css', ), 'differential-revision-comment-css' => array( 'uri' => '/res/678be39a/rsrc/css/application/differential/revision-comment.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/revision-comment.css', ), 'differential-revision-detail-css' => array( 'uri' => '/res/230a67c6/rsrc/css/application/differential/revision-detail.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/revision-detail.css', ), 'differential-revision-history-css' => array( 'uri' => '/res/755f3da3/rsrc/css/application/differential/revision-history.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/revision-history.css', ), 'differential-table-of-contents-css' => array( 'uri' => '/res/e68f6f05/rsrc/css/application/differential/table-of-contents.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/table-of-contents.css', ), 'phabricator-directory-css' => array( 'uri' => '/res/6a000601/rsrc/css/application/directory/phabricator-directory.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/directory/phabricator-directory.css', ), 'phabricator-core-buttons-css' => array( 'uri' => '/res/fe74ba44/rsrc/css/core/buttons.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/buttons.css', ), 'phabricator-core-css' => array( - 'uri' => '/res/41c62455/rsrc/css/core/core.css', + 'uri' => '/res/80cbabe4/rsrc/css/core/core.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/core.css', ), 'phabricator-core-dialog-css' => array( 'uri' => '/res/f66cec41/rsrc/css/core/dialog.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/dialog.css', ), 'phabricator-remarkup-css' => array( 'uri' => '/res/786989c3/rsrc/css/core/remarkup.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/remarkup.css', ), 'syntax-highlighting-css' => array( 'uri' => '/res/fb673ece/rsrc/css/core/syntax.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/syntax.css', ), 'javelin-behavior-dark-console' => array( 'uri' => '/res/020b0265/rsrc/js/application/core/behavior-dark-console.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/application/core/behavior-dark-console.js', ), 'javelin-behavior-aphront-basic-tokenizer' => array( 'uri' => '/res/8317d761/rsrc/js/application/core/behavior-tokenizer.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/core/behavior-tokenizer.js', ), + 'javelin-behavior-workflow' => + array( + 'uri' => '/res/15446e7e/rsrc/js/application/core/behavior-workflow.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-lib-dev', + ), + 'disk' => '/rsrc/js/application/core/behavior-workflow.js', + ), 'javelin-behavior-differential-add-reviewers' => array( 'uri' => '/res/330154e4/rsrc/js/application/differential/behavior-add-reviewers.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-add-reviewers.js', ), 'javelin-behavior-differential-feedback-preview' => array( 'uri' => '/res/8695d8b8/rsrc/js/application/differential/behavior-comment-preview.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-comment-preview.js', ), 'javelin-behavior-differential-diff-radios' => array( 'uri' => '/res/fdeb3823/rsrc/js/application/differential/behavior-diff-radios.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-diff-radios.js', ), 'javelin-behavior-differential-edit-inline-comments' => array( 'uri' => '/res/74747b2e/rsrc/js/application/differential/behavior-edit-inline-comments.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-edit-inline-comments.js', ), 'javelin-behavior-differential-populate' => array( 'uri' => '/res/a13dcd7e/rsrc/js/application/differential/behavior-populate.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-populate.js', ), 'javelin-behavior-differential-show-all-comments' => array( - 'uri' => '/res/625fea99/rsrc/js/application/differential/behavior-show-all-comments.js', + 'uri' => '/res/2a3592b8/rsrc/js/application/differential/behavior-show-all-comments.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-show-all-comments.js', ), 'javelin-behavior-differential-show-more' => array( 'uri' => '/res/ea998002/rsrc/js/application/differential/behavior-show-more.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-show-more.js', ), 'javelin-magical-init' => array( 'uri' => '/res/76614f84/rsrc/js/javelin/init.dev.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/init.dev.js', ), 'javelin-init-prod' => array( 'uri' => '/res/1267c868/rsrc/js/javelin/init.min.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/init.min.js', ), 'javelin-lib-dev' => array( 'uri' => '/res/a0e7a5e9/rsrc/js/javelin/javelin.dev.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/javelin.dev.js', ), 'javelin-lib-prod' => array( 'uri' => '/res/2f2b3b2e/rsrc/js/javelin/javelin.min.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/javelin.min.js', ), 'javelin-typeahead-dev' => array( 'uri' => '/res/6de6ae59/rsrc/js/javelin/typeahead.dev.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/typeahead.dev.js', ), 'javelin-typeahead-prod' => array( 'uri' => '/res/69d5fad1/rsrc/js/javelin/typeahead.min.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/typeahead.min.js', ), 'javelin-workflow-dev' => array( 'uri' => '/res/c6b17f93/rsrc/js/javelin/workflow.dev.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/workflow.dev.js', ), 'javelin-workflow-prod' => array( 'uri' => '/res/b758e0a0/rsrc/js/javelin/workflow.min.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/workflow.min.js', ), ), array ( 'packages' => array ( - '20cc4391' => + '554bfa09' => array ( 'name' => 'core.pkg.css', 'symbols' => array ( 0 => 'phabricator-core-css', 1 => 'phabricator-core-buttons-css', 2 => 'phabricator-standard-page-view', 3 => 'aphront-dialog-view-css', 4 => 'aphront-form-view-css', 5 => 'aphront-panel-view-css', 6 => 'aphront-side-nav-view-css', 7 => 'aphront-table-view-css', 8 => 'aphront-tokenizer-control-css', 9 => 'aphront-typeahead-control-css', 10 => 'phabricator-directory-css', 11 => 'phabricator-remarkup-css', 12 => 'syntax-highlighting-css', ), - 'uri' => '/res/pkg/20cc4391/core.pkg.css', + 'uri' => '/res/pkg/554bfa09/core.pkg.css', 'type' => 'css', ), - 'f7362a6c' => + '4b8af7b5' => array ( 'name' => 'differential.pkg.css', 'symbols' => array ( 0 => 'differential-core-view-css', 1 => 'differential-changeset-view-css', 2 => 'differential-revision-detail-css', 3 => 'differential-revision-history-css', 4 => 'differential-table-of-contents-css', 5 => 'differential-revision-comment-css', 6 => 'differential-revision-add-comment-css', 7 => 'differential-revision-comment-list-css', ), - 'uri' => '/res/pkg/f7362a6c/differential.pkg.css', + 'uri' => '/res/pkg/4b8af7b5/differential.pkg.css', 'type' => 'css', ), '30d594cf' => array ( 'name' => 'differential.pkg.js', 'symbols' => array ( 0 => 'javelin-behavior-differential-feedback-preview', 1 => 'javelin-behavior-differential-edit-inline-comments', 2 => 'javelin-behavior-differential-populate', 3 => 'javelin-behavior-differential-show-more', 4 => 'javelin-behavior-differential-diff-radios', ), 'uri' => '/res/pkg/30d594cf/differential.pkg.js', 'type' => 'js', ), ), 'reverse' => array ( - 'phabricator-core-css' => '20cc4391', - 'phabricator-core-buttons-css' => '20cc4391', - 'phabricator-standard-page-view' => '20cc4391', - 'aphront-dialog-view-css' => '20cc4391', - 'aphront-form-view-css' => '20cc4391', - 'aphront-panel-view-css' => '20cc4391', - 'aphront-side-nav-view-css' => '20cc4391', - 'aphront-table-view-css' => '20cc4391', - 'aphront-tokenizer-control-css' => '20cc4391', - 'aphront-typeahead-control-css' => '20cc4391', - 'phabricator-directory-css' => '20cc4391', - 'phabricator-remarkup-css' => '20cc4391', - 'syntax-highlighting-css' => '20cc4391', - 'differential-core-view-css' => 'f7362a6c', - 'differential-changeset-view-css' => 'f7362a6c', - 'differential-revision-detail-css' => 'f7362a6c', - 'differential-revision-history-css' => 'f7362a6c', - 'differential-table-of-contents-css' => 'f7362a6c', - 'differential-revision-comment-css' => 'f7362a6c', - 'differential-revision-add-comment-css' => 'f7362a6c', - 'differential-revision-comment-list-css' => 'f7362a6c', + 'phabricator-core-css' => '554bfa09', + 'phabricator-core-buttons-css' => '554bfa09', + 'phabricator-standard-page-view' => '554bfa09', + 'aphront-dialog-view-css' => '554bfa09', + 'aphront-form-view-css' => '554bfa09', + 'aphront-panel-view-css' => '554bfa09', + 'aphront-side-nav-view-css' => '554bfa09', + 'aphront-table-view-css' => '554bfa09', + 'aphront-tokenizer-control-css' => '554bfa09', + 'aphront-typeahead-control-css' => '554bfa09', + 'phabricator-directory-css' => '554bfa09', + 'phabricator-remarkup-css' => '554bfa09', + 'syntax-highlighting-css' => '554bfa09', + 'differential-core-view-css' => '4b8af7b5', + 'differential-changeset-view-css' => '4b8af7b5', + 'differential-revision-detail-css' => '4b8af7b5', + 'differential-revision-history-css' => '4b8af7b5', + 'differential-table-of-contents-css' => '4b8af7b5', + 'differential-revision-comment-css' => '4b8af7b5', + 'differential-revision-add-comment-css' => '4b8af7b5', + 'differential-revision-comment-list-css' => '4b8af7b5', 'javelin-behavior-differential-feedback-preview' => '30d594cf', 'javelin-behavior-differential-edit-inline-comments' => '30d594cf', 'javelin-behavior-differential-populate' => '30d594cf', 'javelin-behavior-differential-show-more' => '30d594cf', 'javelin-behavior-differential-diff-radios' => '30d594cf', ), )); diff --git a/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php b/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php index 36d0e9408d..9fb983f220 100644 --- a/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php +++ b/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php @@ -1,86 +1,89 @@ request = $request; return $this; } final public function getRequest() { return $this->request; } final public function getConsole() { return $this->console; } + + final public function setConsole($console) { + $this->console = $console; + } final public function buildController() { $map = $this->getURIMap(); $mapper = new AphrontURIMapper($map); $request = $this->getRequest(); $path = $request->getPath(); list($controller_class, $uri_data) = $mapper->mapPath($path); if (!$controller_class) { return $this->build404Controller(); } PhutilSymbolLoader::loadClass($controller_class); $controller = newv($controller_class, array($request)); return array($controller, $uri_data); } final public function setHost($host) { $this->host = $host; return $this; } final public function getHost() { return $this->host; } final public function setPath($path) { $this->path = $path; return $this; } final public function getPath() { return $this->path; } final public function willBuildRequest() { - $this->console = new DarkConsoleCore(); } } diff --git a/src/aphront/console/controller/DarkConsoleController.php b/src/aphront/console/controller/DarkConsoleController.php index 8ca4128c7e..8c6f0a1925 100755 --- a/src/aphront/console/controller/DarkConsoleController.php +++ b/src/aphront/console/controller/DarkConsoleController.php @@ -1,44 +1,54 @@ getRequest(); $user = $request->getUser(); $visible = $request->getStr('visible'); if (strlen($visible)) { $user->setConsoleVisible((int)$visible); $user->save(); return new AphrontAjaxResponse(); } $tab = $request->getStr('tab'); if (strlen($tab)) { $user->setConsoleTab($tab); $user->save(); return new AphrontAjaxResponse(); } - + + if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) { + $user->setConsoleEnabled(!$user->getConsoleEnabled()); + $user->save(); + if ($request->isAjax()) { + return new AphrontRedirectResponse(); + } else { + return id(new AphrontRedirectResponse())->setURI('/'); + } + } + } } diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index e78c6217b7..5d59e50786 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -1,211 +1,219 @@ array( '$' => 'RepositoryListController', 'new/$' => 'RepositoryEditController', 'edit/(?\d+)/$' => 'RepositoryEditController', 'delete/(?\d+)/$' => 'RepositoryDeleteController', ), '/' => array( '$' => 'PhabricatorDirectoryMainController', ), '/directory/' => array( 'item/$' => 'PhabricatorDirectoryItemListController', 'item/edit/(?:(?\d+)/)?$' => 'PhabricatorDirectoryItemEditController', 'item/delete/(?\d+)/' => 'PhabricatorDirectoryItemDeleteController', 'category/$' => 'PhabricatorDirectoryCategoryListController', 'category/edit/(?:(?\d+)/)?$' => 'PhabricatorDirectoryCategoryEditController', 'category/delete/(?\d+)/' => 'PhabricatorDirectoryCategoryDeleteController', ), '/file/' => array( '$' => 'PhabricatorFileListController', 'upload/$' => 'PhabricatorFileUploadController', '(?info)/(?[^/]+)/' => 'PhabricatorFileViewController', '(?view)/(?[^/]+)/' => 'PhabricatorFileViewController', '(?download)/(?[^/]+)/' => 'PhabricatorFileViewController', ), '/phid/' => array( '$' => 'PhabricatorPHIDLookupController', 'list/$' => 'PhabricatorPHIDListController', 'type/$' => 'PhabricatorPHIDTypeListController', 'type/edit/(?:(?\d+)/)?$' => 'PhabricatorPHIDTypeEditController', 'new/$' => 'PhabricatorPHIDAllocateController', ), '/people/' => array( '$' => 'PhabricatorPeopleListController', 'edit/(?:(?\w+)/)?$' => 'PhabricatorPeopleEditController', ), '/p/(?\w+)/$' => 'PhabricatorPeopleProfileController', '/conduit/' => array( '$' => 'PhabricatorConduitConsoleController', 'method/(?[^/]+)$' => 'PhabricatorConduitConsoleController', 'log/$' => 'PhabricatorConduitLogController', ), '/api/(?[^/]+)$' => 'PhabricatorConduitAPIController', '/D(?\d+)' => 'DifferentialRevisionViewController', '/differential/' => array( '$' => 'DifferentialRevisionListController', 'filter/(?\w+)/$' => 'DifferentialRevisionListController', 'diff/(?\d+)/$' => 'DifferentialDiffViewController', 'changeset/$' => 'DifferentialChangesetViewController', 'revision/edit/(?:(?\d+)/)?$' => 'DifferentialRevisionEditController', 'comment/' => array( 'preview/(?\d+)/$' => 'DifferentialCommentPreviewController', 'save/$' => 'DifferentialCommentSaveController', 'inline/' => array( 'preview/(?\d+)/$' => 'DifferentialInlineCommentPreviewController', 'edit/(?\d+)/$' => 'DifferentialInlineCommentEditController', ), ), ), '/res/' => array( '(?pkg/)?(?[a-f0-9]{8})/(?.+\.(?:css|js))$' => 'CelerityResourceController', ), '/typeahead/' => array( 'common/(?\w+)/$' => 'PhabricatorTypeaheadCommonDatasourceController', ), '/mail/' => array( '$' => 'PhabricatorMetaMTAListController', 'send/$' => 'PhabricatorMetaMTASendController', 'view/(?\d+)/$' => 'PhabricatorMetaMTAViewController', 'lists/$' => 'PhabricatorMetaMTAMailingListsController', 'lists/edit/(?:(?\d+)/)?$' => 'PhabricatorMetaMTAMailingListEditController', ), '/login/' => array( '$' => 'PhabricatorLoginController', 'email/$' => 'PhabricatorEmailLoginController', 'etoken/(?\w+)/$' => 'PhabricatorEmailTokenController', ), '/logout/$' => 'PhabricatorLogoutController', '/facebook-auth/' => array( '$' => 'PhabricatorFacebookAuthController', 'diagnose/$' => 'PhabricatorFacebookAuthDiagnosticsController', ), '/xhprof/' => array( 'profile/(?[^/]+)/$' => 'PhabricatorXHProfProfileController', ), '/~/' => 'DarkConsoleController', ); } public function buildRequest() { $request = new AphrontRequest($this->getHost(), $this->getPath()); $request->setRequestData($_GET + $_POST); $request->setApplicationConfiguration($this); return $request; } public function handleException(Exception $ex) { $class = phutil_escape_html(get_class($ex)); $message = phutil_escape_html($ex->getMessage()); $content = '
'. '

Unhandled Exception "'.$class.'": '.$message.'

'. ''.phutil_escape_html((string)$ex).''. '
'; $view = new PhabricatorStandardPageView(); $view->setRequest($this->getRequest()); $view->appendChild($content); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } public function willSendResponse(AphrontResponse $response) { $request = $this->getRequest(); if ($response instanceof AphrontDialogResponse) { if (!$request->isAjax()) { $view = new PhabricatorStandardPageView(); $view->setRequest($request); $view->appendChild( '
'. $response->buildResponseString(). '
'); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } else { return id(new AphrontAjaxResponse()) ->setContent(array( 'dialog' => $response->buildResponseString(), )); } + } else if ($response instanceof AphrontRedirectResponse) { + if ($request->isAjax()) { + return id(new AphrontAjaxResponse()) + ->setContent( + array( + 'redirect' => $response->getURI(), + )); + } } else if ($response instanceof Aphront404Response) { $failure = new AphrontRequestFailureView(); $failure->setHeader('404 Not Found'); $failure->appendChild( '

The page you requested was not found.

'); $view = new PhabricatorStandardPageView(); $view->setTitle('404 Not Found'); $view->setRequest($this->getRequest()); $view->appendChild($failure); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); $response->setHTTPResponseCode(404); return $response; } return $response; } public function build404Controller() { return array(new Phabricator404Controller($this->getRequest()), array()); } } diff --git a/src/aphront/response/redirect/AphrontRedirectResponse.php b/src/aphront/response/redirect/AphrontRedirectResponse.php index bb8666583c..1939a86f53 100644 --- a/src/aphront/response/redirect/AphrontRedirectResponse.php +++ b/src/aphront/response/redirect/AphrontRedirectResponse.php @@ -1,41 +1,45 @@ uri = $uri; return $this; } + + public function getURI() { + return $this->uri; + } public function getHeaders() { return array( array('Location', $this->uri), ); } public function buildResponseString() { return ''; } } diff --git a/src/applications/base/controller/base/PhabricatorController.php b/src/applications/base/controller/base/PhabricatorController.php index bee50ca2ac..32205c245a 100644 --- a/src/applications/base/controller/base/PhabricatorController.php +++ b/src/applications/base/controller/base/PhabricatorController.php @@ -1,69 +1,77 @@ getRequest(); $user = new PhabricatorUser(); $phusr = $request->getCookie('phusr'); $phsid = $request->getCookie('phsid'); if ($phusr && $phsid) { $info = queryfx_one( $user->establishConnection('r'), 'SELECT u.* FROM %T u JOIN %T s ON u.phid = s.userPHID AND s.type = %s AND s.sessionKey = %s', $user->getTableName(), 'phabricator_session', 'web', $phsid); if ($info) { $user->loadFromArray($info); } } $request->setUser($user); + + if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) { + if ($user->getConsoleEnabled() || + PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { + $console = new DarkConsoleCore(); + $request->getApplicationConfiguration()->setConsole($console); + } + } if ($this->shouldRequireLogin() && !$user->getPHID()) { throw new AphrontRedirectException('/login/'); } } public function buildStandardPageView() { $view = new PhabricatorStandardPageView(); $view->setRequest($this->getRequest()); return $view; } public function buildStandardPageResponse($view, array $data) { $page = $this->buildStandardPageView(); $page->appendChild($view); $response = new AphrontWebpageResponse(); $response->setContent($page->render()); return $response; } } diff --git a/src/view/page/standard/PhabricatorStandardPageView.php b/src/view/page/standard/PhabricatorStandardPageView.php index 0aaef9802e..a2ba41c9ab 100755 --- a/src/view/page/standard/PhabricatorStandardPageView.php +++ b/src/view/page/standard/PhabricatorStandardPageView.php @@ -1,204 +1,238 @@ request = $request; return $this; } public function getRequest() { return $this->request; } public function setApplicationName($application_name) { $this->applicationName = $application_name; return $this; } public function getApplicationName() { return $this->applicationName; } public function setBaseURI($base_uri) { $this->baseURI = $base_uri; return $this; } public function getBaseURI() { return $this->baseURI; } public function setTabs(array $tabs, $selected_tab) { $this->tabs = $tabs; $this->selectedTab = $selected_tab; return $this; } public function getTitle() { return $this->getGlyph().' '.parent::getTitle(); } protected function willRenderPage() { if (!$this->getRequest()) { throw new Exception( "You must set the Request to render a PhabricatorStandardPageView."); } $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); require_celerity_resource('phabricator-core-css'); require_celerity_resource('phabricator-core-buttons-css'); require_celerity_resource('phabricator-standard-page-view'); require_celerity_resource('javelin-lib-dev'); require_celerity_resource('javelin-workflow-dev'); + Javelin::initBehavior('workflow', array()); + if ($console) { require_celerity_resource('aphront-dark-console-css'); Javelin::initBehavior( 'dark-console', array( 'uri' => '/~/', )); } $this->bodyContent = $this->renderChildren(); } protected function getHead() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('css'). ''. ''; } public function setGlyph($glyph) { $this->glyph = $glyph; return $this; } public function getGlyph() { return $this->glyph; } protected function willSendResponse($response) { $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); if ($console) { $response = str_replace( '', $console->render($this->getRequest()), $response); } return $response; } protected function getBody() { $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); $tabs = array(); foreach ($this->tabs as $name => $tab) { $tabs[] = phutil_render_tag( 'a', array( 'href' => idx($tab, 'href'), 'class' => ($name == $this->selectedTab) ? 'phabricator-selected-tab' : null, ), phutil_escape_html(idx($tab, 'name'))); } $tabs = implode('', $tabs); if ($tabs) { $tabs = ''.$tabs.''; } $login_stuff = null; $request = $this->getRequest(); if ($request) { $user = $request->getUser(); if ($user->getPHID()) { $login_stuff = 'Logged in as '.phutil_escape_html($user->getUsername()). ' · '. 'Settings'. ' · '. '
'. phutil_render_tag( 'input', array( 'type' => 'hidden', 'name' => '__csrf__', 'value' => $user->getCSRFToken(), )). phutil_render_tag( 'input', array( 'type' => 'hidden', 'name' => '__form__', 'value' => true, )). ''. '
'; } } + + $foot_links = array(); + + $version = PhabricatorEnv::getEnvConfig('phabricator.version'); + $foot_links[] = phutil_escape_html('Phabricator '.$version); + + if (PhabricatorEnv::getEnvConfig('darkconsole.enabled') && + !PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { + if ($console) { + $link = javelin_render_tag( + 'a', + array( + 'href' => '/~/', + 'sigil' => 'workflow', + ), + 'Disable DarkConsole'); + } else { + $link = javelin_render_tag( + 'a', + array( + 'href' => '/~/', + 'sigil' => 'workflow', + ), + 'Enable DarkConsole'); + } + $foot_links[] = $link; + } + $foot_links = implode(' · ', $foot_links); + return ($console ? '' : null). '
'. '
'. ''. 'Phabricator '. phutil_render_tag( 'a', array( 'href' => $this->getBaseURI(), 'class' => 'phabricator-head-appname', ), phutil_escape_html($this->getApplicationName())). $tabs. '
'. $this->bodyContent. '
'. + '
'. + '
'. + $foot_links. '
'; } protected function getTail() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('js'). $response->renderHTMLFooter(); } } diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index befde48900..c525693278 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -1,51 +1,58 @@ /** * @provides phabricator-standard-page-view */ .phabricator-standard-page { background: #ffffff; border-bottom: 1px solid #888888; -webkit-box-shadow: 0 0 6px #000; -mox-box-shadow: 0 0 6px #000; box-shadow: 0 0 6px #000; } .phabricator-standard-header { background: #003366; color: white; padding: 1em 1em 0.5em 1em; overflow: hidden; position: relative; } .phabricator-standard-header a { color: white; } .phabricator-standard-header .phabricator-head-tabs { padding: 0 1em; font-size: 13px; font-weight: bold; } .phabricator-standard-header .phabricator-head-tabs a { border-bottom: 3px solid transparent; padding: 0.5em 0.75em; position: relative; bottom: 2px; } .phabricator-standard-header .phabricator-head-tabs a.phabricator-selected-tab { border-bottom-color: #cccccc; } .phabricator-standard-header .phabricator-head-appname { padding: 0 1em; text-transform: uppercase; } .phabricator-login-details { float: right; } + +.phabricator-page-foot { + text-align: right; + padding: .5em 1em; + font-size: 11px; + color: #f3f3f3; +} \ No newline at end of file diff --git a/webroot/rsrc/css/core/core.css b/webroot/rsrc/css/core/core.css index bc6836e779..bb11ad23d0 100644 --- a/webroot/rsrc/css/core/core.css +++ b/webroot/rsrc/css/core/core.css @@ -1,107 +1,107 @@ /** * @provides phabricator-core-css */ html { overflow-y: scroll; } body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, p, blockquote, th, td, button { margin: 0; padding: 0; outline: 0; border: 0; } html { - padding-bottom: 16em; + padding-bottom: 4em; } table { border-collapse: collapse; border-spacing: 0; } fieldset, img { border: 0; } address, caption, cite, code, dfn, th, var { font-style: normal; font-weight: normal; } ol, ul { list-style: none; } caption, th { text-align: left; } td, th { vertical-align: top; } h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: bold; } body { font: 13px/1.231 'lucida grande', tahoma, verdana, arial, sans-serif; background: #ACACAC; direction: ltr; text-align: left; unicode-bidi: embed; *font-size: small; } select, input, button, textarea, button { font: 99% 'lucida grande', tahoma, verdana, arial, clean, sans-serif; } select { /* NOTE: In Safari, specifying a border color makes the browser respect "font-size" settings. */ border: 1px solid #999999; } table { font-size: inherit; font: 100%; } h1 { font-size: 16px; } h2 { font-size: 14px; } a { -moz-outline-style: none; text-decoration: none; cursor: pointer; } a:visited { color: #3b5998; } a:link { color: #3b5998; } a:hover { text-decoration: underline; } img { display: block; } diff --git a/webroot/rsrc/js/application/core/behavior-workflow.js b/webroot/rsrc/js/application/core/behavior-workflow.js new file mode 100644 index 0000000000..de6fe9b9df --- /dev/null +++ b/webroot/rsrc/js/application/core/behavior-workflow.js @@ -0,0 +1,33 @@ +/** + * @provides javelin-behavior-workflow + * @requires javelin-lib-dev + */ + +JX.behavior('workflow', function() { + JX.Stratcom.listen( + 'submit', + ['workflow', 'tag:form'], + function(e) { + if (JX.Stratcom.pass()) { + return; + } + if (e.getNode('workflow') !== e.getTarget()) { + return; + } + e.prevent(); + JX.Workflow.newFromForm(e.getTarget()).start(); + }); + JX.Stratcom.listen( + 'click', + ['workflow', 'tag:a'], + function(e) { + if (JX.Stratcom.pass()) { + return; + } + if (e.getNode('workflow') !== e.getTarget()) { + return; + } + e.prevent(); + JX.Workflow.newFromLink(e.getTarget()).start(); + }); +});