最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

WP Rest Api- Update callback (POST request) to existing database table through the rest api

programmeradmin4浏览0评论

I have registed a new rest route to existing database table called wpso_messages. I was able to create a get_callback function that fetches all the data from the database.

I want to add a POST request functionality, that allows me to introduce new data rows to the wpso_messages table through the rest api. Any advise how to accomplish that?

below is my code for registering the rest route and get_callback:

<?php



function get_wp_query() {
    global $wpdb;
    $rows = $wpdb->get_results("SELECT * FROM wpso_messages");
    foreach( $rows as $index => $row ) {
    
           $user_from_id = $rows[$index]->user_from; 
           $user_to_id = $rows[$index]->user_to; 
           $rows[$index]->username_from = get_user_by('id', $user_from_id)->display_name;
           $rows[$index]->username_to = get_user_by('id', $user_to_id)->display_name;
    }
    return $rows;
};
add_action( 'rest_api_init', function () {
    register_rest_route( 'wp/v2', 'messages', array(
        'methods' => 'GET',
        'callback' => 'get_wp_query'
        ) );
    } );

For the POST request, below is an example of an input json to create new entry in the wpso_messages table:

{"user_from": "82", "user_to": "1", "message": "Iam interested to bid", "listing_id": "22775"}

Final Solution based on Sally C.J answer: Note that it includes few checks such as that user ids are valid and that the key values in the json body are in the SQL database columns.

#GET request function

function get_wp_query() {
    global $wpdb;
    $rows = $wpdb->get_results("SELECT * FROM wpso_messages");
    foreach( $rows as $index => $row ) {
    
           $user_from_id = $rows[$index]->user_from; 
           $user_to_id = $rows[$index]->user_to; 
           $rows[$index]->username_from = get_user_by('id', $user_from_id)->display_name;
           $rows[$index]->username_to = get_user_by('id', $user_to_id)->display_name;
           $rows[$index]->author= array('Welcome'=>'Home');
    }
    return $rows;
};

#POST request arguments validation

function my_create_item_args() {
    return array(
        'user_from' => array(
            'required'          => true,
            'validate_callback' => function ( $param ) {
                return is_numeric( $param );
            },
        ),
        'user_to' => array(
            'required'          => true,
            'validate_callback' => function ( $param ) {
                return is_numeric( $param );
            },
        ),
        'message'   => array(
            'required'          => true,
            'sanitize_callback' => function ( $param ) {
                // this allows basic HTML tags like <strong> and <em>
                #return wp_filter_kses( $param );

                // this allows line breaks, but strips all HTML tags
                return sanitize_textarea_field( $param );
            },
        ),
        'listing_id' => array(
            'required'          => true,
            'validate_callback' => function ( $param ) {
                return is_numeric( $param );
            },
        ),
        ''
        // ... other args.
    );
}

#Post request function
function post_function( WP_REST_Request $request ) {



    #getting json body
    $body = $request->get_json_params();
    
    #checking if there is an invalid entry otherwise it wont be processed (example unseen)
    $valid_entries=["user_from","message","user_to","listing_id","seen"];
    foreach( $body as $keysx1=>$valuesx1 ) {
        if (in_array($keysx1, $valid_entries, true)) {
        
        } else {
        return new WP_Error( 'invalid entry', __($keysx1 . ' is an invalid entry'), array( 'status' => 400 ) );
        }
    }
    
    #######Checking users
    $users = get_users();
    foreach( $users as $user ) {
        // get user names from the object and add them to the array
        $useridlist[] = $user->id;
    }
    $userfromx1=$body['user_from'];
    $usertox1=$body['user_to'];
    #Checking sender and reciever are not same
    if ($userfromx1!=$usertox1) {
        
        } else {
        return new WP_Error( 'invalid message', __('Sender and reciever cant be same'), array( 'status' => 400 ) );
        }
    #Checking userto and userfrom are in users list
    if (in_array($userfromx1, $useridlist, true)) {
        
        } else {
        return new WP_Error( 'invalid user id', __('user id specified in user_from is invalid'), array( 'status' => 400 ) );
        }
    
    if (in_array($usertox1, $useridlist, true)) {
        
        } else {
        return new WP_Error( 'invalid user id', __('user id specified in user_to is invalid'), array( 'status' => 400 ) );
        }
    
    global $wpdb;
    $body["created_at"] = current_time('mysql');
    $wpdb->insert('wpso_messages', $body);  
    return $body;

}

