最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

WordPress REST API - Modify JSON before importing

matteradmin8PV0评论

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 );

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 );
Share Improve this question edited Oct 26, 2018 at 16:28 KiwisTasteGood asked Oct 24, 2018 at 15:38 KiwisTasteGoodKiwisTasteGood 1402 silver badges14 bronze badges 2
  • As an aside, you can figure out the ID via the REST API using the job_sector endpoints – Tom J Nowell Commented Oct 24, 2018 at 16:05
  • @TomJNowell Thanks! How would I start going about doing that? – KiwisTasteGood Commented Oct 24, 2018 at 16:15
Add a comment  | 

2 Answers 2

Reset to default 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 );

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.

Post a comment

comment list (0)

  1. No comments so far