diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 05bee37f02..4e18704b1e 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -540,13 +540,16 @@ phutil_register_library_map(array( 'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php', 'PhabricatorApplicationApplications' => 'applications/meta/application/PhabricatorApplicationApplications.php', 'PhabricatorApplicationAudit' => 'applications/audit/application/PhabricatorApplicationAudit.php', + 'PhabricatorApplicationAuth' => 'applications/auth/application/PhabricatorApplicationAuth.php', 'PhabricatorApplicationDifferential' => 'applications/differential/application/PhabricatorApplicationDifferential.php', 'PhabricatorApplicationDiffusion' => 'applications/diffusion/application/PhabricatorApplicationDiffusion.php', 'PhabricatorApplicationFact' => 'applications/fact/application/PhabricatorApplicationFact.php', 'PhabricatorApplicationFlags' => 'applications/flag/application/PhabricatorApplicationFlags.php', 'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php', 'PhabricatorApplicationManiphest' => 'applications/maniphest/application/PhabricatorApplicationManiphest.php', + 'PhabricatorApplicationPeople' => 'applications/people/application/PhabricatorApplicationPeople.php', 'PhabricatorApplicationPhriction' => 'applications/phriction/application/PhabricatorApplicationPhriction.php', + 'PhabricatorApplicationSettings' => 'applications/people/application/PhabricatorApplicationSettings.php', 'PhabricatorApplicationStatusView' => 'applications/meta/view/PhabricatorApplicationStatusView.php', 'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php', 'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php', @@ -1617,13 +1620,16 @@ phutil_register_library_map(array( 'Phabricator404Controller' => 'PhabricatorController', 'PhabricatorApplicationApplications' => 'PhabricatorApplication', 'PhabricatorApplicationAudit' => 'PhabricatorApplication', + 'PhabricatorApplicationAuth' => 'PhabricatorApplication', 'PhabricatorApplicationDifferential' => 'PhabricatorApplication', 'PhabricatorApplicationDiffusion' => 'PhabricatorApplication', 'PhabricatorApplicationFact' => 'PhabricatorApplication', 'PhabricatorApplicationFlags' => 'PhabricatorApplication', 'PhabricatorApplicationLaunchView' => 'AphrontView', 'PhabricatorApplicationManiphest' => 'PhabricatorApplication', + 'PhabricatorApplicationPeople' => 'PhabricatorApplication', 'PhabricatorApplicationPhriction' => 'PhabricatorApplication', + 'PhabricatorApplicationSettings' => 'PhabricatorApplication', 'PhabricatorApplicationStatusView' => 'AphrontView', 'PhabricatorApplicationsController' => 'PhabricatorController', 'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController', diff --git a/src/aphront/AphrontController.php b/src/aphront/AphrontController.php index c626e0e5b8..231a580667 100644 --- a/src/aphront/AphrontController.php +++ b/src/aphront/AphrontController.php @@ -32,6 +32,10 @@ abstract class AphrontController { return; } + public function didProcessRequest($response) { + return $response; + } + abstract public function processRequest(); final public function __construct(AphrontRequest $request) { diff --git a/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php index 459d5b9321..9108c1ed11 100644 --- a/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php @@ -67,15 +67,6 @@ class AphrontDefaultApplicationConfiguration '/phid/' => array( '' => 'PhabricatorPHIDLookupController', ), - '/people/' => array( - '' => 'PhabricatorPeopleListController', - 'logs/' => 'PhabricatorPeopleLogsController', - 'edit/(?:(?P\d+)/(?:(?P\w+)/)?)?' - => 'PhabricatorPeopleEditController', - 'ldap/' => 'PhabricatorPeopleLdapController', - ), - '/p/(?P[\w._-]+)/(?:(?P\w+)/)?' - => 'PhabricatorPeopleProfileController', '/conduit/' => array( '' => 'PhabricatorConduitListController', 'method/(?P[^/]+)/' => 'PhabricatorConduitConsoleController', @@ -152,10 +143,6 @@ class AphrontDefaultApplicationConfiguration '/~/' => 'DarkConsoleController', - '/settings/' => array( - '(?:page/(?P[^/]+)/)?' => 'PhabricatorUserSettingsController', - ), - '/repository/' => array( '' => 'PhabricatorRepositoryListController', 'create/' => 'PhabricatorRepositoryCreateController', @@ -486,35 +473,6 @@ class AphrontDefaultApplicationConfiguration } public function willSendResponse(AphrontResponse $response) { - $request = $this->getRequest(); - $response->setRequest($request); - 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(), - )); - } - } - return $response; } diff --git a/src/applications/auth/application/PhabricatorApplicationAuth.php b/src/applications/auth/application/PhabricatorApplicationAuth.php new file mode 100644 index 0000000000..e4c32594e8 --- /dev/null +++ b/src/applications/auth/application/PhabricatorApplicationAuth.php @@ -0,0 +1,45 @@ +isLoggedIn()) { + require_celerity_resource('phabricator-glyph-css'); + + $item = new PhabricatorMainMenuIconView(); + $item->setName(pht('Log Out')); + $item->addClass('glyph glyph-logout'); + $item->setHref('/logout/'); + $item->setSortOrder(1.0); + $items[] = $item; + } + + return $items; + } + +} diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 93ce67fa21..1419161e47 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -85,6 +85,12 @@ abstract class PhabricatorApplication { return array(); } + public function buildMainMenuItems( + PhabricatorUser $user, + PhabricatorController $controller) { + return array(); + } + /* -( Application Management )--------------------------------------------- */ diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php index ad0055f3aa..b0dcb07cc5 100644 --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -111,6 +111,7 @@ abstract class PhabricatorController extends AphrontController { public function buildStandardPageView() { $view = new PhabricatorStandardPageView(); $view->setRequest($this->getRequest()); + $view->setController($this); if ($this->shouldRequireAdmin()) { $view->setIsAdminInterface(true); @@ -127,4 +128,37 @@ abstract class PhabricatorController extends AphrontController { return $response; } + public function didProcessRequest($response) { + $request = $this->getRequest(); + $response->setRequest($request); + if ($response instanceof AphrontDialogResponse) { + if (!$request->isAjax()) { + $view = new PhabricatorStandardPageView(); + $view->setRequest($request); + $view->setController($this); + $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(), + )); + } + } + return $response; + } + } diff --git a/src/applications/people/application/PhabricatorApplicationPeople.php b/src/applications/people/application/PhabricatorApplicationPeople.php new file mode 100644 index 0000000000..7812da491c --- /dev/null +++ b/src/applications/people/application/PhabricatorApplicationPeople.php @@ -0,0 +1,66 @@ + array( + '' => 'PhabricatorPeopleListController', + 'logs/' => 'PhabricatorPeopleLogsController', + 'edit/(?:(?P\d+)/(?:(?P\w+)/)?)?' + => 'PhabricatorPeopleEditController', + 'ldap/' => 'PhabricatorPeopleLdapController', + ), + '/p/(?P[\w._-]+)/(?:(?P\w+)/)?' + => 'PhabricatorPeopleProfileController', + ); + } + + public function buildMainMenuItems( + PhabricatorUser $user, + PhabricatorController $controller) { + + $items = array(); + + if ($user->isLoggedIn()) { + require_celerity_resource('phabricator-glyph-css'); + $item = new PhabricatorMainMenuIconView(); + $item->setName($user->getUsername()); + $item->addClass('glyph glyph-profile'); + $item->setHref('/p/'.$user->getUsername().'/'); + $item->setSortOrder(0.0); + $items[] = $item; + } + + return $items; + } + +} diff --git a/src/applications/people/application/PhabricatorApplicationSettings.php b/src/applications/people/application/PhabricatorApplicationSettings.php new file mode 100644 index 0000000000..20fc3f55f6 --- /dev/null +++ b/src/applications/people/application/PhabricatorApplicationSettings.php @@ -0,0 +1,61 @@ + array( + '(?:page/(?P[^/]+)/)?' => 'PhabricatorUserSettingsController', + ), + ); + } + + public function buildMainMenuItems( + PhabricatorUser $user, + PhabricatorController $controller) { + + $items = array(); + + if ($user->isLoggedIn()) { + require_celerity_resource('phabricator-glyph-css'); + + $item = new PhabricatorMainMenuIconView(); + $item->setName(pht('Settings')); + $item->addClass('glyph glyph-settings'); + $item->setHref('/settings/'); + $item->setSortOrder(0.90); + $items[] = $item; + } + + return $items; + } + +} diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index bae1245bfd..43b995d859 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -32,6 +32,16 @@ final class PhabricatorStandardPageView extends AphrontPageView { private $disableConsole; private $searchDefaultScope; private $pageObjects = array(); + private $controller; + + public function setController(AphrontController $controller) { + $this->controller = $controller; + return $this; + } + + public function getController() { + return $this->controller; + } public function setIsAdminInterface($is_admin_interface) { $this->isAdminInterface = $is_admin_interface; @@ -505,27 +515,17 @@ final class PhabricatorStandardPageView extends AphrontPageView { Javelin::initBehavior('phabricator-keyboard-shortcuts', $keyboard_config); - if ($user->isLoggedIn()) { - require_celerity_resource('phabricator-glyph-css'); - - $item = new PhabricatorMainMenuIconView(); - $item->setName($user->getUsername()); - $item->addClass('glyph glyph-profile'); - $item->setHref('/p/'.$user->getUsername().'/'); - $menu->appendChild($item); - - $item = new PhabricatorMainMenuIconView(); - $item->setName(pht('Settings')); - $item->addClass('glyph glyph-settings'); - $item->setHref('/settings/'); - $menu->appendChild($item); - - $item = new PhabricatorMainMenuIconView(); - $item->setName(pht('Log Out')); - $item->addClass('glyph glyph-logout'); - $item->setHref('/logout/'); - $menu->appendChild($item); + $applications = PhabricatorApplication::getAllInstalledApplications(); + $icon_views = array(); + foreach ($applications as $application) { + $icon_views[] = $application->buildMainMenuItems( + $this->getRequest()->getUser(), + $this->getController()); } + $icon_views = array_mergev($icon_views); + $icon_views = msort($icon_views, 'getSortOrder'); + + $menu->appendChild($icon_views); return $menu->render(); } diff --git a/src/view/page/menu/PhabricatorMainMenuIconView.php b/src/view/page/menu/PhabricatorMainMenuIconView.php index 8df9fcb697..4a5f18423c 100644 --- a/src/view/page/menu/PhabricatorMainMenuIconView.php +++ b/src/view/page/menu/PhabricatorMainMenuIconView.php @@ -21,6 +21,7 @@ final class PhabricatorMainMenuIconView extends AphrontView { private $classes = array(); private $href; private $name; + private $sortOrder = 0.5; public function setName($name) { $this->name = $name; @@ -45,6 +46,21 @@ final class PhabricatorMainMenuIconView extends AphrontView { return $this; } + /** + * Provide a float, where 0.0 is the profile item and 1.0 is the logout + * item. Normally you should pick something between the two. + * + * @param float Sort order. + * @return this + */ + public function setSortOrder($sort_order) { + $this->sortOrder = $sort_order; + return $this; + } + + public function getSortOrder() { + return $this->sortOrder; + } public function render() { $name = $this->getName(); diff --git a/webroot/index.php b/webroot/index.php index 28edc5a2d3..0b0edf8bd8 100644 --- a/webroot/index.php +++ b/webroot/index.php @@ -192,6 +192,7 @@ try { if (!$response) { $controller->willProcessRequest($uri_data); $response = $controller->processRequest(); + $response = $controller->didProcessRequest($response); } } catch (AphrontRedirectException $ex) { $response = id(new AphrontRedirectResponse()) @@ -202,7 +203,7 @@ try { } try { - $response = $application->willSendResponse($response); + $response = $application->willSendResponse($response, $controller); $response->setRequest($request); $response_string = $response->buildResponseString(); } catch (Exception $ex) { diff --git a/webroot/rsrc/image/app/app_people.png b/webroot/rsrc/image/app/app_people.png new file mode 100755 index 0000000000..f494ec7f23 Binary files /dev/null and b/webroot/rsrc/image/app/app_people.png differ diff --git a/webroot/rsrc/image/app/app_settings.png b/webroot/rsrc/image/app/app_settings.png new file mode 100755 index 0000000000..eff562dbc4 Binary files /dev/null and b/webroot/rsrc/image/app/app_settings.png differ