From ab4355cde0f8913b9e12be345f813f5ba7e0e468 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sat, 21 Jan 2017 08:11:19 -0800 Subject: [PATCH] (stable) Move Favorites and User menus to MenuBarExtensions Summary: Ref T12140. The major effect of this change is that uninstalling "Home" (as we do on admin.phacility.com) no longer uninstalls the user menu (which is required to access settings or log out). This also simplifies the code a bit, by consolidating how menus are built into MenuBarExtensions instead of some in Applications and some in Extensions. Test Plan: - While logged in and logged out, saw main menus in the correct order. - Uninstalled Favorites, saw the menu vanish. - Uninstalled Home, still had a user menu. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12140 Differential Revision: https://secure.phabricator.com/D17239 --- src/__phutil_library_map__.php | 4 + .../PhabricatorAuthMainMenuBarExtension.php | 4 + .../base/PhabricatorApplication.php | 17 --- .../PhabricatorFavoritesApplication.php | 78 ------------ ...abricatorFavoritesMainMenuBarExtension.php | 96 +++++++++++++++ .../PhabricatorHomeApplication.php | 110 ----------------- .../PeopleMainMenuBarExtension.php | 116 ++++++++++++++++++ .../menu/PhabricatorMainMenuBarExtension.php | 5 + .../page/menu/PhabricatorMainMenuView.php | 21 +--- 9 files changed, 231 insertions(+), 220 deletions(-) create mode 100644 src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php create mode 100644 src/applications/people/engineextension/PeopleMainMenuBarExtension.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index c828c6b04e..7ce9b1c72d 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1785,6 +1785,7 @@ phutil_register_library_map(array( 'PeopleBrowseUserDirectoryCapability' => 'applications/people/capability/PeopleBrowseUserDirectoryCapability.php', 'PeopleCreateUsersCapability' => 'applications/people/capability/PeopleCreateUsersCapability.php', 'PeopleHovercardEngineExtension' => 'applications/people/engineextension/PeopleHovercardEngineExtension.php', + 'PeopleMainMenuBarExtension' => 'applications/people/engineextension/PeopleMainMenuBarExtension.php', 'PeopleUserLogGarbageCollector' => 'applications/people/garbagecollector/PeopleUserLogGarbageCollector.php', 'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php', 'PhabricatorAWSConfigOptions' => 'applications/config/option/PhabricatorAWSConfigOptions.php', @@ -2671,6 +2672,7 @@ phutil_register_library_map(array( 'PhabricatorFavoritesApplication' => 'applications/favorites/application/PhabricatorFavoritesApplication.php', 'PhabricatorFavoritesController' => 'applications/favorites/controller/PhabricatorFavoritesController.php', 'PhabricatorFavoritesMainController' => 'applications/favorites/controller/PhabricatorFavoritesMainController.php', + 'PhabricatorFavoritesMainMenuBarExtension' => 'applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php', 'PhabricatorFavoritesMenuItemController' => 'applications/favorites/controller/PhabricatorFavoritesMenuItemController.php', 'PhabricatorFavoritesProfileMenuEngine' => 'applications/favorites/engine/PhabricatorFavoritesProfileMenuEngine.php', 'PhabricatorFaxContentSource' => 'infrastructure/contentsource/PhabricatorFaxContentSource.php', @@ -6662,6 +6664,7 @@ phutil_register_library_map(array( 'PeopleBrowseUserDirectoryCapability' => 'PhabricatorPolicyCapability', 'PeopleCreateUsersCapability' => 'PhabricatorPolicyCapability', 'PeopleHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension', + 'PeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension', 'PeopleUserLogGarbageCollector' => 'PhabricatorGarbageCollector', 'Phabricator404Controller' => 'PhabricatorController', 'PhabricatorAWSConfigOptions' => 'PhabricatorApplicationConfigOptions', @@ -7685,6 +7688,7 @@ phutil_register_library_map(array( 'PhabricatorFavoritesApplication' => 'PhabricatorApplication', 'PhabricatorFavoritesController' => 'PhabricatorController', 'PhabricatorFavoritesMainController' => 'PhabricatorFavoritesController', + 'PhabricatorFavoritesMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension', 'PhabricatorFavoritesMenuItemController' => 'PhabricatorFavoritesController', 'PhabricatorFavoritesProfileMenuEngine' => 'PhabricatorProfileMenuEngine', 'PhabricatorFaxContentSource' => 'PhabricatorContentSource', diff --git a/src/applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php b/src/applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php index 2757bec91c..d9d251ab07 100644 --- a/src/applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php +++ b/src/applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php @@ -9,6 +9,10 @@ final class PhabricatorAuthMainMenuBarExtension return true; } + public function getExtensionOrder() { + return 900; + } + public function buildMainMenus() { $viewer = $this->getViewer(); diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index e50045b0e9..63ab9d2315 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -315,23 +315,6 @@ abstract class PhabricatorApplication } - /** - * Build extra items for the main menu. Generally, this is used to render - * static dropdowns. - * - * @param PhabricatorUser The viewing user. - * @param AphrontController The current controller. May be null for special - * pages like 404, exception handlers, etc. - * @return view List of menu items. - * @task ui - */ - public function buildMainMenuExtraNodes( - PhabricatorUser $viewer, - PhabricatorController $controller = null) { - return array(); - } - - /* -( Application Management )--------------------------------------------- */ diff --git a/src/applications/favorites/application/PhabricatorFavoritesApplication.php b/src/applications/favorites/application/PhabricatorFavoritesApplication.php index 958355a2b5..1d5d3ae2aa 100644 --- a/src/applications/favorites/application/PhabricatorFavoritesApplication.php +++ b/src/applications/favorites/application/PhabricatorFavoritesApplication.php @@ -32,82 +32,4 @@ final class PhabricatorFavoritesApplication extends PhabricatorApplication { return false; } - public function buildMainMenuExtraNodes( - PhabricatorUser $viewer, - PhabricatorController $controller = null) { - - $dropdown = $this->renderFavoritesDropdown($viewer); - if (!$dropdown) { - return null; - } - - return id(new PHUIButtonView()) - ->setTag('a') - ->setHref('#') - ->setIcon('fa-star') - ->addClass('phabricator-core-user-menu') - ->setNoCSS(true) - ->setDropdown(true) - ->setDropdownMenu($dropdown); - } - - private function renderFavoritesDropdown(PhabricatorUser $viewer) { - $application = __CLASS__; - - $applications = id(new PhabricatorApplicationQuery()) - ->setViewer($viewer) - ->withClasses(array($application)) - ->withInstalled(true) - ->execute(); - $favorites = head($applications); - if (!$favorites) { - return null; - } - - $menu_engine = id(new PhabricatorFavoritesProfileMenuEngine()) - ->setViewer($viewer) - ->setProfileObject($favorites); - - if ($viewer->getPHID()) { - $menu_engine - ->setCustomPHID($viewer->getPHID()) - ->setMenuType(PhabricatorProfileMenuEngine::MENU_COMBINED); - } else { - $menu_engine - ->setMenuType(PhabricatorProfileMenuEngine::MENU_GLOBAL); - } - - $filter_view = $menu_engine->buildNavigation(); - - $menu_view = $filter_view->getMenu(); - $item_views = $menu_view->getItems(); - - $view = id(new PhabricatorActionListView()) - ->setViewer($viewer); - foreach ($item_views as $item) { - $type = null; - if (!strlen($item->getName())) { - $type = PhabricatorActionView::TYPE_DIVIDER; - } - $action = id(new PhabricatorActionView()) - ->setName($item->getName()) - ->setHref($item->getHref()) - ->setType($type); - $view->addAction($action); - } - - // Build out edit interface - if ($viewer->isLoggedIn()) { - $view->addAction( - id(new PhabricatorActionView()) - ->setType(PhabricatorActionView::TYPE_DIVIDER)); - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Edit Favorites')) - ->setHref('/favorites/')); - } - - return $view; - } - } diff --git a/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php b/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php new file mode 100644 index 0000000000..990ecad993 --- /dev/null +++ b/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php @@ -0,0 +1,96 @@ +getViewer(); + + $dropdown = $this->newDropdown($viewer); + if (!$dropdown) { + return null; + } + + $favorites_menu = id(new PHUIButtonView()) + ->setTag('a') + ->setHref('#') + ->setIcon('fa-star') + ->addClass('phabricator-core-user-menu') + ->setNoCSS(true) + ->setDropdown(true) + ->setDropdownMenu($dropdown); + + return array( + $favorites_menu, + ); + } + + private function newDropdown(PhabricatorUser $viewer) { + $applications = id(new PhabricatorApplicationQuery()) + ->setViewer($viewer) + ->withClasses(array('PhabricatorFavoritesApplication')) + ->withInstalled(true) + ->execute(); + $favorites = head($applications); + if (!$favorites) { + return null; + } + + $menu_engine = id(new PhabricatorFavoritesProfileMenuEngine()) + ->setViewer($viewer) + ->setProfileObject($favorites); + + if ($viewer->getPHID()) { + $menu_engine + ->setCustomPHID($viewer->getPHID()) + ->setMenuType(PhabricatorProfileMenuEngine::MENU_COMBINED); + } else { + $menu_engine + ->setMenuType(PhabricatorProfileMenuEngine::MENU_GLOBAL); + } + + $filter_view = $menu_engine->buildNavigation(); + + $menu_view = $filter_view->getMenu(); + $item_views = $menu_view->getItems(); + + $view = id(new PhabricatorActionListView()) + ->setViewer($viewer); + foreach ($item_views as $item) { + $type = null; + if (!strlen($item->getName())) { + $type = PhabricatorActionView::TYPE_DIVIDER; + } + $action = id(new PhabricatorActionView()) + ->setName($item->getName()) + ->setHref($item->getHref()) + ->setType($type); + $view->addAction($action); + } + + if ($viewer->isLoggedIn()) { + $view->addAction( + id(new PhabricatorActionView()) + ->setType(PhabricatorActionView::TYPE_DIVIDER)); + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Edit Favorites')) + ->setHref('/favorites/')); + } + + return $view; + } + +} diff --git a/src/applications/home/application/PhabricatorHomeApplication.php b/src/applications/home/application/PhabricatorHomeApplication.php index 20858e4931..a860bc8fb3 100644 --- a/src/applications/home/application/PhabricatorHomeApplication.php +++ b/src/applications/home/application/PhabricatorHomeApplication.php @@ -42,114 +42,4 @@ final class PhabricatorHomeApplication extends PhabricatorApplication { return 9; } - public function buildMainMenuExtraNodes( - PhabricatorUser $viewer, - PhabricatorController $controller = null) { - - if (!$viewer->isLoggedIn()) { - return; - } - - $image = $viewer->getProfileImageURI(); - - $profile_image = id(new PHUIIconView()) - ->setImage($image) - ->setHeadSize(PHUIIconView::HEAD_SMALL); - - if ($controller) { - $application = $controller->getCurrentApplication(); - } else { - $application = null; - } - $dropdown_menu = $this->renderUserDropdown($viewer, $application); - - $menu_id = celerity_generate_unique_node_id(); - - Javelin::initBehavior( - 'user-menu', - array( - 'menuID' => $menu_id, - 'menu' => $dropdown_menu->getDropdownMenuMetadata(), - )); - - return id(new PHUIButtonView()) - ->setID($menu_id) - ->setTag('a') - ->setHref('/p/'.$viewer->getUsername().'/') - ->setIcon($profile_image) - ->addClass('phabricator-core-user-menu') - ->setHasCaret(true) - ->setNoCSS(true); - } - - private function renderUserDropdown( - PhabricatorUser $viewer, - $application) { - - $person_to_show = id(new PHUIObjectItemView()) - ->setObjectName($viewer->getRealName()) - ->setSubHead($viewer->getUsername()) - ->setImageURI($viewer->getProfileImageURI()); - - $user_view = id(new PHUIObjectItemListView()) - ->setViewer($viewer) - ->setFlush(true) - ->setSimple(true) - ->addItem($person_to_show) - ->addClass('phabricator-core-user-profile-object'); - - $view = id(new PhabricatorActionListView()) - ->setViewer($viewer); - - // User Menu - $view->addAction( - id(new PhabricatorActionView()) - ->appendChild($user_view)); - - $view->addAction( - id(new PhabricatorActionView()) - ->setType(PhabricatorActionView::TYPE_DIVIDER)); - - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Profile')) - ->setHref('/p/'.$viewer->getUsername().'/')); - - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Settings')) - ->setHref('/settings/user/'.$viewer->getUsername().'/')); - - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Manage')) - ->setHref('/people/manage/'.$viewer->getID().'/')); - - // Help Menus - if ($application) { - $help_links = $application->getHelpMenuItems($viewer); - if ($help_links) { - foreach ($help_links as $link) { - $view->addAction($link); - } - } - } - - // Logout Menu - $view->addAction( - id(new PhabricatorActionView()) - ->addSigil('logout-item') - ->setType(PhabricatorActionView::TYPE_DIVIDER)); - - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Log Out %s', $viewer->getUsername())) - ->addSigil('logout-item') - ->setHref('/logout/') - ->setColor(PhabricatorActionView::RED) - ->setWorkflow(true)); - - return $view; - } - } diff --git a/src/applications/people/engineextension/PeopleMainMenuBarExtension.php b/src/applications/people/engineextension/PeopleMainMenuBarExtension.php new file mode 100644 index 0000000000..cd1cffa7a2 --- /dev/null +++ b/src/applications/people/engineextension/PeopleMainMenuBarExtension.php @@ -0,0 +1,116 @@ +isLoggedIn(); + } + + public function getExtensionOrder() { + return 1200; + } + + public function buildMainMenus() { + $viewer = $this->getViewer(); + $application = $this->getApplication(); + $dropdown_menu = $this->newDropdown($viewer, $application); + + $menu_id = celerity_generate_unique_node_id(); + + Javelin::initBehavior( + 'user-menu', + array( + 'menuID' => $menu_id, + 'menu' => $dropdown_menu->getDropdownMenuMetadata(), + )); + + $image = $viewer->getProfileImageURI(); + $profile_image = id(new PHUIIconView()) + ->setImage($image) + ->setHeadSize(PHUIIconView::HEAD_SMALL); + + $user_menu = id(new PHUIButtonView()) + ->setID($menu_id) + ->setTag('a') + ->setHref('/p/'.$viewer->getUsername().'/') + ->setIcon($profile_image) + ->addClass('phabricator-core-user-menu') + ->setHasCaret(true) + ->setNoCSS(true); + + return array( + $user_menu, + ); + } + + private function newDropdown( + PhabricatorUser $viewer, + $application) { + + $person_to_show = id(new PHUIObjectItemView()) + ->setObjectName($viewer->getRealName()) + ->setSubHead($viewer->getUsername()) + ->setImageURI($viewer->getProfileImageURI()); + + $user_view = id(new PHUIObjectItemListView()) + ->setViewer($viewer) + ->setFlush(true) + ->setSimple(true) + ->addItem($person_to_show) + ->addClass('phabricator-core-user-profile-object'); + + $view = id(new PhabricatorActionListView()) + ->setViewer($viewer); + + $view->addAction( + id(new PhabricatorActionView()) + ->appendChild($user_view)); + + $view->addAction( + id(new PhabricatorActionView()) + ->setType(PhabricatorActionView::TYPE_DIVIDER)); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Profile')) + ->setHref('/p/'.$viewer->getUsername().'/')); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Settings')) + ->setHref('/settings/user/'.$viewer->getUsername().'/')); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Manage')) + ->setHref('/people/manage/'.$viewer->getID().'/')); + + if ($application) { + $help_links = $application->getHelpMenuItems($viewer); + if ($help_links) { + foreach ($help_links as $link) { + $view->addAction($link); + } + } + } + + $view->addAction( + id(new PhabricatorActionView()) + ->addSigil('logout-item') + ->setType(PhabricatorActionView::TYPE_DIVIDER)); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Log Out %s', $viewer->getUsername())) + ->addSigil('logout-item') + ->setHref('/logout/') + ->setColor(PhabricatorActionView::RED) + ->setWorkflow(true)); + + return $view; + } + +} diff --git a/src/view/page/menu/PhabricatorMainMenuBarExtension.php b/src/view/page/menu/PhabricatorMainMenuBarExtension.php index 8b863c835c..fede2fdb85 100644 --- a/src/view/page/menu/PhabricatorMainMenuBarExtension.php +++ b/src/view/page/menu/PhabricatorMainMenuBarExtension.php @@ -64,12 +64,17 @@ abstract class PhabricatorMainMenuBarExtension extends Phobject { return true; } + public function getExtensionOrder() { + return 1000; + } + abstract public function buildMainMenus(); final public static function getAllExtensions() { return id(new PhutilClassMapQuery()) ->setAncestorClass(__CLASS__) ->setUniqueMethod('getExtensionKey') + ->setSortMethod('getExtensionOrder') ->execute(); } diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php index 75071a9ee5..e923a5e348 100644 --- a/src/view/page/menu/PhabricatorMainMenuView.php +++ b/src/view/page/menu/PhabricatorMainMenuView.php @@ -82,20 +82,6 @@ final class PhabricatorMainMenuView extends AphrontView { phutil_implode_html(' ', $aural)); } - // Build out Header Menus - $applications = PhabricatorApplication::getAllInstalledApplications(); - - $menus = array(); - $controller = $this->getController(); - foreach ($applications as $application) { - $app_extra = $application->buildMainMenuExtraNodes( - $viewer, - $controller); - if ($app_extra !== null) { - $menus[] = $app_extra; - } - } - $extensions = PhabricatorMainMenuBarExtension::getAllEnabledExtensions(); foreach ($extensions as $extension) { $extension->setViewer($viewer); @@ -116,13 +102,18 @@ final class PhabricatorMainMenuView extends AphrontView { } } - // Builds out "login" button + $menus = array(); foreach ($extensions as $extension) { foreach ($extension->buildMainMenus() as $menu) { $menus[] = $menu; } } + // Because we display these with "float: right", reverse their order before + // rendering them into the document so that the extension order and display + // order are the same. + $menus = array_reverse($menus); + foreach ($menus as $menu) { $menu_bar[] = $menu; }