How to get the post_id after you successfully create new post using xmlrpc api wp newPost?

Note: The WP REST API might be a better alternative.

Client

Let’s assume we use the built-in WP_HTTP_IXR_CLIENT (see e.g. my previous answer):

include_once( ABSPATH . WPINC . '/class-IXR.php' );
include_once( ABSPATH . WPINC . '/class-wp-http-ixr-client.php' );

$client = new WP_HTTP_IXR_CLIENT( 'https://example.tld/xmlrpc.php' );

$result = $client->query( 
    'wp.newPost', 
    [
        $blog_id    = 0,
        $user       = "user",     // <-- Edit this
        $password   = "password", // <-- Edit this
        [
            'post_status'  => 'draft', // Here we use 'draft' while testing
            'post_title'   => 'xml-rpc testing - random ' . rand( 0, 999 ),
            'post_content' => 'Hello xml-rpc!' ,
        ]
    ]
);

We don’t get the newly server post ID from the $result, as one might expect.

Note that for successful request the WP_HTTP_IXR_Client::query method only returns true, else false.

wp.newPost response

A successful wp.newPost response is like

<?xml version="1.0"?>
<methodCall>
<methodName>wp.newPost</methodName>
<params>
<param><value><array><data>
  <value><int>0</int></value>
  <value><string>user</string></value>
  <value><string>password</string></value>
  <value><struct>
  <member><name>post_status</name><value><string>draft</string></value></member>
  <member><name>post_title</name><value><string>xml-rpc testing - random 471</string></value></member>
  <member><name>post_content</name><value><string>hello xml-rpc!</string></value></member>
</struct></value>
</data></array></value></param>
</params></methodCall>
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
  <params>
    <param>
      <value>
      <string>123</string>
      </value>
    </param>
  </params>
</methodResponse>

where we displayed it with $client->debug = true; but note that this is displaying the user password in the open!

Here’s how the client handles the debug:

if ( $this->debug ) {
    echo '<pre class="ixr_response">' 
   . htmlspecialchars( wp_remote_retrieve_body( $response ) ) 
   . "\n</pre>\n\n";
}

Message

This is how the message property is constructed:

$this->message = new IXR_Message( wp_remote_retrieve_body( $response ) );

and then we can see how WP_HTTP_IXR_CLIENT::query tries to parse it:

 if ( ! $this->message->parse() ) {
     // XML error
     $this->error = new IXR_Error(-32700, 'parse error. not well formed');
     return false;
 }

It also checks for the fault message type:

 // Is the message a fault?
 if ( $this->message->messageType == 'fault' ) {
     $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
      return false;
 }

and if successful it returns true:

 // Message must be OK
 return true;

The corresponding IXR_Message object looks like

IXR_Message object (
    [message] => 
    [messageType] => methodResponse
    [faultCode] => 
    [faultString] => 
    [methodName] => 
    [params] => Array
        (
            [0] => 123
        )

    [_arraystructs] => Array
        (
        )

    [_arraystructstypes] => Array
        (
        )

    [_currentStructName] => Array
        (
        )

    [_param] => 
    [_value] => 
    [_currentTag] => 
    [_currentTagContents] => 
    [_parser] => Resource id #155
    [currentTag] => string
)

where 123 is the new post ID.

Example

Here’s an example how we could get hold of the new post ID, in a custom method:

$post_id = 0;

if( ! is_a( $client->error, '\IXR_Error' ) )
    return $post_id;

if( ! is_a( $client->message, '\IXR_Message' ) )
    return $post_id;

if( 'methodResponse' !== $client->message->messageType )
    return $post_id;

if( ! isset( $client->message->params[0] ) )
    return $post_id;

$post_id = $client->message->params[0];

return $post_id;

Hope it helps.

tech