7

I'm trying to update a CPT post's metadata using the REST API. I can update a numeric metadata element using a POST such as this:

example.com/wp-json/wp/v2/posts/73/meta/229?value=2

This method is based on a workaround found here: WP REST API "rest_no_route" when trying to update meta

I can also update the meta data using a post here: example.com/wp-json/wp/v2/posts/73/meta/229

with this JSON in the body:

{"value":"2"}

The field I NEED to update contains a serialized array of data, though. When I try to update field using the second method (JSON body), I get this error:

{"value": [
{
  "name": "Related Documents",
  "default": true,
  "documents": [
    {
      "label": "RFA - Revit File",
      "file_location": "http://example.com/wp-content/uploads/2017/03/file.pdf"
    }
  ]
}
]
}

I've also tried sending my data as a serialized array (which is how it gets stored in MySql).

When I send:

{"value": "{a:0}"}

I get:

{
"code": "rest_post_invalid_action",
"message": "Invalid existing meta data for action.",
"data": {
"status": 400
}
}

Notes: This metadata is a field that's part of a WooCommerce Plugin: https://woocommerce.com/products/product-documents/

I have this plugin installed to expose my custom post types to the API (and I'm able to RETRIEVE the data): wordpress.org/plugins/wp-rest-api-controller/

I also have this plugin installed to allow access to the meta endpoints: wordpress.org/plugins/rest-api-meta-endpoints/

My end goal here is to stuff new data into the MySql database for this custom field. I'm learning that the WP REST API is still very undocumented and rather weak when it comes to meta data, especially (1) for custom post types, and (2) for non-string/numeric data types.

I'm considering writing a basic PHP page that will take a product ID, find the correct meta record using a WordPress function, and updating the data by turning posted JSON into a serialized array, but I'm not familiar enough with PHP to do this, and I'd also have to take some security things into account. Any examples or ideas on how to get this started, though, or if there's a better way to get my metadata updated?

  • Sorry for the non-link links in my post... my reputation on SO's main site didn't flow over to the Wordpress SE site. – Chet at C2IT May 11 '17 at 14:01
4

On the initial issues, are you positive the plugin is registering the fields to be made available to the api? the register_meta needs show_in_rest => true assigned.

Also, the CPT needs custom-fields in its supports array, 'supports' => array('title','editor','thumbnail','custom-fields') for that to made available when accessing the CPTs api endpoint.

I cover that (with links, etc.) in this answer to a different question: https://wordpress.stackexchange.com/a/266277/118366

If either of those values are missing, you could possibly hook-in to add them or even overwrite the functions altogether. Just a thought.

I'm considering writing a basic PHP page that will take a product ID, find the correct meta record using a WordPress function, and updating the data by turning posted JSON into a serialized array, but I'm not familiar enough with PHP to do this

For this, look into json_decode and json_encode. You can set assoc argument to true with json_decode and get an array rather than an object.

An (untested) quick example function of retrieving some json and setting the decoded results into a variable:

$json = file_get_contents('PATH/TO/FILE.json');
function the_json_contents($json_to_get){

            $json_in_array = json_decode($json_to_get, true); //json string to array

            return $json_in_array;
        }
function do_stuff_do_json() {
    $json_array = the_json_contents($json);
    foreach($json_array['id'] as $js) { //assuming we have an 'id' key
        $somevariable  = $js['someKey'];
        $somevariable2 = $js['someOtherKey'];
    } 

}

Any examples or ideas on how to get this started, though, or if there's a better way to get my metadata updated?

A custom route and endpoint may be the most effective way to do this (assuming it isn't just the plugin not having exposed those items to the api, as mentioned off the top). You will still need to take into account nonce checks and other possible authentication depending how you're using the endpoints. Routes and Endpoints and Custom Endpoints are what you looking for in the api documentation; probably Controller Classes, too.

Again, I would check the plugin to see if it has the meta fields registered for the api like mentioned initially.

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.