0

I am using the latest version of Wordpress and trying to run a simple PHP script to create a wordpress post but unfortunately it isn't working. I am using Cloudflare plus have a webhost that is providing an SSL certificate if it matters.

There are no errors in the PHP logs and nothing unusual in the Cloudflare logs... I am very confused where this is breaking :(

PHP script:

$usr = 'ABCXYZ';
$pwd = 'ABCXYZ';
$xmlrpc = 'https://www.ABCXYZ.com/xmlrpc.php';
$client = new IXR_Client($xmlrpc);
$category = 'ABCXYZ';
//$tag = 'ABCXYZ';

$client -> debug = true; //optional but useful

$params = array(
    'post_type' => 'post',
    //publish
    'post_status' => 'publish',
    'post_title' => $title,
    'post_author' => 1,
    'comment_status'=> 'open',
    'terms_names'  => array( 
            'post_tag' => array( $tag ), 
            'category' => array( $category )),
    //'post_excerpt' => 'This is my test test',
    'post_content' => $content
);

$res = $client -> query('wp.newPost',1, $usr, $pwd, $params);

Response:

POST /xmlrpc.php HTTP/1.0
Host: www.ABCXYZ.com
Content-Type: text/xml
User-Agent: wp-iphone/4.8.1 (iPhone OS 8.1.3, iPad) Mobile
Content-Length: 1163

<?xml version="1.0"?>
<methodCall>
<methodName>wp.newPost</methodName>
<params>
<param><value><int>1</int></value></param>
<param><value><string>ABCXYZ</string></value></param>
<param><value><string>ABCXYZ</string></value></param>
<param><value><struct>
  <member><name>post_type</name><value><string>post</string></value></member>
  <member><name>post_status</name><value><string>publish</string></value></member>
  <member><name>post_title</name><value><string>test title2</string></value></member>
  <member><name>post_author</name><value><int>1</int></value></member>
  <member><name>comment_status</name><value><string>open</string></value></member>
  <member><name>terms_names</name><value><struct>
  <member><name>post_tag</name><value><array><data>
  <value><string>test tag</string></value>
</data></array></value></member>
  <member><name>category</name><value><array><data>
  <value><string>ABCXYZ</string></value>
</data></array></value></member>
</struct></value></member>
  <member><name>post_content</name><value><string>test content</string></value></member>
</struct></value></param>
</params></methodCall>
8
  • Is the request definitely making it through to the origin server and not e.g. serving a cached response from the edge server? e.g. check the access logs. Can you make your XMLRPC requests directly to the origin server instead?
    – Rup
    Oct 7, 2020 at 12:38
  • @Rup confirmed, I do see an entry in the access log for each request: POST /xmlrpc.php HTTP/1.1" 200 4435 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
    – AAA
    Oct 7, 2020 at 12:49
  • Would it not be easier to use the REST API? Keep in mind that the REST API is capable of doing more, doesn't require XML to parse, and is available in more places, whereas XMLRPC is disabled on a lot of hosts for security reasons. Also are you sure that's the response? It looks more like the request
    – Tom J Nowell
    Oct 7, 2020 at 13:04
  • Looking at the code for IXR_Client that is most likely the request not the response, it displays both assuming there were no issues. What's the value of $res? Are you sure it wouldn't be easier to make a HTTP POST to example.com/wp-json/wp/v2/posts with the basic auth plugin?
    – Tom J Nowell
    Oct 7, 2020 at 13:08
  • @TomJNowell maybe I should switch to HTTP POST - is this the REST API approach? Do you have sample code that would do a post with this approach? I havent heard of it until this post...
    – AAA
    Oct 7, 2020 at 15:09

1 Answer 1

2

Instead of using XMLRPC which isn't available on some hosts, use the REST API instead.

Send a HTTP POST request to the posts endpoint containing a JSON object with your desired post, with an authentication header.

To do this, we're going to need an authentication plugin ( standard WP only supports nonce + cookie which isn't useful for an external app ).

First, install the JSON Basic auth plugin https://github.com/WP-API/Basic-Auth

With this we can now do this on a remote WP site to create posts:

$response = wp_remote_post(
    'https://example.com/wp-json/wp/v2/posts',
    [
        'headers' => [
            'Authorization' => 'Basic ' . base64_encode( 'username:password' )
        ],
        'body' => [
            'title'   => 'Post Title',
            'status'  => 'publish',
            'content' => 'Hello World!',
        ],
    ]
);

if ( wp_remote_retrieve_response_message( $response ) === 'Created' ) {
    echo 'success!';
}

Likewise we can use other tools, e.g. here is the same example written as a curl command for the command line:

curl --user admin:password -X POST -H "Content-Type: application/json" -d "{title:'Post Title',status:'publish',content:'hello world'}" https://example.com/wp-json/wp/v2/posts
3
  • Tom - thank you! I think this is the right path... I installed the plugin, copied the copy to a new PHP file but when I run it... nothing happens. I swapped in my url and a username:password that I know works. No error... in this script what is actually calling the wp_remote_post? I am not running this within Wordpress, I am running this outside of Wordpress and creating posts.
    – AAA
    Oct 7, 2020 at 23:16
  • hmmm and when I try the rest approach I get the following: {"code":"rest_invalid_json","message":"Invalid JSON body passed.","data":{"status":400,"json_error_code":4,"json_error_message":"Syntax error"}}%
    – AAA
    Oct 7, 2020 at 23:22
  • Sounds like the request you sent didn't contain a valid JSON object, run the payload through a JSON validator, or better yet rely on json_encode or whatever your chosen language provides to encode and validate JSON. Remember, the new gutenberg editor uses the REST API to create posts, so anything it can do, so can you
    – Tom J Nowell
    Oct 8, 2020 at 12:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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