add_action( 'rest_api_init', function () {
    register_rest_route( 'my-plugin/v1', 'messages', array(array(
        'methods' => 'GET',
        'callback' => 'get_wp_query'
        ),
        array(
        'methods'  => 'POST',
        'callback' => 'post_function',
        'args'                => my_create_item_args(),
        'permission_callback' => function () {
        // This is just an example of checking the user's permissions..
        return current_user_can( 'edit_posts' );
    },)));
    });

I have registed a new rest route to existing database table called wpso_messages. I was able to create a get_callback function that fetches all the data from the database.

I want to add a POST request functionality, that allows me to introduce new data rows to the wpso_messages table through the rest api. Any advise how to accomplish that?

below is my code for registering the rest route and get_callback:

<?php



function get_wp_query() {
    global $wpdb;
    $rows = $wpdb->get_results("SELECT * FROM wpso_messages");
    foreach( $rows as $index => $row ) {
    
           $user_from_id = $rows[$index]->user_from; 
           $user_to_id = $rows[$index]->user_to; 
           $rows[$index]->username_from = get_user_by('id', $user_from_id)->display_name;
           $rows[$index]->username_to = get_user_by('id', $user_to_id)->display_name;
    }
    return $rows;
};
add_action( 'rest_api_init', function () {
    register_rest_route( 'wp/v2', 'messages', array(
        'methods' => 'GET',
        'callback' => 'get_wp_query'
        ) );
    } );

For the POST request, below is an example of an input json to create new entry in the wpso_messages table:

{"user_from": "82", "user_to": "1", "message": "Iam interested to bid", "listing_id": "22775"}

Final Solution based on Sally C.J answer: Note that it includes few checks such as that user ids are valid and that the key values in the json body are in the SQL database columns.

#GET request function

function get_wp_query() {
    global $wpdb;
    $rows = $wpdb->get_results("SELECT * FROM wpso_messages");
    foreach( $rows as $index => $row ) {
    
           $user_from_id = $rows[$index]->user_from; 
           $user_to_id = $rows[$index]->user_to; 
           $rows[$index]->username_from = get_user_by('id', $user_from_id)->display_name;
           $rows[$index]->username_to = get_user_by('id', $user_to_id)->display_name;
           $rows[$index]->author= array('Welcome'=>'Home');
    }
    return $rows;
};

#POST request arguments validation

function my_create_item_args() {
    return array(
        'user_from' => array(
            'required'          => true,
            'validate_callback' => function ( $param ) {
                return is_numeric( $param );
            },
        ),
        'user_to' => array(
            'required'          => true,
            'validate_callback' => function ( $param ) {
                return is_numeric( $param );
            },
        ),
        'message'   => array(
            'required'          => true,
            'sanitize_callback' => function ( $param ) {
                // this allows basic HTML tags like <strong> and <em>
                #return wp_filter_kses( $param );

                // this allows line breaks, but strips all HTML tags
                return sanitize_textarea_field( $param );
            },
        ),
        'listing_id' => array(
            'required'          => true,
            'validate_callback' => function ( $param ) {
                return is_numeric( $param );
            },
        ),
        ''
        // ... other args.
    );
}

#Post request function
function post_function( WP_REST_Request $request ) {



    #getting json body
    $body = $request->get_json_params();
    
    #checking if there is an invalid entry otherwise it wont be processed (example unseen)
    $valid_entries=["user_from","message","user_to","listing_id","seen"];
    foreach( $body as $keysx1=>$valuesx1 ) {
        if (in_array($keysx1, $valid_entries, true)) {
        
        } else {
        return new WP_Error( 'invalid entry', __($keysx1 . ' is an invalid entry'), array( 'status' => 400 ) );
        }
    }
    
    #######Checking users
    $users = get_users();
    foreach( $users as $user ) {
        // get user names from the object and add them to the array
        $useridlist[] = $user->id;
    }
    $userfromx1=$body['user_from'];
    $usertox1=$body['user_to'];
    #Checking sender and reciever are not same
    if ($userfromx1!=$usertox1) {
        
        } else {
        return new WP_Error( 'invalid message', __('Sender and reciever cant be same'), array( 'status' => 400 ) );
        }
    #Checking userto and userfrom are in users list
    if (in_array($userfromx1, $useridlist, true)) {
        
        } else {
        return new WP_Error( 'invalid user id', __('user id specified in user_from is invalid'), array( 'status' => 400 ) );
        }
    
    if (in_array($usertox1, $useridlist, true)) {
        
        } else {
        return new WP_Error( 'invalid user id', __('user id specified in user_to is invalid'), array( 'status' => 400 ) );
        }
    
    global $wpdb;
    $body["created_at"] = current_time('mysql');
    $wpdb->insert('wpso_messages', $body);  
    return $body;

}

