Question

I am developing a plugin that has a long-running function for setting up a load of posts of a custom post type. I want to run this function asynchronously. In order to do this, I have tried something like this:

add_action( 'admin_post_my_action', 'my_long_running_function' );

$url = admin_url( 'admin-post.php' );
$args = [
    'method'      => 'POST',
    'timeout'     => 50,
    'redirection' => 5,
    'blocking'    => true,
    'headers'     => [] ,
    'body'        => [
        'action' => 'my_action'
    ],
    'cookies'     => []
];
$response = wp_remote_post( $url, $args );

if ( is_wp_error( $response ) ) {
    $error_message = $response->get_error_message();
    printf(
        'Something went wrong: %s',
        $error_message
    );
} else {
    echo 'Response:<pre>';
    print_r( $response );
    echo '</pre>';
}

Please note that I know it has 'blocking' => true, which won't run asynchronously but I changed it to that so I could see the response.

In my_long_running_function, the results are emailed to the site admin. I am also outputting some debugging messages and have a break point in NetBeans.

The function is not getting called via wp_remote_post, the response from which is as follows:

Array
(
    [headers] => Requests_Utility_CaseInsensitiveDictionary Object
        (
            [data:protected] => Array
                (
                    [date] => Wed, 01 Jul 2020 05:23:22 GMT
                    [server] => Apache/2.4.37 (Win64) PHP/7.2.14
                    [x-powered-by] => PHP/7.2.14
                    [expires] => Wed, 11 Jan 1984 05:00:00 GMT
                    [cache-control] => no-cache, must-revalidate, max-age=0
                    [x-frame-options] => SAMEORIGIN
                    [referrer-policy] => strict-origin-when-cross-origin
                    [content-length] => 0
                    [content-type] => text/html; charset=UTF-8
                )
        )
    [body] => 
    [response] => Array
        (
            [code] => 200
            [message] => OK
        )
    [cookies] => Array
        (
        )
    [filename] => 
    [http_response] => WP_HTTP_Requests_Response Object
        (
            [response:protected] => Requests_Response Object
                (
                    [body] => 
                    [raw] => HTTP/1.1 200 OK
Date: Wed, 01 Jul 2020 05:23:22 GMT
Server: Apache/2.4.37 (Win64) PHP/7.2.14
X-Powered-By: PHP/7.2.14
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8
                    [headers] => Requests_Response_Headers Object
                        (
                            [data:protected] => Array
                                (
                                    [date] => Array
                                        (
                                            [0] => Wed, 01 Jul 2020 05:23:22 GMT
                                        )
                                    [server] => Array
                                        (
                                            [0] => Apache/2.4.37 (Win64) PHP/7.2.14
                                        )
                                    [x-powered-by] => Array
                                        (
                                            [0] => PHP/7.2.14
                                        )
                                    [expires] => Array
                                        (
                                            [0] => Wed, 11 Jan 1984 05:00:00 GMT
                                        )
                                    [cache-control] => Array
                                        (
                                            [0] => no-cache, must-revalidate, max-age=0
                                        )
                                    [x-frame-options] => Array
                                        (
                                            [0] => SAMEORIGIN
                                        )
                                    [referrer-policy] => Array
                                        (
                                            [0] => strict-origin-when-cross-origin
                                        )
                                    [content-length] => Array
                                        (
                                            [0] => 0
                                        )
                                    [content-type] => Array
                                        (
                                            [0] => text/html; charset=UTF-8
                                        )
                                )
                        )
                    [status_code] => 200
                    [protocol_version] => 1.1
                    [success] => 1
                    [redirects] => 0
                    [url] => http://my-site/wp-admin/admin-post.php
                    [history] => Array
                        (
                        )
                    [cookies] => Requests_Cookie_Jar Object
                        (
                            [cookies:protected] => Array
                                (
                                )
                        )
                )
            [filename:protected] => 
            [data] => 
            [headers] => 
            [status] => 
        )
)

I have tried invoking this via a url to admin-posts.php:

http://my-site/wp-admin/admin-post.php?action=my_action

This works as expected, with email sent and debugging messages output.

Given that the request above works and is a GET request, I have also tried my call to wp_remote_post with 'method' => 'GET', and I have tried with wp_remote_get. Neither worked.

I have also stepped through all the code that send the request and handles the response. Nothing helps to indicate the cause of the problem.

Any help on solving this much appreciated, even advice on how to debug invoking admin-post.php via wp_remote_post. This is my first experience of wp_remote_post. Or even an alternative approach to call my function asynchronously.

Was it helpful?

Solution

Thanks to the comment by Sally CJ, it turned out that the issue was that the user was not authenticated when invoking admin-post.php via wp_remote_post. The simplest solution was to ensure that the wp_remote_post had all the current cookies, as follows:

$nonce = wp_create_nonce( 'my-action' );
foreach ( $_COOKIE as $name => $value ) {
    $cookies[] = "$name=" . urlencode( is_array( $value ) ? serialize( $value ) : $value );
}
$url = admin_url( 'admin-post.php' );
$args = [
    'method'      => 'POST',
    'timeout'     => 50,
    'redirection' => 5,
    'blocking'    => true,
    'headers'     => [] ,
    'body'        => [
        'action'   => 'gpc_nightly_job',
        'my_nonce' => $nonce
    ],
    'headers'   => [
        'cookie' => implode( '; ', $cookies ),
    ]
];
return wp_remote_post( $url, $args );

EDIT: For increased security, I added a nonce to the request, which is checking in the long-running function via wp_verify_nonce.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top