wp/wp-includes/class-wp-walker.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
    14 class Walker {
    14 class Walker {
    15 	/**
    15 	/**
    16 	 * What the class handles.
    16 	 * What the class handles.
    17 	 *
    17 	 *
    18 	 * @since 2.1.0
    18 	 * @since 2.1.0
    19 	 * @access public
       
    20 	 * @var string
    19 	 * @var string
    21 	 */
    20 	 */
    22 	public $tree_type;
    21 	public $tree_type;
    23 
    22 
    24 	/**
    23 	/**
    54 	 * class methods. This method is called at the start of the output list.
    53 	 * class methods. This method is called at the start of the output list.
    55 	 *
    54 	 *
    56 	 * @since 2.1.0
    55 	 * @since 2.1.0
    57 	 * @abstract
    56 	 * @abstract
    58 	 *
    57 	 *
    59 	 * @param string $output Passed by reference. Used to append additional content.
    58 	 * @param string $output Used to append additional content (passed by reference).
    60 	 * @param int    $depth  Depth of the item.
    59 	 * @param int    $depth  Depth of the item.
    61 	 * @param array  $args   An array of additional arguments.
    60 	 * @param array  $args   An array of additional arguments.
    62 	 */
    61 	 */
    63 	public function start_lvl( &$output, $depth = 0, $args = array() ) {}
    62 	public function start_lvl( &$output, $depth = 0, $args = array() ) {}
    64 
    63 
    69 	 * class methods. This method finishes the list at the end of output of the elements.
    68 	 * class methods. This method finishes the list at the end of output of the elements.
    70 	 *
    69 	 *
    71 	 * @since 2.1.0
    70 	 * @since 2.1.0
    72 	 * @abstract
    71 	 * @abstract
    73 	 *
    72 	 *
    74 	 * @param string $output Passed by reference. Used to append additional content.
    73 	 * @param string $output Used to append additional content (passed by reference).
    75 	 * @param int    $depth  Depth of the item.
    74 	 * @param int    $depth  Depth of the item.
    76 	 * @param array  $args   An array of additional arguments.
    75 	 * @param array  $args   An array of additional arguments.
    77 	 */
    76 	 */
    78 	public function end_lvl( &$output, $depth = 0, $args = array() ) {}
    77 	public function end_lvl( &$output, $depth = 0, $args = array() ) {}
    79 
    78 
    84 	 * class methods. Includes the element output also.
    83 	 * class methods. Includes the element output also.
    85 	 *
    84 	 *
    86 	 * @since 2.1.0
    85 	 * @since 2.1.0
    87 	 * @abstract
    86 	 * @abstract
    88 	 *
    87 	 *
    89 	 * @param string $output            Passed by reference. Used to append additional content.
    88 	 * @param string $output            Used to append additional content (passed by reference).
    90 	 * @param object $object            The data object.
    89 	 * @param object $object            The data object.
    91 	 * @param int    $depth             Depth of the item.
    90 	 * @param int    $depth             Depth of the item.
    92 	 * @param array  $args              An array of additional arguments.
    91 	 * @param array  $args              An array of additional arguments.
    93 	 * @param int    $current_object_id ID of the current item.
    92 	 * @param int    $current_object_id ID of the current item.
    94 	 */
    93 	 */
   100 	 * The $args parameter holds additional values that may be used with the child class methods.
    99 	 * The $args parameter holds additional values that may be used with the child class methods.
   101 	 *
   100 	 *
   102 	 * @since 2.1.0
   101 	 * @since 2.1.0
   103 	 * @abstract
   102 	 * @abstract
   104 	 *
   103 	 *
   105 	 * @param string $output Passed by reference. Used to append additional content.
   104 	 * @param string $output Used to append additional content (passed by reference).
   106 	 * @param object $object The data object.
   105 	 * @param object $object The data object.
   107 	 * @param int    $depth  Depth of the item.
   106 	 * @param int    $depth  Depth of the item.
   108 	 * @param array  $args   An array of additional arguments.
   107 	 * @param array  $args   An array of additional arguments.
   109 	 */
   108 	 */
   110 	public function end_el( &$output, $object, $depth = 0, $args = array() ) {}
   109 	public function end_el( &$output, $object, $depth = 0, $args = array() ) {}
   120 	 * This method should not be called directly, use the walk() method instead.
   119 	 * This method should not be called directly, use the walk() method instead.
   121 	 *
   120 	 *
   122 	 * @since 2.5.0
   121 	 * @since 2.5.0
   123 	 *
   122 	 *
   124 	 * @param object $element           Data object.
   123 	 * @param object $element           Data object.
   125 	 * @param array  $children_elements List of elements to continue traversing.
   124 	 * @param array  $children_elements List of elements to continue traversing (passed by reference).
   126 	 * @param int    $max_depth         Max depth to traverse.
   125 	 * @param int    $max_depth         Max depth to traverse.
   127 	 * @param int    $depth             Depth of current element.
   126 	 * @param int    $depth             Depth of current element.
   128 	 * @param array  $args              An array of arguments.
   127 	 * @param array  $args              An array of arguments.
   129 	 * @param string $output            Passed by reference. Used to append additional content.
   128 	 * @param string $output            Used to append additional content (passed by reference).
   130 	 * @return null Null on failure with no changes to parameters.
       
   131 	 */
   129 	 */
   132 	public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
   130 	public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
   133 
   131 		if ( ! $element ) {
   134 		if ( !$element )
       
   135 			return;
   132 			return;
       
   133 		}
   136 
   134 
   137 		$id_field = $this->db_fields['id'];
   135 		$id_field = $this->db_fields['id'];
   138 		$id       = $element->$id_field;
   136 		$id       = $element->$id_field;
   139 
   137 
   140 		//display this element
   138 		//display this element
   141 		$this->has_children = ! empty( $children_elements[ $id ] );
   139 		$this->has_children = ! empty( $children_elements[ $id ] );
   142 		if ( isset( $args[0] ) && is_array( $args[0] ) ) {
   140 		if ( isset( $args[0] ) && is_array( $args[0] ) ) {
   143 			$args[0]['has_children'] = $this->has_children; // Backwards compatibility.
   141 			$args[0]['has_children'] = $this->has_children; // Back-compat.
   144 		}
   142 		}
   145 
   143 
   146 		$cb_args = array_merge( array(&$output, $element, $depth), $args);
   144 		$cb_args = array_merge( array(&$output, $element, $depth), $args);
   147 		call_user_func_array(array($this, 'start_el'), $cb_args);
   145 		call_user_func_array(array($this, 'start_el'), $cb_args);
   148 
   146 
   149 		// descend only when the depth is right and there are childrens for this element
   147 		// descend only when the depth is right and there are childrens for this element
   150 		if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) {
   148 		if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) {
   151 
   149 
   152 			foreach( $children_elements[ $id ] as $child ){
   150 			foreach ( $children_elements[ $id ] as $child ){
   153 
   151 
   154 				if ( !isset($newlevel) ) {
   152 				if ( !isset($newlevel) ) {
   155 					$newlevel = true;
   153 					$newlevel = true;
   156 					//start the child delimiter
   154 					//start the child delimiter
   157 					$cb_args = array_merge( array(&$output, $depth), $args);
   155 					$cb_args = array_merge( array(&$output, $depth), $args);
   186 	 *
   184 	 *
   187 	 * @param array $elements  An array of elements.
   185 	 * @param array $elements  An array of elements.
   188 	 * @param int   $max_depth The maximum hierarchical depth.
   186 	 * @param int   $max_depth The maximum hierarchical depth.
   189 	 * @return string The hierarchical item output.
   187 	 * @return string The hierarchical item output.
   190 	 */
   188 	 */
   191 	public function walk( $elements, $max_depth) {
   189 	public function walk( $elements, $max_depth ) {
   192 
       
   193 		$args = array_slice(func_get_args(), 2);
   190 		$args = array_slice(func_get_args(), 2);
   194 		$output = '';
   191 		$output = '';
   195 
   192 
   196 		if ($max_depth < -1) //invalid parameter
   193 		//invalid parameter or nothing to walk
       
   194 		if ( $max_depth < -1 || empty( $elements ) ) {
   197 			return $output;
   195 			return $output;
   198 
   196 		}
   199 		if (empty($elements)) //nothing to walk
       
   200 			return $output;
       
   201 
   197 
   202 		$parent_field = $this->db_fields['parent'];
   198 		$parent_field = $this->db_fields['parent'];
   203 
   199 
   204 		// flat display
   200 		// flat display
   205 		if ( -1 == $max_depth ) {
   201 		if ( -1 == $max_depth ) {
   216 		 * Children_elements[10][] contains all sub-elements whose parent is 10.
   212 		 * Children_elements[10][] contains all sub-elements whose parent is 10.
   217 		 */
   213 		 */
   218 		$top_level_elements = array();
   214 		$top_level_elements = array();
   219 		$children_elements  = array();
   215 		$children_elements  = array();
   220 		foreach ( $elements as $e) {
   216 		foreach ( $elements as $e) {
   221 			if ( 0 == $e->$parent_field )
   217 			if ( empty( $e->$parent_field ) )
   222 				$top_level_elements[] = $e;
   218 				$top_level_elements[] = $e;
   223 			else
   219 			else
   224 				$children_elements[ $e->$parent_field ][] = $e;
   220 				$children_elements[ $e->$parent_field ][] = $e;
   225 		}
   221 		}
   226 
   222 
   251 		 * then we got orphans, which should be displayed regardless.
   247 		 * then we got orphans, which should be displayed regardless.
   252 		 */
   248 		 */
   253 		if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
   249 		if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
   254 			$empty_array = array();
   250 			$empty_array = array();
   255 			foreach ( $children_elements as $orphans )
   251 			foreach ( $children_elements as $orphans )
   256 				foreach( $orphans as $op )
   252 				foreach ( $orphans as $op )
   257 					$this->display_element( $op, $empty_array, 1, 0, $args, $output );
   253 					$this->display_element( $op, $empty_array, 1, 0, $args, $output );
   258 		 }
   254 		 }
   259 
   255 
   260 		 return $output;
   256 		 return $output;
   261 	}
   257 	}
   270 	 * $max_depth = 0 means display all levels.
   266 	 * $max_depth = 0 means display all levels.
   271 	 * $max_depth > 0 specifies the number of display levels.
   267 	 * $max_depth > 0 specifies the number of display levels.
   272 	 *
   268 	 *
   273  	 * @since 2.7.0
   269  	 * @since 2.7.0
   274 	 *
   270 	 *
   275  	 * @param int $max_depth The maximum hierarchical depth.
   271 	 * @param array $elements
   276  	 * @param int $page_num  The specific page number, beginning with 1.
   272 	 * @param int   $max_depth The maximum hierarchical depth.
   277  	 * @return string XHTML of the specified page of elements
   273 	 * @param int   $page_num The specific page number, beginning with 1.
   278  	 */
   274 	 * @param int   $per_page
       
   275 	 * @return string XHTML of the specified page of elements
       
   276 	 */
   279 	public function paged_walk( $elements, $max_depth, $page_num, $per_page ) {
   277 	public function paged_walk( $elements, $max_depth, $page_num, $per_page ) {
   280 
   278 		if ( empty( $elements ) || $max_depth < -1 ) {
   281 		/* sanity check */
       
   282 		if ( empty($elements) || $max_depth < -1 )
       
   283 			return '';
   279 			return '';
       
   280 		}
   284 
   281 
   285 		$args = array_slice( func_get_args(), 4 );
   282 		$args = array_slice( func_get_args(), 4 );
   286 		$output = '';
   283 		$output = '';
   287 
   284 
   288 		$parent_field = $this->db_fields['parent'];
   285 		$parent_field = $this->db_fields['parent'];
   374 		}
   371 		}
   375 
   372 
   376 		if ( $end >= $total_top && count( $children_elements ) > 0 ) {
   373 		if ( $end >= $total_top && count( $children_elements ) > 0 ) {
   377 			$empty_array = array();
   374 			$empty_array = array();
   378 			foreach ( $children_elements as $orphans )
   375 			foreach ( $children_elements as $orphans )
   379 				foreach( $orphans as $op )
   376 				foreach ( $orphans as $op )
   380 					$this->display_element( $op, $empty_array, 1, 0, $args, $output );
   377 					$this->display_element( $op, $empty_array, 1, 0, $args, $output );
   381 		}
   378 		}
   382 
   379 
   383 		return $output;
   380 		return $output;
   384 	}
   381 	}
   385 
   382 
       
   383 	/**
       
   384 	 * Calculates the total number of root elements.
       
   385 	 *
       
   386 	 * @since 2.7.0
       
   387 	 *
       
   388 	 * @param array $elements Elements to list.
       
   389 	 * @return int Number of root elements.
       
   390 	 */
   386 	public function get_number_of_root_elements( $elements ){
   391 	public function get_number_of_root_elements( $elements ){
   387 
       
   388 		$num = 0;
   392 		$num = 0;
   389 		$parent_field = $this->db_fields['parent'];
   393 		$parent_field = $this->db_fields['parent'];
   390 
   394 
   391 		foreach ( $elements as $e) {
   395 		foreach ( $elements as $e) {
   392 			if ( 0 == $e->$parent_field )
   396 			if ( 0 == $e->$parent_field )
   393 				$num++;
   397 				$num++;
   394 		}
   398 		}
   395 		return $num;
   399 		return $num;
   396 	}
   400 	}
   397 
   401 
   398 	// Unset all the children for a given top level element.
   402 	/**
       
   403 	 * Unset all the children for a given top level element.
       
   404 	 *
       
   405 	 * @since 2.7.0
       
   406 	 *
       
   407 	 * @param object $e
       
   408 	 * @param array $children_elements
       
   409 	 */
   399 	public function unset_children( $e, &$children_elements ){
   410 	public function unset_children( $e, &$children_elements ){
   400 
   411 		if ( ! $e || ! $children_elements ) {
   401 		if ( !$e || !$children_elements )
       
   402 			return;
   412 			return;
       
   413 		}
   403 
   414 
   404 		$id_field = $this->db_fields['id'];
   415 		$id_field = $this->db_fields['id'];
   405 		$id = $e->$id_field;
   416 		$id = $e->$id_field;
   406 
   417 
   407 		if ( !empty($children_elements[$id]) && is_array($children_elements[$id]) )
   418 		if ( !empty($children_elements[$id]) && is_array($children_elements[$id]) )
   408 			foreach ( (array) $children_elements[$id] as $child )
   419 			foreach ( (array) $children_elements[$id] as $child )
   409 				$this->unset_children( $child, $children_elements );
   420 				$this->unset_children( $child, $children_elements );
   410 
   421 
   411 		if ( isset($children_elements[$id]) )
   422 		unset( $children_elements[ $id ] );
   412 			unset( $children_elements[$id] );
       
   413 
       
   414 	}
   423 	}
   415 
   424 
   416 } // Walker
   425 } // Walker