I'm developing a plugin and I want to add a menu entry that forces a file download (a CSV).
There are a few posts in this forum and over the internet with a similar solution, all of them are quite old and that solution seems not to work anymore.
This is my current approach (based on the mentioned posts). This does force a file download, but the file is actually a generated HTML with all WP admin menu and everything.
MyPlugin::__construct()
$capability = 'manage_options';
$menu_slug = 'myplugin-data-export';
$function = [$this, 'exportCSVdata'];
add_submenu_page(null, '', '', $capability, $menu_slug, $function);
MyPlugin::exportCSVdata()
public function exportCSVdata()
{
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
}
This function is executed when I enter the URL http://example.com/wp-admin/admin.php?page=myplugin-data-export
So, the question maybe is,
how can I create a function inside my plugin class that generates a naked page? With no header, includes and all the WP html stuff?
In some ohter posts I saw a proposal to use admin-post.php
instead of admin.php
but didn't work either.
EDIT Plugin is being run as follows:
if ( !class_exists( 'MyPlugin' ) ) {
class MyPlugin
{
static $instance = false;
public static function getInstance()
{
if ( !self::$instance )
self::$instance = new self;
return self::$instance;
}
public function __construct()
{
register_activation_hook( __FILE__, [$this, 'mypluginInstall']);
add_action('admin_menu', [$this, 'adminMenuEntries']);
}
public function adminMenuEntries()
{
//... some stuff
$capability = 'manage_options';
$menu_slug = 'myplugin-data-export';
$function = [$this, 'exportCSVdata'];
add_submenu_page(null, '', '', $capability, $menu_slug, $function);
}
}
}
admin-post.php
, it serves a blank page with no error message or log. I'll try to elaborate if you say it should work.