1

I use the following function to create a random unique 6 digit number and save it in a custom post type meta field.

I am unsure about the use of rewind_posts() inside a while loop. The idea is that it checks if the $random number already exists inside any of the existing custom posts. If it exists it generates a new random number and checks again against all custom posts.

function create_random_unique_id() {

  // Create random 6 digit number
  $random   = substr( rand() * 900000 + 100000, 0, 6 );

  // Get all Custom Posts  
  $args = array( 'post_type' => 'my_custom_post_type', 'posts_per_page' => -1 );
  $loop = new WP_Query( $args );

  // For each Custom Post, check if $random matches $cpt_id
  while ( $loop->have_posts() ) {

    $loop->the_post();
    $cpt_id = get_post_meta ( get_the_id(), 'id', true );

    // If $random matches $subscriber_id assign a different random 6 digit number
    if ( $cpt_id == $random ) {
      $random = substr( rand() * 900000 + 100000, 0, 6 );
      rewind_posts();
    }

  }

  return $random;
}
3

This quite an expensive operation what you are doing, and IMHO wrong worksflow as well. What you want to do is, is the following

  • Get all the meta_values from the specific meta_key you need.

  • You can then check the random number against the values returned from a specific meta_key

Here is a very basic idea in code: (Credit to Chinmoy Paul from pwdtechnology.com for the code. Code is commented for easy understanding)

The following goes into functions.php

/**    
 * Description: Getting all the values associated with a specific custom post meta key, across all posts
 * Author: Chinmoy Paul
 * Author URL: http://pwdtechnology.com
 *
 * @param string $key Post Meta Key.
 *
 * @param string $type Post Type. Default is post. You can pass custom post type here.
 *
 * @param string $status Post Status like Publish, draft, future etc. default is publish
 *
 * @return array
 */
function get_unique_post_meta_values( $key = '', $type = 'post', $status = 'publish' ) 
{
    global $wpdb;
    if( empty( $key ) )
        return;
    $res = $wpdb->get_col( 
        $wpdb->prepare( 
            "SELECT DISTINCT pm.meta_value 
            FROM {$wpdb->postmeta} pm
            LEFT JOIN {$wpdb->posts} p 
            ON p.ID = pm.post_id
            WHERE pm.meta_key = '%s'
            AND p.post_status = '%s'
            AND p.post_type = '%s'", 
            $key, 
            $status, 
            $type 
        ) 
    );
    return $res;
}

Now, to get a specific array of meta values from a given meta_key from a specific post_type and post_status, you can try the following

// Get ids to exclude
$ids_to_exclude = get_unique_post_meta_values(
    'id', // This is our meta_key to get values from
    'MY_POST_TYPE', // This is the name of your custom post type
    'POST_STATUS' // Any other post status except publish as publish is default
);

/**
 * Generate a unique id
 * Thanks to Gautam3164 for the code
 * @see http://stackoverflow.com/a/17109530/1908141
 */
do {   
    // This is taken as is from your code in question
    $random   = substr( rand() * 900000 + 100000, 0, 6 );
} 
while( in_array( $random, $ids_to_exclude ) );
echo $random;

EDIT

You can put everything together in one fully functional function.

/**    
 * Description: Get a random unique 6 number id for any given meta_key
 *
 * @param string $key Post Meta Key.
 *
 * @param string $type Post Type. Default is post. You can pass custom post type here.
 *
 * @param string $status Post Status like Publish, draft, future etc. default is publish
 *
 * @return array
 */
function get_unique_random_value( 
    $key = '', 
    $type = 'post', 
    $status = 'publish' 
) {
    global $wpdb;

    // Check if we have a meta_key before continuing, if not, return false
    if( empty( $key ) )
        return false;

    $res = $wpdb->get_col( 
        $wpdb->prepare( 
            "SELECT DISTINCT pm.meta_value 
            FROM {$wpdb->postmeta} pm
            LEFT JOIN {$wpdb->posts} p 
            ON p.ID = pm.post_id
            WHERE pm.meta_key = '%s'
            AND p.post_status = '%s'
            AND p.post_type = '%s'", 
            $key, 
            $status, 
            $type 
        ) 
    );
    // Check if we actually have an array of values, if not, return false
    if ( !$res )
        return false;

    /**
     * Generate a unique id
     * Thanks to Gautam3164 for the code
     * @see http://stackoverflow.com/a/17109530/1908141
     */
    do {   
        // This is taken as is from your code in question
        $random   = substr( rand() * 900000 + 100000, 0, 6 );
    } 
    while( in_array( $random, $res ) );
    return $random;
}

Then you can use it as follow

$random_id = get_unique_random_value (
    'id', // This is our meta_key to get values from
    'MY_POST_TYPE', // This is the name of your custom post type
    'POST_STATUS' // Any other post status except publish as publish is default
);
echo $random_id;
  • Thanks a lot @PieterGoosen, this looks great. I had never come across a usecase where I had to do a direct call to the WP Database. But this is obviously way more effective. I will try it out later to check if it works as intented – Snowball Sep 21 '15 at 9:40
  • My pleasure, hope you get this working. Good luck :-) – Pieter Goosen Sep 21 '15 at 9:47
  • Works perfect. You just forgot a closing ) in the last while loop :) – Snowball Sep 21 '15 at 15:24
  • My pleasure, thanks for the note on the error, will fix in. Many thanks. Enjoy :-) – Pieter Goosen Sep 21 '15 at 16:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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