Depending on what exactly you’re trying to achieve, I agree with Tom’s comment, that a WP-CLI command might be better. The advantage is that the command runs from php directly on the server (usually has no max execution time, loads different php.ini, etc.) and you don’t need to involve the webserver.
If that is not possible, the next best way is probably to create a custom REST endpoint. WordPress has a class WP_REST_Controller
, usually I write classes that extend
this and work from there. For simplicity the following example is not using inheritence, but I try to keep to the same lingo.
1. Register new route
New/custom routes are registered via register_rest_route()
like so
$version = 1;
$namespace = sprintf('acme/v%u', $version);
$base="/import";
\register_rest_route(
$namespace,
$base,
[
[
'methods' => \WP_REST_Server::CREATABLE,
// equals ['POST','PUT','PATCH']
'callback' => [$this, 'import_csv'],
'permission_callback' => [$this, 'get_import_permissions_check'],
'args' => [],
// used for OPTIONS calls, left out for simplicity's sake
],
]
);
This will create a new route that you can call via
http://www.example.com/wp-json/acme/v1/import/
default REST start-^ ^ ^
namespace with version-| |-base
2. Define permissions check
Maybe you need authentication? Use nonces?
public function get_import_permissions_check($request)
{
//TODO: implement
return true;
}
3. Create your actual endpoint callback
The method previously defined gets passed a WP_REST_Request
object, use that to access request body, etc. To stay consistent, it is usually best to return a WP_REST_Response
instead of custom printing of JSON or similar.
public function import_csv($request)
{
$data = [];
// do stuff
return new \WP_REST_Response($data, 200);
}
If you do all of this in OOP style, you’ll get the following class
class Import_CSV
{
/**
* register routes for this controller
*/
public function register_routes()
{
$version = 1;
$namespace = sprintf('acme/v%u', $version);
$base="/import";
\register_rest_route(
$namespace,
$base,
[
[
'methods' => \WP_REST_Server::CREATABLE,
'callback' => [$this, 'import_csv'],
'permission_callback' => [$this, 'get_import_permissions_check'],
'args' => [],
],
]
);
}
/**
* endpoint for POST|PUT|PATCH /acme/v1/import
*/
public function import_csv($request)
{
$data = [];
// do stuff
return new \WP_REST_Response($data, 200);
}
/**
* check if user is permitted to access the import route
*/
public function get_import_permissions_check($request)
{
//TODO: implement
return true;
}
}
But .. still 404? Yes, simply defining the class sadly doesn’t work (no autoloading by default 🙁 ), so we need to run register_routes()
like so (in your plugin file)
require_once 'Import_CSV.php';
add_action('rest_api_init', function(){
$import_csv = new \Import_CSV;
$import_csv->register_routes();
});