WordPress.org

Make WordPress Core

Ticket #5458: 5458_walk_core.diff

File 5458_walk_core.diff, 7.3 KB (added by hailin, 12 years ago)

patch

  • C:/xampp/htdocs/wordpress_trunk/wp-includes/classes.php

     
    386386        return false;
    387387}
    388388
    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 */
    392393class Walker {
    393394        var $tree_type;
    394395        var $db_fields;
     
    399400        function start_el($output)  { return $output; }
    400401        function end_el($output)    { return $output; }
    401402
    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       
    410417                $id_field = $this->db_fields['id'];
    411418                $parent_field = $this->db_fields['parent'];
     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);
    412423
    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;
     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--;
    431448                        }
     449                }
     450                return $output;
     451        }
    432452
    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                                 }
     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 = '';
    457463
    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                         }
     464                $id_field = $this->db_fields['id'];
     465                $parent_field = $this->db_fields['parent'];
    477466
    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;
     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;
    487473                }
    488 
    489                 return $output;
     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;
    490503        }
    491504}
    492505