Changeset 6384
- Timestamp:
- 12/14/2007 09:46:52 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-includes/classes.php
r6365 r6384 387 387 } 388 388 389 390 // A class for displaying various tree-like structures. Extend the Walker class to use it, see examples at the bottom 391 389 /* 390 * A class for displaying various tree-like structures. 391 * Extend the Walker class to use it, see examples at the bottom 392 */ 392 393 class Walker { 393 394 var $tree_type; … … 400 401 function end_el($output) { return $output; } 401 402 402 function walk($elements, $to_depth) { 403 $args = array_slice(func_get_args(), 2); $parents = array(); $depth = 1; $previous_element = ''; $output = ''; 404 405 //padding at the end 406 $last_element->post_parent = 0; 407 $last_element->post_id = 0; 408 $elements[] = $last_element; 409 403 /* 404 * display one element if the element doesn't have any children 405 * otherwise, display the element and its children 406 */ 407 function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, $output ) { 408 409 if ( !$element) 410 return $output; 411 412 if ( $max_depth != 0 ) { 413 if ($depth >= $max_depth) 414 return $output; 415 } 416 410 417 $id_field = $this->db_fields['id']; 411 418 $parent_field = $this->db_fields['parent']; 412 413 $flat = ($to_depth == -1) ? true : false; 414 415 foreach ( $elements as $element ) { 416 // If flat, start and end the element and skip the level checks. 417 if ( $flat) { 418 // Start the element. 419 if ( isset($element->$id_field) && $element->$id_field != 0 ) { 420 $cb_args = array_merge( array($output, $element, $depth - 1), $args); 421 $output = call_user_func_array(array(&$this, 'start_el'), $cb_args); 422 } 423 424 // End the element. 425 if ( isset($element->$id_field) && $element->$id_field != 0 ) { 426 $cb_args = array_merge( array($output, $element, $depth - 1), $args); 427 $output = call_user_func_array(array(&$this, 'end_el'), $cb_args); 428 } 429 430 continue; 419 420 //display this element 421 $cb_args = array_merge( array($output, $element, $depth), $args); 422 $output = call_user_func_array(array(&$this, 'start_el'), $cb_args); 423 424 if ( !$children_elements ) { 425 //close off this element 426 $cb_args = array_merge( array($output, $element, $depth), $args); 427 $output = call_user_func_array(array(&$this, 'end_el'), $cb_args); 428 return $output; 429 } 430 431 for ( $i = 0; $i < sizeof( $children_elements ); $i++ ) { 432 $child = $children_elements[$i]; 433 434 if ( $child->$parent_field == $element->$id_field ) { 435 436 array_splice( $children_elements, $i, 1 ); 437 438 //start the child delimiter 439 $cb_args = array_merge( array($output, $depth), $args); 440 $output = call_user_func_array(array(&$this, 'start_lvl'), $cb_args); 441 442 $output = $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output ); 443 444 //end the child delimiter 445 $cb_args = array_merge( array($output, $depth), $args); 446 $output = call_user_func_array(array(&$this, 'end_lvl'), $cb_args); 447 $i--; 431 448 } 432 433 // Walk the tree. 434 if ( !empty($previous_element) && ($element->$parent_field == $previous_element->$id_field) ) { 435 // Previous element is my parent. Descend a level. 436 array_unshift($parents, $previous_element); 437 if ( !$to_depth || ($depth < $to_depth) ) { //only descend if we're below $to_depth 438 $cb_args = array_merge( array($output, $depth), $args); 439 $output = call_user_func_array(array(&$this, 'start_lvl'), $cb_args); 440 } else if ( $to_depth && $depth == $to_depth ) { // If we've reached depth, end the previous element. 441 $cb_args = array_merge( array($output, $previous_element, $depth), $args); 442 $output = call_user_func_array(array(&$this, 'end_el'), $cb_args); 443 } 444 $depth++; //always do this so when we start the element further down, we know where we are 445 } else if ( $element->$parent_field == $previous_element->$parent_field) { 446 // On the same level as previous element. 447 if ( !$to_depth || ($depth <= $to_depth) ) { 448 $cb_args = array_merge( array($output, $previous_element, $depth - 1), $args); 449 $output = call_user_func_array(array(&$this, 'end_el'), $cb_args); 450 } 451 } else if ( $depth > 1 ) { 452 // Ascend one or more levels. 453 if ( !$to_depth || ($depth <= $to_depth) ) { 454 $cb_args = array_merge( array($output, $previous_element, $depth - 1), $args); 455 $output = call_user_func_array(array(&$this, 'end_el'), $cb_args); 456 } 457 458 while ( $parent = array_shift($parents) ) { 459 $depth--; 460 if ( !$to_depth || ($depth < $to_depth) ) { 461 $cb_args = array_merge( array($output, $depth), $args); 462 $output = call_user_func_array(array(&$this, 'end_lvl'), $cb_args); 463 $cb_args = array_merge( array($output, $parent, $depth - 1), $args); 464 $output = call_user_func_array(array(&$this, 'end_el'), $cb_args); 465 } 466 if ( $element->$parent_field == $parents[0]->$id_field ) { 467 break; 468 } 469 } 470 } else if ( !empty($previous_element) ) { 471 // Close off previous element. 472 if ( !$to_depth || ($depth <= $to_depth) ) { 473 $cb_args = array_merge( array($output, $previous_element, $depth - 1), $args); 474 $output = call_user_func_array(array(&$this, 'end_el'), $cb_args); 475 } 476 } 477 478 // Start the element. 479 if ( !$to_depth || ($depth <= $to_depth) ) { 480 if ( $element->$id_field != 0 ) { 481 $cb_args = array_merge( array($output, $element, $depth - 1), $args); 482 $output = call_user_func_array(array(&$this, 'start_el'), $cb_args); 483 } 484 } 485 486 $previous_element = $element; 487 } 488 489 return $output; 449 } 450 return $output; 451 } 452 453 /* 454 * displays array of elements hierarchically 455 * max_depth = -1 means flatly display every element 456 * max_depth = 0 means display all levels 457 * max_depth > 0 specifies the number of display levels. 458 */ 459 function walk( $elements, $max_depth) { 460 461 $args = array_slice(func_get_args(), 2); 462 $output = ''; 463 464 $id_field = $this->db_fields['id']; 465 $parent_field = $this->db_fields['parent']; 466 467 $flat = ($max_depth == -1) ? true : false; 468 if ( $flat ) { 469 $empty_array = array(); 470 foreach ( $elements as $e ) 471 $output = $this->display_element( $e, $empty_array, 1, 0, $args, $output ); 472 return $output; 473 } 474 475 /* 476 * need to display in hierarchical order 477 * splice elements into two buckets: those without parent and those with parent 478 */ 479 480 $top_level_elements = array(); 481 $children_elements = array(); 482 483 foreach ( $elements as $e) { 484 if ( 0 == $e->$parent_field ) 485 $top_level_elements[] = $e; 486 else 487 $children_elements[] = $e; 488 } 489 490 foreach ( $top_level_elements as $e ) 491 $output = $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); 492 493 /* 494 * if we are displaying all levels, and remaining children_elements is not empty, 495 * then we got orphans, which should be displayed regardless 496 */ 497 if ( ( $max_depth == 0 ) && sizeof( $children_elements ) > 0 ) { 498 $empty_array = array(); 499 foreach ( $children_elements as $orphan_e ) 500 $output = $this->display_element( $orphan_e, $empty_array, 1, 0, $args, $output ); 501 } 502 return $output; 490 503 } 491 504 }
Note: See TracChangeset
for help on using the changeset viewer.