Search code examples
phparrayswordpressvariablesshortcode

Creating a shortcode from the results of an array_rand function


The functions.php file of my WordPress site currently has in place blocks of code like this:

function examplecode01() { 
$i = '<a href="/path/" class="exampleclass" id="example-code-01"><img class="example01imgclass" src="path/example01.jpg" alt="Example 01"/></a>';
return $i;
} 
add_shortcode('example-code-01', 'examplecode01');

There are 5 or more of these, each with their respective variations of "example code ##" and such as described above. The shortcode line allows for an editor to specify a shortcode and pull in a specific banner image into a Blog post (using the first parameter of the add_shortcode), as follow:

[example-code-01]

What I wanted to do instead was to randomize it, in such a way that an editor can use the same shortcode anywhere and it will be a random banner image from those available.

In working toward this, I slightly modified the above code block as follows:

function examplecode01() { 
echo '<a href="/path/" class="exampleclass" id="example-code-01"><img class="example01imgclass" src="path/example01.jpg" alt="Example 01"/></a>;
}  

(I removed the shortcode line because it would cause problems in the output of the next section -- bear with me).

Okay, so there's several of the modified code blocks, each with their own image. At the end of them, I then have a function, as follows:

$functions = array('examplecode01', 'examplecode02', 'examplecode03', 'examplecode04', 'examplecode05'); 
$functions[array_rand($functions)]();

When I throw this into an otherwise-blank PHP file (for testing) and run it online, it outputs a random banner image from the ones I've listed. Hooray! Success... sort of.

See, what I need now is a way for the editors to call up that random result by way of a shortcode. I'm not 100% sure on how to make this happen, though. The original shortcode basically was ["id used in the code block", "function name"]

I thought about setting the result to a variable and then calling that variable, but I'm still not sure how it would "convert" (so to speak) to a shortcode...

Can anyone help me with this final part of the puzzle? Thank you in advance!


Solution

  • This is how I would do it

    function examplecode01(){
        return __FUNCTION__;
    }
    
    function examplecode02(){
        return __FUNCTION__;
    }
    
    function examplecode03(){
        return __FUNCTION__;
    }
    
    function examplecode04(){
        return __FUNCTION__;
    }
    
    function examplecode05(){
        return __FUNCTION__;
    }
    
    function examplecode() { 
        $functions = array('examplecode01', 'examplecode02', 'examplecode03', 'examplecode04', 'examplecode05'); 
        shuffle($functions); //randomize array
        $function = array_shift($functions); //get first array element
    
        return function_exists($function) ? $function() : '';
    } 
    //add_shortcode('example-code-random', 'examplecode');
    
    echo examplecode();
    

    Sandbox

    The __FUNCTION__ "magic" constant is the name of the current function, you can replace this with your actual code, it just makes seeing what function was called a bit easier.

    To be honest instead of doing this examplecode01 and examplecode02 (iterative functions) I would just make one short code (to rule them all) like:

    [examplecode]  //random
    [examplecode banner="1"] //examplecode01
    

    And so on, it will be easy to expand on later. Something like this:

    function examplecode($attr) { 
        $banners = array('example01.jpg', 'example02.jpg', 'example03.jpg', 'example04.jpg', 'example05.jpg'); 
        $atts = shortcode_atts(array(
            'banner' => false
        ), $atts );
    
        if($atts['banner'] && isset($banners[$atts['banner']-1])){
            //make sure to check if the index exists
            //you could handle this differently, such as not show a banner, show an error message etc...
            $index =  $atts['banner']-1;  //0 based vs 1 based
        }else{
            $index = rand(0, (count($banners)-1));
        }
    
        //pad with a leading 0 if less then 2
        $i = str_pad($index+1, 2, '0', STR_PAD_LEFT);       
    
        return '<a href="/path/" class="exampleclass" id="example-code-'.$i.'"><img class="example'.$i.'imgclass" src="path/'.$banners[$index].'" alt="Example '.$i.'"/></a>';
    } 
    add_shortcode('examplecode', 'examplecode');
    

    See if you do function{n} and you want to add a banner, you have to make a whole new function and shortcode. However, if you use the shortcode attributes then you only need to add the image to the array. No "banner" attribute it's random, otherwise it's the banner image number from the array. There is a bit of jiggling to keep your banners 1 based because arrays are 0 based. You can simplify it a lot by starting at 0 instead. But whatever...

    The last thing is whenever I write shortcodes I wrap them in a function exists, you don't have to do that. It's just something I like to do, just to be safe.

    if(!function_exists('examplecode')){
        function examplecode($attr) { ... }
    }
    

    Basically it prevents it from defining the function if it's already been defined.