Page MenuHomePhabricator

D20353.diff
No OneTemporary

D20353.diff

diff --git a/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php b/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php
--- a/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php
+++ b/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php
@@ -54,6 +54,11 @@
->setProfileObject($favorites)
->setCustomPHID($viewer->getPHID());
+ $controller = $this->getController();
+ if ($controller) {
+ $menu_engine->setController($controller);
+ }
+
$filter_view = $menu_engine->buildNavigation();
$menu_view = $filter_view->getMenu();
diff --git a/src/applications/home/controller/PhabricatorHomeController.php b/src/applications/home/controller/PhabricatorHomeController.php
--- a/src/applications/home/controller/PhabricatorHomeController.php
+++ b/src/applications/home/controller/PhabricatorHomeController.php
@@ -31,6 +31,7 @@
$engine = id(new PhabricatorHomeProfileMenuEngine())
->setViewer($viewer)
+ ->setController($this)
->setProfileObject($home)
->setCustomPHID($viewer->getPHID());
diff --git a/src/applications/project/controller/PhabricatorProjectBoardController.php b/src/applications/project/controller/PhabricatorProjectBoardController.php
--- a/src/applications/project/controller/PhabricatorProjectBoardController.php
+++ b/src/applications/project/controller/PhabricatorProjectBoardController.php
@@ -1,14 +1,4 @@
<?php
abstract class PhabricatorProjectBoardController
- extends PhabricatorProjectController {
-
- protected function getProfileMenu() {
- $menu = parent::getProfileMenu();
-
- $menu->selectFilter(PhabricatorProject::ITEM_WORKBOARD);
- $menu->addClass('project-board-nav');
-
- return $menu;
- }
-}
+ extends PhabricatorProjectController {}
diff --git a/src/applications/project/controller/PhabricatorProjectBoardViewController.php b/src/applications/project/controller/PhabricatorProjectBoardViewController.php
--- a/src/applications/project/controller/PhabricatorProjectBoardViewController.php
+++ b/src/applications/project/controller/PhabricatorProjectBoardViewController.php
@@ -172,8 +172,7 @@
return $content;
}
- $nav = $this->getProfileMenu();
- $nav->selectFilter(PhabricatorProject::ITEM_WORKBOARD);
+ $nav = $this->newWorkboardProfileMenu();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Workboard'));
@@ -720,7 +719,7 @@
->appendChild($board)
->addClass('project-board-wrapper');
- $nav = $this->getProfileMenu();
+ $nav = $this->newWorkboardProfileMenu();
$divider = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_DIVIDER);
@@ -1504,4 +1503,15 @@
->addCancelButton($profile_uri);
}
+ private function newWorkboardProfileMenu() {
+ $default_item = id(new PhabricatorProfileMenuItemConfiguration())
+ ->setBuiltinKey(PhabricatorProject::ITEM_WORKBOARD);
+
+ $menu = parent::getProfileMenu($default_item);
+
+ $menu->addClass('project-board-nav');
+
+ return $menu;
+ }
+
}
diff --git a/src/applications/project/controller/PhabricatorProjectController.php b/src/applications/project/controller/PhabricatorProjectController.php
--- a/src/applications/project/controller/PhabricatorProjectController.php
+++ b/src/applications/project/controller/PhabricatorProjectController.php
@@ -97,11 +97,11 @@
return $menu;
}
- protected function getProfileMenu() {
+ protected function getProfileMenu($default_item = null) {
if (!$this->profileMenu) {
$engine = $this->getProfileMenuEngine();
if ($engine) {
- $this->profileMenu = $engine->buildNavigation();
+ $this->profileMenu = $engine->buildNavigation($default_item);
}
}
diff --git a/src/applications/search/engine/PhabricatorProfileMenuEngine.php b/src/applications/search/engine/PhabricatorProfileMenuEngine.php
--- a/src/applications/search/engine/PhabricatorProfileMenuEngine.php
+++ b/src/applications/search/engine/PhabricatorProfileMenuEngine.php
@@ -183,7 +183,7 @@
break;
}
- $navigation = $this->buildNavigation();
+ $navigation = $this->buildNavigation($selected_item);
$crumbs = $controller->buildApplicationCrumbsForEditEngine();
@@ -223,8 +223,6 @@
switch ($item_action) {
case 'view':
if ($selected_item) {
- $navigation->selectFilter($selected_item->getDefaultMenuItemKey());
-
try {
$content = $this->buildItemViewContent($selected_item);
} catch (Exception $ex) {
@@ -335,7 +333,9 @@
return $page;
}
- public function buildNavigation() {
+ public function buildNavigation(
+ PhabricatorProfileMenuItemConfiguration $selected_item = null) {
+
if ($this->navigation) {
return $this->navigation;
}
@@ -398,6 +398,12 @@
$nav->selectFilter(null);
+ $navigation_items = $nav->getMenu()->getItems();
+ $select_key = $this->pickHighlightedMenuItem(
+ $navigation_items,
+ $selected_item);
+ $nav->selectFilter($select_key);
+
$this->navigation = $nav;
return $this->navigation;
}
@@ -1367,4 +1373,97 @@
return null;
}
+ private function pickHighlightedMenuItem(
+ array $items,
+ PhabricatorProfileMenuItemConfiguration $selected_item = null) {
+
+ assert_instances_of($items, 'PHUIListItemView');
+
+ $default_key = null;
+ if ($selected_item) {
+ $default_key = $selected_item->getDefaultMenuItemKey();
+ }
+
+ $controller = $this->getController();
+
+ // In some rare cases, when like building the "Favorites" menu on a
+ // 404 page, we may not have a controller. Just accept whatever default
+ // behavior we'd otherwise end up with.
+ if (!$controller) {
+ return $default_key;
+ }
+
+ $request = $controller->getRequest();
+
+ // See T12949. If one of the menu items is a link to the same URI that
+ // the page was accessed with, we want to highlight that item. For example,
+ // this allows you to add links to a menu that apply filters to a
+ // workboard.
+
+ $matches = array();
+ foreach ($items as $item) {
+ $href = $item->getHref();
+ if ($this->isMatchForRequestURI($request, $href)) {
+ $matches[] = $item;
+ }
+ }
+
+ foreach ($matches as $match) {
+ if ($match->getKey() === $default_key) {
+ return $default_key;
+ }
+ }
+
+ if ($matches) {
+ return head($matches)->getKey();
+ }
+
+ return $default_key;
+ }
+
+ private function isMatchForRequestURI(AphrontRequest $request, $item_uri) {
+ $request_uri = $request->getAbsoluteRequestURI();
+ $item_uri = new PhutilURI($item_uri);
+
+ // If the request URI and item URI don't have matching paths, they
+ // do not match.
+ if ($request_uri->getPath() !== $item_uri->getPath()) {
+ return false;
+ }
+
+ // If the request URI and item URI don't have matching parameters, they
+ // also do not match. We're specifically trying to let "?filter=X" work
+ // on Workboards, among other use cases, so this is important.
+ $request_params = $request_uri->getQueryParamsAsPairList();
+ $item_params = $item_uri->getQueryParamsAsPairList();
+ if ($request_params !== $item_params) {
+ return false;
+ }
+
+ // If the paths and parameters match, the item domain must be: empty; or
+ // match the request domain; or match the production domain.
+
+ $request_domain = $request_uri->getDomain();
+
+ $production_uri = PhabricatorEnv::getProductionURI('/');
+ $production_domain = id(new PhutilURI($production_uri))
+ ->getDomain();
+
+ $allowed_domains = array(
+ '',
+ $request_domain,
+ $production_domain,
+ );
+ $allowed_domains = array_fuse($allowed_domains);
+
+ $item_domain = $item_uri->getDomain();
+ $item_domain = (string)$item_domain;
+
+ if (isset($allowed_domains[$item_domain])) {
+ return true;
+ }
+
+ return false;
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 11, 12:38 PM (1 w, 5 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6730902
Default Alt Text
D20353.diff (7 KB)

Event Timeline