1

Hi guys so I have some data hitting my WP from an external company at /wp-json/wp/v2/jobs/ to be imported as a post.

This data contains JSON that needs to be imported, however it tried to set taxonomies using strings e.g. "Manager" rather than the term_id which would be say "381". This means I get an error returned.

{
    "code": "rest_invalid_param",
    "message": "Invalid parameter(s): job_location, job_industry, job_sector",
    "data": {
        "status": 400,
        "params": {
            "job_location": "job_location[0] is not of type integer.",
            "job_industry": "job_industry[0] is not of type integer.",
            "job_sector": "job_sector[0] is not of type integer."
        }
    }
}

So what I want is when they post this value to us, for example:

"job_sector":"Manager"

I want to instead loop through our taxonomies, and find the ID for this "Manager" job_sector, rebuild the JSON and THEN have WP import the data I pass, error free with the proper ID.

Can anyone help on how I can intercept the JSON and pass it along in the proper format?

I tried "rest_pre_dispatch" but this seems to be only editing the result sent back to them, it has already been processed by WP.

EDIT: Here is my code:

 function wpse281916_rest_check_referer( $result, $server, $request ) {
     if ( null !== $result ) {
         // Core starts with a null value.
         // If it is no longer null, another callback has claimed this request.
         // Up to you how to handle - for this example we will just return early.
         return $result;
     }

     $array = json_decode($result, true);
     $term = get_term_by('name',$array["job_sector"],'job_sector');
     $term = json_decode(json_encode($term),true);
     $termid = $term['term_id'];   
     $array['job_sector'] = $termid;
     $result = json_encode($array);
     return $result;
 }

// add the filter
add_filter( 'rest_pre_dispatch', 'wpse281916_rest_check_referer', 10, 3 );

EDIT2: After suggestion

    function wpse281916_rest_check_referer( $result, $server, $request ) {
        if ( null !== $result ) {
            // Core starts with a null value.
            // If it is no longer null, another callback has claimed this request.
            // Up to you how to handle - for this example we will just return early.
            return $result;
        }

        $array = json_decode($request, true);
        $term = get_term_by('name',$array["job_sector"],'job_sector');
        $term = json_decode(json_encode($term),true);
        $termid = $term['term_id'];
        $array['job_sector'] = $termid;
        $request = json_encode($array);
        return null;
    }

   // add the filter
   add_filter( 'rest_pre_dispatch', 'wpse281916_rest_check_referer', 10, 3 );
  • As an aside, you can figure out the ID via the REST API using the job_sector endpoints – Tom J Nowell Oct 24 '18 at 16:05
  • @TomJNowell Thanks! How would I start going about doing that? – KiwisTasteGood Oct 24 '18 at 16:15
1
+50

Using the rest_pre_dispatch hook is probably the most straightforward way to go, but you need to be careful about putting your new request data back into the WP_REST_Request object properly.

You were reassigning the WP_REST_Request object to an array of request data. Those changes are not persisted because the parameter is not passed by reference. Instead, you want to modify the WP_REST_Request object.

You can assign a parameter to the request object using array like syntax, or by using WP_REST_Request::set_param( $param_name, $param_value ).

You should also check to make sure you are only running this code on the correct route. I'd also move the priority to fire the hook earlier since you essentially are saying that this change should apply to everything happening on this request.

function wpse281916_rest_check_referer( $result, $server, $request ) {

    if ( '/wp/v2/jobs' !== $request->get_route() || 'POST' !== $request->get_method()) {
        return $result;
    }

    $job_sector = $request['job_sector'];

    if ( null === $job_sector ) {
        return $result;
    }

    $term = get_term_by( 'name', $job_sector, 'job_sector' );

    if ( $term && ! is_wp_error( $term ) ) {
        $request['job_sector'] = $term->term_id;
    } else {
        $request['job_sector'] = 0;
    }

    return $result;
}

// add the filter
add_filter( 'rest_pre_dispatch', 'wpse281916_rest_check_referer', 0, 3 );
  • Hi Timonthy, thanks for this the job seems to be going in but I get a blank response in postman and the software needs to get the right response or it wont know its been updated do you know why it would be blank? It seems $result is returning blank after I set the sector "$request['job_sector'] = $term->term_id;" but if I return $response before this point I get the proper response. Any ideas? – KiwisTasteGood Oct 29 '18 at 13:41
  • Are you modifying $result? The result returned from rest_pre_dispatch must be an empty value like null. That tells WordPress to continue processing the request and actually let the jobs route process your request. If you return the response now, you'll get a proper response back, but the job won't have actually been created. – Timothy Jacobs Oct 29 '18 at 16:19
  • Thanks for this, I aren't modifying result, but when I post in postman I get blank back, where as when I post without this custom script I get back all the post info that has been created - EDIT: I also just noticed in postman I get "500 Internal Server Error" top right! – KiwisTasteGood Oct 29 '18 at 16:31
  • If I remove all our custom code I get a response and a 201 Created which is correct, but with that custom code I get blank and a 500 :( – KiwisTasteGood Oct 29 '18 at 16:47
  • That typically indicates a PHP error. Could you check your error logs? Should be in wp-content/debug.log. You may have to add define( 'WP_DEBUG_LOG', true ); to your wp-config.php file. Codex – Timothy Jacobs Oct 29 '18 at 17:09
2

Seems like you looking for the rest_pre_dispatch hook.

This hook allows hijacking the request before dispatching by returning a non-empty. The returned value will be used to serve the request instead.

From the docs:

$result

(mixed) Response to replace the requested version with. Can be anything a normal endpoint can return, or null to not hijack the request.

Seems like to you have to modify the $request and return null in order to no hijack the default response.

  • It seems that this only lets me edit the response back for the request, it doesnt let me change their INITIAL JSON - BEFORE wordpress tried to import any of the data. – KiwisTasteGood Oct 25 '18 at 9:16
  • Could you add the full code in question? – BenB Oct 25 '18 at 13:44
  • Added my code! :) – KiwisTasteGood Oct 26 '18 at 11:29
  • 1
    Added to my answer :) – BenB Oct 26 '18 at 15:24
  • Amended my code is that what you meant? Doesnt work :( – KiwisTasteGood Oct 26 '18 at 16:21

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.