Changeset 6503
- Timestamp:
- 11/09/2012 04:28:30 PM (12 years ago)
- Location:
- trunk/bp-core
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/bp-core/bp-core-classes.php
r6493 r6503 1797 1797 } 1798 1798 } 1799 1800 /** 1801 * Create HTML list of BP nav items 1802 * 1803 * @since BuddyPress (1.7) 1804 */ 1805 class BP_Walker_Nav_Menu extends Walker_Nav_Menu { 1806 /** 1807 * @since BuddyPress (1.7) 1808 * @var array 1809 */ 1810 var $db_fields = array( 'id' => 'css_id', 'parent' => 'parent' ); 1811 1812 /** 1813 * @since BuddyPress (1.7) 1814 * @var string 1815 */ 1816 var $tree_type = array(); 1817 1818 /** 1819 * Display array of elements hierarchically. 1820 * 1821 * This method is almost identical to the version in {@link Walker::walk()}. The only change is on one line 1822 * which has been commented. An IF was comparing 0 to a non-empty string which was preventing child elements 1823 * being grouped under their parent menu element. 1824 * 1825 * This caused a problem for BuddyPress because our primary/secondary navigations doesn't have a unique numerical 1826 * ID that describes a hierarchy (we use a slug). Obviously, WordPress Menus use Posts, and those have ID/post_parent. 1827 * 1828 * @param array $elements 1829 * @param int $max_depth 1830 * @return string 1831 * @see Walker::walk() 1832 * @since BuddyPress (1.7) 1833 */ 1834 function walk( $elements, $max_depth ) { 1835 $args = array_slice( func_get_args(), 2 ); 1836 $output = ''; 1837 1838 if ( $max_depth < -1 ) // invalid parameter 1839 return $output; 1840 1841 if ( empty( $elements ) ) // nothing to walk 1842 return $output; 1843 1844 $id_field = $this->db_fields['id']; 1845 $parent_field = $this->db_fields['parent']; 1846 1847 // flat display 1848 if ( -1 == $max_depth ) { 1849 1850 $empty_array = array(); 1851 foreach ( $elements as $e ) 1852 $this->display_element( $e, $empty_array, 1, 0, $args, $output ); 1853 1854 return $output; 1855 } 1856 1857 /* 1858 * need to display in hierarchical order 1859 * separate elements into two buckets: top level and children elements 1860 * children_elements is two dimensional array, eg. 1861 * children_elements[10][] contains all sub-elements whose parent is 10. 1862 */ 1863 $top_level_elements = array(); 1864 $children_elements = array(); 1865 1866 foreach ( $elements as $e ) { 1867 // BuddyPress: changed '==' to '==='. This is the only change from version in Walker::walk(). 1868 if ( 0 === $e->$parent_field ) 1869 $top_level_elements[] = $e; 1870 else 1871 $children_elements[$e->$parent_field][] = $e; 1872 } 1873 1874 /* 1875 * when none of the elements is top level 1876 * assume the first one must be root of the sub elements 1877 */ 1878 if ( empty( $top_level_elements ) ) { 1879 1880 $first = array_slice( $elements, 0, 1 ); 1881 $root = $first[0]; 1882 $top_level_elements = array(); 1883 $children_elements = array(); 1884 1885 foreach ( $elements as $e ) { 1886 if ( $root->$parent_field == $e->$parent_field ) 1887 $top_level_elements[] = $e; 1888 else 1889 $children_elements[$e->$parent_field][] = $e; 1890 } 1891 } 1892 1893 foreach ( $top_level_elements as $e ) 1894 $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); 1895 1896 /* 1897 * if we are displaying all levels, and remaining children_elements is not empty, 1898 * then we got orphans, which should be displayed regardless 1899 */ 1900 if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) { 1901 $empty_array = array(); 1902 1903 foreach ( $children_elements as $orphans ) 1904 foreach ( $orphans as $op ) 1905 $this->display_element( $op, $empty_array, 1, 0, $args, $output ); 1906 } 1907 1908 return $output; 1909 } 1910 1911 /** 1912 * Displays the current <li> that we are on. 1913 * 1914 * @param string $output Passed by reference. Used to append additional content. 1915 * @param object $item Menu item data object. 1916 * @param int $depth Depth of menu item. Used for padding. Optional, defaults to 0. 1917 * @param array $args Optional 1918 * @param int $current_page Menu item ID. Optional. 1919 * @since BuddyPress (1.7) 1920 */ 1921 function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { 1922 // If we're someway down the tree, indent the HTML with the appropriate number of tabs 1923 $indent = $depth ? str_repeat( "\t", $depth ) : ''; 1924 1925 // Add HTML classes 1926 $class_names = join( ' ', apply_filters( 'bp_nav_menu_css_class', array_filter( $item->class ), $item, $args ) ); 1927 $class_names = ! empty( $class_names ) ? ' class="' . esc_attr( $class_names ) . '"' : ''; 1928 1929 // Add HTML ID 1930 $id = sanitize_html_class( $item->css_id . '-personal-li' ); // Backpat with BP pre-1.7 1931 $id = apply_filters( 'bp_nav_menu_item_id', $id, $item, $args ); 1932 $id = ! empty( $id ) ? ' id="' . esc_attr( $id ) . '"' : ''; 1933 1934 // Opening tag; closing tag is handled in Walker_Nav_Menu::end_el(). 1935 $output .= $indent . '<li' . $id . $class_names . '>'; 1936 1937 // Add href attribute 1938 $attributes = ! empty( $item->link ) ? ' href="' . esc_attr( esc_url( $item->link ) ) . '"' : ''; 1939 1940 // Construct the link 1941 $item_output = $args->before; 1942 $item_output .= '<a' . $attributes . '>'; 1943 $item_output .= $args->link_before . apply_filters( 'the_title', $item->name, 0 ) . $args->link_after; 1944 $item_output .= '</a>'; 1945 $item_output .= $args->after; 1946 1947 // $output is byref 1948 $output .= apply_filters( 'bp_walker_nav_menu_start_el', $item_output, $item, $depth, $args ); 1949 } 1950 } -
trunk/bp-core/bp-core-template.php
r6484 r6503 1743 1743 } 1744 1744 add_filter( 'body_class', 'bp_get_the_body_class', 10, 2 ); 1745 1746 /** 1747 * Sort BuddyPress nav menu items by their position property. 1748 * 1749 * This is an internal convenience function and it will probably be removed in a later release. Do not use. 1750 * 1751 * @access private 1752 * @param array $a First item 1753 * @param array $b Second item 1754 * @return int Returns an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second. 1755 * @since BuddyPress (1.7) 1756 */ 1757 function _bp_nav_menu_sort( $a, $b ) { 1758 if ( $a["position"] == $b["position"] ) 1759 return 0; 1760 1761 else if ( $a["position"] < $b["position"] ) 1762 return -1; 1763 1764 else 1765 return 1; 1766 } 1767 1768 /** 1769 * Get an array of all the items registered in the primary and secondary BuddyPress navigation menus 1770 * 1771 * @return array 1772 * @since BuddyPress (1.7) 1773 */ 1774 function bp_get_nav_menu_items() { 1775 $menus = $selected_menus = array(); 1776 1777 // Get the second level menus 1778 foreach ( (array) buddypress()->bp_options_nav as $parent_menu => $sub_menus ) { 1779 1780 // The root menu's ID is "xprofile", but the Profile submenus are using "profile". See BP_Core::setup_nav(). 1781 if ( 'profile' == $parent_menu ) 1782 $parent_menu = 'xprofile'; 1783 1784 // Sort the items in this menu's navigation by their position property 1785 $second_level_menus = (array) $sub_menus; 1786 usort( $second_level_menus, '_bp_nav_menu_sort' ); 1787 1788 // Iterate through the second level menus 1789 foreach( $second_level_menus as $sub_nav ) { 1790 1791 // Skip items we don't have access to 1792 if ( ! $sub_nav['user_has_access'] ) 1793 continue; 1794 1795 // Add this menu 1796 $menu = new stdClass; 1797 $menu->class = array(); 1798 $menu->css_id = $sub_nav['css_id']; 1799 $menu->link = $sub_nav['link']; 1800 $menu->name = $sub_nav['name']; 1801 $menu->parent = $parent_menu; // Associate this sub nav with a top-level menu 1802 1803 // If we're viewing this item's screen, record that we need to mark its parent menu to be selected 1804 if ( $sub_nav['slug'] == bp_current_action() ) { 1805 $menu->class = array( 'current-menu-item' ); 1806 $selected_menus[] = $parent_menu; 1807 } 1808 1809 $menus[] = $menu; 1810 } 1811 } 1812 1813 // Get the top-level menu parts (Friends, Groups, etc) and sort by their position property 1814 $top_level_menus = (array) buddypress()->bp_nav; 1815 usort( $top_level_menus, '_bp_nav_menu_sort' ); 1816 1817 // Iterate through the top-level menus 1818 foreach ( $top_level_menus as $nav ) { 1819 1820 // Skip items marked as user-specific if you're not on your own profile 1821 if ( ! $nav['show_for_displayed_user'] && ! bp_is_my_profile() ) 1822 continue; 1823 1824 // Get the correct menu link. See http://buddypress.trac.wordpress.org/ticket/4624 1825 $link = bp_loggedin_user_domain() ? str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $nav['link'] ) : trailingslashit( bp_displayed_user_domain() . $nav['link'] ); 1826 1827 // Add this menu 1828 $menu = new stdClass; 1829 $menu->class = array(); 1830 $menu->css_id = $nav['css_id']; 1831 $menu->link = $link; 1832 $menu->name = $nav['name']; 1833 $menu->parent = 0; 1834 1835 // Check if we need to mark this menu as selected 1836 if ( in_array( $nav['css_id'], $selected_menus ) ) 1837 $menu->class = array( 'current-menu-parent' ); 1838 1839 $menus[] = $menu; 1840 } 1841 1842 return apply_filters( 'bp_get_nav_menu_items', $menus ); 1843 } 1844 1845 /** 1846 * Displays a navigation menu. 1847 * 1848 * @param string|array $args Optional arguments: 1849 * before - Text before the link text. 1850 * container - Whether to wrap the ul, and what to wrap it with. Defaults to div. 1851 * container_class - The class that is applied to the container. Defaults to 'menu-bp-container'. 1852 * container_id - The ID that is applied to the container. Defaults to blank. 1853 * depth - How many levels of the hierarchy are to be included. 0 means all. Defaults to 0. 1854 * echo - Whether to echo the menu or return it. Defaults to echo. 1855 * fallback_cb - If the menu doesn't exists, a callback function will fire. Defaults to false (no fallback). 1856 * items_wrap - How the list items should be wrapped. Defaults to a ul with an id and class. Uses printf() format with numbered placeholders. 1857 * link_after - Text after the link. 1858 * link_before - Text before the link. 1859 * menu_class - CSS class to use for the ul element which forms the menu. Defaults to 'menu'. 1860 * menu_id - The ID that is applied to the ul element which forms the menu. Defaults to 'menu-bp', incremented. 1861 * walker - Allows a custom walker to be specified. Defaults to 'BP_Walker_Nav_Menu'. 1862 * @since BuddyPress (1.7) 1863 */ 1864 function bp_nav_menu( $args = array() ) { 1865 static $menu_id_slugs = array(); 1866 1867 $defaults = array( 1868 'after' => '', 1869 'before' => '', 1870 'container' => 'div', 1871 'container_class' => '', 1872 'container_id' => '', 1873 'depth' => 0, 1874 'echo' => true, 1875 'fallback_cb' => false, 1876 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 1877 'link_after' => '', 1878 'link_before' => '', 1879 'menu_class' => 'menu', 1880 'menu_id' => '', 1881 'walker' => '', 1882 ); 1883 $args = wp_parse_args( $args, $defaults ); 1884 $args = apply_filters( 'bp_nav_menu_args', $args ); 1885 $args = (object) $args; 1886 1887 $items = $nav_menu = ''; 1888 $show_container = false; 1889 1890 // Create custom walker if one wasn't set 1891 if ( empty( $args->walker ) ) 1892 $args->walker = new BP_Walker_Nav_Menu; 1893 1894 // Sanitise values for class and ID 1895 $args->container_class = sanitize_html_class( $args->container_class ); 1896 $args->container_id = sanitize_html_class( $args->container_id ); 1897 1898 // Whether to wrap the ul, and what to wrap it with 1899 if ( $args->container ) { 1900 $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav', ) ); 1901 1902 if ( in_array( $args->container, $allowed_tags ) ) { 1903 $show_container = true; 1904 1905 $class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-bp-container"'; 1906 $id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : ''; 1907 $nav_menu .= '<' . $args->container . $id . $class . '>'; 1908 } 1909 } 1910 1911 // Get the BuddyPress menu items 1912 $menu_items = apply_filters( 'bp_nav_menu_objects', bp_get_nav_menu_items(), $args ); 1913 $items = walk_nav_menu_tree( $menu_items, $args->depth, $args ); 1914 unset( $menu_items ); 1915 1916 // Set the ID that is applied to the ul element which forms the menu. 1917 if ( ! empty( $args->menu_id ) ) { 1918 $wrap_id = $args->menu_id; 1919 1920 } else { 1921 $wrap_id = 'menu-bp'; 1922 1923 // If a specific ID wasn't requested, and there are multiple menus on the same screen, make sure the autogenerated ID is unique 1924 while ( in_array( $wrap_id, $menu_id_slugs ) ) { 1925 if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) ) 1926 $wrap_id = preg_replace('#-(\d+)$#', '-' . ++$matches[1], $wrap_id ); 1927 else 1928 $wrap_id = $wrap_id . '-1'; 1929 } 1930 } 1931 $menu_id_slugs[] = $wrap_id; 1932 1933 // Allow plugins to hook into the menu to add their own <li>'s 1934 $items = apply_filters( 'bp_nav_menu_items', $items, $args ); 1935 1936 // Build the output 1937 $wrap_class = $args->menu_class ? $args->menu_class : ''; 1938 $nav_menu .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items ); 1939 unset( $items ); 1940 1941 // If we've wrapped the ul, close it 1942 if ( $show_container ) 1943 $nav_menu .= '</' . $args->container . '>'; 1944 1945 // Final chance to modify output 1946 $nav_menu = apply_filters( 'bp_nav_menu', $nav_menu, $args ); 1947 1948 if ( $args->echo ) 1949 echo $nav_menu; 1950 else 1951 return $nav_menu; 1952 }
Note: See TracChangeset
for help on using the changeset viewer.