WP REST API-通过REST API更新对现有数据库表的回调(POST请求)

时间:2022-02-25 作者:The Oracle

我已经注册了一个新的rest路由到现有的数据库表wpso\\U messages。我能够创建一个get\\u回调函数,从数据库中获取所有数据。

我想添加一个POST请求功能,它允许我通过rest api向wpso\\U消息表引入新的数据行。如何做到这一点,有什么建议吗?

下面是我注册rest路由和get\\u回调的代码:

<?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\'
        ) );
    } );
对于POST请求,下面是一个输入json的示例,用于在wpso\\U消息表中创建新条目:

{"user_from": "82", "user_to": "1", "message": "Iam interested to bid", "listing_id": "22775"}
基于Sally C.J答案的最终解决方案:请注意,它包括一些检查,例如用户ID是否有效以及json正文中的键值是否在SQL数据库列中。

#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\' );
    },)));
    });

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

我想添加一个POST请求功能,它允许我通过restapi向wpso\\U消息表中引入新的数据行。如何做到这一点,有什么建议吗?

是的,请注意,我是根据官方REST API handbook 以及核心端点。

所以从"Routes and Endpoints → Routes vs Endpoints" section — 请注意突出显示的第一部分:

路由是用于访问端点的“名称”,在URL中使用。A route can have multiple endpoints associated with it, 使用哪个取决于HTTP动词。

其中;HTTP动词;这里本质上是一个HTTP请求方法,如GET或POST。

例如,核心/wp/v2/posts 路由有两个端点-一个端点具有GET方法(用于检索帖子),另一个端点具有POST方法(用于创建帖子)。

因此,您可以遵循相同的方法,即将端点添加到;“消息”;路由,可能使用POST方法,如下所示:

// 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...
}
<执行新行/数据插入的实际代码将完全取决于您,但您希望使用wpdb::insert().

其他注意事项路由的命名空间由<vendor name>/<version>, 您应该使用自己的供应商名称,例如。my-plugin, 而不是wp. 所以my-plugin/v2 很好,但是wp/v2 不应使用。

因为"Routes and Endpoints → Namespaces" section 声明:

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

permission 为端点回调。

看见"Routes and Endpoints → Permissions Callback""Adding Custom Endpoints → Permissions Callback"E;有关更多详细信息,但对于打算公开的REST API路由,可以使用__return_true() 作为权限回调,即。\'permission_callback\' => \'__return_true\'.

您还需要使用args key, 并设置一个验证和清理回调,该回调将验证/清理参数。例如。

上述端点2的参数:

// 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(),
)
  • my_create_item_args() 功能:

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