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.