Ticket #5458: 5458_walk_core.diff

File 5458_walk_core.diff, 7.3 KB (added by hailin, 4 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