3

I was creating my application to automate all of my blogs from my desktop. Target, I'll post blog. That's all. I used XMLRPC service, as you know "xmlrpc.php".

I built many of parts, near to done... But stucked at custom fields which are starting with (_) an underscore. I would like to save as "_thumbnail_id" => (int)number. Nothing happened.

But when I tried "thumbnail_id" or something like that without starting with underscore. It's ok. Working well but start with underscore...

I need it for determine featured image of post. Without that tag; I couldn't. And I don't know alternatives.

I find this: https://wordpress.org/support/topic/how-can-i-change-protected-params-xmlrpc But not solving my problem. I don't want to change wordpress files. If I have to, I can write a small script without RPC.

Any help will be FANTASTIC!

3

Playing with XML-RPC and underscored custom fields:

Let's say we want to set the featured image to a given post with $remote_post_id.

We want it to be the attachment with ID equal to 300, so we want _thumbnail_id to be 300.

Here are three methods how one could achieve that:

Method #1 - Using post_thumbnail

It's possible to update/add the featured image with the post_thumbnail parameter:

$result = $client->query( 
    'wp.editPost', 
    array(
        $blog_id,
        $username,
        $password,
        $remote_post_id,
        $post_data = array(
            'post_thumbnail' => '300',
        ),
    ) 
);

as can be seen [here in the wp_xmlrpc_server][1] class.

Method #2 - Using custom_fields with meta_id

If we want to update a custom field of a post, we must know it's database meta_id value.

But how do we know the meta_id?

The custom fields are actually included by default, when we fetch a post with:

$result = $client->query( 
    'wp.getPost', 
    array(
        $blog_id,
        $username,
        $password,
        $remote_post_id,
    ) 
);

If the post has a featured post thumbnail, then the above result will contain this part:

<member>
    <name>custom_fields</name>
    <value>
        <array>
            <data>
                <value>
                    <struct>
                        <member>
                            <name>id</name>
                            <value>
                                <string>560</string>
                            </value>
                        </member>
                        <member>
                            <name>key</name>
                            <value>
                                <string>_thumbnail_id</string>
                            </value>
                        </member>
                        <member>
                            <name>value</name>
                            <value>
                                <string>200</string>
                            </value>
                        </member>
                    </struct>
                </value>
            </data>
        </array>
    </value>
 </member>

where the meta_id is for example 560 and the old meta_value is 200.

Now we can update the meta value of _thumbnail_id with our new value:

$result = $client->query( 
    'wp.editPost', 
    array(
        $blog_id,
        $username,
        $password,
        $remote_post_id,
        $post_data = array(
            'custom_fields' => array( 
                array( 
                    'id'    => '560', 
                    'key'   => '_thumbnail_id', 
                    'value' => 300 
                )
            ),
        ),
    ) 
);

Notice that if we skip the meta_id part, we would only run add_post_meta(), instead of the [update_metadata_by_mid()][2] that was introduced in this trac. We must also have the edit_post_meta capability.

But this is not the whole story, because meta keys that begin with underscore (_) are protected.

We can fix that by using the [register_meta()][3] function on the remote site.

For example:

/**
 * Unprotect the _thumbnail_id meta key to allow updates via XML-RPC 
 * We need to set this up on the remote site.
 */

add_action( 'init', function() {
        register_meta( 'post', '_thumbnail_id', 'absint', '__return_true' );
});

to unprotect the _thumbnail_id meta key. I first tried the intval as a sanitization callback but that didn't work.

We could use a similar setup for other protected meta keys.

Method #3 Using a custom XML-RPC method.

As @MarkKaplun mentioned in his answer, we could extend the XML-RPC setup to our needs. We could for example use the xmlrpc_methods filter to add our own method.

The Codex provides more information on that matter.

References:

Here are some links that helped me while testing this:

  • 1
    Have you tested that? Would be nice to see better docs than those in Codex about that (highly unnoticed function). – kaiser Nov 27 '14 at 20:59
  • I haven't test it yet, but I will try it out when I've the change. I wonder if @ErçinDedeoğlu had any success with the problem? – birgire Nov 27 '14 at 21:18
  • Some more info about it on an issue at Justin Tadlocks content standard GitHub repo. – kaiser Nov 27 '14 at 23:26
  • Thanks for the link. I did some testing and played around with this some more. @kaiser – birgire Dec 3 '14 at 3:56
  • 1
    ok thanks, will check it out when I've gotten some sleep ;-) – birgire Dec 3 '14 at 4:04
1

_Underscored meta data is defined to be data which is internal to the software and not directly changed by a user. This is probably why you can't change it via XMLRPC.

If you need this kind of functionality you can write a small plugin that extends the set of data you can change with XMLRPC.

But Since you question is specifically about featured images you should look for an api that lets you associate an attachment as a featured images. Fast google didn't epose any documentation for that but seems like people have done it successfully https://stackoverflow.com/questions/12355922/set-featured-image-for-wordpress-post-via-xml-rpc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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