diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index fdbd1d7539..22f7832780 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1500,6 +1500,7 @@ phutil_register_library_map(array( 'PHUIListItemView' => 'view/phui/PHUIListItemView.php', 'PHUIListView' => 'view/phui/PHUIListView.php', 'PHUIListViewTestCase' => 'view/layout/__tests__/PHUIListViewTestCase.php', + 'PHUIMainMenuView' => 'view/phui/PHUIMainMenuView.php', 'PHUIObjectBoxView' => 'view/phui/PHUIObjectBoxView.php', 'PHUIObjectItemListExample' => 'applications/uiexample/examples/PHUIObjectItemListExample.php', 'PHUIObjectItemListView' => 'view/phui/PHUIObjectItemListView.php', @@ -1722,6 +1723,7 @@ phutil_register_library_map(array( 'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php', 'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php', 'PhabricatorAuthLoginHandler' => 'applications/auth/handler/PhabricatorAuthLoginHandler.php', + 'PhabricatorAuthMainMenuBarExtension' => 'applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php', 'PhabricatorAuthManagementCachePKCS8Workflow' => 'applications/auth/management/PhabricatorAuthManagementCachePKCS8Workflow.php', 'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php', 'PhabricatorAuthManagementListFactorsWorkflow' => 'applications/auth/management/PhabricatorAuthManagementListFactorsWorkflow.php', @@ -2363,6 +2365,7 @@ phutil_register_library_map(array( 'PhabricatorHelpDocumentationController' => 'applications/help/controller/PhabricatorHelpDocumentationController.php', 'PhabricatorHelpEditorProtocolController' => 'applications/help/controller/PhabricatorHelpEditorProtocolController.php', 'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php', + 'PhabricatorHelpMainMenuBarExtension' => 'applications/help/extension/PhabricatorHelpMainMenuBarExtension.php', 'PhabricatorHeraldApplication' => 'applications/herald/application/PhabricatorHeraldApplication.php', 'PhabricatorHighSecurityRequestExceptionHandler' => 'aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php', 'PhabricatorHomeApplication' => 'applications/home/application/PhabricatorHomeApplication.php', @@ -2480,6 +2483,7 @@ phutil_register_library_map(array( 'PhabricatorMailSetupCheck' => 'applications/config/check/PhabricatorMailSetupCheck.php', 'PhabricatorMailTarget' => 'applications/metamta/replyhandler/PhabricatorMailTarget.php', 'PhabricatorMailgunConfigOptions' => 'applications/config/option/PhabricatorMailgunConfigOptions.php', + 'PhabricatorMainMenuBarExtension' => 'view/page/menu/PhabricatorMainMenuBarExtension.php', 'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php', 'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php', 'PhabricatorManagementWorkflow' => 'infrastructure/management/PhabricatorManagementWorkflow.php', @@ -2724,6 +2728,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleLogQuery' => 'applications/people/query/PhabricatorPeopleLogQuery.php', 'PhabricatorPeopleLogSearchEngine' => 'applications/people/query/PhabricatorPeopleLogSearchEngine.php', 'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php', + 'PhabricatorPeopleMainMenuBarExtension' => 'applications/people/extension/PhabricatorPeopleMainMenuBarExtension.php', 'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php', 'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php', 'PhabricatorPeopleOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php', @@ -3091,6 +3096,7 @@ phutil_register_library_map(array( 'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php', 'PhabricatorSettingsApplication' => 'applications/settings/application/PhabricatorSettingsApplication.php', 'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php', + 'PhabricatorSettingsMainMenuBarExtension' => 'applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php', 'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php', 'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php', 'PhabricatorSetupCheckTestCase' => 'applications/config/check/__tests__/PhabricatorSetupCheckTestCase.php', @@ -5615,6 +5621,7 @@ phutil_register_library_map(array( 'PHUIListItemView' => 'AphrontTagView', 'PHUIListView' => 'AphrontTagView', 'PHUIListViewTestCase' => 'PhabricatorTestCase', + 'PHUIMainMenuView' => 'AphrontView', 'PHUIObjectBoxView' => 'AphrontView', 'PHUIObjectItemListExample' => 'PhabricatorUIExample', 'PHUIObjectItemListView' => 'AphrontTagView', @@ -5863,6 +5870,7 @@ phutil_register_library_map(array( 'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController', 'PhabricatorAuthLoginController' => 'PhabricatorAuthController', 'PhabricatorAuthLoginHandler' => 'Phobject', + 'PhabricatorAuthMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension', 'PhabricatorAuthManagementCachePKCS8Workflow' => 'PhabricatorAuthManagementWorkflow', 'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow', 'PhabricatorAuthManagementListFactorsWorkflow' => 'PhabricatorAuthManagementWorkflow', @@ -6631,6 +6639,7 @@ phutil_register_library_map(array( 'PhabricatorHelpDocumentationController' => 'PhabricatorHelpController', 'PhabricatorHelpEditorProtocolController' => 'PhabricatorHelpController', 'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController', + 'PhabricatorHelpMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension', 'PhabricatorHeraldApplication' => 'PhabricatorApplication', 'PhabricatorHighSecurityRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 'PhabricatorHomeApplication' => 'PhabricatorApplication', @@ -6748,6 +6757,7 @@ phutil_register_library_map(array( 'PhabricatorMailSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorMailTarget' => 'Phobject', 'PhabricatorMailgunConfigOptions' => 'PhabricatorApplicationConfigOptions', + 'PhabricatorMainMenuBarExtension' => 'Phobject', 'PhabricatorMainMenuSearchView' => 'AphrontView', 'PhabricatorMainMenuView' => 'AphrontView', 'PhabricatorManagementWorkflow' => 'PhutilArgumentWorkflow', @@ -7037,6 +7047,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorPeopleLogSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController', + 'PhabricatorPeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension', 'PhabricatorPeopleNewController' => 'PhabricatorPeopleController', 'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorPeopleOwnerDatasource' => 'PhabricatorTypeaheadCompositeDatasource', @@ -7488,6 +7499,7 @@ phutil_register_library_map(array( 'PhabricatorSettingsAdjustController' => 'PhabricatorController', 'PhabricatorSettingsApplication' => 'PhabricatorApplication', 'PhabricatorSettingsMainController' => 'PhabricatorController', + 'PhabricatorSettingsMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension', 'PhabricatorSettingsPanel' => 'Phobject', 'PhabricatorSetupCheck' => 'Phobject', 'PhabricatorSetupCheckTestCase' => 'PhabricatorTestCase', diff --git a/src/applications/auth/application/PhabricatorAuthApplication.php b/src/applications/auth/application/PhabricatorAuthApplication.php index dfa1be6f75..a9831b20e3 100644 --- a/src/applications/auth/application/PhabricatorAuthApplication.php +++ b/src/applications/auth/application/PhabricatorAuthApplication.php @@ -38,48 +38,6 @@ final class PhabricatorAuthApplication extends PhabricatorApplication { return array(); } - public function buildMainMenuItems( - PhabricatorUser $user, - PhabricatorController $controller = null) { - - $items = array(); - - if ($user->isLoggedIn()) { - $item = id(new PHUIListItemView()) - ->addClass('core-menu-item') - ->setName(pht('Log Out')) - ->setIcon('fa-sign-out') - ->setWorkflow(true) - ->setHref('/logout/') - ->setSelected(($controller instanceof PhabricatorLogoutController)) - ->setAural(pht('Log Out')) - ->setOrder(900); - $items[] = $item; - } else { - if ($controller instanceof PhabricatorAuthController) { - // Don't show the "Login" item on auth controllers, since they're - // generally all related to logging in anyway. - } else { - $uri = new PhutilURI('/auth/start/'); - if ($controller) { - $path = $controller->getRequest()->getPath(); - $uri->setQueryParam('next', $path); - } - $item = id(new PHUIListItemView()) - ->addClass('core-menu-item') - ->setName(pht('Log In')) - // TODO: Login icon? - ->setIcon('fa-sign-in') - ->setHref($uri) - ->setAural(pht('Log In')) - ->setOrder(900); - $items[] = $item; - } - } - - return $items; - } - public function getApplicationGroup() { return self::GROUP_ADMIN; } diff --git a/src/applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php b/src/applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php new file mode 100644 index 0000000000..47264517e0 --- /dev/null +++ b/src/applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php @@ -0,0 +1,73 @@ +getViewer(); + + if ($viewer->isLoggedIn()) { + return array( + $this->buildLogoutMenu(), + ); + } + + $controller = $this->getController(); + if ($controller instanceof PhabricatorAuthController) { + // Don't show the "Login" item on auth controllers, since they're + // generally all related to logging in anyway. + return array(); + } + + return array( + $this->buildLoginMenu(), + ); + } + + private function buildLogoutMenu() { + $controller = $this->getController(); + + $is_selected = ($controller instanceof PhabricatorLogoutController); + + $bar_item = id(new PHUIListItemView()) + ->addClass('core-menu-item') + ->setName(pht('Log Out')) + ->setIcon('fa-sign-out') + ->setWorkflow(true) + ->setHref('/logout/') + ->setSelected($is_selected) + ->setAural(pht('Log Out')); + + return id(new PHUIMainMenuView()) + ->setOrder(900) + ->setMenuBarItem($bar_item); + } + + private function buildLoginMenu() { + $controller = $this->getController(); + + $uri = new PhutilURI('/auth/start/'); + if ($controller) { + $path = $controller->getRequest()->getPath(); + $uri->setQueryParam('next', $path); + } + + $bar_item = id(new PHUIListItemView()) + ->addClass('core-menu-item') + ->setName(pht('Log In')) + ->setIcon('fa-sign-in') + ->setHref($uri) + ->setAural(pht('Log In')); + + return id(new PHUIMainMenuView()) + ->setOrder(900) + ->setMenuBarItem($bar_item); + } + +} diff --git a/src/applications/help/application/PhabricatorHelpApplication.php b/src/applications/help/application/PhabricatorHelpApplication.php index b1f66b02cd..deeae7fa94 100644 --- a/src/applications/help/application/PhabricatorHelpApplication.php +++ b/src/applications/help/application/PhabricatorHelpApplication.php @@ -25,84 +25,4 @@ final class PhabricatorHelpApplication extends PhabricatorApplication { ); } - public function buildMainMenuItems( - PhabricatorUser $user, - PhabricatorController $controller = null) { - - $application = null; - if ($controller) { - $application = $controller->getCurrentApplication(); - } - - $items = array(); - - $help_id = celerity_generate_unique_node_id(); - - Javelin::initBehavior( - 'aphlict-dropdown', - array( - 'bubbleID' => $help_id, - 'dropdownID' => 'phabricator-help-menu', - 'applicationClass' => __CLASS__, - 'local' => true, - 'desktop' => true, - 'right' => true, - )); - - $item = id(new PHUIListItemView()) - ->setIcon('fa-life-ring') - ->addClass('core-menu-item') - ->setID($help_id) - ->setOrder(200); - - $hide = true; - if ($application) { - $help_name = pht('%s Help', $application->getName()); - $item - ->setName($help_name) - ->setHref('/help/documentation/'.get_class($application).'/') - ->setAural($help_name); - $help_items = $application->getHelpMenuItems($user); - if ($help_items) { - $hide = false; - } - } - if ($hide) { - $item->setStyle('display: none'); - } - $items[] = $item; - - return $items; - } - - public function buildMainMenuExtraNodes( - PhabricatorUser $viewer, - PhabricatorController $controller = null) { - - $application = null; - if ($controller) { - $application = $controller->getCurrentApplication(); - } - - $view = null; - if ($application) { - $help_items = $application->getHelpMenuItems($viewer); - if ($help_items) { - $view = new PHUIListView(); - foreach ($help_items as $item) { - $view->addMenuItem($item); - } - } - } - - return phutil_tag( - 'div', - array( - 'id' => 'phabricator-help-menu', - 'class' => 'phabricator-main-menu-dropdown phui-list-sidenav', - 'style' => 'display: none', - ), - $view); - } - } diff --git a/src/applications/help/extension/PhabricatorHelpMainMenuBarExtension.php b/src/applications/help/extension/PhabricatorHelpMainMenuBarExtension.php new file mode 100644 index 0000000000..f12714b5ac --- /dev/null +++ b/src/applications/help/extension/PhabricatorHelpMainMenuBarExtension.php @@ -0,0 +1,70 @@ +getApplication(); + if (!$application) { + return array(); + } + + $viewer = $this->getViewer(); + $help_links = $application->getHelpMenuItems($viewer); + if (!$help_links) { + return array(); + } + + $help_id = celerity_generate_unique_node_id(); + + Javelin::initBehavior( + 'aphlict-dropdown', + array( + 'bubbleID' => $help_id, + 'dropdownID' => 'phabricator-help-menu', + 'local' => true, + 'desktop' => true, + 'right' => true, + )); + + $help_name = pht('%s Help', $application->getName()); + + $help_item = id(new PHUIListItemView()) + ->setIcon('fa-life-ring') + ->addClass('core-menu-item') + ->setID($help_id) + ->setName($help_name) + ->setHref('/help/documentation/'.get_class($application).'/') + ->setAural($help_name); + + $view = new PHUIListView(); + foreach ($help_links as $help_link) { + $view->addMenuItem($help_link); + } + + $dropdown_menu = phutil_tag( + 'div', + array( + 'id' => 'phabricator-help-menu', + 'class' => 'phabricator-main-menu-dropdown phui-list-sidenav', + 'style' => 'display: none', + ), + $view); + + $help_menu = id(new PHUIMainMenuView()) + ->setOrder(200) + ->setMenuBarItem($help_item) + ->appendChild($dropdown_menu); + + return array( + $help_menu, + ); + } + +} diff --git a/src/applications/people/application/PhabricatorPeopleApplication.php b/src/applications/people/application/PhabricatorPeopleApplication.php index d1cb552e18..45599907c8 100644 --- a/src/applications/people/application/PhabricatorPeopleApplication.php +++ b/src/applications/people/application/PhabricatorPeopleApplication.php @@ -123,48 +123,6 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication { return $status; } - public function buildMainMenuItems( - PhabricatorUser $user, - PhabricatorController $controller = null) { - - $items = array(); - - if ($user->isLoggedIn() && $user->isUserActivated()) { - $profile = id(new PhabricatorPeopleQuery()) - ->setViewer($user) - ->needProfileImage(true) - ->withPHIDs(array($user->getPHID())) - ->executeOne(); - $image = $profile->getProfileImageURI(); - - $item = id(new PHUIListItemView()) - ->setName($user->getUsername()) - ->setHref('/p/'.$user->getUsername().'/') - ->addClass('core-menu-item') - ->setAural(pht('Profile')) - ->setOrder(100); - - $classes = array( - 'phabricator-core-menu-icon', - 'phabricator-core-menu-profile-image', - ); - - $item->appendChild( - phutil_tag( - 'span', - array( - 'class' => implode(' ', $classes), - 'style' => 'background-image: url('.$image.')', - ), - '')); - - $items[] = $item; - } - - return $items; - } - - public function getQuickCreateItems(PhabricatorUser $viewer) { $items = array(); diff --git a/src/applications/people/extension/PhabricatorPeopleMainMenuBarExtension.php b/src/applications/people/extension/PhabricatorPeopleMainMenuBarExtension.php new file mode 100644 index 0000000000..a92c5ba235 --- /dev/null +++ b/src/applications/people/extension/PhabricatorPeopleMainMenuBarExtension.php @@ -0,0 +1,49 @@ +getViewer(); + + // TODO: This should get cached. + + $profile = id(new PhabricatorPeopleQuery()) + ->setViewer($viewer) + ->needProfileImage(true) + ->withPHIDs(array($viewer->getPHID())) + ->executeOne(); + $image = $profile->getProfileImageURI(); + + $bar_item = id(new PHUIListItemView()) + ->setName($viewer->getUsername()) + ->setHref('/p/'.$viewer->getUsername().'/') + ->addClass('core-menu-item') + ->setAural(pht('Profile')); + + $classes = array( + 'phabricator-core-menu-icon', + 'phabricator-core-menu-profile-image', + ); + + $bar_item->appendChild( + phutil_tag( + 'span', + array( + 'class' => implode(' ', $classes), + 'style' => 'background-image: url('.$image.')', + ), + '')); + + $profile_menu = id(new PHUIMainMenuView()) + ->setOrder(100) + ->setMenuBarItem($bar_item); + + return array( + $profile_menu, + ); + } + +} diff --git a/src/applications/settings/application/PhabricatorSettingsApplication.php b/src/applications/settings/application/PhabricatorSettingsApplication.php index da0daf65d2..2608cabd88 100644 --- a/src/applications/settings/application/PhabricatorSettingsApplication.php +++ b/src/applications/settings/application/PhabricatorSettingsApplication.php @@ -40,26 +40,4 @@ final class PhabricatorSettingsApplication extends PhabricatorApplication { return self::GROUP_UTILITIES; } - public function buildMainMenuItems( - PhabricatorUser $user, - PhabricatorController $controller = null) { - - $items = array(); - - if ($user->isLoggedIn() && $user->isUserActivated()) { - $selected = ($controller instanceof PhabricatorSettingsMainController); - $item = id(new PHUIListItemView()) - ->setName(pht('Settings')) - ->setIcon('fa-wrench') - ->addClass('core-menu-item') - ->setSelected($selected) - ->setHref('/settings/') - ->setAural(pht('Settings')) - ->setOrder(400); - $items[] = $item; - } - - return $items; - } - } diff --git a/src/applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php b/src/applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php new file mode 100644 index 0000000000..21534c4237 --- /dev/null +++ b/src/applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php @@ -0,0 +1,29 @@ +getController(); + $is_selected = ($controller instanceof PhabricatorSettingsMainController); + + $bar_item = id(new PHUIListItemView()) + ->setName(pht('Settings')) + ->setIcon('fa-wrench') + ->addClass('core-menu-item') + ->setSelected($is_selected) + ->setHref('/settings/') + ->setAural(pht('Settings')); + + $settings_menu = id(new PHUIMainMenuView()) + ->setMenuBarItem($bar_item) + ->setOrder(400); + + return array( + $settings_menu, + ); + } + +} diff --git a/src/view/page/menu/PhabricatorMainMenuBarExtension.php b/src/view/page/menu/PhabricatorMainMenuBarExtension.php new file mode 100644 index 0000000000..8b863c835c --- /dev/null +++ b/src/view/page/menu/PhabricatorMainMenuBarExtension.php @@ -0,0 +1,88 @@ +viewer = $viewer; + return $this; + } + + public function getViewer() { + return $this->viewer; + } + + public function setApplication(PhabricatorApplication $application) { + $this->application = $application; + return $this; + } + + public function getApplication() { + return $this->application; + } + + public function setController(PhabricatorController $controller) { + $this->controller = $controller; + return $this; + } + + public function getController() { + return $this->controller; + } + + final public function getExtensionKey() { + return $this->getPhobjectClassConstant('MAINMENUBARKEY'); + } + + public function isExtensionEnabled() { + return true; + } + + public function isExtensionEnabledForViewer(PhabricatorUser $viewer) { + if (!$viewer->isLoggedIn()) { + return false; + } + + if (!$viewer->isUserActivated()) { + return false; + } + + // Don't show menus for users with partial sessions. This usually means + // they have logged in but have not made it through MFA, so we don't want + // to show notification counts, saved queries, etc. + if (!$viewer->hasSession()) { + return false; + } + + if ($viewer->getSession()->getIsPartial()) { + return false; + } + + return true; + } + + abstract public function buildMainMenus(); + + final public static function getAllExtensions() { + return id(new PhutilClassMapQuery()) + ->setAncestorClass(__CLASS__) + ->setUniqueMethod('getExtensionKey') + ->execute(); + } + + final public static function getAllEnabledExtensions() { + $extensions = self::getAllExtensions(); + + foreach ($extensions as $key => $extension) { + if (!$extension->isExtensionEnabled()) { + unset($extensions[$key]); + } + } + + return $extensions; + } + +} diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php index 1dc8466df3..54ba622f80 100644 --- a/src/view/page/menu/PhabricatorMainMenuView.php +++ b/src/view/page/menu/PhabricatorMainMenuView.php @@ -30,7 +30,7 @@ final class PhabricatorMainMenuView extends AphrontView { require_celerity_resource('sprite-main-header-css'); $header_id = celerity_generate_unique_node_id(); - $menus = array(); + $menu_bar = array(); $alerts = array(); $search_button = ''; $app_button = ''; @@ -41,7 +41,7 @@ final class PhabricatorMainMenuView extends AphrontView { if (array_filter($menu)) { $alerts[] = $menu; } - $menus = array_merge($menus, $dropdowns); + $menu_bar = array_merge($menu_bar, $dropdowns); $app_button = $this->renderApplicationMenuButton($header_id); $search_button = $this->renderSearchMenuButton($header_id); } else { @@ -73,13 +73,69 @@ final class PhabricatorMainMenuView extends AphrontView { } $applications = PhabricatorApplication::getAllInstalledApplications(); + + $menus = array(); + $controller = $this->getController(); foreach ($applications as $application) { - $menus[] = $application->buildMainMenuExtraNodes( + $app_actions = $application->buildMainMenuItems( $user, - $this->getController()); + $controller); + $app_extra = $application->buildMainMenuExtraNodes( + $user, + $controller); + + foreach ($app_actions as $action) { + $menus[] = id(new PHUIMainMenuView()) + ->setMenuBarItem($action) + ->setOrder($action->getOrder()); + } + + if ($app_extra !== null) { + $menus[] = id(new PHUIMainMenuView()) + ->appendChild($app_extra); + } } - $application_menu = $this->renderApplicationMenu(); + $extensions = PhabricatorMainMenuBarExtension::getAllEnabledExtensions(); + foreach ($extensions as $extension) { + $extension->setViewer($user); + + $controller = $this->getController(); + if ($controller) { + $extension->setController($controller); + $application = $controller->getCurrentApplication(); + if ($application) { + $extension->setApplication($application); + } + } + } + + foreach ($extensions as $key => $extension) { + if (!$extension->isExtensionEnabledForViewer($extension->getViewer())) { + unset($extensions[$key]); + } + } + + foreach ($extensions as $extension) { + foreach ($extension->buildMainMenus() as $menu) { + $menus[] = $menu; + } + } + + $menus = msort($menus, 'getOrder'); + $bar_items = array(); + foreach ($menus as $menu) { + $menu_bar[] = $menu; + + $item = $menu->getMenuBarItem(); + if ($item === null) { + continue; + } + + $bar_items[] = $item; + } + + $application_menu = $this->renderApplicationMenu($bar_items); $classes = array(); $classes[] = 'phabricator-main-menu sprite-main-header'; $classes[] = 'phabricator-main-menu-background'; @@ -98,7 +154,7 @@ final class PhabricatorMainMenuView extends AphrontView { $aural, $application_menu, $search_menu, - $menus, + $menu_bar, )); } @@ -174,21 +230,8 @@ final class PhabricatorMainMenuView extends AphrontView { '')); } - public function renderApplicationMenu() { + private function renderApplicationMenu(array $bar_items) { $user = $this->getUser(); - $controller = $this->getController(); - - $applications = PhabricatorApplication::getAllInstalledApplications(); - - $actions = array(); - foreach ($applications as $application) { - $app_actions = $application->buildMainMenuItems($user, $controller); - foreach ($app_actions as $action) { - $actions[] = $action; - } - } - - $actions = msort($actions, 'getOrder'); $view = $this->getApplicationMenu(); @@ -199,13 +242,13 @@ final class PhabricatorMainMenuView extends AphrontView { $view->addClass('phabricator-dark-menu'); $view->addClass('phabricator-application-menu'); - if ($actions) { + if ($bar_items) { $view->addMenuItem( id(new PHUIListItemView()) ->setType(PHUIListItemView::TYPE_LABEL) ->setName(pht('Actions'))); - foreach ($actions as $action) { - $view->addMenuItem($action); + foreach ($bar_items as $bar_item) { + $view->addMenuItem($bar_item); } } diff --git a/src/view/phui/PHUIMainMenuView.php b/src/view/phui/PHUIMainMenuView.php new file mode 100644 index 0000000000..7d5910dd7b --- /dev/null +++ b/src/view/phui/PHUIMainMenuView.php @@ -0,0 +1,31 @@ +menuItem = $menu_item; + return $this; + } + + public function getMenuBarItem() { + return $this->menuItem; + } + + public function setOrder($order) { + $this->order = $order; + return $this; + } + + public function getOrder() { + return $this->order; + } + + public function render() { + return $this->renderChildren(); + } + +}