• Resolved nad33m

    (@nad33m)


    This code gets a letter ($letter) from the array ($alphabet) randomly. This PHP is at the top of the functions.php file in WordPress and gets used in an action to echo the $letter in an email when an order is placed in woo.

    How do I change the code so $letter holds the next letter each time the action is is called? So the 1st email echos ‘a’ , 2nd email ‘b’ e.t.c.

    
    $alphabet = array ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' );
    
    $rand_keys = array_rand($alphabet, 1);
    
    $letter = $alphabet[$rand_keys] . "\n";
    

    Thank you in advance.

    • This topic was modified 5 years, 9 months ago by nad33m.
    • This topic was modified 5 years, 9 months ago by nad33m.
Viewing 6 replies - 1 through 6 (of 6 total)
  • Moderator bcworkz

    (@bcworkz)

    The next available index needs to be stored somewhere. I assume this value needs to persist over multiple requests over an extended period of time, and that the value is to be globally applied site wide (not per user or per order). One place to save such a value is in the options table. Use update_option() and get_option() to save and retrieve the saved value.

    Naturally you need code to reset the index to zero once it uses the last element in the array.

    Thread Starter nad33m

    (@nad33m)

    @bcworkz thanks, I have thought about doing it this way, need help advancing the pointer, and return to zero when at the end of the array:

    add_option( 'last-letter-key', 0 ) <--Adds new database variable -->

    $last_key = get_option( 'last-letter-key' );  <--Retrieves last key from database -->
    
    $letter = $alphabet[$last_key];  <--sets letter using $last_key -->
    
    $letter = next($alphabet); <-- advances to next name -->
    
    <---here is where I think I need to put a loop to advance the pointer, what code goes here? -->
    
    $last_key = key($alphabet); <-- gets new key that is +1 now -->
    
    update_option( 'last-letter-key', $last_key ); <--saves new key to database -->
    • This reply was modified 5 years, 9 months ago by nad33m.
    • This reply was modified 5 years, 9 months ago by nad33m.
    Moderator bcworkz

    (@bcworkz)

    Unless you know otherwise, I don’t think there is an easy way to directly set the internal pointer to a particular value, so using next() is not an effective way to get the next available letter. No problem, array elements can be accessed directly, like so:
    $letter = $alphabet[$last_key+1];

    Before doing that though, check if ( $last_key+1 == count( $alphabet )). If it is, the end of the alphabet has been reached and $last_key needs to be reset to -1 so when we add 1 to it, it gets the first element in the array at index 0.

    You see, we are not using the internal pointer at all now. Instead, we are keeping track of the last array index used. No looping is required. Yes, you could reset the internal pointer, then do a loop of $last_key calls to next() to get to the right place, but there is no need. After getting the next letter from $alphabet, update the option to $last_key+1

    Also, you don’t really need to initialize the option with add_option(). update_option() will add it if it does not already exist. So you start off your code with getting the option. We don’t yet know if it even exists at first, but we try to get it anyway.

    Next, check if ( false === $last_key ). If so, there is no saved value so initialize $last_key to -1, again so when we add 1 to it we get the first array value. To summarize:
    get the option
    if false comes back, set $last_key to -1
    if $last_key has reached the alphabet end, reset $last_key back to -1
    Assign to $letter the value extracted from $alphabet
    update the option
    return $letter

    Thread Starter nad33m

    (@nad33m)

    @bcworkz Thank you so much. The part about not needing the internal pointer now makes it simpler. With your answer I am confident I can now write the new code. I will report back with results and my final code.

    Thread Starter nad33m

    (@nad33m)

    function getNextLetter(){
    	$alphabet = array ('A', 'B', 'C, 'D');
    
    	$letterKey = LetterKey;
    	$recIndex = 0;
    	if(get_option( $letterKey ) !== false){
    		$recIndex = get_option( $letterKey );
    		$updateNextIndex = ($recIndex+1) < count($alphabet) ? ($recIndex+1) : 0;
    		update_option($letterKey, $updateNextIndex);
    		return $alphabet[$recIndex];
    	}else{
    		add_option($letterKey, 1);
    		return $alphabet[$recIndex];
    	}
    }

    So I got it to work using the above code, each time the function is called it returns the next letter, and starts from the beginning when it returns the last letter.

    $letterKey is stored in the database, which holds the last letter position.

    Hope that will help anyone needing similar code. Probably could of been coded more elegantly, but it works, so my problem is solved.

    A big thank you to bcworkz for pointing me in the right direction.

    Moderator bcworkz

    (@bcworkz)

    Nicely done! You’re most welcome.

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Sequential selection from array’ is closed to new replies.