Error with Custom Admin Screen in iframe Thickbox

I have a plugin that adds a new admin screen in an iframe. I created a PHP file in my plugin, and I put a link with a class of Thickbox to that. Everything works just fine, but it produces a PHP error when WP_DEBUG is set to true. Looking at the WordPress source code, there’s no way around the error if I put a PHP from outside /wp-admin/ directly in an iframe.

Notice: Undefined offset: 1 in …/wp-includes/vars.php on line 28

Read More

It happens because WordPress is running regex on the web address to extract the file name to set the $pagenow variable, but it assumes the file will be in /wp-admin/. Since it’s not, there are no matches.

Here is the plugin. The file is children.php.

Is there a better way to create a custom admin screen that can be included in an iframe Thickbox that runs through a /wp-admin/ file?

Related posts

Leave a Reply

1 comment

  1. Interesting question.
    Investigating it, I’ve found a [wp-hackers] thread by the same Dion Hulse which gives a bit more of information.

    First, a testing page with a simple link which will open another admin page in a thickbox.

    add_action('admin_menu', 'wpse_71437_admin_submenu');
    
    function wpse_71437_admin_submenu() 
    {
        add_menu_page(
            'TB', 
            '<span style="color:#e57300;">Thickbox</span>', 
            'edit_pages', 
            'open_hidden_page_in_thickbox', 
            'wpse_71437_submenu_page',
            '', // no icon
            1 // create before Dashboard menu item
        );
    }
    
    function wpse_71437_submenu_page() 
    {
        wp_enqueue_style('thickbox');
        wp_enqueue_script('thickbox');
        ?>
        <div id="icon-upload" class="icon32"></div><h2>Thickbox</h2>
        <br><br>
        <a href="#" id="open-tb">Click Here</a>
    
        <script type="text/javascript">
        jQuery(document).ready(function() {   
            jQuery("#open-tb").click(function() {                 
                tb_show("", "index.php?page=video_page_hidden&TB_iframe=true");
                return false;
            });
        });             
        </script>
        <?php
    }
    

    Now, the page that will be opened in the thickbox. It’s parent is defined as null, so it doesn’t show up in the menu. And the callback is an empty function, if accessed directly nothing appears.

    /**
     * Add a hidden and empty submenu page
     */
    add_action('admin_menu', 'wpse_71437_admin_menu');
    
    function wpse_71437_admin_menu() 
    {
        add_submenu_page(
            null, // doesn't show up in the menu, attached to "index.php" (not sure why)
            'Video', 
            'Video', 
            'edit_pages', 
            'video_page_hidden', 
            'wpse_71437_menu_options'
        );
    }
    
    function wpse_71437_menu_options() { /* Print nothing */ }
    

    And finally, the trick!
    Intercept the hidden page load and print some iframe content:

    /**
     * Intercept our hidden/empty page and print the Thickbox content
     */
    add_action( 'load-dashboard_page_video_page_hidden', 'wpse_71437_intercept_thickbox' ); 
    
    function wpse_71437_intercept_thickbox() 
    { 
        iframe_header(); 
        echo '<iframe width="100%" height="380px" src="http://www.youtube.com/embed/cL6qe0b-_BA" frameborder="0" allowfullscreen></iframe>';
        iframe_footer(); 
        exit; //Die to prevent the page continueing loading and adding the admin menu's etc. 
    }