1

I'm using a plugin that lets me order posts and set some as "sticky" and always on top.
I have the example code below that will randomize all posts except for the sticky posts, they will remain on top.

function randomize_order_with_sticky_on_top ( $post_list, $sort_view_id, $orderBy, $query )
{
    shuffle($post_list);
        
    //retrieve the sticky list for current sort ID
    $sticky_list = get_post_meta( $sort_view_id , '_sticky_data', TRUE);
    
    if ( ! is_array ( $sticky_list )    ||  count ( $sticky_list ) < 1 )
        return $post_list;    
        
    //remove the sticky items in the $post_list
    foreach ( $sticky_list as $position => $object_id ) 
        {
            if ( isset ( $post_list [ $object_id ] ) )
                unset ( $post_list [ array_search( $object_id, $post_list ) ] );
        }
    
    $post_list  =   array_values ( $post_list );
            
    foreach ( $sticky_list as $position => $object_id ) 
        {
            // Insert the ID at the specified position
            array_splice( $post_list, $position - 1, 0, $object_id );
        }

    return $post_list;
        
}

However I have an Advanced Custom field post type that can have multiple values (it's a checkbox) lets say the acf field is "color" and the possible values are red, green, blue. Since it's a checkbox it can be any one of these ore multiple and return an array of colors. I'm trying to make it so it will guarantee all of those that include blue (so not just blue but if they're also red and blue) will all be among the top 50% of the randomized order. I've tried multiple variations of this but I either break the sticky or the blue items are randomized throughout.

2
  • So, the output you are trying to have is like this - <Sticky posts> <"Blue" posts> <All other posts> - right? What is $post_list ? I mean, can you show an example of how are you defining that variable and then calling the randomize_order_with_sticky_on_top function?
    – Sally CJ
    Feb 6 at 0:46
  • It would be <sticky posts> <randomized posts with all blue in the top 50%>. I'm using this plugin to call the function nsp-code.com/…
    – dagnabbit
    Feb 6 at 20:38

1 Answer 1

0

Issue with the way you are unsetting sticky posts from the $post_list array and then reinserting them at the specified positions and should work correctly like below code structure.

Removed the unnecessary $position variable in the foreach loop.

Changed the way sticky items are inserted back into the $post_list array using array_unshift to add them at the beginning of the array

function randomize_order_with_sticky_on_top( $post_list, $sort_view_id, $orderBy, $query ) {
    shuffle( $post_list );

    // Retrieve the sticky list for the current sort ID
    $sticky_list = get_post_meta( $sort_view_id, '_sticky_data', TRUE );

    if ( ! is_array( $sticky_list ) || count( $sticky_list ) < 1 ) {
        return $post_list;
    }

    // Remove the sticky items from the $post_list
    foreach ( $sticky_list as $object_id ) {
        $index = array_search( $object_id, $post_list );
        if ( $index !== false ) {
            unset( $post_list[ $index ] );
        }
    }

    // Reset array keys
    $post_list = array_values( $post_list );

    // Reinsert sticky items at the beginning of the $post_list
    foreach ( $sticky_list as $object_id ) {
        array_unshift( $post_list, $object_id );
    }

    return $post_list;
}
1
  • My first code works if I only wanted to do random but including the acf field in the top 50% is the tricky part So to also include the ACF would I insert this before the last foreach? ''foreach ($post_list as $key => $post_id) { $colors = get_field('color', $post_id); if (is_array($colors) && in_array('blue', $colors)) { $blue_color[] = $post_id; unset($post_list[$key]); } } ''
    – dagnabbit
    Feb 6 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.