I wrote a plugin that displays all products in a woocommerce store in admin settings option, now I want to add a link to download the products as CSV file.

The problem is, when I click the link I get a permission error saying I don't have permission to view this page.

Here's my code:

function extra_tablenav($which) {
    if ($which == "top") {
        echo '<h3 style="display:inline">'
        . __('These products are currently in the database:')
        . '</h3>' .
        '&nbsp;&nbsp;&nbsp;' .
        '<a href="' . admin_url('admin.php?page=download_csv.php') . '">' . __('Export to CSV') . '</a>';

How can I fix those permissions?

1 Answer 1


Do not point the URL to admin.php, use admin-post.php instead:

'<a href="' . admin_url( 'admin-post.php?action=print.csv' ) . '">'

In your plugin register a callback for that action:

add_action( 'admin_post_print.csv', 'print_csv' );

function print_csv()
    if ( ! current_user_can( 'manage_options' ) )

    header('Content-Type: application/csv');
    header('Content-Disposition: attachment; filename=example.csv');
    header('Pragma: no-cache');

    // output the CSV data

If you want to make the data available for anonymous users (not logged in), then register the callback again with:

add_action( 'admin_post_nopriv_print.csv', 'print_csv' );

… and remove the capability check from the function.

  • Just wanted to add for future reference that adding extra parameters to the URL can be accessed in the callback function by parsing the $_REQUEST variable.
    – eballeste
    Jun 29, 2017 at 7:09
  • 1
    @eballeste Parsing $_GET, not $_REQUEST. Always use only the data from expected places. $_REQUEST includes POST and COOKIE data.
    – fuxia
    Jun 29, 2017 at 7:11
  • Just adding for further clarity that although it is true that parsing the $_GET variable to parse the URL parameters is preferable to using the $_REQUEST variable, for security purposes, you should also be using nonces. Here's a useful link: tipsandtricks-hq.com/introduction-to-wordpress-nonces-5357
    – eballeste
    Jun 29, 2017 at 7:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.