BP_Walker_Nav_Menu::do_walk( array $elements, int $max_depth, array $args = array() )

Display array of elements hierarchically.


Description Description

This method is almost identical to the version in Walker::walk(). The only change is on one line which has been commented. An IF was comparing 0 to a non-empty string which was preventing child elements being grouped under their parent menu element.

This caused a problem for BuddyPress because our primary/secondary navigations don’t have a unique numerical ID that describes a hierarchy (we use a slug). Obviously, WordPress Menus use Posts, and those have ID/post_parent.

See also See also


Top ↑

Parameters Parameters

$elements

(array) (Required) See Walker::walk().

$max_depth

(int) (Required) See Walker::walk().

$args

(array) (Optional) additional arguments.

Default value: array()


Top ↑

Return Return

(string) See Walker::walk().


Top ↑

Source Source

File: bp-core/classes/class-bp-walker-nav-menu.php

	public function do_walk( $elements, $max_depth, $args = array() ) {
		$output = '';

		if ( $max_depth < -1 ) // Invalid parameter.
			return $output;

		if ( empty( $elements ) ) // Nothing to walk.
			return $output;

		$parent_field = $this->db_fields['parent'];

		// Flat display.
		if ( -1 == $max_depth ) {

			$empty_array = array();
			foreach ( $elements as $e )
				$this->display_element( $e, $empty_array, 1, 0, $args, $output );

			return $output;
		}

		/*
		 * Need to display in hierarchical order
		 * separate elements into two buckets: top level and children elements
		 * children_elements is two dimensional array, eg.
		 * children_elements[10][] contains all sub-elements whose parent is 10.
		 */
		$top_level_elements = array();
		$children_elements  = array();

		foreach ( $elements as $e ) {
			// BuddyPress: changed '==' to '==='. This is the only change from version in Walker::walk().
			if ( 0 === $e->$parent_field )
				$top_level_elements[] = $e;
			else
				$children_elements[$e->$parent_field][] = $e;
		}

		/*
		 * When none of the elements is top level
		 * assume the first one must be root of the sub elements.
		 */
		if ( empty( $top_level_elements ) ) {

			$first              = array_slice( $elements, 0, 1 );
			$root               = $first[0];
			$top_level_elements = array();
			$children_elements  = array();

			foreach ( $elements as $e ) {
				if ( $root->$parent_field == $e->$parent_field )
					$top_level_elements[] = $e;
				else
					$children_elements[$e->$parent_field][] = $e;
			}
		}

		foreach ( $top_level_elements as $e )
			$this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );

		/*
		 * If we are displaying all levels, and remaining children_elements is not empty,
		 * then we got orphans, which should be displayed regardless.
		 */
		if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
			$empty_array = array();

			foreach ( $children_elements as $orphans )
				foreach ( $orphans as $op )
					$this->display_element( $op, $empty_array, 1, 0, $args, $output );
		 }

		 return $output;
	}


Top ↑

Changelog Changelog

Changelog
Version Description
5.1.0 Method was renamed from walk to do_walk to ensure PHP 5.3 compatibility
1.7.0 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

You must log in before being able to contribute a note or feedback.