setBaseURI($some_uri) * ->addLabel('Cats') * ->addFilter('meow', 'Meow') * ->addFilter('purr', 'Purr') * ->addLabel('Dogs') * ->addFilter('woof', 'Woof') * ->addFilter('bark', 'Bark'); * $valid_filter = $nav->selectFilter($user_selection, $default = 'meow'); * */ final class AphrontSideNavFilterView extends AphrontView { private $items = array(); private $baseURI; private $selectedFilter = false; private $flexible; private $collapsed = false; private $active; private $menu; private $crumbs; private $classes = array(); private $menuID; public function setMenuID($menu_id) { $this->menuID = $menu_id; return $this; } public function getMenuID() { return $this->menuID; } public function __construct() { $this->menu = new PHUIListView(); } public function addClass($class) { $this->classes[] = $class; return $this; } public static function newFromMenu(PHUIListView $menu) { $object = new AphrontSideNavFilterView(); $object->setBaseURI(new PhutilURI('/')); $object->menu = $menu; return $object; } public function setCrumbs(PhabricatorCrumbsView $crumbs) { $this->crumbs = $crumbs; return $this; } public function getCrumbs() { return $this->crumbs; } public function setActive($active) { $this->active = $active; return $this; } public function setFlexible($flexible) { $this->flexible = $flexible; return $this; } public function setCollapsed($collapsed) { $this->collapsed = $collapsed; return $this; } public function getMenuView() { return $this->menu; } public function addMenuItem(PHUIListItemView $item) { $this->menu->addMenuItem($item); return $this; } public function getMenu() { return $this->menu; } public function addFilter($key, $name, $uri = null) { return $this->addThing( $key, $name, $uri, PHUIListItemView::TYPE_LINK); } public function addButton($key, $name, $uri = null) { return $this->addThing( $key, $name, $uri, PHUIListItemView::TYPE_BUTTON); } private function addThing( $key, $name, $uri = null, $type) { $item = id(new PHUIListItemView()) ->setName($name) ->setType($type); if (strlen($key)) { $item->setKey($key); } if ($uri) { $item->setHref($uri); } else { $href = clone $this->baseURI; $href->setPath(rtrim($href->getPath().$key, '/').'/'); $href = (string)$href; $item->setHref($href); } return $this->addMenuItem($item); } public function addCustomBlock($block) { $this->menu->addMenuItem( id(new PHUIListItemView()) ->setType(PHUIListItemView::TYPE_CUSTOM) ->appendChild($block)); return $this; } public function addLabel($name) { return $this->addMenuItem( id(new PHUIListItemView()) ->setType(PHUIListItemView::TYPE_LABEL) ->setName($name)); } public function setBaseURI(PhutilURI $uri) { $this->baseURI = $uri; return $this; } public function getBaseURI() { return $this->baseURI; } public function selectFilter($key, $default = null) { $this->selectedFilter = $default; if ($this->menu->getItem($key) && strlen($key)) { $this->selectedFilter = $key; } return $this->selectedFilter; } public function getSelectedFilter() { return $this->selectedFilter; } public function render() { if ($this->menu->getItems()) { if (!$this->baseURI) { throw new Exception(pht('Call setBaseURI() before render()!')); } if ($this->selectedFilter === false) { throw new Exception(pht('Call selectFilter() before render()!')); } } if ($this->selectedFilter !== null) { $selected_item = $this->menu->getItem($this->selectedFilter); if ($selected_item) { $selected_item->addClass('phui-list-item-selected'); } } require_celerity_resource('phabricator-side-menu-view-css'); return $this->renderFlexNav(); } private function renderFlexNav() { $user = $this->user; require_celerity_resource('phabricator-nav-view-css'); $nav_classes = array(); $nav_classes[] = 'phabricator-nav'; $nav_id = null; $drag_id = null; $content_id = celerity_generate_unique_node_id(); $local_id = null; $background_id = null; $local_menu = null; $main_id = celerity_generate_unique_node_id(); if ($this->flexible) { $drag_id = celerity_generate_unique_node_id(); $flex_bar = phutil_tag( 'div', array( 'class' => 'phabricator-nav-drag', 'id' => $drag_id, ), ''); } else { $flex_bar = null; } $nav_menu = null; if ($this->menu->getItems()) { $local_id = celerity_generate_unique_node_id(); $background_id = celerity_generate_unique_node_id(); if (!$this->collapsed) { $nav_classes[] = 'has-local-nav'; } $menu_background = phutil_tag( 'div', array( 'class' => 'phabricator-nav-column-background', 'id' => $background_id, ), ''); $local_menu = array( $menu_background, phutil_tag( 'div', array( 'class' => 'phabricator-nav-local phabricator-side-menu', 'id' => $local_id, ), $this->menu->setID($this->getMenuID())), ); } $crumbs = null; if ($this->crumbs) { $crumbs = $this->crumbs->render(); $nav_classes[] = 'has-crumbs'; } if ($this->flexible) { if (!$this->collapsed) { $nav_classes[] = 'has-drag-nav'; } Javelin::initBehavior( 'phabricator-nav', array( 'mainID' => $main_id, 'localID' => $local_id, 'dragID' => $drag_id, 'contentID' => $content_id, 'backgroundID' => $background_id, 'collapsed' => $this->collapsed, )); if ($this->active) { Javelin::initBehavior( 'phabricator-active-nav', array( 'localID' => $local_id, )); } } $nav_classes = array_merge($nav_classes, $this->classes); return phutil_tag( 'div', array( 'class' => implode(' ', $nav_classes), 'id' => $main_id, ), array( $local_menu, $flex_bar, phutil_tag( 'div', array( 'class' => 'phabricator-nav-content mlb', 'id' => $content_id, ), array( $crumbs, $this->renderChildren(), )), )); } }