WordPress.org

Make WordPress Core

Opened 3 years ago

Last modified 5 weeks ago

#39003 new defect (bug)

menu_page_url() not working on Ajax call

Reported by: vinoth06 Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.6.1
Component: Administration Keywords: needs-testing reporter-feedback
Focuses: Cc:
PR Number:

Description

menu_page_url( 'menu_slug', false ) is always returning empty string on AJAX response. The global $_parent_pages; is return NULL on AJAX call. But the same menu slug is working on normal page load.

Change History (4)

#1 @mostafa.s1990
7 months ago

  • Keywords needs-testing added

#2 @SergeyBiryukov
3 months ago

  • Component changed from General to Administration

#3 @donmhico
2 months ago

  • Keywords reporter-feedback added

Hello @vinoth06,

Welcome to WordPress trac! Thank you for submitting this ticket.

I looked more into the issue and I found out that I'm getting the correct value from menu_page_url() via AJAX if the current user has the capability to see the created admin page. If the user isn't logged-in or lacking capability then I also receive nothing.

Here's the code I used for testing.

<?php
// Create admin menu page.
function test_admin_menu_page() {
        add_menu_page( 'Test Menu', 'Test Menu', 'manage_options', 'test_menu', 'test_menu_page' );
}
add_action( 'admin_init', 'test_admin_menu_page' );

// AJAX handler.
function test_ajax_menu_page_url() {
        // Outputs - http://wp.test/wp-admin/admin.php?page=test_menu if logged in as admin.
        // Outputs nothing if logged-out.
        echo menu_page_url( 'test_menu', false );
        wp_die();
}
add_action( 'wp_ajax_ampu', 'test_ajax_menu_page_url' );
add_action( 'wp_ajax_nopriv_ampu', 'test_ajax_menu_page_url' );

#4 @vinoth06
5 weeks ago

Hi donmhico

Thanks for you code, I have modified your code which will get the result from AJAX request. Kindly check and share feedback.

I have created as an plugin, so you can add it in your plugin directory to activate.

I have added the comments too for your clarifications.

<?php
/**
 * Plugin Name: Menu Page URL on AJAX
 * Plugin URI: https://buffercode.com/plugin/frontend-dashboard
 * Description: Menu Page URL on AJAX
 * Version: 1
 * Author: vinoth06
 * Author URI: https://buffercode.com/
 * License: GPLv2
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 *
 */

if ( ! defined( 'ABSPATH' ) ) {
        exit;
}

add_action( 'admin_init', 'enqueue_jquery' );
function enqueue_jquery() {
        wp_enqueue_script( 'jquery' );
}

// Create admin menu page.
function test_admin_menu_page() {
        add_menu_page( 'Test Menu', 'Test Menu', 'manage_options', 'test_menu_slug', 'test_menu_page' );
}

// Hope its not admin_init. it should be admin_menu like in the line 21, Correct me if am wrong
//add_action( 'admin_init', 'test_admin_menu_page' );
add_action( 'admin_menu', 'test_admin_menu_page' );

// AJAX handler.
function test_ajax_menu_page_url() {
        // Outputs - http://wp.test/wp-admin/admin.php?page=test_menu if logged in as admin.
        // Outputs nothing if logged-out.
        echo menu_page_url( 'test_menu', false );
        // Try the below it will give the exact URL of the page.
        //echo admin_url( '/admin.php?page=test_menu' );

        // Conclusion: If you use menu_page_url in ajax return it will send empty string.
        wp_die();
}

add_action( 'wp_ajax_ampu', 'test_ajax_menu_page_url' );
add_action( 'wp_ajax_nopriv_ampu', 'test_ajax_menu_page_url' );

function test_menu_page() {
        ?>
    <form method="post" class="submitOnAjax" action="<?php echo admin_url( 'admin-ajax.php?action=ampu' ) ?>">
        <button type="submit">Submit</button>
    </form>
    <script>
        jQuery(document).ready(function ($) {
            $('body').on('submit', '.submitOnAjax', function (e) {
                var form = $(this);
                $.ajax({
                    type: 'POST',
                    url: form.attr('action'),
                    data: form.serialize(),
                    success: function (results) {
                        //Check the Value here
                        console.log(results);
                        // It will echo empty string
                    }
                });
                e.preventDefault();
            });
        });
    </script>
        <?php
}
Note: See TracTickets for help on using tickets.