get_pages() not ordering as it should

I’m using get_pages() function to get all subpages from a page like this:

$childrens = get_pages(array('child_of' => 7, 
                             'sort_column' => 'post_date', 
                             'sort_order' => 'DESC', 
                             'depth' => -1));

This is supossed to get me a list of all pages (no matter if direct children, children of children, etc) orderen by the date they were created, but instead its showing me the list of pages in a strange order, here’s the output when I run a foreach on the $childrens array and output the post_date on each:

Read More
2011-05-10 15:37:03
2011-05-10 15:35:59
2011-05-10 15:01:18
2011-05-10 17:12:32
2011-05-10 15:00:47
2011-05-10 14:00:14
2011-05-11 04:19:08
2011-05-10 23:52:54
2011-05-10 15:20:12
2011-05-10 15:05:10

As you can see they’re not ordered by date descending, I tried using other options in the sort_column key but none seemed to e working correctly, does anyone know what could be wrong?

Thanks in advance!

Related posts

Leave a Reply

5 comments

  1. This is indeed an error, and probably caused by the child_of argument.

    Because child_of requests the whole subtree of the given page (not only the direct children, but also children of those children and so on), WordPress first queries for all the pages and then selects a subset of those pages. The first query respects the order, but the second subselection messes this up by just using array_merge().

    I have created a Trac ticket for this.

  2. after looking around a bit I managed it to make it work using the following:

    function sort_pages_by_date($a, $b){
        if ($a->post_date == $b->post_date)
            return 0;
        if ($a->post_date < $b->post_date)
            return -1;
        return 1;
    }
    
    function get_filtered_news($pages) {
        usort($pages, 'sort_pages_by_date');
        rsort($pages);
    
        return $pages;
    }
    
    add_filter('get_pages', 'get_filtered_news');
    

    I’m using the usort function to sort the array by the objects’ date, and the reversing it to get it ordered from newest to oldest, thanks all for pointing me in the right direction I voted all you guys up.

  3. Im not sure how to remedy the problem with WordPress – im getting the same results as you are, but this can be achieved using the PHP functions sort() and rsort() and a little bit of dirty work using foreach.

    rsort() would sort an array in reverse order and sort() from lowest to highest.

    Try this:

    <?php 
        $children = get_pages( array( 'child_of' => 7 ) );
    
        foreach ( $children as $child ) {
            // get post date of each page/child
            $post_date = $child->post_date;
            // populate the array with the post dates
            $dates[] = $post_date;
    
        }
    
        // Sort the array in reverse order
        rsort( $dates ); // or sort( $dates ) for the lowest to highest
    
        foreach ( $dates as $date ) {
    
            echo $date;
            echo '<br />';
    
       }
    ?>
    
  4. Some sidenotes while searching for a solution:

    • Reading through this ticket at trac, the arguments will change with a coming version to align with the get_posts() arguments.
    • You can find the function at /core-root/wp-includes/post.php line 3.284

    Questions:

    • Are you sure, you’re not using 'include' as argument? This sets 'child_of' to zero.

    Try this and tell me about the result you get. Maybe you can re-order them there until you got a satisfying solution:

    function wpse16921_get_pages( $pages, $r )
    {
        echo '<pre>'; print_r($pages); echo '</pre>';
    }
    add_filter( 'get_pages', 'wpse16921_get_pages' );
    

    Edit

    Here you got a set of functions that help you working around until the patch has gone into a wp release:

    // First: Loop through your pages inside the filter
    function wpse16921_get_pages_filter( $pages, $r )
    {
        # echo '<pre>'; 
            foreach ( $pages as $page )
            {
                $page = (array) $page;
                $pages_temp[$page['post_date']] = $page;
            } 
            # echo 'Before manipulation: '; print_r($pages_temp);
            $pages_temp = '/* handle sorting of your new date keys over here */';
            # echo 'After manipulation: '; print_r($pages_temp);
        # echo '</pre>';
    
        return $pages = $pages_temp;
    }
    
    // Second: Attach the filter to the appropriate hook
    function wpse16921_get_pages_filter_hook()
    {
        add_filter( 'get_pages', 'wpse16921_get_pages_filter', 10, 2 );
    }
    add_action( 'after_setup_theme', 'wpse16921_get_pages_filter_hook', 0 );
    
    // Call your pages
    function wpse16921_get_pages_call() 
    {
        $pages = get_pages();
    
        # >>>> start modifying/preparing the output
        echo '<pre>'; 
            foreach ( $pages as $date => $page )
                echo $date.'<br />';     
        echo '</pre>';
        # <<<< end modifying/preparing the output
    } 
    add_action( 'after_setup_theme', 'wpse16921_get_pages_call' );
    
  5. use get_children instead – replace child_of with post_parent / sort_column / sort_order – ie.:

    $nav_args = array(
    'sort_column' => 'date', 
    'sort_order' => 'desc', 
    'post_parent' => get_the_ID(),
    );
    
    $list = get_children( $nav_args ); // list results ##