add_action( 'rest_api_init', function () {
    register_rest_route( 'my-plugin/v1', 'messages', array(array(
        'methods' => 'GET',
        'callback' => 'get_wp_query'
        ),
        array(
        'methods'  => 'POST',
        'callback' => 'post_function',
        'args'                => my_create_item_args(),
        'permission_callback' => function () {
        // This is just an example of checking the user's permissions..
        return current_user_can( 'edit_posts' );
    },)));
    });
Share Improve this question edited Mar 1, 2022 at 18:22 The Oracle asked Feb 25, 2022 at 21:46 The OracleThe Oracle 971 silver badge12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I want to add a POST request functionality, that allows me to introduce new data rows to the wpso_messages table through the rest api. Any advise how to accomplish that?

Yes, and note that I wrote this based on the official REST API handbook and the core endpoints.

So from the "Routes and Endpoints → Routes vs Endpoints" section — note the part I highlighted:

A route is the “name” you use to access endpoints, used in the URL. A route can have multiple endpoints associated with it, and which is used depends on the HTTP verb.

Where "HTTP verb" here is essentially a HTTP request method like GET or POST.

So for example, the core /wp/v2/posts route has 2 endpoints — one with a GET method (for retrieving posts) and the other with a POST method (for creating a post).

Therefore, you could follow the same approach, i.e. add an endpoint to your "messages" route, possibly with the POST method, like so:

// I intentionally used my-plugin as the vendor name, and not "wp". See the
// "Additional Notes" at the bottom in my answer.
register_rest_route( 'my-plugin/v2', 'messages', array(
    // Endpoint 1 - list items.
    array(
        'methods'  => 'GET',
        'callback' => 'get_wp_query',
        // ... other args.
    ),

    // Endpoint 2 - create items.
    array(
        'methods'  => 'POST',
        'callback' => 'my_create_item',
        // ... other args.
    )
) );

function my_create_item( WP_REST_Request $request ) {
    // your code here...
}

The actual code that performs the new row/data insertion will depend entirely on you, but you would want to use wpdb::insert().

Additional Notes

  1. A route's namespace is composed of <vendor name>/<version>, and you should use your own vendor name, e.g. my-plugin, and not wp. So my-plugin/v2 is good, but wp/v2 shouldn't be used.

    Because the "Routes and Endpoints → Namespaces" section stated:

    Do not place anything into the wp namespace unless you are making endpoints with the intention of merging them into core.

  2. Remember to always set a permission callback for your endpoints.

    See "Routes and Endpoints → Permissions Callback" and "Adding Custom Endpoints → Permissions Callback" for more details, but for REST API routes that are intended to be public, one can use __return_true() as the permission callback, i.e. 'permission_callback' => '__return_true'.

  3. You would also want to register your endpoint arguments using the args key, and set a validate and sanitize callback which will validate/sanitize the arguments. E.g.

    • The args for Endpoint 2 above:

      // Endpoint 2 - create items.
      array(
          'methods'             => 'POST',
          'callback'            => 'my_create_item',
          'permission_callback' => function () {
              // This is just an example of checking the user's permissions..
              return current_user_can( 'edit_posts' );
          },
          'args'                => my_create_item_args(),
      )
      
    • The my_create_item_args() function:

      function my_create_item_args() {
          return array(
              'user_from' => array(
                  'required'          => true,
                  'validate_callback' => function ( $param ) {
                      return is_numeric( $param );
                  },
              ),
              'message'   => array(
                  'required'          => true,
                  'sanitize_callback' => function ( $param ) {
                      // this allows basic HTML tags like <strong> and <em>
                      return wp_filter_kses( $param );
      
                      // this allows line breaks, but strips all HTML tags
      //              return sanitize_textarea_field( $param );
                  },
              ),
              // ... other args.
          );
      }
      
发布评论

评论列表(0)

  1. 暂无评论