1

I am trying to sort a navigation menu list, that I am being provided(as a $response in an array). So, it would be by parent_id (null is the top tier nav.) then the sub pages would fall in under the parent id's which would be page_id then in the page_order. Basically in the order that you would see the Nav. Menu on a website.

For example:

First Nav
--First Nav Sub Page 1
--First Nav Sub Page 2
--First Nav Sub Page 3
--First Nav Sub Page 4
--First Nav Sub Page 5
Second Nav
Third Nav
--Third Nav Sub Page 1
--Third Nav Sub Page 2
Fourth Nav

The Array:

Array (
[0] => stdClass Object
    (
        [page_id] => 122021
        [title] => First Nav
        [page_order] => 1
        [parent_id] => null
    )

[1] => stdClass Object
    (
        [page_id] => 99122
        [title] => Second Nav
        [page_order] => 2
        [parent_id] => null
    )

[2] => stdClass Object
    (
        [page_id] => 260447
        [title] => Third Nav
        [page_order] => 3
        [parent_id] => null
    )

[3] => stdClass Object
    (
        [page_id] => 170627
        [title] => Fourth Nav
        [page_order] => 4
        [parent_id] => null
    )

[4] => stdClass Object
    (
        [page_id] => 134788
        [title] => Third Nav Sub Page 1
        [page_order] => 1
        [parent_id] => 260447
    )

[5] => stdClass Object
    (
        [page_id] => 157074
        [title] => Third Nav Sub Page 2
        [page_order] => 2
        [parent_id] => 260447
    )

[6] => stdClass Object
    (
        [page_id] => 699423
        [title] => First Nav Sub Page 1
        [page_order] => 1
        [parent_id] => 122021
    )

[7] => stdClass Object
    (
        [page_id] => 346209
        [title] => First Nav Sub Page 2
        [page_order] => 2
        [parent_id] => 122021
    )

[8] => stdClass Object
    (
        [page_id] => 732773
        [title] => First Nav Sub Page 3
        [page_order] => 3
        [parent_id] => 122021
    )

[9] => stdClass Object
    (
        [page_id] => 164338
        [title] => First Nav Sub Page 4
        [page_order] => 4
        [parent_id] => 122021
    )

[10] => stdClass Object
    (
        [page_id] => 671117
        [title] => First Nav Sub Page 5
        [page_order] => 5
        [parent_id] => 122021
    )
)

I have managed to get this in a partial order, by parent_id then page_order (as shown in the array above) using the ArrSort function noted below, but I have not been able to put the sub pages page_order 'underneath' their parent_id.

I have tried:

function ArrSort ($Array){
   $parent_id = array();
   $page_order = array();
   foreach($Array as $key => $value){
       $parent_id[] = $value->parent_id;
       $page_order[] = $value->page_order;
   }
   array_multisort($parent_id, SORT_ASC, $page_order, SORT_ASC, $Array);
   return $Array;
}
$sorted_pages_array = ArrSort($response);

I have also tried the following,

function PageList($a, $b){
  if ( $a->page_id == $b->page_id ) {
    return 0;
  } else if ( $a->parent_id ) {
      if ( $a->parent_id == $b->parent_id ) {
         return ( $a->page_id < $b->page_id ? -1 : 1 );
      } else {
         return ( $a->parent_id >= $b->page_id ? 1 : -1 );
      }
  } else if ( $b->parent_id ) {
    return ( $b->parent_id >= $a->page_id ? -1 : 1);
  } else {
    return ( $a->page_id < $b->page_id ? -1 : 1 );
  }
}
usort($response, "PageList");

And a combination of both:

$sorted_pages_array = ArrSort($response);
usort($sorted_pages_array, "PageList");

Unfortunately I am not that familiar with arrays, and sorting, and could use some assistance.

Jeffrey Kastner
  • 651
  • 6
  • 15

2 Answers2

0

Try this:

usort($sorted_pages_array, function($a, $b){
    if($a->parent_id === $b->parent_id && $a->page_id === $b->page_id){
        return $a->page_order - $b->page_order;
    }
    elseif($a->parent_id === $b->parent_id){
        return $a->page_id - $b->page_id;
    } else {
        return $a->parent_id - $b->parent_id;
    }
});

It would probably be easier to sort your data in the database first.

LeDoc
  • 935
  • 2
  • 12
  • 24
  • This doesn't work. Not only does it not put the parent_id 'null' first, but the page_order also is not in order. Matter of fact, I can't see any order in the results which is actually 'worse' than my ArrSort function. – Jeffrey Kastner Jul 22 '16 at 16:57
0

After doing some digging, I found this: https://stackoverflow.com/a/8021033/3925032

So, with the exception of changing the following, from the above linked solution:

$node['object']->id to $node['object']->page_id

$node['object']->top_id to $node['object']->parent_id

$node['object']->name to $node['object']->title

(and adding a few of my own updates), that was what I was looking for. And when I added it after the function ArrSort (in my original question), all was well!

Community
  • 1
  • 1
Jeffrey Kastner
  • 651
  • 6
  • 15