| | 547 | |
| | 548 | /** |
| | 549 | * paged_walk() - produce a page of nested elements |
| | 550 | * |
| | 551 | * Given an array of hierarchical elements, the maximum depth, a specific page number, |
| | 552 | * and number of elements per page, this function first determines all top level root elements |
| | 553 | * belonging to that page, then lists them and all of their children in hierarchical order. |
| | 554 | * |
| | 555 | * @package WordPress |
| | 556 | * @since 2.7 |
| | 557 | * @param $max_depth = 0 means display all levels; $max_depth > 0 specifies the number of display levels. |
| | 558 | * @param $page_num the specific page number, beginning with 1. |
| | 559 | * @return XHTML of the specified page of elements |
| | 560 | */ |
| | 561 | function paged_walk( $elements, $max_depth, $page_num, $per_page ) { |
| | 562 | |
| | 563 | /* sanity check */ |
| | 564 | if ( empty($elements) || $max_depth<0 || $page_num<1 || $per_page<0 ) |
| | 565 | return ''; |
| | 566 | |
| | 567 | $args = array_slice( func_get_args(), 4 ); |
| | 568 | $output = ''; |
| | 569 | |
| | 570 | $id_field = $this->db_fields['id']; |
| | 571 | $parent_field = $this->db_fields['parent']; |
| | 572 | |
| | 573 | /* |
| | 574 | * seperate elements into two buckets: top level and children elements |
| | 575 | * children_elements is two dimensional array, eg. |
| | 576 | * children_elements[10][] contains all sub-elements whose parent is 10. |
| | 577 | */ |
| | 578 | $top_level_elements = array(); |
| | 579 | $children_elements = array(); |
| | 580 | foreach ( $elements as $e) { |
| | 581 | if ( 0 == $e->$parent_field ) |
| | 582 | $top_level_elements[] = $e; |
| | 583 | else |
| | 584 | $children_elements[ $e->$parent_field ][] = $e; |
| | 585 | } |
| | 586 | |
| | 587 | $count = -1; |
| | 588 | $start = ( (int)$page_num - 1 ) * (int)$per_page; |
| | 589 | $end = $start + $per_page; |
| | 590 | $total_top = count( $top_level_elements ); |
| | 591 | |
| | 592 | foreach( $top_level_elements as $e ){ |
| | 593 | |
| | 594 | $count++; |
| | 595 | |
| | 596 | //for the last page, need to unset earlier children in order to keep track of orphans |
| | 597 | if ( $end >= $total_top && $count < $start ) |
| | 598 | $this->unset_children( $e, $children_elements ); |
| | 599 | |
| | 600 | if ( $count < $start ) |
| | 601 | continue; |
| | 602 | |
| | 603 | if ( $count >= $end ) |
| | 604 | break; |
| | 605 | |
| | 606 | $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); |
| | 607 | } |
| | 608 | |
| | 609 | if ( $end >= $total_top && count( $children_elements ) > 0 ){ |
| | 610 | $empty_array = array(); |
| | 611 | foreach ( $children_elements as $orphans ) |
| | 612 | foreach( $orphans as $op ) |
| | 613 | $this->display_element( $op, $empty_array, 1, 0, $args, $output ); |
| | 614 | } |
| | 615 | |
| | 616 | return $output; |
| | 617 | } |
| | 618 | |
| | 619 | function get_number_of_root_elements( $elements ){ |
| | 620 | |
| | 621 | $num = 0; |
| | 622 | $parent_field = $this->db_fields['parent']; |
| | 623 | |
| | 624 | foreach ( $elements as $e) { |
| | 625 | if ( 0 == $e->$parent_field ) |
| | 626 | $num++; |
| | 627 | } |
| | 628 | return $num; |
| | 629 | } |
| | 630 | |
| | 631 | // unset all the children for a given top level element |
| | 632 | function unset_children( $e, &$children_elements ){ |
| | 633 | |
| | 634 | if ( !$e || !$children_elements ) |
| | 635 | return; |
| | 636 | |
| | 637 | $id_field = $this->db_fields['id']; |
| | 638 | $id = $e->$id_field; |
| | 639 | |
| | 640 | foreach ( (array)$children_elements[$id] as $child ) |
| | 641 | $this->unset_children( $child, $children_elements ); |
| | 642 | |
| | 643 | unset( $children_elements[$id] ); |
| | 644 | |
| | 645 | } |