Search code examples
phpwordpressshortcode

How to place php inside php


Yes, this is similar to Can you put PHP inside PHP with echo?, but not identical and I would like to actually find a solution or a way to accomplish this.

Surely, there must be a way to show content to specific user groups within a template...

I have a wordpress menu that I'd like to only display to users with a set role.

I use this code to display my menu:

<?php wp_nav_menu( array( 'theme_location' => 'max_mega_menu_1' ) ); ?>

But the problem is that I need to use a snippet like the one below to execute opening and closing shortcodes to hide the menu from everyone else:

<?php
    $menu = "my menu code here";
    echo do_shortcode("[um_show_content roles='um_efa-pack'] ". $menu ." [/um_show_content]");
?>

How can I come up with a way of getting my original menu code within that PHP variable? I've been looking, but I can't find a good solution and I'm not even sure what to search for anymore.

If it helps, there is also a shortcode for the menu, but that would also require PHP to execute, no?

[maxmegamenu location=max_mega_menu_1]

Solution

  • Take a look at Output Control, specifically Output Buffering.

    If you need PHP output as a variable, it's an invaluable tool that's really easy to use.

    <?php
        /* Turn on Output Buffering, effectively 'pausing'
         * all PHP output, putting it in a buffer instead.
         */
        ob_start();
    
        /* Output/Display the menu. Since we started Output
         * Buffering, it won't actually display yet - instead
         * it gets added to the buffer.
         */
        wp_nav_menu( array( 'theme_location' => 'max_mega_menu_1' ) );
    
        /* Dump the buffer into a variable, and turn off
         * the Output Buffer so we can start actually sending
         * output to the client again.
         */
        $menu = ob_get_clean();
    
        /* Now use the shortcode as you would normally, since
         * $menu contains the HTML markup from the nav menu and
         * Output Buffering has been turned off with ob_get_clean()
         */
        echo do_shortcode( '[um_show_content roles="um_efa-pack"]'. $menu .'[um_show_content]' );
    ?>
    

    I couldn't speak to the embedding a shortcode inside a shortcode, as it depends on how each of those shortcodes was built. Some don't integrate very well together, especially ones with enclosed content. Though, it may not hurt to try simply using them:

    echo do_shortcode( '[um_show_content roles="um_efa-pack"][maxmegamenu location="max_mega_menu_1"][/um_show_content]' );
    

    It looks like you're using a plugin (um?) to handle this. Natively in WordPress it would as simple as checking the user's role using current_user_can() or comparing against the current User's Roles

    $user = wp_get_current_user();
    if( in_array( 'whatever-role', (array) $user->roles ) ){
        // Has the role, show first menu
        wp_nav_menu( array( 'theme_location' => 'max_mega_menu_1' ) );
    } else {
        // Doesn't have the role, show second menu
        wp_nav_menu( array( 'theme_location' => 'max_mega_menu_2' ) );
    }